During normal processing, many transactions are queued in the SCSI device driver. As the SCSI device driver processes these transactions and passes them to the SCSI adapter device driver, the SCSI device driver moves them to the in-process queue. When the SCSI adapter device driver returns through the iodone service with one of these transactions, the SCSI device driver either recovers any errors on the transaction or returns using the iodone kernel service to the calling level.
The SCSI device driver can send only one sc_buf structure per call to the SCSI adapter device driver. Thus, the sc_buf.bufstruct.av_forw pointer should be null when given to the SCSI adapter device driver, which indicates that this is the only request. The SCSI device driver can queue multiple sc_buf requests by making multiple calls to the SCSI adapter device driver strategy routine.
Some kernel operations might be composed of sequential operations to a device. For example, if consecutive blocks are written to disk, blocks might or might not be in physically consecutive buffer pool blocks.
To enhance SCSI bus performance, the SCSI device driver should consolidate multiple queued requests when possible into a single SCSI command. To allow the SCSI adapter device driver the ability to handle the scatter and gather operations required, the sc_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 SCSI 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, because the SCSI adapter device driver must be given a single SCSI command to handle the requests. The spanned request should always consist of complete I/O requests (including the additional struct buf entries). The SCSI 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 SCSI adapter device driver's maximum allowable transfer size. To ease the design, implementation, and testing of components that might need to interact with multiple SCSI-adapter device drivers, a required minimum size has been established that all SCSI 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.h file:
SC_MAXREQUEST /* maximum transfer request for a single */ /* SCSI command (in bytes) */
If a transfer size larger than the supported maximum is attempted, the SCSI adapter device driver returns a value of EINVAL in the sc_buf.bufstruct.b_error field.
Due to system hardware requirements, the SCSI 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 SCSI commands and bus 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) SCSI bus transactions.
Single I/O requests larger than the maximum transfer size must be divided into smaller requests by the SCSI device driver. For calls to a SCSI 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 sc_buf.bp field should be null so that the SCSI adapter device driver uses only the information in the sc_buf structure to prepare for the DMA operation.
The gathered write commands facilitate communication applications that are required to send header and trailer messages with data buffers. These headers and trailers are typically the same or similar for each transfer. Therefore, there might be a single copy of these messages but multiple data buffers.
The gathered write commands, accessed through the sc_buf.resvd1 field, differ from the spanned commands, accessed through the sc_buf.bp field, in several ways:
To execute a gathered write command, the SCSI device driver must:
If any of these conditions are not met, the gathered write commands do not succeed and the sc_buf.bufstruct.b_error is set to EINVAL.
This interface allows the SCSI adapter device driver to perform the gathered write commands in both software or and hardware as long as the adapter supports this capability. Because the gathered write commands can be performed in software (by using such kernel services as uiomove), the contents of the resvd1 field and the uio struct can be altered. Therefore, the caller must restore the contents of both the resvd1 field and the uio struct before attempting a retry. Also, the retry must occur from the process level; it must not be performed from the caller's iodone subroutine.
To support SCSI adapter device drivers that perform the gathered write commands in software, additional return values in the sc_buf.bufstruct.b_error field are possible when gathered write commands are unsuccessful.
ENOMEM | Error due to lack of system memory to perform copy. |
EFAULT | Error due to memory copy problem. |
Note: The gathered write command facility is optional for both the SCSI device driver and the SCSI adapter device driver. Attempting a gathered write command to a SCSI adapter device driver that does not support gathered write can cause a system crash. Therefore, any SCSI device driver must issue a SCIOGTHW ioctl operation to the SCSI adapter device driver before using gathered writes. A SCSI adapter device driver that supports gathered writes must support the SCIOGTHW ioctl as well. The ioctl returns a successful return code if gathered writes are supported. If the ioctl fails, the SCSI device driver must not attempt a gathered write. Typically, a SCSI device driver places the SCIOGTHW call in its open routine for device instances that it will send gathered writes to.