Commit ef1081cb authored by Finn Thain's avatar Finn Thain Committed by Christoph Hellwig

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: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent f5275902
...@@ -241,6 +241,7 @@ ...@@ -241,6 +241,7 @@
#define FLAG_NCR53C400 4 /* NCR53c400 */ #define FLAG_NCR53C400 4 /* NCR53c400 */
#define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */ #define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */
#define FLAG_DTC3181E 16 /* DTC3181E */ #define FLAG_DTC3181E 16 /* DTC3181E */
#define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */
#ifndef ASM #ifndef ASM
struct NCR5380_hostdata { struct NCR5380_hostdata {
...@@ -269,6 +270,9 @@ struct NCR5380_hostdata { ...@@ -269,6 +270,9 @@ struct NCR5380_hostdata {
struct delayed_work coroutine; /* our co-routine */ struct delayed_work coroutine; /* our co-routine */
struct scsi_eh_save ses; struct scsi_eh_save ses;
char info[256]; char info[256];
int read_overruns; /* number of bytes to cut from a
* transfer to handle chip overruns */
int retain_dma_intr;
#ifdef PSEUDO_DMA #ifdef PSEUDO_DMA
unsigned spin_max_r; unsigned spin_max_r;
unsigned spin_max_w; unsigned spin_max_w;
......
...@@ -839,7 +839,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) ...@@ -839,7 +839,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->issue_queue = NULL; hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL; hostdata->disconnected_queue = NULL;
hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT; hostdata->flags = flags;
if (!the_template) { if (!the_template) {
the_template = instance->hostt; the_template = instance->hostt;
...@@ -1054,7 +1054,7 @@ static void NCR5380_main(struct work_struct *work) ...@@ -1054,7 +1054,7 @@ static void NCR5380_main(struct work_struct *work)
hostdata->issue_queue = NEXT(tmp); hostdata->issue_queue = NEXT(tmp);
} }
SET_NEXT(tmp, NULL); SET_NEXT(tmp, NULL);
falcon_dont_release++; hostdata->retain_dma_intr++;
/* reenable interrupts after finding one */ /* reenable interrupts after finding one */
local_irq_restore(flags); local_irq_restore(flags);
...@@ -1082,7 +1082,7 @@ static void NCR5380_main(struct work_struct *work) ...@@ -1082,7 +1082,7 @@ static void NCR5380_main(struct work_struct *work)
cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE); cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE);
#endif #endif
if (!NCR5380_select(instance, tmp)) { if (!NCR5380_select(instance, tmp)) {
falcon_dont_release--; hostdata->retain_dma_intr--;
/* release if target did not response! */ /* release if target did not response! */
falcon_release_lock_if_possible(hostdata); falcon_release_lock_if_possible(hostdata);
break; break;
...@@ -1094,7 +1094,7 @@ static void NCR5380_main(struct work_struct *work) ...@@ -1094,7 +1094,7 @@ static void NCR5380_main(struct work_struct *work)
#ifdef SUPPORT_TAGS #ifdef SUPPORT_TAGS
cmd_free_tag(tmp); cmd_free_tag(tmp);
#endif #endif
falcon_dont_release--; hostdata->retain_dma_intr--;
local_irq_restore(flags); local_irq_restore(flags);
dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, " dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
"returned to issue_queue\n", HOSTNO); "returned to issue_queue\n", HOSTNO);
...@@ -1151,7 +1151,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) ...@@ -1151,7 +1151,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
return; return;
} }
if (atari_read_overruns) { if (hostdata->read_overruns) {
p = hostdata->connected->SCp.phase; p = hostdata->connected->SCp.phase;
if (p & SR_IO) { if (p & SR_IO) {
udelay(10); udelay(10);
...@@ -1181,9 +1181,9 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) ...@@ -1181,9 +1181,9 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
*data += transfered; *data += transfered;
*count -= transfered; *count -= transfered;
if (atari_read_overruns) { if (hostdata->read_overruns) {
if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) { if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
cnt = toPIO = atari_read_overruns; cnt = toPIO = hostdata->read_overruns;
if (overrun) { if (overrun) {
dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n"); dprintk(NDEBUG_DMA, "Got an input overrun, using saved byte\n");
*(*data)++ = saved_data; *(*data)++ = saved_data;
...@@ -1838,8 +1838,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, ...@@ -1838,8 +1838,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
return -1; return -1;
} }
if (atari_read_overruns && (p & SR_IO)) if (hostdata->read_overruns && (p & SR_IO))
c -= atari_read_overruns; c -= hostdata->read_overruns;
dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n", dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
HOSTNO, (p & SR_IO) ? "reading" : "writing", HOSTNO, (p & SR_IO) ? "reading" : "writing",
...@@ -1851,7 +1851,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, ...@@ -1851,7 +1851,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY); NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
#endif /* def REAL_DMA */ #endif /* def REAL_DMA */
if (IS_A_TT()) { if (!(hostdata->flags & FLAG_LATE_DMA_SETUP)) {
/* On the Medusa, it is a must to initialize the DMA before /* On the Medusa, it is a must to initialize the DMA before
* starting the NCR. This is also the cleaner way for the TT. * starting the NCR. This is also the cleaner way for the TT.
*/ */
...@@ -1869,7 +1869,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, ...@@ -1869,7 +1869,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
NCR5380_write(START_DMA_SEND_REG, 0); NCR5380_write(START_DMA_SEND_REG, 0);
} }
if (!IS_A_TT()) { if (hostdata->flags & FLAG_LATE_DMA_SETUP) {
/* On the Falcon, the DMA setup must be done after the last */ /* On the Falcon, the DMA setup must be done after the last */
/* NCR access, else the DMA setup gets trashed! /* NCR access, else the DMA setup gets trashed!
*/ */
...@@ -2084,7 +2084,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -2084,7 +2084,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* Accept message by clearing ACK */ /* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
/* ++guenther: possible race with Falcon locking */ /* ++guenther: possible race with Falcon locking */
falcon_dont_release++; hostdata->retain_dma_intr++;
hostdata->connected = NULL; hostdata->connected = NULL;
dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu " dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
"completed\n", HOSTNO, cmd->device->id, cmd->device->lun); "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
...@@ -2167,7 +2167,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -2167,7 +2167,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
barrier(); barrier();
falcon_dont_release--; hostdata->retain_dma_intr--;
/* ++roman: For Falcon SCSI, release the lock on the /* ++roman: For Falcon SCSI, release the lock on the
* ST-DMA here if no other commands are waiting on the * ST-DMA here if no other commands are waiting on the
* disconnected queue. * disconnected queue.
...@@ -2474,7 +2474,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) ...@@ -2474,7 +2474,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
#endif #endif
) { ) {
/* ++guenther: prevent race with falcon_release_lock */ /* ++guenther: prevent race with falcon_release_lock */
falcon_dont_release++; hostdata->retain_dma_intr++;
if (prev) { if (prev) {
REMOVE(prev, NEXT(prev), tmp, NEXT(tmp)); REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
SET_NEXT(prev, NEXT(tmp)); SET_NEXT(prev, NEXT(tmp));
...@@ -2512,7 +2512,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) ...@@ -2512,7 +2512,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
hostdata->connected = tmp; hostdata->connected = tmp;
dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n", dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag); HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
falcon_dont_release--; hostdata->retain_dma_intr--;
} }
......
...@@ -196,8 +196,6 @@ static char *atari_dma_orig_addr; ...@@ -196,8 +196,6 @@ static char *atari_dma_orig_addr;
/* mask for address bits that can't be used with the ST-DMA */ /* mask for address bits that can't be used with the ST-DMA */
static unsigned long atari_dma_stram_mask; static unsigned long atari_dma_stram_mask;
#define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0) #define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0)
/* number of bytes to cut from a transfer to handle NCR overruns */
static int atari_read_overruns;
#endif #endif
static int setup_can_queue = -1; static int setup_can_queue = -1;
...@@ -446,8 +444,6 @@ static void atari_scsi_fetch_restbytes(void) ...@@ -446,8 +444,6 @@ static void atari_scsi_fetch_restbytes(void)
#endif /* REAL_DMA */ #endif /* REAL_DMA */
static int falcon_dont_release = 0;
/* This function releases the lock on the DMA chip if there is no /* This function releases the lock on the DMA chip if there is no
* connected command and the disconnected queue is empty. * connected command and the disconnected queue is empty.
*/ */
...@@ -464,7 +460,7 @@ static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata) ...@@ -464,7 +460,7 @@ static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata)
if (!hostdata->disconnected_queue && if (!hostdata->disconnected_queue &&
!hostdata->issue_queue && !hostdata->issue_queue &&
!hostdata->connected && !hostdata->connected &&
!falcon_dont_release && !hostdata->retain_dma_intr &&
stdma_is_locked_by(scsi_falcon_intr)) stdma_is_locked_by(scsi_falcon_intr))
stdma_release(); stdma_release();
...@@ -846,6 +842,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -846,6 +842,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
struct Scsi_Host *instance; struct Scsi_Host *instance;
int error; int error;
struct resource *irq; struct resource *irq;
int host_flags = 0;
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) if (!irq)
...@@ -942,7 +939,9 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -942,7 +939,9 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
instance->irq = irq->start; instance->irq = irq->start;
NCR5380_init(instance, 0); host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
NCR5380_init(instance, host_flags);
if (IS_A_TT()) { if (IS_A_TT()) {
error = request_irq(instance->irq, scsi_tt_intr, 0, error = request_irq(instance->irq, scsi_tt_intr, 0,
...@@ -965,12 +964,16 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -965,12 +964,16 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
* *
* In principle it should be sufficient to do max. 1 byte with * In principle it should be sufficient to do max. 1 byte with
* PIO, but there is another problem on the Medusa with the DMA * PIO, but there is another problem on the Medusa with the DMA
* rest data register. So 'atari_read_overruns' is currently set * rest data register. So read_overruns is currently set
* to 4 to avoid having transfers that aren't a multiple of 4. * to 4 to avoid having transfers that aren't a multiple of 4.
* If the rest data bug is fixed, this can be lowered to 1. * If the rest data bug is fixed, this can be lowered to 1.
*/ */
if (MACH_IS_MEDUSA) if (MACH_IS_MEDUSA) {
atari_read_overruns = 4; struct NCR5380_hostdata *hostdata =
shost_priv(instance);
hostdata->read_overruns = 4;
}
#endif #endif
} else { } else {
/* Nothing to do for the interrupt: the ST-DMA is initialized /* Nothing to do for the interrupt: the ST-DMA is initialized
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment