On Mon, 15 Oct 2018, Hannes Reinecke wrote:

> On 10/14/18 8:12 AM, Finn Thain wrote:
> > As a temporary measure, the code to implement PIO transfers was
> > duplicated in zorro_esp and mac_esp. Now that it has stabilized
> > move the common code into the core driver but don't build it unless
> > needed.
> > 
> > This replaces the inline assembler with more portable writesb() calls.
> > Optimizing the m68k writesb() implementation is a separate patch.
> > 
> > Tested-by: Stan Johnson <user...@yahoo.com>
> > Signed-off-by: Finn Thain <fth...@telegraphics.com.au>
> > Tested-by: Michael Schmitz <schmitz...@gmail.com>
> > ---
> > Changed since v1:
> >   - Use shost_printk() instead of pr_err().
> >   - Add new symbol CONFIG_SCSI_ESP_PIO to Kconfig.
> > ---
> >   drivers/scsi/Kconfig     |   6 +
> >   drivers/scsi/esp_scsi.c  | 128 +++++++++++++++++++++
> >   drivers/scsi/esp_scsi.h  |   5 +
> >   drivers/scsi/mac_esp.c   | 173 +----------------------------
> >   drivers/scsi/zorro_esp.c | 232 ++++++---------------------------------
> >   5 files changed, 179 insertions(+), 365 deletions(-)
> > 
> > diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
> > index 35c909bbf8ba..81c6872f24f8 100644
> > --- a/drivers/scsi/Kconfig
> > +++ b/drivers/scsi/Kconfig
> > @@ -42,6 +42,10 @@ config SCSI_DMA
> >     bool
> >     default n
> >   +config SCSI_ESP_PIO
> > +   bool
> > +   default n
> > +
> >   config SCSI_NETLINK
> >     bool
> >     default n
> > @@ -1355,6 +1359,7 @@ config SCSI_ZORRO_ESP
> >     tristate "Zorro ESP SCSI support"
> >     depends on ZORRO && SCSI
> >     select SCSI_SPI_ATTRS
> > +   select SCSI_ESP_PIO
> >     help
> >       Support for various NCR53C9x (ESP) based SCSI controllers on Zorro
> >       expansion boards for the Amiga.
> > @@ -1397,6 +1402,7 @@ config SCSI_MAC_ESP
> >     tristate "Macintosh NCR53c9[46] SCSI"
> >     depends on MAC && SCSI
> >     select SCSI_SPI_ATTRS
> > +   select SCSI_ESP_PIO
> >     help
> >       This is the NCR 53c9x SCSI controller found on most of the 68040
> >       based Macintoshes.
> > diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
> > index 6ccaf818357e..305a322ad13c 100644
> > --- a/drivers/scsi/esp_scsi.c
> > +++ b/drivers/scsi/esp_scsi.c
> > @@ -2776,3 +2776,131 @@ MODULE_PARM_DESC(esp_debug,
> >     module_init(esp_init);
> >   module_exit(esp_exit);
> > +
> > +#ifdef CONFIG_SCSI_ESP_PIO
> > +static inline unsigned int esp_wait_for_fifo(struct esp *esp)
> > +{
> > +   int i = 500000;
> > +
> > +   do {
> > +           unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
> > +
> > +           if (fbytes)
> > +                   return fbytes;
> > +
> > +           udelay(2);
> > +   } while (--i);
> > +
> > +   shost_printk(KERN_ERR, esp->host, "FIFO is empty (sreg %02x)\n",
> > +                esp_read8(ESP_STATUS));
> > +   return 0;
> > +}
> > +
> > +static inline int esp_wait_for_intr(struct esp *esp)
> > +{
> > +   int i = 500000;
> > +
> > +   do {
> > +           esp->sreg = esp_read8(ESP_STATUS);
> > +           if (esp->sreg & ESP_STAT_INTR)
> > +                   return 0;
> > +
> > +           udelay(2);
> > +   } while (--i);
> > +
> > +   shost_printk(KERN_ERR, esp->host, "IRQ timeout (sreg %02x)\n",
> > +                esp->sreg);
> > +   return 1;
> > +}
> > +
> > +#define ESP_FIFO_SIZE 16
> > +
> > +void esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
> > +                 u32 dma_count, int write, u8 cmd)
> > +{
> > +   u8 phase = esp->sreg & ESP_STAT_PMASK;
> > +
> > +   cmd &= ~ESP_CMD_DMA;
> > +   esp->send_cmd_error = 0;
> > +
> > +   if (write) {
> > +           u8 *dst = (u8 *)addr;
> > +           u8 mask = ~(phase == ESP_MIP ? ESP_INTR_FDONE :
> > ESP_INTR_BSERV);
> > +
> > +           scsi_esp_cmd(esp, cmd);
> > +
> > +           while (1) {
> > +                   if (!esp_wait_for_fifo(esp))
> > +                           break;
> > +
> > +                   *dst++ = esp_read8(ESP_FDATA);
> > +                   --esp_count;
> > +
> > +                   if (!esp_count)
> > +                           break;
> > +
> > +                   if (esp_wait_for_intr(esp)) {
> > +                           esp->send_cmd_error = 1;
> > +                           break;
> > +                   }
> > +
> > +                   if ((esp->sreg & ESP_STAT_PMASK) != phase)
> > +                           break;
> > +
> > +                   esp->ireg = esp_read8(ESP_INTRPT);
> > +                   if (esp->ireg & mask) {
> > +                           esp->send_cmd_error = 1;
> > +                           break;
> > +                   }
> > +
> > +                   if (phase == ESP_MIP)
> > +                           scsi_esp_cmd(esp, ESP_CMD_MOK);
> > +
> > +                   scsi_esp_cmd(esp, ESP_CMD_TI);
> > +           }
> > +   } else {
> > +           unsigned int n = ESP_FIFO_SIZE;
> > +           u8 *src = (u8 *)addr;
> > +
> > +           scsi_esp_cmd(esp, ESP_CMD_FLUSH);
> > +
> > +           if (n > esp_count)
> > +                   n = esp_count;
> > +           writesb(esp->fifo_reg, src, n);
> > +           src += n;
> > +           esp_count -= n;
> > +
> > +           scsi_esp_cmd(esp, cmd);
> > +
> > +           while (esp_count) {
> > +                   if (esp_wait_for_intr(esp)) {
> > +                           esp->send_cmd_error = 1;
> > +                           break;
> > +                   }
> > +
> > +                   if ((esp->sreg & ESP_STAT_PMASK) != phase)
> > +                           break;
> > +
> > +                   esp->ireg = esp_read8(ESP_INTRPT);
> > +                   if (esp->ireg & ~ESP_INTR_BSERV) {
> > +                           esp->send_cmd_error = 1;
> > +                           break;
> > +                   }
> > +
> > +                   n = ESP_FIFO_SIZE -
> > +                       (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);
> > +
> > +                   if (n > esp_count)
> > +                           n = esp_count;
> > +                   writesb(esp->fifo_reg, src, n);
> > +                   src += n;
> > +                   esp_count -= n;
> > +
> > +                   scsi_esp_cmd(esp, ESP_CMD_TI);
> > +           }
> > +   }
> > +
> > +   esp->send_cmd_residual = esp_count;
> > +}
> > +EXPORT_SYMBOL(esp_send_pio_cmd);
> > +#endif
> > diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h
> > index d0c032803749..2590e5eda595 100644
> > --- a/drivers/scsi/esp_scsi.h
> > +++ b/drivers/scsi/esp_scsi.h
> > @@ -431,6 +431,7 @@ struct esp_driver_ops {
> >   struct esp {
> >     void __iomem            *regs;
> >     void __iomem            *dma_regs;
> > +   u8 __iomem              *fifo_reg;
> >             const struct esp_driver_ops *ops;
> >   @@ -540,6 +541,7 @@ struct esp {
> >     void                    *dma;
> >     int                     dmarev;
> >   + int                     send_cmd_error;
> >     int                     send_cmd_residual;
> >   };
> >   
> These variables are only used within esp_send_pio_cmd(); consider making them
> conditional based on the config option.
> 

In the case of send_cmd_residual, that would mean a second #ifdef added to 
esp_data_bytes_sent() where it gets used. I'm happy to comply but I fear 
that all these #ifdefs may harm readability...

There are already other variables in struct esp that may go unused, such 
as dma_regs, that don't have #ifdefs to elide them. Are these also 
problematic in some way?

Thanks for your review.

-- 

> > @@ -581,4 +583,7 @@ extern void scsi_esp_unregister(struct esp *);
> >   extern irqreturn_t scsi_esp_intr(int, void *);
> >   extern void scsi_esp_cmd(struct esp *, u8);
> >   +extern void esp_send_pio_cmd(struct esp *esp, u32 dma_addr, u32
> > esp_count,
> > +                        u32 dma_count, int write, u8 cmd);
> > +
> >   #endif /* !(_ESP_SCSI_H) */
> Same here; the declaration only makes sense when the config option is set.
> 
> Cheers,
> 
> Hannes
> 

Reply via email to