summaryrefslogtreecommitdiffstats
path: root/arch/mips64
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-01-26 20:07:53 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-01-26 20:07:53 +0000
commit1e25e41c4f5474e14452094492dbc169b800e4c8 (patch)
tree970227246eb3e253c894334dc86e98f29b588c55 /arch/mips64
parent2e8f976227bb832345dab1b70ce7791612da5a99 (diff)
Allow scsi intrs to be serviced.
Diffstat (limited to 'arch/mips64')
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index 977a6edb1..6a76b1966 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -111,20 +111,41 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
/* unmasking and bottom half handling is done magically for us. */
}
+/*
+ * Find first bit set
+ */
+static int ms1bit(unsigned long x)
+{
+ int b;
+
+ if (x >> 32) b = 32, x >>= 32;
+ else b = 0;
+ if (x >> 16) b += 16, x >>= 16;
+ if (x >> 8) b += 8, x >>= 8;
+ if (x >> 4) b += 4, x >>= 4;
+ if (x >> 2) b += 2, x >>= 2;
+
+ return b + (int) (x >> 1);
+}
+
/* For now ... */
void ip27_do_irq(struct pt_regs *regs)
{
+ int irq;
hubreg_t pend0, mask0;
- pend0 = LOCAL_HUB_L(PI_INT_PEND0);
- mask0 = LOCAL_HUB_L(PI_INT_MASK0_A);
-
- if (pend0 & mask0 & (1 << 9)) {
- LOCAL_HUB_S(PI_INT_MASK0_A, mask0 & ~(1 << 9));
- LOCAL_HUB_S(PI_INT_PEND_MOD, 9);
- LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
- do_IRQ(9, regs);
- LOCAL_HUB_S(PI_INT_MASK0_A, mask0);
+ /* copied from Irix intpend0() */
+ while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) &
+ (mask0 = LOCAL_HUB_L(PI_INT_MASK0_A))) != 0) {
+ do {
+ irq = ms1bit(pend0);
+ LOCAL_HUB_S(PI_INT_MASK0_A, mask0 & ~(1 << irq));
+ LOCAL_HUB_S(PI_INT_PEND_MOD, irq);
+ LOCAL_HUB_L(PI_INT_MASK0_A); /* Flush */
+ do_IRQ(irq, regs);
+ LOCAL_HUB_S(PI_INT_MASK0_A, mask0);
+ pend0 ^= 1ULL << irq;
+ } while (pend0);
}
}