|
|
The ability to share interrupts on Intel x86-based systems varies widely, ranging from complete unavailability on most ISA-bus systems, to full support on all MCA-bus systems.
Note the following when implementing shared interrupts:
If interrupts are shared between multiple instances of the same device (a single driver running multiple similar boards), the driver's interrupt handler has the responsibility to loop through the various devices to service all interrupts (line 9, as shown in ``Sample DDI Code Fragment Illustrating Interrupt Sharing''). Often registers are available with different adapters that can uniquely identify whether a device has signaled an interrupt. If a driver identifies that a device has not interrupted (for example, from the Interrupt Service Register (ISR)), it should gracefully return to allow for continuation of the loop.
This is demonstrated in the example in ``Sample DDI Code Fragment Illustrating Interrupt Sharing'', where devintr( ) processes the interrupts by invoking verify_process_intr( ) (line 7) for every device configured for that interrupt. verify_process_intr( ) returns immediately (line 11) if the device in question does not need servicing.
In contrast, the operating system assumes responsibility for conditions where interrupts are shared across devices. The ivec[] table will be updated with a new routine which will loop through and invoke the different interrupt handlers when the processor is interrupted over a shared line.
``Sample DDI Code Fragment Illustrating Interrupt Sharing'' shows a sample sdevice file and code fragment, illustrating interrupt sharing between two devices programmed to interrupt on line 12.
Sample sdevice file
sampdrv Y 4 6 3 12 310 31F C8000 CFFFF sampdrv Y 4 6 3 12 330 33F D8000 DFFFF 3 -1
Sample DDI Code Fragment Illustrating Interrupt Sharing
1 devintr(intr_no) 2 int intr_no; 3 { 4 for (i = 0; i < numboards; i++) 6 if (devtab[i].int_num == intro_no) 7 verify_process_intr(&devtab[i]); 8 9 } 10 11 verify_process_intr(devp) 12 struct device_entry devp; 13 { 14 uchar_t isr; 15 16 isr = inb(devp->isr_register); 17 if (isr & NO_INTERRUPT) 18 return; 19 /* Process interrupt */ 10 }
Here is an example showing how an interrupt can be shared between multiple drivers. Assume interrupt 6 is shared by drivers xxx, yyy and zzz. The following routine would be constructed:
void shrint6() { xxx_intr(6); yyy_intr(6); zzz_intr(6); }Thus, the address of shrint6() is assigned to ivect[6].
For information about how to configure shared interrupts on SCO OpenServer 5 systems, see ``Configuring interrupt handlers''.
The number of devices on a system that can share an interrupt is determined by the NSHINTR tunable parameter. By default, this is set to 8 but it can be set as high as 20.