Commit 69e1a948 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Christoph Hellwig

[PATCH] fix up NCR5380 private data

Use the private data passed to request_irq instead of looping over all
controllers.  The patch was ACKed by Alan a while ago.

Note that the patch only looks so huge because of the two leves of
indentation removed by the tiny chage.
parent 26281b14
...@@ -1326,81 +1326,71 @@ static void NCR5380_main(void *p) ...@@ -1326,81 +1326,71 @@ static void NCR5380_main(void *p)
static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs) static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
NCR5380_local_declare(); NCR5380_local_declare();
struct Scsi_Host *instance; struct Scsi_Host *instance = (struct Scsi_Host *)dev_id;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
int done; int done;
unsigned char basr; unsigned char basr;
struct NCR5380_hostdata *hostdata;
int handled = 0;
dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n", irq)); dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n", irq));
do { do {
done = 1; done = 1;
/* The instance list is constant while the driver is spin_lock_irq(instance->host_lock);
loaded */ /* Look for pending interrupts */
for (hostdata = first_host; hostdata != NULL; hostdata = hostdata->next) NCR5380_setup(instance);
{ basr = NCR5380_read(BUS_AND_STATUS_REG);
instance = hostdata->host; /* XXX dispatch to appropriate routine if found and done=0 */
if (instance->irq == irq) { if (basr & BASR_IRQ) {
handled = 1; NCR5380_dprint(NDEBUG_INTR, instance);
spin_lock_irq(instance->host_lock); if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
/* Look for pending interrupts */ done = 0;
NCR5380_setup(instance); dprintk(NDEBUG_INTR, ("scsi%d : SEL interrupt\n", instance->host_no));
basr = NCR5380_read(BUS_AND_STATUS_REG); NCR5380_reselect(instance);
/* XXX dispatch to appropriate routine if found and done=0 */ (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
if (basr & BASR_IRQ) { } else if (basr & BASR_PARITY_ERROR) {
NCR5380_dprint(NDEBUG_INTR, instance); dprintk(NDEBUG_INTR, ("scsi%d : PARITY interrupt\n", instance->host_no));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
done = 0; } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
dprintk(NDEBUG_INTR, ("scsi%d : SEL interrupt\n", instance->host_no)); dprintk(NDEBUG_INTR, ("scsi%d : RESET interrupt\n", instance->host_no));
NCR5380_reselect(instance); (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); } else {
} else if (basr & BASR_PARITY_ERROR) {
dprintk(NDEBUG_INTR, ("scsi%d : PARITY interrupt\n", instance->host_no));
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
} else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
dprintk(NDEBUG_INTR, ("scsi%d : RESET interrupt\n", instance->host_no));
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
} else {
#if defined(REAL_DMA) #if defined(REAL_DMA)
/* /*
* We should only get PHASE MISMATCH and EOP interrupts * We should only get PHASE MISMATCH and EOP interrupts
* if we have DMA enabled, so do a sanity check based on * if we have DMA enabled, so do a sanity check based on
* the current setting of the MODE register. * the current setting of the MODE register.
*/ */
if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) { if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) {
int transfered; int transfered;
if (!hostdata->connected) if (!hostdata->connected)
panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno); panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
transfered = (hostdata->dmalen - NCR5380_dma_residual(instance)); transfered = (hostdata->dmalen - NCR5380_dma_residual(instance));
hostdata->connected->SCp.this_residual -= transferred; hostdata->connected->SCp.this_residual -= transferred;
hostdata->connected->SCp.ptr += transferred; hostdata->connected->SCp.ptr += transferred;
hostdata->dmalen = 0; hostdata->dmalen = 0;
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
/* FIXME: we need to poll briefly then defer a workqueue task ! */ /* FIXME: we need to poll briefly then defer a workqueue task ! */
NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ); NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ);
NCR5380_write(MODE_REG, MR_BASE); NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
} }
#else #else
dprintk(NDEBUG_INTR, ("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG))); dprintk(NDEBUG_INTR, ("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG)));
(void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
#endif #endif
} }
} /* if BASR_IRQ */ } /* if BASR_IRQ */
spin_unlock_irq(instance->host_lock); spin_unlock_irq(instance->host_lock);
if(!done) if(!done)
schedule_work(&hostdata->coroutine); schedule_work(&hostdata->coroutine);
} /* if (instance->irq == irq) */
}
} while (!done); } while (!done);
return IRQ_RETVAL(handled); return IRQ_HANDLED;
} }
#endif #endif
......
...@@ -450,7 +450,7 @@ int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt) ...@@ -450,7 +450,7 @@ int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt)
instance->irq = NCR5380_probe_irq(instance, 0xffff); instance->irq = NCR5380_probe_irq(instance, 0xffff);
if (instance->irq != SCSI_IRQ_NONE) if (instance->irq != SCSI_IRQ_NONE)
if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) { if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", instance)) {
printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
instance->irq = SCSI_IRQ_NONE; instance->irq = SCSI_IRQ_NONE;
} }
......
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