diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-01-26 20:07:53 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-01-26 20:07:53 +0000 |
commit | 1e25e41c4f5474e14452094492dbc169b800e4c8 (patch) | |
tree | 970227246eb3e253c894334dc86e98f29b588c55 | |
parent | 2e8f976227bb832345dab1b70ce7791612da5a99 (diff) |
Allow scsi intrs to be serviced.
-rw-r--r-- | arch/mips64/sgi-ip27/ip27-irq.c | 39 |
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); } } |