When IRQ_AUTO is used, the interrupt for HP C2502 cards gets disabled.
Fix this by programming the card for a suitable free irq. The code for
the free irq search comes from ALSA.

Also allow IRQ 9 to work (it aliases to IRQ 2 on the card), as per
Ondrej Zary's patch.

Suggested-by: Ondrej Zary <li...@rainbow-software.org>
Signed-off-by: Finn Thain <fth...@telegraphics.com.au>
---
 drivers/scsi/g_NCR5380.c | 70 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 57 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 6d245a7..58a0b82 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -131,14 +131,33 @@ static void magic_configure(int idx, u8 irq, u8 magic[])
        outb(magic[3], 0x379);
        outb(magic[4], 0x379);
 
-       /* allowed IRQs for HP C2502 */
-       if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7)
-               irq = 0;
+       if (irq == 9)
+               irq = 2;
+
        if (idx >= 0 && idx <= 7)
                cfg = 0x80 | idx | (irq << 4);
        outb(cfg, 0x379);
 }
 
+static irqreturn_t legacy_empty_irq_handler(int irq, void *dev_id)
+{
+       return IRQ_HANDLED;
+}
+
+static int legacy_find_free_irq(int *irq_table)
+{
+       while (*irq_table != -1) {
+               if (!request_irq(*irq_table, legacy_empty_irq_handler,
+                                IRQF_PROBE_SHARED, "Test IRQ",
+                                (void *)irq_table)) {
+                       free_irq(*irq_table, (void *) irq_table);
+                       return *irq_table;
+               }
+               irq_table++;
+       }
+       return -1;
+}
+
 static unsigned int ncr_53c400a_ports[] = {
        0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
 };
@@ -151,6 +170,9 @@ static u8 ncr_53c400a_magic[] = {   /* 53C400A & DTC436 */
 static u8 hp_c2502_magic[] = { /* HP C2502 */
        0x0f, 0x22, 0xf0, 0x20, 0x80
 };
+static int hp_c2502_irqs[] = {
+       9, 5, 7, 3, 4, -1
+};
 
 static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
                        struct device *pdev, int base, int irq, int board)
@@ -319,19 +341,41 @@ static int generic_NCR5380_init_one(struct 
scsi_host_template *tpnt,
 
        NCR5380_maybe_reset_bus(instance);
 
-       if (irq != IRQ_AUTO)
-               instance->irq = irq;
-       else
-               instance->irq = g_NCR5380_probe_irq(instance);
-
        /* Compatibility with documented NCR5380 kernel parameters */
-       if (instance->irq == 255)
-               instance->irq = NO_IRQ;
+       if (irq == 255 || irq == 0)
+               irq = NO_IRQ;
+
+       if (board == BOARD_HP_C2502) {
+               int *irq_table = hp_c2502_irqs;
+               int board_irq = -1;
+
+               switch (irq) {
+               case NO_IRQ:
+                       board_irq = 0;
+                       break;
+               case IRQ_AUTO:
+                       board_irq = legacy_find_free_irq(irq_table);
+                       break;
+               default:
+                       while (*irq_table != -1)
+                               if (*irq_table++ == irq)
+                                       board_irq = irq;
+               }
+
+               if (board_irq <= 0) {
+                       board_irq = 0;
+                       irq = NO_IRQ;
+               }
+
+               magic_configure(port_idx, board_irq, magic);
+       }
+
+       if (irq == IRQ_AUTO)
+               instance->irq = g_NCR5380_probe_irq(instance);
+       else
+               instance->irq = irq;
 
        if (instance->irq != NO_IRQ) {
-               /* set IRQ for HP C2502 */
-               if (board == BOARD_HP_C2502)
-                       magic_configure(port_idx, instance->irq, magic);
                if (request_irq(instance->irq, generic_NCR5380_intr,
                                0, "NCR5380", instance)) {
                        printk(KERN_WARNING "scsi%d : IRQ%d not free, 
interrupts disabled\n", instance->host_no, instance->irq);
-- 
2.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to