Skip to content

Commit 53dce33

Browse files
Finn Thainmartinkpetersen
authored andcommitted
scsi: esp_scsi: De-duplicate PIO routines
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. [mkp: applied by hand] Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Tested-by: Stan Johnson <userm57@yahoo.com> Tested-by: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 8bca214 commit 53dce33

File tree

5 files changed

+179
-365
lines changed

5 files changed

+179
-365
lines changed

drivers/scsi/Kconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ config SCSI_DMA
4242
bool
4343
default n
4444

45+
config SCSI_ESP_PIO
46+
bool
47+
4548
config SCSI_NETLINK
4649
bool
4750
default n
@@ -1362,6 +1365,7 @@ config SCSI_ZORRO_ESP
13621365
tristate "Zorro ESP SCSI support"
13631366
depends on ZORRO && SCSI
13641367
select SCSI_SPI_ATTRS
1368+
select SCSI_ESP_PIO
13651369
help
13661370
Support for various NCR53C9x (ESP) based SCSI controllers on Zorro
13671371
expansion boards for the Amiga.
@@ -1404,6 +1408,7 @@ config SCSI_MAC_ESP
14041408
tristate "Macintosh NCR53c9[46] SCSI"
14051409
depends on MAC && SCSI
14061410
select SCSI_SPI_ATTRS
1411+
select SCSI_ESP_PIO
14071412
help
14081413
This is the NCR 53c9x SCSI controller found on most of the 68040
14091414
based Macintoshes.

drivers/scsi/esp_scsi.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,3 +2782,131 @@ MODULE_PARM_DESC(esp_debug,
27822782

27832783
module_init(esp_init);
27842784
module_exit(esp_exit);
2785+
2786+
#ifdef CONFIG_SCSI_ESP_PIO
2787+
static inline unsigned int esp_wait_for_fifo(struct esp *esp)
2788+
{
2789+
int i = 500000;
2790+
2791+
do {
2792+
unsigned int fbytes = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;
2793+
2794+
if (fbytes)
2795+
return fbytes;
2796+
2797+
udelay(2);
2798+
} while (--i);
2799+
2800+
shost_printk(KERN_ERR, esp->host, "FIFO is empty. sreg [%02x]\n",
2801+
esp_read8(ESP_STATUS));
2802+
return 0;
2803+
}
2804+
2805+
static inline int esp_wait_for_intr(struct esp *esp)
2806+
{
2807+
int i = 500000;
2808+
2809+
do {
2810+
esp->sreg = esp_read8(ESP_STATUS);
2811+
if (esp->sreg & ESP_STAT_INTR)
2812+
return 0;
2813+
2814+
udelay(2);
2815+
} while (--i);
2816+
2817+
shost_printk(KERN_ERR, esp->host, "IRQ timeout. sreg [%02x]\n",
2818+
esp->sreg);
2819+
return 1;
2820+
}
2821+
2822+
#define ESP_FIFO_SIZE 16
2823+
2824+
void esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
2825+
u32 dma_count, int write, u8 cmd)
2826+
{
2827+
u8 phase = esp->sreg & ESP_STAT_PMASK;
2828+
2829+
cmd &= ~ESP_CMD_DMA;
2830+
esp->send_cmd_error = 0;
2831+
2832+
if (write) {
2833+
u8 *dst = (u8 *)addr;
2834+
u8 mask = ~(phase == ESP_MIP ? ESP_INTR_FDONE : ESP_INTR_BSERV);
2835+
2836+
scsi_esp_cmd(esp, cmd);
2837+
2838+
while (1) {
2839+
if (!esp_wait_for_fifo(esp))
2840+
break;
2841+
2842+
*dst++ = esp_read8(ESP_FDATA);
2843+
--esp_count;
2844+
2845+
if (!esp_count)
2846+
break;
2847+
2848+
if (esp_wait_for_intr(esp)) {
2849+
esp->send_cmd_error = 1;
2850+
break;
2851+
}
2852+
2853+
if ((esp->sreg & ESP_STAT_PMASK) != phase)
2854+
break;
2855+
2856+
esp->ireg = esp_read8(ESP_INTRPT);
2857+
if (esp->ireg & mask) {
2858+
esp->send_cmd_error = 1;
2859+
break;
2860+
}
2861+
2862+
if (phase == ESP_MIP)
2863+
scsi_esp_cmd(esp, ESP_CMD_MOK);
2864+
2865+
scsi_esp_cmd(esp, ESP_CMD_TI);
2866+
}
2867+
} else {
2868+
unsigned int n = ESP_FIFO_SIZE;
2869+
u8 *src = (u8 *)addr;
2870+
2871+
scsi_esp_cmd(esp, ESP_CMD_FLUSH);
2872+
2873+
if (n > esp_count)
2874+
n = esp_count;
2875+
writesb(esp->fifo_reg, src, n);
2876+
src += n;
2877+
esp_count -= n;
2878+
2879+
scsi_esp_cmd(esp, cmd);
2880+
2881+
while (esp_count) {
2882+
if (esp_wait_for_intr(esp)) {
2883+
esp->send_cmd_error = 1;
2884+
break;
2885+
}
2886+
2887+
if ((esp->sreg & ESP_STAT_PMASK) != phase)
2888+
break;
2889+
2890+
esp->ireg = esp_read8(ESP_INTRPT);
2891+
if (esp->ireg & ~ESP_INTR_BSERV) {
2892+
esp->send_cmd_error = 1;
2893+
break;
2894+
}
2895+
2896+
n = ESP_FIFO_SIZE -
2897+
(esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);
2898+
2899+
if (n > esp_count)
2900+
n = esp_count;
2901+
writesb(esp->fifo_reg, src, n);
2902+
src += n;
2903+
esp_count -= n;
2904+
2905+
scsi_esp_cmd(esp, ESP_CMD_TI);
2906+
}
2907+
}
2908+
2909+
esp->send_cmd_residual = esp_count;
2910+
}
2911+
EXPORT_SYMBOL(esp_send_pio_cmd);
2912+
#endif

drivers/scsi/esp_scsi.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,9 @@ struct esp {
524524
void *dma;
525525
int dmarev;
526526

527+
/* These are used by esp_send_pio_cmd() */
528+
u8 __iomem *fifo_reg;
529+
int send_cmd_error;
527530
u32 send_cmd_residual;
528531
};
529532

@@ -564,4 +567,7 @@ extern void scsi_esp_unregister(struct esp *);
564567
extern irqreturn_t scsi_esp_intr(int, void *);
565568
extern void scsi_esp_cmd(struct esp *, u8);
566569

570+
extern void esp_send_pio_cmd(struct esp *esp, u32 dma_addr, u32 esp_count,
571+
u32 dma_count, int write, u8 cmd);
572+
567573
#endif /* !(_ESP_SCSI_H) */

0 commit comments

Comments
 (0)