Re: [PATCH v2 5/6] esp_scsi: De-duplicate PIO routines

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <userm57@xxxxxxxxx>
> > Signed-off-by: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>
> > Tested-by: Michael Schmitz <schmitzmic@xxxxxxxxx>
> > ---
> > 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
> 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux