diff -urN 2.4.5ac2/arch/alpha/kernel/sys_rawhide.c 2.4.5ac3/arch/alpha/kernel/sys_rawhide.c --- 2.4.5ac2/arch/alpha/kernel/sys_rawhide.c Sun Apr 1 01:17:07 2001 +++ 2.4.5ac3/arch/alpha/kernel/sys_rawhide.c Mon May 28 20:07:11 2001 @@ -59,10 +59,11 @@ irq -= 16; hose = irq / 24; irq -= hose * 24; + mask = 1 << irq; spin_lock(&rawhide_irq_lock); - mask = cached_irq_masks[hose] |= 1 << irq; - mask |= hose_irq_masks[hose]; + mask |= cached_irq_masks[hose]; + cached_irq_masks[hose] = mask; rawhide_update_irq_hw(hose, mask); spin_unlock(&rawhide_irq_lock); } @@ -75,14 +76,37 @@ irq -= 16; hose = irq / 24; irq -= hose * 24; + mask = ~(1 << irq) | hose_irq_masks[hose]; spin_lock(&rawhide_irq_lock); - mask = cached_irq_masks[hose] &= ~(1 << irq); - mask |= hose_irq_masks[hose]; + mask &= cached_irq_masks[hose]; + cached_irq_masks[hose] = mask; rawhide_update_irq_hw(hose, mask); spin_unlock(&rawhide_irq_lock); } +static void +rawhide_mask_and_ack_irq(unsigned int irq) +{ + unsigned int mask, mask1, hose; + + irq -= 16; + hose = irq / 24; + irq -= hose * 24; + mask1 = 1 << irq; + mask = ~mask1 | hose_irq_masks[hose]; + + spin_lock(&rawhide_irq_lock); + + mask &= cached_irq_masks[hose]; + cached_irq_masks[hose] = mask; + rawhide_update_irq_hw(hose, mask); + + /* Clear the interrupt. */ + *(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1; + + spin_unlock(&rawhide_irq_lock); +} static unsigned int rawhide_startup_irq(unsigned int irq) @@ -104,7 +128,7 @@ shutdown: rawhide_disable_irq, enable: rawhide_enable_irq, disable: rawhide_disable_irq, - ack: rawhide_disable_irq, + ack: rawhide_mask_and_ack_irq, end: rawhide_end_irq, }; @@ -145,8 +169,12 @@ mcpcia_init_hoses(); for (hose = hose_head; hose; hose = hose->next) { - int h = hose->index; - rawhide_update_irq_hw(h, hose_irq_masks[h]); + unsigned int h = hose->index; + unsigned int mask = hose_irq_masks[h]; + + cached_irq_masks[h] = mask; + *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask; + *(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0; } for (i = 16; i < 128; ++i) {