| From foo@baz Sat Nov 10 11:24:34 PST 2018 |
| From: Finn Thain <fthain@telegraphics.com.au> |
| Date: Tue, 16 Oct 2018 16:31:25 +1100 |
| Subject: scsi: esp_scsi: Track residual for PIO transfers |
| |
| From: Finn Thain <fthain@telegraphics.com.au> |
| |
| [ Upstream commit fd47d919d0c336e7c22862b51ee94927ffea227a ] |
| |
| 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. |
| That 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. |
| |
| 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> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/scsi/esp_scsi.c | 1 + |
| drivers/scsi/esp_scsi.h | 2 ++ |
| drivers/scsi/mac_esp.c | 2 ++ |
| 3 files changed, 5 insertions(+) |
| |
| --- a/drivers/scsi/esp_scsi.c |
| +++ b/drivers/scsi/esp_scsi.c |
| @@ -1349,6 +1349,7 @@ static int esp_data_bytes_sent(struct es |
| |
| bytes_sent = esp->data_dma_len; |
| bytes_sent -= ecount; |
| + bytes_sent -= esp->send_cmd_residual; |
| |
| /* |
| * The am53c974 has a DMA 'pecularity'. The doc states: |
| --- a/drivers/scsi/esp_scsi.h |
| +++ b/drivers/scsi/esp_scsi.h |
| @@ -540,6 +540,8 @@ struct esp { |
| |
| void *dma; |
| int dmarev; |
| + |
| + u32 send_cmd_residual; |
| }; |
| |
| /* A front-end driver for the ESP chip should do the following in |
| --- a/drivers/scsi/mac_esp.c |
| +++ b/drivers/scsi/mac_esp.c |
| @@ -426,6 +426,8 @@ static void mac_esp_send_pio_cmd(struct |
| scsi_esp_cmd(esp, ESP_CMD_TI); |
| } |
| } |
| + |
| + esp->send_cmd_residual = esp_count; |
| } |
| |
| static int mac_esp_irq_pending(struct esp *esp) |