This driver supports the following system calls, most of which are typical for a character device driver in Linux. They are:
open()
close()
write()
read()
ioctl()
poll()
fcntl(sg_fd, F_SETFL, oflags | FASYNC)
mmap()
The interface to these calls as seem from Linux applications is well documented in the "man" pages (in section 2).
A user application accesses the sg driver by using the open() system call
on sg device file name. Each sg device file name corresponds to one
(potentially) attached SCSI device. These are usually found in the
/dev
directory. Here are some sg device file names:
$ ls -l /dev/sg[01] crw-rw---- 1 root disk 21, 0 Aug 30 16:30 /dev/sg0 crw-rw---- 1 root disk 21, 1 Aug 30 16:30 /dev/sg1
The leading "c" at the front of the permissions indicates a character device. The absence of read or write permissions for "others" is prudent security. The major number of all sg device names is 21 while the minor number is the same as the number following "sg" in the device file name. When the device file system (devfs) is active on a system then the primarily sg device file names are found at the bottom of an informative subtree:
$ cd /dev/scsi/host1/bus0/target0/lun0 $ ls -l generic crw-r----- 1 root root 21, 1 Dec 31 1969 generic
Under devfs (when its daemon [devfsd] is running) there would usually
be a symbolic link from /dev/sg1
to
/dev/scsi/host1/bus0/target0/lun0/generic
. This is
so existing applications looking for the abridged device file name will
not be surprised. One advantage of devfs is that only attached SCSI devices
appear in the /dev/scsi
subtree.
A significant addition in sg v3 is an ioctl() called SG_IO which is functionally equivalent to a write() followed by a blocking read(). In certain contexts the write()/read() combination have advantages over SG_IO (e.g. command queuing) and continue to be supported.
The existing (and original) sg interface based on the sg_header structure is still available using a write()/read() sequence as before. The SG_IO ioctl will only accept the new interface based on the sg_io_hdr_t structure.
The sg v3 driver thus has a write() call that can accept either the older sg_header structure or the new sg_io_hdr_t structure. The write() calls decides which interface is being used based on the second integer position of the passed header (i.e. sg_header::reply_len or sg_io_hdr_t::dxfer_direction). If it is a positive number then the old interface is assumed. If it is a negative number then the new interface is assumed. The direction constants placed in 'dxfer_direction' in the new interface have been chosen to have negative values.
If a request is sent to a write() with the sg_io_hdr_t interface then the corresponding read() that fetches the response must also use the sg_io_hdr_t interface. The same rule applies to the sg_header interface.
This document concentrates on the sg_io_hdr_t interface introduced in the sg version 3 driver. For the definition of the older sg_header interface see the sg version 2 documentation. A brief description is given in Appendix B, sg_header, the original sg control structure.