Re: [PATCH 10/22] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
On 03/14/2016 05:27 AM, Finn Thain wrote: > Adopt the DMA implementation from atari_NCR5380.c. This means that > atari_scsi and sun3_scsi can make use of the NCR5380.c core driver > and the atari_NCR5380.c driver fork can be made redundant. > > Signed-off-by: Finn Thain> > --- > drivers/scsi/NCR5380.c | 170 > +++- > drivers/scsi/arm/cumana_1.c |3 > drivers/scsi/arm/oak.c |3 > drivers/scsi/dmx3191d.c |1 > drivers/scsi/dtc.c |2 > drivers/scsi/dtc.h |1 > drivers/scsi/g_NCR5380.c|2 > drivers/scsi/g_NCR5380.h|1 > drivers/scsi/mac_scsi.c |3 > drivers/scsi/pas16.c|2 > drivers/scsi/pas16.h|1 > drivers/scsi/t128.c |2 > drivers/scsi/t128.h |1 > 13 files changed, 152 insertions(+), 40 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
Re: [PATCH 10/22] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
On 03/14/2016 05:27 AM, Finn Thain wrote: > Adopt the DMA implementation from atari_NCR5380.c. This means that > atari_scsi and sun3_scsi can make use of the NCR5380.c core driver > and the atari_NCR5380.c driver fork can be made redundant. > > Signed-off-by: Finn Thain > > --- > drivers/scsi/NCR5380.c | 170 > +++- > drivers/scsi/arm/cumana_1.c |3 > drivers/scsi/arm/oak.c |3 > drivers/scsi/dmx3191d.c |1 > drivers/scsi/dtc.c |2 > drivers/scsi/dtc.h |1 > drivers/scsi/g_NCR5380.c|2 > drivers/scsi/g_NCR5380.h|1 > drivers/scsi/mac_scsi.c |3 > drivers/scsi/pas16.c|2 > drivers/scsi/pas16.h|1 > drivers/scsi/t128.c |2 > drivers/scsi/t128.h |1 > 13 files changed, 152 insertions(+), 40 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg)
[PATCH 10/22] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
Adopt the DMA implementation from atari_NCR5380.c. This means that atari_scsi and sun3_scsi can make use of the NCR5380.c core driver and the atari_NCR5380.c driver fork can be made redundant. Signed-off-by: Finn Thain--- drivers/scsi/NCR5380.c | 170 +++- drivers/scsi/arm/cumana_1.c |3 drivers/scsi/arm/oak.c |3 drivers/scsi/dmx3191d.c |1 drivers/scsi/dtc.c |2 drivers/scsi/dtc.h |1 drivers/scsi/g_NCR5380.c|2 drivers/scsi/g_NCR5380.h|1 drivers/scsi/mac_scsi.c |3 drivers/scsi/pas16.c|2 drivers/scsi/pas16.h|1 drivers/scsi/t128.c |2 drivers/scsi/t128.h |1 13 files changed, 152 insertions(+), 40 deletions(-) Index: linux/drivers/scsi/NCR5380.c === --- linux.orig/drivers/scsi/NCR5380.c 2016-03-14 15:26:37.0 +1100 +++ linux/drivers/scsi/NCR5380.c2016-03-14 15:26:39.0 +1100 @@ -31,9 +31,6 @@ /* * Further development / testing that should be done : - * 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete - * code so that everything does the same thing that's done at the - * end of a pseudo-DMA read operation. * * 4. Test SCSI-II tagged queueing (I have no devices which support * tagged queueing) @@ -117,6 +114,8 @@ * * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases. * + * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. + * * These macros MUST be defined : * * NCR5380_read(register) - read from the specified register @@ -801,6 +800,72 @@ static void NCR5380_main(struct work_str } while (!done); } +/* + * NCR5380_dma_complete - finish DMA transfer + * @instance: the scsi host instance + * + * Called by the interrupt handler when DMA finishes or a phase + * mismatch occurs (which would end the DMA transfer). + */ + +static void NCR5380_dma_complete(struct Scsi_Host *instance) +{ + struct NCR5380_hostdata *hostdata = shost_priv(instance); + int transferred; + unsigned char **data; + int *count; + int saved_data = 0, overrun = 0; + unsigned char p; + + if (hostdata->read_overruns) { + p = hostdata->connected->SCp.phase; + if (p & SR_IO) { + udelay(10); + if ((NCR5380_read(BUS_AND_STATUS_REG) & +(BASR_PHASE_MATCH | BASR_ACK)) == + (BASR_PHASE_MATCH | BASR_ACK)) { + saved_data = NCR5380_read(INPUT_DATA_REG); + overrun = 1; + dsprintk(NDEBUG_DMA, instance, "read overrun handled\n"); + } + } + } + + NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + NCR5380_read(RESET_PARITY_INTERRUPT_REG); + + transferred = hostdata->dma_len - NCR5380_dma_residual(instance); + hostdata->dma_len = 0; + + data = (unsigned char **)>connected->SCp.ptr; + count = >connected->SCp.this_residual; + *data += transferred; + *count -= transferred; + + if (hostdata->read_overruns) { + int cnt, toPIO; + + if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { + cnt = toPIO = hostdata->read_overruns; + if (overrun) { + dsprintk(NDEBUG_DMA, instance, +"Got an input overrun, using saved byte\n"); + *(*data)++ = saved_data; + (*count)--; + cnt--; + toPIO--; + } + if (toPIO > 0) { + dsprintk(NDEBUG_DMA, instance, +"Doing %d byte PIO to 0x%p\n", cnt, *data); + NCR5380_transfer_pio(instance, , , data); + *count -= toPIO - cnt; + } + } + } +} + #ifndef DONT_USE_INTR /** @@ -855,7 +920,22 @@ static irqreturn_t NCR5380_intr(int irq, dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n", irq, basr, sr, mr); - if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) && + if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) { + /* Probably End of DMA, Phase Mismatch or Loss of BSY. +* We ack IRQ after clearing Mode Register. Workarounds +* for End of DMA errata need to happen in DMA Mode. +
[PATCH 10/22] ncr5380: Merge DMA implementation from atari_NCR5380 core driver
Adopt the DMA implementation from atari_NCR5380.c. This means that atari_scsi and sun3_scsi can make use of the NCR5380.c core driver and the atari_NCR5380.c driver fork can be made redundant. Signed-off-by: Finn Thain --- drivers/scsi/NCR5380.c | 170 +++- drivers/scsi/arm/cumana_1.c |3 drivers/scsi/arm/oak.c |3 drivers/scsi/dmx3191d.c |1 drivers/scsi/dtc.c |2 drivers/scsi/dtc.h |1 drivers/scsi/g_NCR5380.c|2 drivers/scsi/g_NCR5380.h|1 drivers/scsi/mac_scsi.c |3 drivers/scsi/pas16.c|2 drivers/scsi/pas16.h|1 drivers/scsi/t128.c |2 drivers/scsi/t128.h |1 13 files changed, 152 insertions(+), 40 deletions(-) Index: linux/drivers/scsi/NCR5380.c === --- linux.orig/drivers/scsi/NCR5380.c 2016-03-14 15:26:37.0 +1100 +++ linux/drivers/scsi/NCR5380.c2016-03-14 15:26:39.0 +1100 @@ -31,9 +31,6 @@ /* * Further development / testing that should be done : - * 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete - * code so that everything does the same thing that's done at the - * end of a pseudo-DMA read operation. * * 4. Test SCSI-II tagged queueing (I have no devices which support * tagged queueing) @@ -117,6 +114,8 @@ * * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases. * + * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. + * * These macros MUST be defined : * * NCR5380_read(register) - read from the specified register @@ -801,6 +800,72 @@ static void NCR5380_main(struct work_str } while (!done); } +/* + * NCR5380_dma_complete - finish DMA transfer + * @instance: the scsi host instance + * + * Called by the interrupt handler when DMA finishes or a phase + * mismatch occurs (which would end the DMA transfer). + */ + +static void NCR5380_dma_complete(struct Scsi_Host *instance) +{ + struct NCR5380_hostdata *hostdata = shost_priv(instance); + int transferred; + unsigned char **data; + int *count; + int saved_data = 0, overrun = 0; + unsigned char p; + + if (hostdata->read_overruns) { + p = hostdata->connected->SCp.phase; + if (p & SR_IO) { + udelay(10); + if ((NCR5380_read(BUS_AND_STATUS_REG) & +(BASR_PHASE_MATCH | BASR_ACK)) == + (BASR_PHASE_MATCH | BASR_ACK)) { + saved_data = NCR5380_read(INPUT_DATA_REG); + overrun = 1; + dsprintk(NDEBUG_DMA, instance, "read overrun handled\n"); + } + } + } + + NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + NCR5380_read(RESET_PARITY_INTERRUPT_REG); + + transferred = hostdata->dma_len - NCR5380_dma_residual(instance); + hostdata->dma_len = 0; + + data = (unsigned char **)>connected->SCp.ptr; + count = >connected->SCp.this_residual; + *data += transferred; + *count -= transferred; + + if (hostdata->read_overruns) { + int cnt, toPIO; + + if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { + cnt = toPIO = hostdata->read_overruns; + if (overrun) { + dsprintk(NDEBUG_DMA, instance, +"Got an input overrun, using saved byte\n"); + *(*data)++ = saved_data; + (*count)--; + cnt--; + toPIO--; + } + if (toPIO > 0) { + dsprintk(NDEBUG_DMA, instance, +"Doing %d byte PIO to 0x%p\n", cnt, *data); + NCR5380_transfer_pio(instance, , , data); + *count -= toPIO - cnt; + } + } + } +} + #ifndef DONT_USE_INTR /** @@ -855,7 +920,22 @@ static irqreturn_t NCR5380_intr(int irq, dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n", irq, basr, sr, mr); - if ((NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_mask) && + if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) { + /* Probably End of DMA, Phase Mismatch or Loss of BSY. +* We ack IRQ after clearing Mode Register. Workarounds +* for End of DMA errata need to happen in DMA Mode. +*/ + +