During initialization, error recovery, and open or close operations, device drivers initiate some transactions not directly related to an operating system request. These transactions are called internal commands and are relatively simple to handle.
Internal commands differ from operating system-initiated transactions in several ways. The primary difference is that the device driver is required to generate a struct buf that is not related to a specific request. Also, the actual commands are typically more control-oriented than data transfer-related.
The only special requirement for commands with short data-phase transfers (less than or equal to 256 bytes) is that the device driver must have pinned the memory being transferred into or out of system memory pages. However, due to system hardware considerations, additional precautions must be taken for data transfers into system memory pages when the transfers are larger than 256 bytes. The problem is that any system memory area with a DMA data operation in progress causes the entire memory page that contains it to become inaccessible.
As a result, a device driver that initiates an internal command with more than 256 bytes must have preallocated and pinned an area of some multiple whose size is the system page size. The driver must not place in this area any other data areas that it may need to access while I/O is being performed into or out of that page. Memory pages so allocated must be avoided by the device driver from the moment the transaction is passed to the adapter device driver until the device driver iodone routine is called for the transaction (and for any other transactions to those pages).