kernels/linux-2.4.0/arch/mips64/sgi-ip27/ip27-irq.c
/*
 * This code is unnecessarily complex, because we do SA_INTERRUPT
 * intr enabling. Basically, once we grab the set of intrs we need
 * to service, we must mask _all_ these interrupts; firstly, to make
 * sure the same intr does not intr again, causing recursion that 
 * can lead to stack overflow. Secondly, we can not just mask the
 * one intr we are do_IRQing, because the non-masked intrs in the
 * first set might intr again, causing multiple servicings of the
 * same intr. This effect is mostly seen for intercpu intrs.
 * Kanoj 05.13.00
 */
This code is unnecessarily complex, because we do SA_INTERRUPT
intr enabling. Basically, once we grab the set of intrs we need
to service, we must mask _all_ these interrupts; firstly, to make
sure the same intr does not intr again, causing recursion that
can lead to stack overflow. Secondly, we can not just mask the
one intr we are do_IRQing, because the non-masked intrs in the
first set might intr again, causing multiple servicings of the
same intr. This effect is mostly seen for intercpu intrs.
This code is unnecessarily complex because we do SA_INTERRUPT intr enabling . Basically once we grab the set of intrs we need to service we must mask _all_ these interrupts ; firstly to make sure the same intr does not intr again causing recursion that can lead to stack overflow . Secondly we can not just mask the one intr we are do_IRQing because the non - masked intrs in the first set might intr again causing multiple servicings of the same intr . This effect is mostly seen for intercpu intrs .
void ip27_do_irq(struct pt_regs *regs)
{
	int irq, swlevel;
	hubreg_t pend0, mask0;
	cpuid_t thiscpu = smp_processor_id();
	int pi_int_mask0 = ((cputoslice(thiscpu) == 0) ?
					PI_INT_MASK0_A : PI_INT_MASK0_B);
	while (((pend0 = LOCAL_HUB_L(PI_INT_PEND0)) & 
				(mask0 = LOCAL_HUB_L(pi_int_mask0))) != 0) {
		pend0 &= mask0;		
		if (pend0) {
			LOCAL_HUB_S(pi_int_mask0, mask0 & ~(pend0));
			do {
				swlevel = ms1bit(pend0);
				LOCAL_HUB_CLR_INTR(swlevel);
				irq = SWLEVEL_TO_IRQ(thiscpu, swlevel);
				do_IRQ(thiscpu, irq, regs);
				pend0 ^= 1ULL << swlevel;
			} while(pend0);
			LOCAL_HUB_S(pi_int_mask0, mask0);
			LOCAL_HUB_L(PI_INT_PEND0);
		}
	}
}
void ip27_do_irq ( struct pt_regs * regs ) { int irq , swlevel ; hubreg_t pend0 , mask0 ; cpuid_t thiscpu = smp_processor_id ( ) ; int pi_int_mask0 = ( ( cputoslice ( thiscpu ) == 0 ) ? PI_INT_MASK0_A : PI_INT_MASK0_B ) ; while ( ( ( pend0 = LOCAL_HUB_L ( PI_INT_PEND0 ) ) & ( mask0 = LOCAL_HUB_L ( pi_int_mask0 ) ) ) != 0 ) { pend0 &= mask0 ; if ( pend0 ) { LOCAL_HUB_S ( pi_int_mask0 , mask0 & ~ ( pend0 ) ) ; do { swlevel = ms1bit ( pend0 ) ; LOCAL_HUB_CLR_INTR ( swlevel ) ; irq = SWLEVEL_TO_IRQ ( thiscpu , swlevel ) ; do_IRQ ( thiscpu , irq , regs ) ; pend0 ^= 1ULL << swlevel ; } while ( pend0 ) ; LOCAL_HUB_S ( pi_int_mask0 , mask0 ) ; LOCAL_HUB_L ( PI_INT_PEND0 ) ; } } }
This code is unnecessarily complex, because we do SA_INTERRUPT
 intr enabling.
This code is unnecessarily complex because we do SA_INTERRUPT intr enabling .
/* copied from Irix intpend0() */ /* Pick intrs we should look at */ /* Prevent any of the picked intrs from recursing */ /* "map" swlevel to irq */ /* clear bit in pend0 */ /* Now allow the set of serviced intrs again */