A driver written in user mode uses WinDriver's API (WDC_xxx and/or
WD_xxx [B.2]) to access devices.
If a certain function that was implemented in the user mode requires kernel
performance (the interrupt handler, for example), that function is moved to the
WinDriver Kernel PlugIn. Generally it should be possible to move code that uses
WDC_xxx / WD_xxx function calls from the user mode to the kernel
without modification, since the same WinDriver API is supported both in the user
mode and in the Kernel PlugIn.
There are two types of interaction between the WinDriver kernel and the WinDriver Kernel PlugIn:
At the end of your Kernel PlugIn development cycle, your driver will have the following components:
WDC_xxx /
WD_xxx API.
WDC_xxx / WD_xxx API, and contains the driver functionality
that you have selected to bring down to the kernel level.
The following is a typical event sequence that covers all the functions that you can implement in your Kernel PlugIn:
| Event/Callback | Notes |
|---|---|
| Event: Windows loads your Kernel PlugIn driver. | This takes place at boot time, by dynamic loading, or as instructed by the registry. |
Callback: Your KP_Init() Kernel PlugIn
routine [B.6.2] is called
|
KP_Init() informs WinDriver of the name of your
KP_Open() routine [B.6.2]. WinDriver
will call this routine when the application wishes to open your driver
– when it calls WDC_xxxDeviceOpen()
(PCI: [B.3.10], PCMCIA: [B.3.11],
ISA: [B.3.12]]) with the name of a Kernel
PlugIn driver to open, or when it calls the low-level
WD_KernelPlugInOpen() function (see the WinDriver PCI Low-Level API Reference),
which is called by the wrapper WDC_xxxDeviceOpen() functions.
|
Event: Your user-mode driver application calls
WDC_xxxDeviceOpen()
(PCI: [B.3.10],
PCMCIA: [B.3.11],
ISA: [B.3.12]) with the name of a Kernel
PlugIn driver to open, or it calls the low-level
WD_KernelPlugInOpen() function (see the WinDriver PCI Low-Level API Reference),
which is called by the wrapper WDC_xxxDeviceOpen() functions.
| |
Callback: Your KP_Open() Kernel PlugIn
routine [B.6.2] is called.
|
The KP_Open() function [B.6.2] is
used to inform WinDriver of the names of all the callback functions that you
have implemented in your Kernel PlugIn driver and to initiate the Kernel
PlugIn driver, if needed.
|
| Event/Callback | Notes |
|---|---|
Event: Your application calls
WDC_CallKerPlug() [B.3.18], or
the low-level WD_KernelPlugInCall() function (see the
WinDriver PCI Low-Level API Reference).
|
Your application calls WDC_CallKerPlug() /
WD_KernelPlugInCall() to execute code in the kernel mode (in
the Kernel PlugIn driver). The application passes a message to the Kernel
PlugIn driver. The Kernel PlugIn driver will select the code to execute
according to the message sent.
|
Callback: Your KP_Call() Kernel PlugIn
routine [B.6.4] is called.
|
KP_Call() [B.6.4] executes code
according to the message passed to it from the user mode.
|
| Event/Callback | Notes |
|---|---|
Event: Your application calls
WDC_IntEnable() [B.3.46] with
the fUseKP parameter set to TRUE (after having
opened the device with a Kernel PlugIn); or calls the low-level
InterruptEnable() or WD_IntEnable() functions
(see the WinDriver PCI Low-Level API Reference) with a handle to a Kernel PlugIn driver (set in
the hKernelPlugIn field of the WD_INTERRUPT
structure passed to the function).
| |
Callback: Your KP_IntEnable() Kernel PlugIn
routine [B.6.6] is called.
| This function should contain any initialization required for your Kernel PlugIn interrupt handling. |
| Event: Your hardware creates an interrupt. | |
Callback: Your high-IRQL Kernel PlugIn interrupt handler
routine – KP_IntAtIrql() [B.6.8] (legacy
interrupts) or KP_IntAtIrqlMSI() [B.6.10]
(MSI/MSI-X) – is called.
|
KP_IntAtIrql() [B.6.8] and KP_IntAtIrqlMSI() [B.6.10] run at a high priority, and therefore should
perform only the basic interrupt handling, such as lowering the HW
interrupt signal of level-sensitive interrupts to acknowledge the
interrupt.If more interrupt processing is required, KP_IntAtDpc() (legacy
interrupts) or KP_IntAtDpcMSI()
(MSI/MSI-X) can return TRUE in order to defer additional
processing to the relevant deferred processing interrupt handler –
KP_IntAtDpc() [B.6.9] or KP_IntAtDpcMSI() [B.6.11].
|
Event: Your application calls
WDC_IntDisable() [B.3.47], or
the low-level InterruptDisable() or
WD_IntDisable() functions (see the WinDriver PCI Low-Level API Reference), when
the interrupts were previously enabled in the Kernel PlugIn (see the
description of the interrupt enable event above.)
| |
Callback: Your KP_IntDisable() Kernel PlugIn
routine [B.6.7] is called.
|
This function should free any memory that was allocated by the
KP_IntEnable() [B.6.6] callback.
|
| Event/Callback | Notes |
|---|---|
Event: The Kernel PlugIn high-IRQL interrupt handler –
KP_IntAtIrql() [B.6.8] or KP_IntAtIrqlMSI() [B.6.10] – returns TRUE.
| This informs WinDriver that additional interrupt processing is required as a Deferred Procedure Call (DPC) in the kernel. |
Callback: Your Kernel PlugIn DPC interrupt handler –
KP_IntAtDpc() [B.6.9] (legacy
interrupts) or KP_IntAtDpcMSI() [B.6.11]
(MSI/MSI-X) – is called.
| Processes the rest of the interrupt code, but at a lower priority than the high-IRQL interrupt handler. |
Event: The DPC interrupt handler – KP_IntAtDpc() [B.6.9] or KP_IntAtDpcMSI() [B.6.11] –
returns a value greater than 0.
| This informs WinDriver that additional user-mode interrupt processing is required. |
Callback: WD_IntWait() (see the WinDriver PCI Low-Level API Reference)
returns.
| Your user-mode interrupt handler routine is executed. |
| Event/Callback | Notes |
|---|---|
Event: Your application registers to receive Plug-and-Play and power
management notifications using a Kernel PlugIn driver, by calling
WDC_EventRegister() [B.3.49]
with the with the fUseKP parameter set to TRUE
(after having opened the device with a Kernel PlugIn), or calls the
low-level EventRegister() (see the WinDriver PCI Low-Level API Reference) or
WD_EventRegister() functions with a handle to a Kernel PlugIn
driver (set in the hKernelPlugIn field of the
WD_EVENT structure that is passed to the function).
| |
| Event: A Plug-and-Play or power management event (to which the application registered to listen) occurs. | |
Callback: Your KP_Event() Kernel PlugIn
routine [B.6.5] is called.
|
KP_Event() receives information about the event that occurred
and can proceed to handle it as needed.
|
Event: KP_Event() [B.6.5]
returns TRUE.
| This informs WinDriver that the event also requires user-mode handling. |
Callback: WD_IntWait() (see the WinDriver PCI Low-Level API Reference)
returns.
| Your user-mode event handler routine is executed. |