Message ID | 11a3a80e74a006040460fa051747e6a79c6382ce.1539497520.git.fthain@telegraphics.com.au (mailing list archive) |
---|---|
State | Changes Requested |
Headers | show |
Series | mac_esp, zorro_esp, esp_scsi: Various improvements | expand |
Hi Finn, On Sun, Oct 14, 2018 at 8:36 AM Finn Thain <fthain@telegraphics.com.au> wrote: > If a target disconnects during a PIO data transfer the command may > fail when the target reconnects: > > scsi host1: DMA length is zero! > scsi host1: cur adr[04380000] len[00000000] > > The scsi bus is then reset. This happens because the residual reached > zero before the transfer was completed. > > The usual residual calculation relies on the Transfer Count registers > which works for DMA transfers but not for PIO transfers. Fix the problem > by storing the PIO transfer residual and using that to correctly > calculate bytes_sent. Thanks for yur patch! > Fixes: 6fe07aaffbf0 Fixes: 6fe07aaffbf0 ("[SCSI] m68k: new mac_esp scsi driver") > Tested-by: Stan Johnson <userm57@yahoo.com> > Signed-off-by: Finn Thain <fthain@telegraphics.com.au> > Tested-by: Michael Schmitz <schmitzmic@gmail.com> > --- a/drivers/scsi/esp_scsi.h > +++ b/drivers/scsi/esp_scsi.h > @@ -540,6 +540,8 @@ struct esp { > > void *dma; > int dmarev; > + > + int send_cmd_residual; unsigned int? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On Sun, 14 Oct 2018, Geert Uytterhoeven wrote: > > > Fixes: 6fe07aaffbf0 > > Fixes: 6fe07aaffbf0 ("[SCSI] m68k: new mac_esp scsi driver") > Fixed. > > Tested-by: Stan Johnson <userm57@yahoo.com> > > Signed-off-by: Finn Thain <fthain@telegraphics.com.au> > > Tested-by: Michael Schmitz <schmitzmic@gmail.com> > > > --- a/drivers/scsi/esp_scsi.h > > +++ b/drivers/scsi/esp_scsi.h > > @@ -540,6 +540,8 @@ struct esp { > > > > void *dma; > > int dmarev; > > + > > + int send_cmd_residual; > > unsigned int? > My first thought was to use u32, same as esp_count. But it turns out that the end result really is an int -- static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent, struct scsi_cmnd *cmd) { int fifo_cnt, ecount, bytes_sent, flush_fifo; ... bytes_sent = esp->data_dma_len; bytes_sent -= ecount; bytes_sent -= esp->send_cmd_residual; ... return bytes_sent; } Apparently over/underflow is a real possibility, because there is a test for this in esp_process_event().
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index c3fc34b9964d..9e5d3f7d29ae 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -1338,6 +1338,7 @@ static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent, bytes_sent = esp->data_dma_len; bytes_sent -= ecount; + bytes_sent -= esp->send_cmd_residual; /* * The am53c974 has a DMA 'pecularity'. The doc states: diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index 8163dca2071b..db4b6ea94caa 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -540,6 +540,8 @@ struct esp { void *dma; int dmarev; + + int send_cmd_residual; }; /* A front-end driver for the ESP chip should do the following in diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index eb551f3cc471..71879f2207e0 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -427,6 +427,8 @@ static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count, scsi_esp_cmd(esp, ESP_CMD_TI); } } + + esp->send_cmd_residual = esp_count; } static int mac_esp_irq_pending(struct esp *esp)