next up previous contents
Next: 2.19 InterruptDisable() Up: 2. WD_xxx PCI/PCMCIA/ISA Functions Previous: 2.17 WD_PcmciaControl()   Contents


2.18 InterruptEnable()


PURPOSE

$\bullet$Call a callback function upon interrupt reception. A convenient function for setting up interrupt handling.


PROTOTYPE

DWORD InterruptEnable(
    HANDLE *phThread,
    HANDLE hWD,
    WD_INTERRUPT *pInt,
    INT_HANDLER func,
    PVOID pData);


PARAMETERS

Name Type Input/Output
$\bullet$phThread HANDLE* Output
$\bullet$hWD HANDLE Input
$\bullet$pInt WD_INTERRUPT*  
$\gg$hInterrupt DWORD Input
$\gg$dwOptions DWORD Input
$\gg$Cmd WD_TRANSFER* Input
$\gg$dwCmds DWORD Input
$\gg$kpCall WD_KERNEL_PLUGIN_CALL  
$\diamond$hKernelPlugIn DWORD Input
$\diamond$dwMessage DWORD N/A
$\diamond$pData PVOID N/A
$\diamond$dwResult DWORD N/A
$\gg$fEnableOk DWORD N/A
$\gg$dwCounter DWORD N/A
$\gg$dwLost DWORD N/A
$\gg$fStopped DWORD N/A
$\bullet$func INT_HANDLER Input
$\bullet$pData PVOID Input


DESCRIPTION

Name Description
phThread Pointer to the handle to the spawned interrupt thread, which should be passed to InterruptDisable() [2.19] when disabling the interrupt
hWD The handle to WinDriver's kernel-mode driver received from WD_Open() [5.2]
pInt Pointer to an interrupt information structure:
hInterrupt Internal interrupt handle, as received from WD_CardRegister() [2.8] in I.Int.hInterrupt
dwOptions Interrupt options bit-mask. Can be set to zero or to:
$\bullet$INTERRUPT_CMD_COPY: if set, WinDriver will copy the data received from the read commands that were used to acknowledge the interrupt, in the kernel mode, back to the user mode. The data will be available to the user when the interrupt handler routine (func) is called.
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 NULL if no transfer commands are required.

NOTE: When handling level sensitive interrupts (such as PCI interrupts) in the user mode (without a Kernel PlugIn driver), you must use this array to define the hardware-specific commands for acknowledging the interrupts in the kernel, immediately when they are received.

The commands in the array can be either of the following:

$\bullet$A read/write transfer command that conforms to the following format: <dir><p>_[S]<size> - see the description of pTrans->cmdTrans in section 2.11.

$\bullet$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.
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() [6.1].
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)


RETURN VALUE

Returns WD_STATUS_SUCCESS (0) on success, or an appropriate error code otherwise [A].


REMARKS


EXAMPLE

VOID 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 = TRUE;
    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);
    ....
}


next up previous contents
Next: 2.19 InterruptDisable() Up: 2. WD_xxx PCI/PCMCIA/ISA Functions Previous: 2.17 WD_PcmciaControl()   Contents