Handling Transfers Asynchronously
Except for highest-level drivers, all drivers handle IRP_MJ_READ and IRP_MJ_WRITE requests asynchronously. The DispatchRead and DispatchWrite routines in even a highest-level driver cannot wait for lower-level drivers to finish processing an asynchronous read or write request; they must pass such a request on to lower drivers and return STATUS_PENDING.
Similarly, a lowest-level device driver's DispatchReadWrite routine must pass the transfer request on to other driver routines that process device I/O requests and then return STATUS_PENDING.
A higher-level driver sometimes must set up partial-transfer IRPs and pass them on to lower drivers. The higher-level driver can complete the original read/write IRP only when its partial-transfer requests have been completed by the lower drivers.
For example, a SCSI class driver's DispatchReadWrite routine is required to split large transfer requests that exceed the underlying HBA's transfer capabilities into a set of partial-transfer requests. The class driver must set up the parameters in its partial-transfer IRPs so that the SCSI port/miniport drivers can satisfy each partial-transfer request in a single DMA operation.
Other device drivers that use DMA or PIO also might need to split up large transfer requests for themselves.
For more information about using DMA and PIO, see Input/Output Techniques.