A convenient function for setting up interrupt handling.
DWORD InterruptEnable(
HANDLE *phThread,
HANDLE hWD,
WD_INTERRUPT *pInt,
INT_HANDLER func,
PVOID pData);
| Name | Type | Input/Output |
|---|---|---|
| phThread | HANDLE* | Output |
| hWD | HANDLE | Input |
| pInt | WD_INTERRUPT* | |
| • hInterrupt | DWORD | Input |
| • dwOptions | DWORD | Input |
| • Cmd | WD_TRANSFER* | Input |
| • dwCmds | DWORD | Input |
| • kpCall | WD_KERNEL_PLUGIN_CALL | |
| * hKernelPlugIn | DWORD | Input |
| * dwMessage | DWORD | N/A |
| * pData | PVOID | N/A |
| * dwResult | DWORD | N/A |
| • fEnableOk | DWORD | N/A |
| • dwCounter | DWORD | N/A |
| • dwLost | DWORD | N/A |
| • fStopped | DWORD | N/A |
| • dwLastMessage | DWORD | N/A |
| • dwEnabledIntType | DWORD | Output |
| func | typedef void (*INT_HANDLER)(PVOID pData); | Input |
| pData | PVOID | Input |
| Name | Description |
|---|---|
| phThread |
Pointer to the handle to the spawned interrupt thread, which should be
passed to InterruptDisable() |
| hWD | Handle to WinDriver's kernel-mode driver as
received from WD_Open() |
| pInt | Pointer to an interrupt information structure: |
| • hInterrupt |
Internal interrupt handle, as received from WD_CardRegister()I.Int.hInterrupt
|
| • dwOptions |
|
| • Cmd |
An array of transfer commands information structures that define the
operations to be performed at the kernel level upon the detection of an
interrupt, or
NOTE:
The commands in the array can be either of the following: CMD_MASK:
an interrupt mask command for determining the source of the interrupt: When
this command is set, upon the arrival of an interrupt in the kernel WinDriver
masks the value of the previous read command in the WD_TRANSFER
commands array with the mask that is set in the relevant Data
field union member of the mask transfer command. For example, for a
Cmd WD_TRANSFER array, if
Cmd[i-1].cmdTrans
is RM_BYTE, WinDriver performs the following mask:
Cmd[i-1].Data.Byte &
Cmd[i].Data.Byte.
If the mask is successful, the driver claims ownership of the interrupt and
when the control is returned to the user mode, the interrupt handler routine
that was passed to the interrupt enable function is invoked; otherwise, the
driver rejects ownership of the interrupt, the interrupt handler routine is
not invoked and the subsequent transfer commands in the array are not
executed.(Acceptance and rejection of the interrupt is relevant only when handling legacy interrupts; since MSI/MSI-X interrupts are not shared, WinDriver will always accept control of such interrupts.) NOTE: A CMD_MASK command must be preceded by a read transfer
command (RM_XXX / RP_XXX).
|
| • dwCmds | Number of transfer commands in the Cmd array |
| • kpCall | Kernel PlugIn message information structure: |
| * hKernelPlugIn |
Handle to Kernel PlugIn returned from WD_KernelPlugInOpen() |
| • dwEnabledIntType |
Updated by the function to indicate the type of interrupt enabled for the
device. Can be set to any of the following values:
NOTE: |
| func |
The interrupt handler routine, which will be called once for every
interrupt occurrence. (Note: The INT_HANDLER function type
is defined in windrvr_int_thread.h).
|
| pData |
Pointer to the data to be passed as the argument to the interrupt handler
routine (func)
|
Returns WD_STATUS_SUCCESS (0) on success, or an appropriate
error code otherwise
InterruptEnable() uses the low-level
WD_IntEnable()WD_IntWait()WD_IntCount()InterruptEnable()
will fail with a WD_NO_DEVICE_OBJECT errorVOID DLLCALLCONV interrupt_handler(PVOID pData)
{
WD_INTERRUPT *pIntrp = (WD_INTERRUPT *)pData;
/* Implement your interrupt handler routine here */
printf("Got interrupt %d\n", pIntrp->dwCounter);
}
....
main()
{
WD_CARD_REGISTER cardReg;
WD_INTERRUPT Intrp;
HANDLE hWD, thread_handle;
....
hWD = WD_Open();
BZERO(cardReg);
cardReg.Card.dwItems = 1;
cardReg.Card.Item[0].item = ITEM_INTERRUPT;
cardReg.Card.Item[0].fNotSharable = 1;
cardReg.Card.Item[0].I.Int.dwInterrupt = MY_IRQ;
cardReg.Card.Item[0].I.Int.dwOptions = 0;
....
WD_CardRegister(hWd, &cardReg);
....
PVOID pdata = NULL;
BZERO (Intrp);
Intrp.hInterrupt = cardReg.Card.Item[0].I.Int.hInterrupt;
Intrp.Cmd = NULL;
Intrp.dwCmds = 0;
Intrp.dwOptions = 0;
printf("starting interrupt thread\n");
pData = &Intrp;
if (InterruptEnable(&thread_handle, hWD, &Intrp,
interrupt_handler, pdata))
{
printf ("failed enabling interrupt\n")
}
else
{
printf("Press Enter to uninstall interrupt\n");
fgets(line, sizeof(line), stdin);
InterruptDisable(thread_handle); /* Calls WD_IntDisable() */
}
WD_CardUnregister(hWD, &cardReg);
....
}