Processing Read and Write Requests

< BACK  NEXT >
[oR]

The most basic of I/O requests is to exchange data between a user buffer and a device. The I/O Manager presents a traditional read/write abstraction to requestors for such data transfers. The requests are presented to a driver in the form of an IRP with major function code of either IRP_MJ_READ or IRP_MJ_WRITE. Another field within the IRP specifies the address of the requestor's buffer. Whether the buffer address is a direct virtual address or an intermediate nonpaged pool buffer allocated and maintained by the I/O Manager is determined by the device object's Flags field. Regardless, it is the responsibility of the read and write Dispatch routines to transfer data between the buffer and the actual device for the requested number of bytes.

User Buffer Access

As discussed in chapter 6, a driver can specify DO_DIRECT_IO or DO_BUFFERED_IO on a per-device basis (via the Flags field of the device object.) The exact behavior of the I/O Manager as well as the subsequent responsibilities of the Dispatch routine is discussed in the following sections.

BUFFERED I/O

At the start of either a read or write operation, the I/O Manager validates that all virtual memory pages spanned by the user's buffer are valid. For buffered I/O, it then allocates a nonpaged pool buffer of a size sufficient to hold the user's request. The address of this temporary buffer is place in the IRP field AssociatedIrp.SystemBuffer. This address remains valid for the duration of the transfer (i.e., until the IRP is marked as complete).

For read operations, the I/O Manager remembers the address of the original user buffer in the UserBuffer field of the IRP. It then uses this retained address upon completion of the request to copy data from the nonpaged pool into user memory.

For write operations, the I/O Manager copies the user buffer into the nonpaged buffer before invoking the write Dispatch routine. It then sets the UserBuffer field of the IRP to NULL, since there is no additional need to retain this state.

DIRECT I/O

At the start of the operation, the I/O Manager validates the page table entries spanned by the user's buffer. It then builds a data structure known as a Memory Descriptor List (MDL) and stores the address of the MDL in the IRP's MdlAddress field. Both the AssociatedIrp. SystemBuffer and UserBuffer fields are set to NULL.

For DMA operations, the MDL structure is used directly with an adapter object to perform the data transfer. Chapter 12 will discuss this process in detail. For programmed I/O devices, the MDL can be used with the function MmGetSystemAddressForMdl to get a system-address view of the user buffer. Using this technique, the user's buffer is locked down into physical memory (i.e., forced to be nonpagable) and is made accessible to driver code via an address above 0x80000000. (User-mode code must still access the same physical memory with its original address below 0x7FFFFFFF.) When the I/O request is ultimately completed, the user buffer is unlocked and unmapped from system address space.

NEITHER METHOD

There are two bits within the Flags field of the device object which specify either DO_BUFFERED_IO or DO_DIRECT_IO. If neither bit is set for a device, the I/O Manager performs neither action specified above. Instead, it simply places the user-space address of the requestor's buffer into the IRP's UserBuffer field. The AssociatedIrp.SystemBuffer and MdlAddress fields are set to NULL.

A simple user-mode address is not terribly useful. Most routines within a driver cannot be assured that at the time of their execution the original requestor's page tables are mapped. Thus, the user buffer address is usually worthless. There is one exception: At the time a Dispatch routine of a highest-level driver is invoked, execution occurs using the original requestor's thread. As such, the user-space address is mapped and valid. An intermediate driver or any DPC or Interrupt Service Routine (ISR) can never rely upon a user-space buffer being valid.

< BACK  NEXT >


The Windows 2000 Device Driver Book(c) A Guide for Programmers
The Windows 2000 Device Driver Book: A Guide for Programmers (2nd Edition)
ISBN: 0130204315
EAN: 2147483647
Year: 2000
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net