In addition to the basic responsibilities of these routines, already mentioned in Sections 9.1.2 and 9.1.3, every DpcForIsr or CustomDpc routine is responsible for using ISR-provided context to complete one or more interrupt-driven I/O operations.
In other words, besides ensuring that the next device I/O operation is started promptly and completing the current IRP, the work done by any DpcForIsr or CustomDpc routine depends on the driver’s design and/or on the nature of its device.
For example, the DpcForIsr or CustomDpc routine also can do any of the following in order to complete an interrupt-driven I/O operation:
For more information about handling I/O errors, see Chapter 16.
Even a driver that uses buffered I/O might have to split up a transfer request if its device has very limited transfer capabilities.
If a requested transfer is only partly satisfied by a single DMA operation, the DpcForIsr is usually responsible for setting up one or more DMA operations until the current IRP’s requested Length (number of bytes) has been fully transferred.
For more information about using DMA, see Chapter 3. See also Chapter 11 for more information about AdapterControl routines and Chapter 16 for more information about maintaining cache coherency during DMA.
If a requested transfer is only partly satisfied by a single PIO operation, the DpcForIsr (or CustomDpc) is usually responsible for setting up one or more transfer operations until the current IRP’s requested Length (number of bytes) has been fully transferred.
For more information about using PIO, see Chapter 3. See also Chapter 16 for more information about maintaining processor cache coherency during PIO reads.
For more information about controller objects, see Chapter 3. For more information about ControllerControl routines, see Chapter 11.
Note that an NT device driver’s DpcForIsr (or CustomDpc) routine usually does most of the driver’s device I/O processing to satisfy IRPs. This routine also shares some of the responsibility for queueing IRPs to the device with the driver’s Dispatch routines.
Any DpcForIsr or CustomDpc routine should call IoStartNextPacket as soon as it can safely make this call: that is, without possibly causing a resource conflict or race condition with the driver’s StartIo routine or with any other routine the StartIo routine causes to run.
If a driver manages its own queueing of IRPs, its DpcForIsr or CustomDpc routine should notify the driver as soon as it is safe to dequeue the next IRP and to set up the device for the next request.
A DpcForIsr or CustomDpc routine must call IoStartNextPacket, or otherwise notify the appropriate driver routine when device I/O processing for the next request can be started, before the DpcForIsr or CustomDpc returns control. Depending on the driver and its device, this can occur well before the DpcForIsr or CustomDpc routine completes the current IRP with IoCompleteRequest, or it can occur immediately before this routine completes the current IRP and returns control.