嘿嘿,以前在论坛看过paul,chao关于共享中断的一些回帖,刚才在看wifi驱动的时候也看到了,现在发个帖子探讨一下。
看了一下MSDN,一目了然,就是不知道具体如何实现的。
Installable ISRs and Device Drivers
Send Feedback
Installable interrupt service routines (ISRs) allow multiple devices to share interrupts and to share a single hardware platform interrupt request (IRQ). ISRs also extend the ability of the OS to process the device in the ISR in addition to the interrupt service thread (IST). If you want to allow interrupt sharing, you should update the ISRs for your device driver. If an installable ISR must recognize the device generating the input, you can usually use the generic installable ISR sample, GIISR.dll.
Because most devices indicate interrupt activity in a single register that is possibly masked, the sample installable ISR handler, GIISR.dll, is adequate for many devices. If necessary, you can write a custom installable ISR handler to implement complex interrupt detection.
You might choose to install an ISR to handle interrupts for the device. This is required if the interrupt is shared between two or more devices, which is a common occurrence with PCI devices. The installed ISR can be a generic routine that simply checks to see if the device is the one requesting service, or it can be a custom design. Giisr.dll is the generic installable ISR. If the IsrHandler and IsrDll values are provided in the device's registry key, then the driver should load the ISR DLL through the LoadIntChainHandler call.
After the ISR is loaded with LoadIntChainHandler, GIISR_INFO, defined in Giisr.h, is filled in and passed to the ISR through KernelLibIoControl with IOCTL_GIISR_INFO. The interrupt handler is unloaded with FreeIntChainHandler.
The following code example shows how to load the ISR DLL with LoadIntChainHandler.
- #include
- #include
- // InstallIsr is a flag that indicates that there is an ISR to be installed.
- // IsrDll is the ISR DLL name, obtained from the registry.
- // IsrHandler is the ISR function name, obtained from the registry.
- // IfcType is the bus interface type, obtained from the registry.
- // BusNumber is the PCI bus number, obtained from the registry.
- // Install ISR handler if there is one.
- if (InstallIsr) {
- // Install ISR handler
- g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq);
- if (!g_IsrHandle) {
- DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: Couldn't install ISR handler\r\n"));
- } else {
- GIISR_INFO Info;
- PVOID PhysAddr;
- DWORD inIoSpace = 1; // io space
- PHYSICAL_ADDRESS PortAddress = {ulIoBase, 0};
- if (!TransBusAddrToStatic(PCIBus, 0, PortAddress, ulIoLen, &inIoSpace, &PhysAddr)) {
- DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: Failed TransBusAddrToStatic\r\n"));
- return FALSE;
- }
- DEBUGMSG(ZONE_PDD, (L"WAVEDEV: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d, PhysAddr = 0x%x\r\n", IsrDll, IsrHandler, Irq, PhysAddr));
- // Set up ISR handler
- Info.SysIntr = ulSysIntr;
- Info.CheckPort = TRUE;
- Info.PortIsIO = TRUE;
- Info.UseMaskReg = FALSE;
- Info.PortAddr = (DWORD)PhysAddr + ES1371_dSTATUS_OFF;
- Info.PortSize = sizeof(DWORD);
- Info.Mask = ES1371_INTSTAT_PENDING;
- if (!KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) {
- DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: KernelLibIoControl call failed.\r\n"));
- }
- }
- }
从这里可以看出,这个GIISR.dll 实现了这个功能。就是动态添加isr的功能,并且可以创建一个物理中断,和多个isr、ist 对应的 功能,真强啊。!呵呵。
学习了。