Chapter 8. Ioctl()s

Table of Contents

SG_IO
SG_GET_ACCESS_COUNT
SG_SET_COMMAND_Q (and _GET_)
SG_SET_DEBUG
SG_EMULATED_HOST
SG_SET_KEEP_ORPHAN (and _GET_)
SG_SET_FORCE_LOW_DMA
SG_GET_LOW_DMA
SG_NEXT_CMD_LEN
SG_GET_NUM_WAITING
SG_SET_FORCE_PACK_ID
SG_GET_PACK_ID
SG_GET_REQUEST_TABLE
SG_SET_RESERVED_SIZE (and _GET_ )
SG_SCSI_RESET
SG_GET_SCSI_ID
SG_GET_SG_TABLESIZE
SG_GET_TIMEOUT
SG_SET_TIMEOUT
SG_SET_TRANSFORM
SG_GET_TRANSFORM
Sg ioctls removed in version 3
SCSI_IOCTL_GET_IDLUN
SCSI_IOCTL_GET_PCI
SCSI_IOCTL_PROBE_HOST
SCSI_IOCTL_SEND_COMMAND

The Linux SCSI upper level drivers, including sg, have a "trickle down" ioctl() architecture. This means that ioctl()s whose request value (i.e. the second argument) is not understood by the upper level driver, are passed down to the SCSI mid-level. Those ioctl()s that are not understood by the mid level driver are passed down to the lower level (adapter) driver. If none of the 3 levels understands the ioctl() request value then -1 is returned and EINVAL is placed in errno. By convention the beginning of the request value's symbolic name indicates which level will respond to the ioctl(). For example, request values starting with "SG_" are processed by the sg driver while those starting with "SCSI_" are processed by the mid level.

Most of the sg ioctl()s read or write information via a pointer given as the third argument to the ioctl() call and return 0 on success. A few of the older ioctl()s that get a value from the driver return that value as the result of the ioctl() call (e.g. ioctl(SG_GET_TIMEOUT) ).

All sg driver ioctl()s are listed below. They all start with "SG_". They are followed by several interesting SCSI mid level ioctl()s which start with "SCSI_IOCTL_". The sg ioctl()s are roughly in alphabetical order (with _SET_, _GET_ and _FORCE_ ignored). Since ioctl(SG_IO) is a complete SCSI command request/response sequence then it is listed first.

SG_IO

SG_IO 0x2285.  The idea is deceptively simple: just hand a sg_io_hdr_t object to an ioctl() and it will return when the SCSI command is finished. It is logically equivalent to doing a write() followed by a blocking read(). The word "blocking" here implies the read() will wait until the SCSI command is complete.

The same file descriptor can be used both for SG_IO synchronous calls and the write() read() sequences at the same time. The sg driver makes sure that the response to a SG_IO call will never accidentally be fetched by a read(). Even though a single file descriptor can be shared in this manner, it is probably more sensible (and results in cleaner code) if separate file descriptors to the same SCSI device are used in this case.

It is possible that the wait for the command completion is interrupted by a signal. In this case the SG_IO call will yield an EINTR error. This is reasonably complex to handle and is discussed in the ioctl(SG_SET_KEEP_ORPHAN) description below. The following SCSI commands will be permitted by SG_IO when the sg file descriptor was opened O_RDONLY:

  • TEST UNIT READY

  • REQUEST SENSE

  • INQUIRY

  • READ CAPACITY

  • READ BUFFER

  • READ(6) (10) and (12)

  • MODE SENSE(6) and (10)

  • LOG SENSE

All commands to SCSI device type SCANNER are accepted. Other cases yield an EPERM error. Note that the write() read() interface must have the sg file descriptor open()-ed with O_RDWR as write permission is required by Linux to execute a write() system call.

The ability of the SG_IO ioctl() to issue certain SCSI commands has led to some relaxation on file descriptors open()ed "read-only" compared with the version 2 sg driver. The open() call will now attempt to allocate a reserved buffer for all newly opened file descriptors. The ioctl(SG_SET_RESERVED_SIZE) will now work on "read-only" file descriptors.