During initialization, error recovery, and open or close operations, IDE 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 IDE device driver is required to generate a struct buf that is not related to a specific request. Also, the actual IDE commands are typically more control oriented than data transfer-related.
The only special requirement for commands is that the IDE device driver must have pinned the memory 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. 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, an IDE device driver that initiates an internal command 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 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).