The SG_IO ioctl
I decided that it would
be a good idea to write a little article about the SG_IO ioctl. Why
this ? are you asking. Now the first reason because I had a hard time
understanding it very well (not the SG_IO ioctl itself but the
evolution of the implementation in the Linux kernel) and maybe
there are some other developers like myself and maybe those would
like to understand better the whole system, so for those this
would be a helpful documentation (at least I think so). Another reason
is that right now I had nothing else to do, so I thought it is a good
time to write things down now.
Now lets dive in to the deep sea
Synopsis
The SG_IO ioctl can be incorporated in user applications to send low level SCSI specific commands (those defined in SPC, MMC, SBC and other standards, controlled, released by the T10 technical committee www.t10.org ) to devices . Not just SCSI devices use these commands but other devices either, like ATAPI and S-ATAPI CD/DVD devices, S-ATA hard drives, USB devices and more.
That SG_IO ioctl is implemented in the Linux SCSI subsystem architecture more precisely in the SCSI generic (sg) driver and later was ported to the Linux block subsystem too (like sd SCSI disk driver, sr, scd the SCSI CD drivers, and st the SCSI tape driver).
Now lets dive in to the deep sea
First of all we must to understand some basic things to understand the other more complex ones.
The Linux SCSI subsystem
The Linux SCSI subsystem is formed from Linux device drivers. Those device drivers controls the SCSI related devices found in a computer. The SCSI subsystem can be divided in 3 major parts: upper level drivers, middle level driver (scsi-mod) and low level drivers (LLD) like the ide-scsi driver or drivers like aic7xxx, qla2xxx . . .
The SCSI subsystem upper level drivers contains the sg SCSI generic character driver, the sd SCSI disc block driver, sr and scd the SCSI cd-rom block drivers and the st SCSI character tape driver. The upper level drivers are the closest to the Linux kernel. When a command is sent from a user application the command is passed to one of the SCSI upper level drivers (depending which driver controls the target device) then the upper level driver passes the command to the mid level driver then the mid level driver forwards the command to the low level driver (that are the closest to the real device). The command returning path is the same only backward (low level driver -> mid level driver -> upper level driver -> user application)
The Linux SCSI subsystem is formed from Linux device drivers. Those device drivers controls the SCSI related devices found in a computer. The SCSI subsystem can be divided in 3 major parts: upper level drivers, middle level driver (scsi-mod) and low level drivers (LLD) like the ide-scsi driver or drivers like aic7xxx, qla2xxx . . .
The SCSI subsystem upper level drivers contains the sg SCSI generic character driver, the sd SCSI disc block driver, sr and scd the SCSI cd-rom block drivers and the st SCSI character tape driver. The upper level drivers are the closest to the Linux kernel. When a command is sent from a user application the command is passed to one of the SCSI upper level drivers (depending which driver controls the target device) then the upper level driver passes the command to the mid level driver then the mid level driver forwards the command to the low level driver (that are the closest to the real device). The command returning path is the same only backward (low level driver -> mid level driver -> upper level driver -> user application)
Synopsis
The SG_IO ioctl can be incorporated in user applications to send low level SCSI specific commands (those defined in SPC, MMC, SBC and other standards, controlled, released by the T10 technical committee www.t10.org ) to devices . Not just SCSI devices use these commands but other devices either, like ATAPI and S-ATAPI CD/DVD devices, S-ATA hard drives, USB devices and more.
That SG_IO ioctl is implemented in the Linux SCSI subsystem architecture more precisely in the SCSI generic (sg) driver and later was ported to the Linux block subsystem too (like sd SCSI disk driver, sr, scd the SCSI CD drivers, and st the SCSI tape driver).
A little history
The first time when the sg driver
appeared in the Linux kernel was 1992, and the kernel version was
0.99.14. The developer of the driver Lawrence Foard. And remained unchanged until 1998 when two developers (Heiko
Eissfeldt and Joerg Schilling) resurrected
the sg driver and released a version 2 (2.1.31) in 1999 with the
help of the original author of the driver. This new sg driver was
incorporated in Linux kernel 2.2.6 in the same year.
In year 2000 another version of the driver was released sg v3 (3.1.10) and incorporated in the Linux kernel 2.3.43. One of this version major change was the SG_IO ioctl. Before this release there was no such ioctl, all the low level commands where sent via send() and write() functions asynchronously. Now the SG_IO ioctl was synchronous. That means that you do not need to send a write() command and then poll a read() function to get the returned data from the target device. With the SG_IO ioctl you send the command with the ioctl() function and the function blocks until a response is gained from the device or until an error occurred.
In 2001 a newer version 3 ( 3.1.17) was released with the Linux 2.4.0 series.
In December 2003 with the release of the Linux kernel 2.6.0 a major enhancement was added to the SG_IO ioctl. The implementation of that ioctl in the Linux kernel block layer.
Here is a table with the sg driver evolution over the years.
The listi is sorted by sg driver versions (not by year nor kernel version)
(if you find mistkes in the table, or if you could add to it please contact me)
Basic usage
In year 2000 another version of the driver was released sg v3 (3.1.10) and incorporated in the Linux kernel 2.3.43. One of this version major change was the SG_IO ioctl. Before this release there was no such ioctl, all the low level commands where sent via send() and write() functions asynchronously. Now the SG_IO ioctl was synchronous. That means that you do not need to send a write() command and then poll a read() function to get the returned data from the target device. With the SG_IO ioctl you send the command with the ioctl() function and the function blocks until a response is gained from the device or until an error occurred.
In 2001 a newer version 3 ( 3.1.17) was released with the Linux 2.4.0 series.
In December 2003 with the release of the Linux kernel 2.6.0 a major enhancement was added to the SG_IO ioctl. The implementation of that ioctl in the Linux kernel block layer.
Here is a table with the sg driver evolution over the years.
The listi is sorted by sg driver versions (not by year nor kernel version)
sg driver version | appeared in kernel | appeared in year | important driver changes, enhancements |
original sg (v1) | 0.99.14 | 1992 | - sg driver - allow user programs to control SCSI devices at a low level - interface structure sg_header |
original sg (v1) | 1.1.19 | 1994 | - added a 16 byte sense buffer to the sg_header structure interface |
sg v2 (2.1.31) | 2.2.6 | 1999 | - added scsi, host, and driver status fields to the sg_header structure - scatter-gather support added (allowing potentially megabyte transfers) - command queuing support |
sg v2 (2.1.32) | 2.2.8 | 1999 | |
sg v2 (2.1.34) | 2.2.10 | 1999 | |
sg v2 (2.1.36) | 2.2.14 | 2000 | |
sg v2 (2.1.38) | 2.2.16 | 2000 | |
sg v2 (2.1.39) | 2.2.17 | 2000 | |
sg v2 (2.1.40) | 2.2.20 | 2001 | |
sg v2 (2.1.41) | 2.2.41 | ||
sg v2 (2.3.35) | 2.3.20 | 1999 | |
sg v3 (3.1.10) | 2.3.43 | 2000 | - implemented the SG_IO syncronous ioctl (replaces the old read, write functions) - new interface structure (sg_io_hdr_t) - 64 byte sense buffer (before was 16 byte) - Direct IO support added - DMA residual count - proc_fs support in /proc/scsi/sg/ |
sg v3 (3.1.12) | 2.3.50 | 2000 | |
sg v3 (3.1.17) | 2.4.0 | 2001 | |
sg v3 (3.1.19) | 2.4.7 | 2001 | |
sg v3 (3.1.20) | 2.4.10 | 2001 | - SCSI commands up to 16 bytes (before was limited to 12 bytes) |
sg v3 (3.1.22) | 2.4.17 | 2001 | |
sg v3 (3.1.23) | 2.4.19 | 2002 | |
sg v3 (3.1.24) | 2.4.20 | 2002 | |
sg v3 (3.1.25) | 2.4.21 | 2003 | |
sg v3 (3.5.23) | 2.5.3 | 2002 | |
sg v3 (3.5.25) | 2.5.11 | 2002 | |
sg v3 (3.5.26) | 2.5.26 | 2002 | |
sg v3 (3.5.27) | 2.5.32 | 2002 | |
sg v3 (3.5.29) | 2.5.71 | 2003 | |
sg v3 (3.5.29) | 2.6.0 | 2003 | - SG_IO implemented in the block layer |
sg v3 (3.5.33) | 2.6.12 | 2005 | |
sg v3 (3.5.34) | 2.6.18 | 2006 |
(if you find mistkes in the table, or if you could add to it please contact me)
Basic usage
Some notes: Before the
release of the 2.6.0 kernel you could use
that ioctl only with the sg driver (if a device was mapped as
a sg device) like /dev/sg0, /dev/sg1 . . . The sg driver is
character
type so any device mapped as a sg device is a character device.
Once implemented in the block layer (particularly in the scsi_ioctl.c source file) you could use the SG_IO with block devices too. With the SCSI disk driver (sd) such devices are mapped as /dev/sda, /dev/sdb . . . and with the sr, scd block drivers for CD/DVD devices, like /dev/sr0, /dev/sr1 or /dev/scd0, dev/scd1 . . .
Once implemented in the block layer (particularly in the scsi_ioctl.c source file) you could use the SG_IO with block devices too. With the SCSI disk driver (sd) such devices are mapped as /dev/sda, /dev/sdb . . . and with the sr, scd block drivers for CD/DVD devices, like /dev/sr0, /dev/sr1 or /dev/scd0, dev/scd1 . . .
You can also use SG_IO with PATA or SATA CD/DVD drives which are not mapped as a SCSI device like
/dev/hda, or /dev/hdb . . . This is possible because CD/DVD drives
have a lot in common with SCSI devices, for instance the command sets,
and command data block structure. So even if your CD/DVD drive is not
mapped with any high level SCSI driver (sr, scd, sg) you can still use
the SG_IO ioctl because linux handles the drive almost like a SCSI
device and the SG_IO command is conveyed through the routines which
were in the scsi_ioctl.c source code (before kernel compilation).
You can not use the SG_IO with ATA hard drives if they are not mapped as a SCSI device because the ATA interface is totally different from the SCSI one. So to use SG_IO with ATA hard drives the kernel must to map the hard drive with the sd or sg SCSI driver first.
You can not use the SG_IO with ATA hard drives if they are not mapped as a SCSI device because the ATA interface is totally different from the SCSI one. So to use SG_IO with ATA hard drives the kernel must to map the hard drive with the sd or sg SCSI driver first.
SATA hard drives are closer to SCSI then ATA hard drives so you
can use the SG_IO beacuse those drives are mapped by the kernel
directly as SCSI devices (with the sd driver).
To be continued . . .
External references:
These are some useful URL-s related to the Linux SCSI subsystem and the SG_IO ioctl
- SCSI Generic HOWTO
- SCSI 2.4 HOWTOTo be continued . . .
External references:
These are some useful URL-s related to the Linux SCSI subsystem and the SG_IO ioctl
- SCSI Generic HOWTO
- Linux SG FAQ
- The Linux GS_IO ioctl in the lk 2.6 series
- The Linux SCSI Generic (sg) driver
Last updated: August 19 2008, 11:42 PM (UTC time)