diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2014-11-12 00:12:14 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-20 03:11:16 -0500 |
commit | ef1081cbf05b22d3d0e05b267a5559a8cd8e8d4a (patch) | |
tree | 327b642eab6b4d83d5cc268e78a1fb62bfa097ff /drivers/scsi | |
parent | f527590278f1b823ba979a234241d09ed2c436b4 (diff) |
atari_NCR5380: Refactor Falcon special cases
Make the atari_NCR5380.c core driver usable by sun3_scsi, mac_scsi and
others by moving some of the Falcon-specific code out of the core driver:
!IS_A_TT, atari_read_overruns and falcon_dont_release. Replace these with
hostdata variables and flags. FLAG_CHECK_LAST_BYTE_SENT is unused in
atari_NCR5380.c so don't set it.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/NCR5380.h | 4 | ||||
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 30 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.c | 21 |
3 files changed, 31 insertions, 24 deletions
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 11257784b2d7..7b1a0913d94c 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h | |||
@@ -241,6 +241,7 @@ | |||
241 | #define FLAG_NCR53C400 4 /* NCR53c400 */ | 241 | #define FLAG_NCR53C400 4 /* NCR53c400 */ |
242 | #define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */ | 242 | #define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */ |
243 | #define FLAG_DTC3181E 16 /* DTC3181E */ | 243 | #define FLAG_DTC3181E 16 /* DTC3181E */ |
244 | #define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */ | ||
244 | 245 | ||
245 | #ifndef ASM | 246 | #ifndef ASM |
246 | struct NCR5380_hostdata { | 247 | struct NCR5380_hostdata { |
@@ -269,6 +270,9 @@ struct NCR5380_hostdata { | |||
269 | struct delayed_work coroutine; /* our co-routine */ | 270 | struct delayed_work coroutine; /* our co-routine */ |
270 | struct scsi_eh_save ses; | 271 | struct scsi_eh_save ses; |
271 | char info[256]; | 272 | char info[256]; |
273 | int read_overruns; /* number of bytes to cut from a | ||
274 | * transfer to handle chip overruns */ | ||
275 | int retain_dma_intr; | ||
272 | #ifdef PSEUDO_DMA | 276 | #ifdef PSEUDO_DMA |
273 | unsigned spin_max_r; | 277 | unsigned spin_max_r; |
274 | unsigned spin_max_w; | 278 | unsigned spin_max_w; |
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 75d34031c280..371ca14f08ea 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -839,7 +839,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
839 | hostdata->connected = NULL; | 839 | hostdata->connected = NULL; |
840 | hostdata->issue_queue = NULL; | 840 | hostdata->issue_queue = NULL; |
841 | hostdata->disconnected_queue = NULL; | 841 | hostdata->disconnected_queue = NULL; |
842 | hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT; | 842 | hostdata->flags = flags; |
843 | 843 | ||
844 | if (!the_template) { | 844 | if (!the_template) { |
845 | the_template = instance->hostt; | 845 | the_template = instance->hostt; |
@@ -1054,7 +1054,7 @@ static void NCR5380_main(struct work_struct *work) | |||
1054 | hostdata->issue_queue = NEXT(tmp); | 1054 | hostdata->issue_queue = NEXT(tmp); |
1055 | } | 1055 | } |
1056 | SET_NEXT(tmp, NULL); | 1056 | SET_NEXT(tmp, NULL); |
1057 | falcon_dont_release++; | 1057 | hostdata->retain_dma_intr++; |
1058 | 1058 | ||
1059 | /* reenable interrupts after finding one */ | 1059 | /* reenable interrupts after finding one */ |
1060 | local_irq_restore(flags); | 1060 | local_irq_restore(flags); |
@@ -1082,7 +1082,7 @@ static void NCR5380_main(struct work_struct *work) | |||
1082 | cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE); | 1082 | cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE); |
1083 | #endif | 1083 | #endif |
1084 | if (!NCR5380_select(instance, tmp)) { | 1084 | if (!NCR5380_select(instance, tmp)) { |
1085 | falcon_dont_release--; | 1085 | hostdata->retain_dma_intr--; |
1086 | /* release if target did not response! */ | 1086 | /* release if target did not response! */ |
1087 | falcon_release_lock_if_possible(hostdata); | 1087 | falcon_release_lock_if_possible(hostdata); |
1088 | break; | 1088 | break; |
@@ -1094,7 +1094,7 @@ static void NCR5380_main(struct work_struct *work) | |||
1094 | #ifdef SUPPORT_TAGS | 1094 | #ifdef SUPPORT_TAGS |
1095 | cmd_free_tag(tmp); | 1095 | cmd_free_tag(tmp); |
1096 | #endif | 1096 | #endif |
1097 | falcon_dont_release--; | 1097 | hostdata->retain_dma_intr--; |
1098 | local_irq_restore(flags); | 1098 | local_irq_restore(flags); |
1099 | dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, " | 1099 | dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, " |
1100 | "returned to issue_queue\n", HOSTNO); | 1100 | "returned to issue_queue\n", HOSTNO); |
@@ -1151,7 +1151,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1151 | return; | 1151 | return; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | if (atari_read_overruns) { | 1154 | if (hostdata->read_overruns) { |
1155 | p = hostdata->connected->SCp.phase; | 1155 | p = hostdata->connected->SCp.phase; |
1156 | if (p & SR_IO) { | 1156 | if (p & SR_IO) { |
1157 | udelay(10); | 1157 | udelay(10); |
@@ -1181,9 +1181,9 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1181 | *data += transfered; | 1181 | *data += transfered; |
1182 | *count -= transfered; | 1182 | *count -= transfered; |
1183 | 1183 | ||
1184 | if (atari_read_overruns) { | 1184 | if (hostdata->read_overruns) { |
1185 | if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { | 1185 | if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { |
1186 | cnt = toPIO = atari_read_overruns; | 1186 | cnt = toPIO = hostdata->read_overruns; |
1187 | if (overrun) { | 1187 | if (overrun) { |
1188 | dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n"); | 1188 | dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n"); |
1189 | *(*data)++ = saved_data; | 1189 | *(*data)++ = saved_data; |
@@ -1838,8 +1838,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1838 | return -1; | 1838 | return -1; |
1839 | } | 1839 | } |
1840 | 1840 | ||
1841 | if (atari_read_overruns && (p & SR_IO)) | 1841 | if (hostdata->read_overruns && (p & SR_IO)) |
1842 | c -= atari_read_overruns; | 1842 | c -= hostdata->read_overruns; |
1843 | 1843 | ||
1844 | dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n", | 1844 | dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n", |
1845 | HOSTNO, (p & SR_IO) ? "reading" : "writing", | 1845 | HOSTNO, (p & SR_IO) ? "reading" : "writing", |
@@ -1851,7 +1851,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1851 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); | 1851 | NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); |
1852 | #endif /* def REAL_DMA */ | 1852 | #endif /* def REAL_DMA */ |
1853 | 1853 | ||
1854 | if (IS_A_TT()) { | 1854 | if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) { |
1855 | /* On the Medusa, it is a must to initialize the DMA before | 1855 | /* On the Medusa, it is a must to initialize the DMA before |
1856 | * starting the NCR. This is also the cleaner way for the TT. | 1856 | * starting the NCR. This is also the cleaner way for the TT. |
1857 | */ | 1857 | */ |
@@ -1869,7 +1869,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, | |||
1869 | NCR5380_write(START_DMA_SEND_REG, 0); | 1869 | NCR5380_write(START_DMA_SEND_REG, 0); |
1870 | } | 1870 | } |
1871 | 1871 | ||
1872 | if (!IS_A_TT()) { | 1872 | if (hostdata->flags & FLAG_LATE_DMA_SETUP) { |
1873 | /* On the Falcon, the DMA setup must be done after the last */ | 1873 | /* On the Falcon, the DMA setup must be done after the last */ |
1874 | /* NCR access, else the DMA setup gets trashed! | 1874 | /* NCR access, else the DMA setup gets trashed! |
1875 | */ | 1875 | */ |
@@ -2084,7 +2084,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2084 | /* Accept message by clearing ACK */ | 2084 | /* Accept message by clearing ACK */ |
2085 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 2085 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
2086 | /* ++guenther: possible race with Falcon locking */ | 2086 | /* ++guenther: possible race with Falcon locking */ |
2087 | falcon_dont_release++; | 2087 | hostdata->retain_dma_intr++; |
2088 | hostdata->connected = NULL; | 2088 | hostdata->connected = NULL; |
2089 | dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu " | 2089 | dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu " |
2090 | "completed\n", HOSTNO, cmd->device->id, cmd->device->lun); | 2090 | "completed\n", HOSTNO, cmd->device->id, cmd->device->lun); |
@@ -2167,7 +2167,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2167 | while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) | 2167 | while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) |
2168 | barrier(); | 2168 | barrier(); |
2169 | 2169 | ||
2170 | falcon_dont_release--; | 2170 | hostdata->retain_dma_intr--; |
2171 | /* ++roman: For Falcon SCSI, release the lock on the | 2171 | /* ++roman: For Falcon SCSI, release the lock on the |
2172 | * ST-DMA here if no other commands are waiting on the | 2172 | * ST-DMA here if no other commands are waiting on the |
2173 | * disconnected queue. | 2173 | * disconnected queue. |
@@ -2474,7 +2474,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2474 | #endif | 2474 | #endif |
2475 | ) { | 2475 | ) { |
2476 | /* ++guenther: prevent race with falcon_release_lock */ | 2476 | /* ++guenther: prevent race with falcon_release_lock */ |
2477 | falcon_dont_release++; | 2477 | hostdata->retain_dma_intr++; |
2478 | if (prev) { | 2478 | if (prev) { |
2479 | REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); | 2479 | REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); |
2480 | SET_NEXT(prev, NEXT(tmp)); | 2480 | SET_NEXT(prev, NEXT(tmp)); |
@@ -2512,7 +2512,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) | |||
2512 | hostdata->connected = tmp; | 2512 | hostdata->connected = tmp; |
2513 | dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n", | 2513 | dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n", |
2514 | HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag); | 2514 | HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag); |
2515 | falcon_dont_release--; | 2515 | hostdata->retain_dma_intr--; |
2516 | } | 2516 | } |
2517 | 2517 | ||
2518 | 2518 | ||
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 78324e056d4c..70c662f9fee4 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c | |||
@@ -196,8 +196,6 @@ static char *atari_dma_orig_addr; | |||
196 | /* mask for address bits that can't be used with the ST-DMA */ | 196 | /* mask for address bits that can't be used with the ST-DMA */ |
197 | static unsigned long atari_dma_stram_mask; | 197 | static unsigned long atari_dma_stram_mask; |
198 | #define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0) | 198 | #define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0) |
199 | /* number of bytes to cut from a transfer to handle NCR overruns */ | ||
200 | static int atari_read_overruns; | ||
201 | #endif | 199 | #endif |
202 | 200 | ||
203 | static int setup_can_queue = -1; | 201 | static int setup_can_queue = -1; |
@@ -446,8 +444,6 @@ static void atari_scsi_fetch_restbytes(void) | |||
446 | #endif /* REAL_DMA */ | 444 | #endif /* REAL_DMA */ |
447 | 445 | ||
448 | 446 | ||
449 | static int falcon_dont_release = 0; | ||
450 | |||
451 | /* This function releases the lock on the DMA chip if there is no | 447 | /* This function releases the lock on the DMA chip if there is no |
452 | * connected command and the disconnected queue is empty. | 448 | * connected command and the disconnected queue is empty. |
453 | */ | 449 | */ |
@@ -464,7 +460,7 @@ static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata) | |||
464 | if (!hostdata->disconnected_queue && | 460 | if (!hostdata->disconnected_queue && |
465 | !hostdata->issue_queue && | 461 | !hostdata->issue_queue && |
466 | !hostdata->connected && | 462 | !hostdata->connected && |
467 | !falcon_dont_release && | 463 | !hostdata->retain_dma_intr && |
468 | stdma_is_locked_by(scsi_falcon_intr)) | 464 | stdma_is_locked_by(scsi_falcon_intr)) |
469 | stdma_release(); | 465 | stdma_release(); |
470 | 466 | ||
@@ -846,6 +842,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev) | |||
846 | struct Scsi_Host *instance; | 842 | struct Scsi_Host *instance; |
847 | int error; | 843 | int error; |
848 | struct resource *irq; | 844 | struct resource *irq; |
845 | int host_flags = 0; | ||
849 | 846 | ||
850 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 847 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
851 | if (!irq) | 848 | if (!irq) |
@@ -942,7 +939,9 @@ static int __init atari_scsi_probe(struct platform_device *pdev) | |||
942 | 939 | ||
943 | instance->irq = irq->start; | 940 | instance->irq = irq->start; |
944 | 941 | ||
945 | NCR5380_init(instance, 0); | 942 | host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP; |
943 | |||
944 | NCR5380_init(instance, host_flags); | ||
946 | 945 | ||
947 | if (IS_A_TT()) { | 946 | if (IS_A_TT()) { |
948 | error = request_irq(instance->irq, scsi_tt_intr, 0, | 947 | error = request_irq(instance->irq, scsi_tt_intr, 0, |
@@ -965,12 +964,16 @@ static int __init atari_scsi_probe(struct platform_device *pdev) | |||
965 | * | 964 | * |
966 | * In principle it should be sufficient to do max. 1 byte with | 965 | * In principle it should be sufficient to do max. 1 byte with |
967 | * PIO, but there is another problem on the Medusa with the DMA | 966 | * PIO, but there is another problem on the Medusa with the DMA |
968 | * rest data register. So 'atari_read_overruns' is currently set | 967 | * rest data register. So read_overruns is currently set |
969 | * to 4 to avoid having transfers that aren't a multiple of 4. | 968 | * to 4 to avoid having transfers that aren't a multiple of 4. |
970 | * If the rest data bug is fixed, this can be lowered to 1. | 969 | * If the rest data bug is fixed, this can be lowered to 1. |
971 | */ | 970 | */ |
972 | if (MACH_IS_MEDUSA) | 971 | if (MACH_IS_MEDUSA) { |
973 | atari_read_overruns = 4; | 972 | struct NCR5380_hostdata *hostdata = |
973 | shost_priv(instance); | ||
974 | |||
975 | hostdata->read_overruns = 4; | ||
976 | } | ||
974 | #endif | 977 | #endif |
975 | } else { | 978 | } else { |
976 | /* Nothing to do for the interrupt: the ST-DMA is initialized | 979 | /* Nothing to do for the interrupt: the ST-DMA is initialized |