9.2 SCSI Port I/O Control Codes
All SCSI class drivers are required to set the minor function code with IRP_MN_SCSI_CLASS in the port driver’s I/O stack location of any IRP that a class driver allocates and sets up to send on to the system port driver. For example, all SCSI class drivers must set this minor function code when they make IOCTL_SCSI_GET_INQUIRY_DATA and IOCTL_SCSI_GET_CAPABILITIES requests during initialization.
For incoming IRPs originating with a user I/O request or with a higher-level driver, SCSI class drivers should ignore the minor function code in the port driver’s I/O stack location, leaving it as is. In general, such requests can be sent directly to the system-supplied port driver only if no SCSI class driver for the target device exists. Otherwise, such requests must be directed to the SCSI class driver for the appropriate type of underlying SCSI device.
The following shows I/O control requests that the system SCSI port driver supports. All public I/O control codes for the SCSI port driver use buffered I/O. Consequently, most input or output data for these requests is at Irp->AssociatedIrp.SystemBuffer.
IOCTL_SCSI_GET_INQUIRY_DATA
Operation
Returns the SCSI inquiry data for all devices on a given SCSI bus. Usually, the caller is a SCSI class driver, but the caller can be an application that makes IOCTL_SCSI_MINIPORT, IOCTL_SCSI_PASS_THROUGH, IOCTL_SCSI_PASS_THROUGH_DIRECT, or IOCTL_SCSI_RESCAN_BUS requests to the port driver.
Input
Parameters.DeviceIoControl.OutputBufferLength indicates the size in bytes of the buffer which must be >= (sizeof(SCSI_ADAPTER_BUS_INFO) + (NumberOfBuses -1) * sizeof(SCSI_BUS_DATA)) + (InquiryDataSize * NumberOfLUs), where the InquiryDataSize is (sizeof(SCSI_INQUIRY_DATA) - 1 + INQUIRYDATABUFFERSIZE) rounded up to an alignment boundary.
Output
The buffer at Irp->AssociatedIrp.SystemBuffer contains the returned inquiry data.
I/O Status Block
The Information field contains the number of bytes returned in the output buffer. The Status field indicates the results of the operation.
IOCTL_SCSI_GET_CAPABILITIES
Operation
Returns the capabilities and limitations of the underlying SCSI HBA. The most important information is returned in the MaximumTransferLength and AlignmentMask members. Class drivers and users of IOCTL_SCSI_PASS_THROUGH and IOCTL_SCSI_PASS_THROUGH_DIRECT are required to honor these limitations.
Input
Parameters.DeviceIoControl.OutputBufferLength in the I/O stack location indicates the size in bytes of the buffer, which must be >= sizeof(IO_SCSI_CAPABILITIES).
Output
Updated IO_SCSI_CAPABILITIES information is returned to the buffer at Irp->AssociatedIrp.SystemBuffer.
I/O Status Block
The Information field contains the number of bytes returned in the output buffer. The Status field indicates the results of the operation.
IOCTL_SCSI_GET_ADDRESS
Operation
Returns the address information, such as the target id (TID) and the logical unit number (LUN) of a particular SCSI target. This request must be directed at a class driver.
Input
Parameters.DeviceIoControl.OutputBufferLength in the I/O stack location indicates the size in bytes of the buffer, which must be >= sizeof(SCSI_ADDRESS).
Output
Updated SCSI_ADDRESS information is returned to the buffer at Irp->AssociatedIrp.SystemBuffer.
I/O Status Block
The Information field contains the number of bytes returned in the output buffer. The Status field indicates the results of the operation.
IOCTL_SCSI_MINIPORT
Operation
Sends a special control function to an HBA-specific miniport driver. Results vary, depending on the particular miniport driver to which this request is forwarded. If the caller specifies a nonzero Length, either the input or output buffer must be at least (sizeof(SRB_IO_CONTROL) + DataBufferLength)).
Input
The buffer at Irp->AssociatedIrp.SystemBuffer must contain an SRB_IO_CONTROL structure. Parameters.DeviceIoControl.InputBufferLength indicates the size in bytes of the buffer, which must be at least sizeof (SRB_IO_CONTROL), with additional storage for data if the Length field is nonzero.
Output
An updated SRB_IO_CONTROL structure is returned to the buffer at Irp->AssociatedIrp.SystemBuffer.
I/O Status Block
The Information field contains the number of bytes returned in the output buffer. The Status field indicates the results of the operation.
IOCTL_SCSI_PASS_THROUGH
Operation
Allows an application to send almost any SCSI command to a target device, with the following restrictions:
·Multitarget commands, such as COPY, are not allowed.
·Bidirectional data transfer operations are not supported.
·If a class driver for the target type of device exists, the request must be sent to that class driver. Thus, an application can send this request directly to the system port driver for a target logical unit only if there is no class driver for the type of device connected to that LU.
·This request cannot be used if the CDB might require the underlying miniport driver to access memory directly. If the caller’s CDB might require direct access to memory, use IOCTL_SCSI_PASS_THROUGH_DIRECT instead.
The calling application creates the SCSI command descriptor block, which can include a request for request-sense data if a CHECK CONDITION occurs. Any data transferred is double buffered.
Input
Parameters.DeviceIoControl.InputBufferLength indicates the size in bytes of the buffer at Irp->AssociatedIrp.SystemBuffer, which must be at least (RequestSenseStorageSize + sizeof (SCSI_PASS_THROUGH)). The size of the SCSI_PASS_THROUGH structure varies, depending on its DataTransferLength specification.
This structure includes a SCSI CDB, which must be initialized by the caller. For a data-out command, the data to be transferred is included in the buffer at Irp->AssociatedIrp.SystemBuffr at DataBufferOffset in the SCSI_PASS_THROUGH structure. However, the caller must allocate additional storage, immediately following SCSI_PASS_THROUGH, if the caller asks for request-sense data.
Output
The port driver returns any request-sense data and any data transferred from the device to the buffer at Irp->AssociatedIrp.SystemBuffer. The SenseInfoLength and DataTransferLength in the SCSI_PASS_THROUGH structure are updated to indicate the amount of data transferred.
I/O Status Block
The Information field is set to the number of bytes returned in the output buffer at Irp->AssociatedIrp.SystemBuffer. The Status field is set to STATUS_SUCCESS or possibly to STATUS_BUFFER_TOO_SMALL or STATUS_INVALID_PARAMETER if the input Length value in SCSI_PASS_THROUGH is improperly set.
IOCTL_SCSI_PASS_THROUGH_DIRECT
Operation
Allows an application to send almost any SCSI command to a target device, with the following restrictions:
·Multitarget commands, such as COPY, are not allowed.
·Bidirectional data transfer operations are not supported.
·If a class driver for the target type of device exists, the request must be sent to that class driver. Thus, an application can send this request directly to the system port driver for a target logical unit only if there is no class driver for the type of device connected to that LU.
·This request must be made if the input CDB might require the underlying miniport driver to access memory directly.
The calling application creates the SCSI command descriptor block, which can include a request for request-sense data if a CHECK CONDITION occurs. If the CDB requests a data transfer operation, the caller must set up a cache-aligned buffer from which or into which the miniport driver can transfer data directly.
Input
Parameters.DeviceIoControl.InputBufferLength indicates the size in bytes of the buffer at Irp->AssociatedIrp.SystemBuffer, which must be at least (RequestSenseStorageSize + sizeof (SCSI_PASS_THROUGH_DIRECT)). The size of the SCSI_PASS_THROUGH_DIRECT structure is fixed.
This structure includes a SCSI CDB, which must be initialized by the caller. For a data-out command, the data to be transferred must be in a cache-aligned buffer. The DataBuffer member of SCSI_PASS_THROUGH_DIRECT is a pointer to this cache-aligned buffer. The caller must allocate additional storage, following the SCSI_PASS_THROUGH_DIRECT structure, if the caller asks for request-sense data.
Output
The port driver returns any request-sense data and the SCSI_PASS_THROUGH_DIRECT structure to the buffer at Irp->AssociatedIrp.SystemBuffer. The SenseInfoLength and DataTransferLength are updated to indicate the amount of data transferred. The port driver returns any data transferred from the device to the supplied cache-aligned buffer at DataBuffer.
I/O Status Block
The Information field is set to the number of bytes returned in the output buffer at Irp->AssociatedIrp.SystemBuffer. The Status field is set to STATUS_SUCCESS or possibly to STATUS_BUFFER_TOO_SMALL or STATUS_INVALID_PARAMETER if the input Length value in SCSI_PASS_THROUGH is improperly set.
IOCTL_SCSI_RESCAN_BUS
Operation
The port driver rescans the LUNs on the bus(es). It collects SCSI inquiry data about all devices on the bus(es), while preserving any claims on their respective devices for SCSI class drivers.
Usually, this request originates in a system-supplied Win32 application such as Windisk or Setup when the user connects new device(s) on a SCSI bus dynamically: that is, without shutting down the system. When this request is satisfied, such an application next makes an IOCTL_SCSI_GET_INQUIRY_DATA request to the system port driver and examines the returned inquiry data. If the application finds any unclaimed devices of a given type, it then sends one or more IOCTL_DeviceType_FIND_NEW_DEVICES requests to the appropriate SCSI class drivers.
Input
None
Output
None
I/O Status Block
The Information field is set to zero. The Status field indicates the results of the operation.