[ Next Article | Previous Article | Book Contents | Library Home | Legal | Search ]
Kernel Extensions and Device Support Programming Concepts

Understanding the Execution of Initiator I/O Requests

During normal processing, many transactions are queued in the FCP device driver. As the FCP device driver processes these transactions and passes them to the FCP adapter device driver, the FCP device driver moves them to the in-process queue. When the FCP adapter device driver returns through the iodone service with one of these transactions, the FCP device driver either recovers any errors on the transaction or returns using the iodone kernel service to the calling level.

The FCP device driver can send only one scsi_buf structure per call to the FCP adapter device driver. Thus, the scsi_buf.bufstruct.av_forw pointer should be null when given to the FCP adapter device driver, which indicates that this is the only request. The FCP device driver can queue multiple scsi_buf requests by making multiple calls to the FCP adapter device driver strategy routine.

Spanned (Consolidated) Commands

Some kernel operations may be composed of sequential operations to a device. For example, if consecutive blocks are written to disk, blocks may or may not be in physically consecutive buffer pool blocks.

To enhance FCP transport layer performance, the FCP device driver should consolidate multiple queued requests when possible into a single FCP command. To allow the FCP adapter device driver the ability to handle the scatter and gather operations required, the scsi_buf.bp should always point to the first buf structure entry for the spanned transaction. A null-terminated list of additional struct buf entries should be chained from the first field through the buf.av_forw field to give the FCP adapter device driver enough information to perform the DMA scatter and gather operations required. This information must include at least the buffer's starting address, length, and cross-memory descriptor.

The spanned requests should always be for requests in either the read or write direction but not both, since the FCP adapter device driver must be given a single FCP command to handle the requests. The spanned request should always consist of complete I/O requests (including the additional struct buf entries). The FCP device driver should not attempt to use partial requests to reach the maximum transfer size.

The maximum transfer size is actually adapter-dependent. The IOCINFO ioctl operation can be used to discover the FCP adapter device driver's maximum allowable transfer size. To ease the design, implementation, and testing of components that may need to interact with multiple FCP-adapter device drivers, a required minimum size has been established that all FCP adapter device drivers must be capable of supporting. The value of this minimum/maximum transfer size is defined as the following value in the /usr/include/sys/scsi_buf.h file:

	SC_MAXREQUEST	/* maximum transfer request for a single */
 		        /* FCP command (in bytes)                */

If a transfer size larger than the supported maximum is attempted, the FCP adapter device driver returns a value of EINVAL in the scsi_buf.bufstruct.b_error field.

Due to system hardware requirements, the FCP device driver must consolidate only commands that are memory page-aligned at both their starting and ending addresses. Specifically, this applies to the consolidation of inner memory buffers. The ending address of the first buffer and the starting address of all subsequent buffers should be memory page-aligned. However, the starting address of the first memory buffer and the ending address of the last do not need to be aligned so.

The purpose of consolidating transactions is to decrease the number of FCP commands and transport layer phases required to perform the required operation. The time required to maintain the simple chain of buf structure entries is significantly less than the overhead of multiple (even two) FCP transport layer transactions.

Fragmented Commands

Single I/O requests larger than the maximum transfer size must be divided into smaller requests by the FCP device driver. For calls to a FCP device driver's character I/O (read/write) entry points, the uphysio kernel service can be used to break up these requests. For a fragmented command such as this, the scsi_buf.bp field should be null so that the FCP adapter device driver uses only the information in the scsi_buf structure to prepare for the DMA operation.

Related Information

FCP Subsystem Overview

FCP Error Recovery

Understanding the scsi_buf Structure


[ Next Article | Previous Article | Book Contents | Library Home | Legal | Search ]