Listing 3 Interrupt service thread
// ISTDemo.c
// Code adapted from \Public\Common\Oak\Drivers\Serial\MDD.c
// Reformatted for clarity (i.e. lots of lines removed)
// COM_Init: Called when the driver is initialized.
HANDLE COM_Init(ULONG Identifier)
{
PHW_INDEP_INFO pSerialHead = NULL;
// Allocate our control structure.
pSerialHead = (PHW_INDEP_INFO) LocalAlloc(LPTR, sizeof(HW_INDEP_INFO));
// pSerialHead is initialized here (simplified for clarity)
// Note: SYSINTR_FIRMWARE = 16 (from public\common\oak\inc\nkintr.h)
pSerialHead->pHWObj->dwIntID = SYSINTR_FIRMWARE + Irq;
// Create the event flag for the IST.
pSerialHead->hSerialEvent = CreateEvent(0,FALSE,FALSE,NULL);
// Hook the interrupt and start the associated thread.
// Initialize the interrupt to be associated with the hSerialEvent event.
InterruptInitialize(
pSerialHead->pHWObj->dwIntID, // Logical ID = SYSINTR_FIRMWARE (16)+Irq
pSerialHead->hSerialEvent,` // Created in COM_Init
// ..., // Ptr passed to OEMInterruptEnable
0);
// Create and start the IST thread
pSerialHead->pDispatchThread =
CreateThread(NULL, 0, IST, pSerialHead, 0, NULL);
return (pSerialHead);
}
// IST: The actual Interrupt Service Thread.
static DWORD WINAPI
IST(PVOID pContext)
{
// pContext is a pointer to main data structure (see CreateThread()).
PHW_INDEP_INFO pSerialHead = (PHW_INDEP_INFO) pContext;
ULONG WaitReturn;
while (!Done())
{
// Wait for the kernel to set the event flag.
WaitReturn = WaitForSingleObject(pSerialHead->hSerialEvent, INFINITE);
// Call an internal function to process the interrupt
SerialEventHandler(pSerialHead);
// Signal the end of interrupt processing
InterruptDone(pSerialHead->pHWObj->dwIntID);
}
return (0);
}
|