diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2014-11-12 00:11:56 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-20 03:11:07 -0500 |
commit | 22f5f10d2dadc50bf26a482b782a5e04f6e9b362 (patch) | |
tree | 0aa5f5690db24e368f6f3b2dded068889858e9f8 /drivers/scsi/NCR5380.c | |
parent | 3f9e986e2f1df8fa69ffe213098c1ee98f1c9584 (diff) |
ncr5380: Fix SCSI_IRQ_NONE bugs
Oak scsi doesn't use any IRQ, but it sets irq = IRQ_NONE rather than
SCSI_IRQ_NONE. Problem is, the core NCR5380 driver expects SCSI_IRQ_NONE
if it is to issue IDENTIFY commands that prevent target disconnection.
And, as Geert points out, IRQ_NONE is part of enum irqreturn.
Other drivers, when they can't get an IRQ or can't use one, will set
host->irq = SCSI_IRQ_NONE (that is, 255). But when they exit they will
attempt to free IRQ 255 which was never requested.
Fix these bugs by using NO_IRQ in place of SCSI_IRQ_NONE and IRQ_NONE.
That means IRQ 0 is no longer probed by ISA drivers but I don't think
this matters.
Setting IRQ = 255 for these ISA drivers is understood to mean no IRQ.
This remains supported so as to avoid breaking existing ISA setups (which
can be difficult to get working) and because existing documentation
(SANE, TLDP etc) describes this usage for the ISA NCR5380 driver options.
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/NCR5380.c')
-rw-r--r-- | drivers/scsi/NCR5380.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index e17e64e3e0d9..c4b80219868d 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c | |||
@@ -574,12 +574,12 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | |||
574 | int trying_irqs, i, mask; | 574 | int trying_irqs, i, mask; |
575 | NCR5380_setup(instance); | 575 | NCR5380_setup(instance); |
576 | 576 | ||
577 | for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1) | 577 | for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1) |
578 | if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) | 578 | if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) |
579 | trying_irqs |= mask; | 579 | trying_irqs |= mask; |
580 | 580 | ||
581 | timeout = jiffies + (250 * HZ / 1000); | 581 | timeout = jiffies + (250 * HZ / 1000); |
582 | probe_irq = SCSI_IRQ_NONE; | 582 | probe_irq = NO_IRQ; |
583 | 583 | ||
584 | /* | 584 | /* |
585 | * A interrupt is triggered whenever BSY = false, SEL = true | 585 | * A interrupt is triggered whenever BSY = false, SEL = true |
@@ -596,13 +596,13 @@ static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | |||
596 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); | 596 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); |
597 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); | 597 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); |
598 | 598 | ||
599 | while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout)) | 599 | while (probe_irq == NO_IRQ && time_before(jiffies, timeout)) |
600 | schedule_timeout_uninterruptible(1); | 600 | schedule_timeout_uninterruptible(1); |
601 | 601 | ||
602 | NCR5380_write(SELECT_ENABLE_REG, 0); | 602 | NCR5380_write(SELECT_ENABLE_REG, 0); |
603 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | 603 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); |
604 | 604 | ||
605 | for (i = 0, mask = 1; i < 16; ++i, mask <<= 1) | 605 | for (i = 1, mask = 2; i < 16; ++i, mask <<= 1) |
606 | if (trying_irqs & mask) | 606 | if (trying_irqs & mask) |
607 | free_irq(i, NULL); | 607 | free_irq(i, NULL); |
608 | 608 | ||
@@ -730,7 +730,7 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m, | |||
730 | 730 | ||
731 | SPRINTF("\nBase Addr: 0x%05lX ", (long) instance->base); | 731 | SPRINTF("\nBase Addr: 0x%05lX ", (long) instance->base); |
732 | SPRINTF("io_port: %04x ", (int) instance->io_port); | 732 | SPRINTF("io_port: %04x ", (int) instance->io_port); |
733 | if (instance->irq == SCSI_IRQ_NONE) | 733 | if (instance->irq == NO_IRQ) |
734 | SPRINTF("IRQ: None.\n"); | 734 | SPRINTF("IRQ: None.\n"); |
735 | else | 735 | else |
736 | SPRINTF("IRQ: %d.\n", instance->irq); | 736 | SPRINTF("IRQ: %d.\n", instance->irq); |
@@ -1501,7 +1501,7 @@ part2: | |||
1501 | } | 1501 | } |
1502 | 1502 | ||
1503 | dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id); | 1503 | dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id); |
1504 | tmp[0] = IDENTIFY(((instance->irq == SCSI_IRQ_NONE) ? 0 : 1), cmd->device->lun); | 1504 | tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun); |
1505 | 1505 | ||
1506 | len = 1; | 1506 | len = 1; |
1507 | cmd->tag = 0; | 1507 | cmd->tag = 0; |