Technical Document #40

Technical Document #40
How do I call WD_Transfer() in the Kernel PlugIn interrupt handler?

You can call WD_Transfer() from within the KP_IntAtIrql or KP_IntAtDpc functions (replace "KP" in the function names with your Kernel PlugIn driver name — e.g., "KP_PCI") in order to access the hardware (see below).

Please note that you can also access the memory/IO directly from within the Kernel PlugIn interrupt functions. (For direct memory access, use the kernel mapping of the memory, returned from WD_CardRegister() in cardReg.Card.Item[i].I.Mem.dwTransAddr.)

When calling WD_Transfer() you will need to pass as the first argument a handle to WinDriver (hWD). You can refer to Technical Document #38 to find out how to obtain a handle to WinDriver from within the Kernel PlugIn.

As specified in the aforementioned Technical Document, you can store the handle to WinDriver in a global Kernel PlugIn variable (recommended), or pass it from one function to another. Below is an example of passing a handle to WinDriver from KP_Open() to KP_IntAtIrql:

Add the following line to KP_Open() :

*ppDrvContext = (PVOID) hWD;
Add the following line to KP_IntEnable():
*ppIntContext = pDrvContext;
You can now use WD_Transfer() to access memory/IO from within KP_IntAtIrql. For example (IO access):
HANDLE hWD = (HANDLE) pIntContext;
WD_TRANSFER trans;
BZERO(trans);
trans.cmdTrans = WP_BYTE;
trans.dwPort = 0x378;
trans.Data.Byte = 0x65;
WD_Transfer(hWD, &trans);
This will write 0x65 to port 0x378 upon interrupt. The hWD handle is passed from KP_Open() to KP_IntEnable() to KP_IntAtIrql via the context.
(Beginning with version 5.2.0 of WinDriver you can also view the generated DriverWizard Kernel PlugIn code for an example of calling WD_MultiTransfer() from KP_IntAtIrql, provided you have used the DriverWizard to define and assign the register/s for the interrupt acknowledgment before generating the code.)