Using Direct I/O
Drivers for devices that can transfer large amounts of data at a time should use direct I/O for those transfers. Using direct I/O for large transfers improves a driver's performance, both by reducing its interrupt overhead and by eliminating the memory allocation and copying operations inherent in buffered I/O.
Generally, mass-storage device drivers request direct I/O for transfer requests, including lowest-level drivers that use direct memory access (DMA) or programmed I/O (PIO), as well as any intermediate drivers chained above them.
The I/O manager determines that an I/O operation is using direct I/O as follows:
For IRP_MJ_READ and IRP_MJ_WRITE requests, DO_DIRECT_IO is set in the Flags member of the DEVICE_OBJECT structure. For more information, see Initializing a Device Object.
For IRP_MJ_DEVICE_CONTROL and IRP_MJ_INTERNAL_DEVICE_CONTROL requests, the IOCTL code's value contains METHOD_IN_DIRECT or METHOD_OUT_DIRECT as the TransferType value in the IOCTL value. For more information, see Defining I/O Control Codes.
Drivers that use direct I/O will sometimes also use buffered I/O to handle some IRPs. In particular, drivers typically use buffered I/O for some I/O control codes for IRP_MJ_DEVICE_CONTROL requests that require data transfers, regardless of whether the driver uses direct I/O for read and write operations.
Setting up a direct I/O transfer varies slightly, depending on whether DMA or PIO is being used. For more information, see:
Drivers must take steps to maintain cache coherency during DMA and PIO transfers. For more information, see Maintaining Cache Coherency.