Penguin
Diff: HowToSCSIGenericHOWTO
EditPageHistoryDiffInfoLikePages

Differences between current version and predecessor to the previous major change of HowToSCSIGenericHOWTO.

Other diffs: Previous Revision, Previous Author, or view the Annotated Edit History

Newer page: version 2 Last edited on Tuesday, October 26, 2004 5:02:24 pm by AristotlePagaltzis
Older page: version 1 Last edited on Friday, June 7, 2002 1:07:26 am by perry Revert
@@ -1,3264 +1 @@
-The Linux SCSI Generic (sg) HOWTO  
-!!!The Linux SCSI Generic (sg) HOWTO  
-!Douglas Gilbert  
-  
- dgilbert@interlog.com  
-  
-  
-  
-  
-Copyright (c) 2001, 2002 by Douglas Gilbert  
-  
-  
-  
-2002-05-03  
-  
-  
-__Revision History__Revision 1.22002-05-03Revised by: dpgENOMEM, EPERM; DRIVER_SENSE-bCHECK_CONDITIONRevision 1.12002-01-26Revised by: dpgcorrections, host_status, odd dxfer_lenRevision 1.02001-12-21Revised by: dpgoriginal, displace SCSI-PROGRAMMING-HOWTO  
-  
-  
-  
-  
-  
- This HOWTO describes the SCSI Generic driver (sg) found in the Linux  
-2.4 production series of kernels.  
-It focuses on the the interface and characteristics of the driver  
-that application writers may need to know. The driver's theory of  
-operations is covered and some brief examples are included.  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
-  
- Permission is granted to copy, distribute and/or modify this document  
-under the terms of the GNU Free Documentation License, Version 1.1  
-or any later version published by the Free Software Foundation;  
-with no Invariant Sections, with no Front-Cover Texts, and with  
-no Back-Cover Texts.  
-  
-  
-  
-  
- For an online copy of the license see  
- www.fsf.org/copyleft/fdl.html.  
-  
-  
-  
-  
-  
-  
-----; __Table of Contents__; 1. Introduction; 2. What the sg driver does; 3. Identifying the version of the SG driver; 4. Interface; 5. Theory of operation; 6. The sg_io_hdr_t structure in detail: ; 6.1. interface_id; 6.2. dxfer_direction; 6.3. cmd_len; 6.4. mx_sb_len; 6.5. iovec_count; 6.6. dxfer_len; 6.7. dxferp; 6.8. cmdp; 6.9. sbp; 6.10. timeout; 6.11. flags; 6.12. pack_id; 6.13. usr_ptr; 6.14. status; 6.15. masked_status; 6.16. msg_status; 6.17. sb_len_wr; 6.18. host_status; 6.19. driver_status; 6.20. resid; 6.21. duration; 6.22. info; 7. System calls: ; 7.1. open(); 7.2. write(); 7.3. read(); 7.4. poll(); 7.5. close(); 7.6. mmap(); 7.7. fcntl(sg_fd, F_SETFL, oflags | FASYNC); 7.8. Errors reported in errno; 8. Ioctl()s: ; 8.1. SG_IO; 8.2. SG_GET_ACCESS_COUNT; 8.3. SG_SET_COMMAND_Q (and _GET_); 8.4. SG_SET_DEBUG; 8.5. SG_EMULATED_HOST; 8.6. SG_SET_KEEP_ORPHAN (and _GET_); 8.7. SG_SET_FORCE_LOW_DMA; 8.8. SG_GET_LOW_DMA; 8.9. SG_NEXT_CMD_LEN; 8.10. SG_GET_NUM_WAITING; 8.11. SG_SET_FORCE_PACK_ID; 8.12. SG_GET_PACK_ID; 8.13. SG_GET_REQUEST_TABLE; 8.14. SG_SET_RESERVED_SIZE (and _GET_ ); 8.15. SG_SCSI_RESET; 8.16. SG_GET_SCSI_ID; 8.17. SG_GET_SG_TABLESIZE; 8.18. SG_GET_TIMEOUT; 8.19. SG_SET_TIMEOUT; 8.20. SG_SET_TRANSFORM; 8.21. SG_GET_TRANSFORM; 8.22. Sg ioctls removed in version 3; 8.23. SCSI_IOCTL_GET_IDLUN; 8.24. SCSI_IOCTL_GET_PCI; 8.25. SCSI_IOCTL_PROBE_HOST; 8.26. SCSI_IOCTL_SEND_COMMAND; 9. Direct and Mmap-ed IO: ; 9.1. Direct IO; 9.2. Mmap-ed IO; 10. Driver and module initialization; 11. Sg and the "proc" file system: ; 11.1. /proc/scsi/sg/debug; 12. Asynchronous usage of sg; A. Sg3_utils package; B. sg_header, the original sg control structure; C. Programming example; D. Debugging; E. Other references----  
-!!!Chapter 1. Introduction  
-  
-This document outlines the Linux SCSI Generic (sg) driver  
-interface as found in the 2.4 series kernels. The driver's purpose is to  
-allow SCSI commands to be sent directly to SCSI devices. The responses of  
-those commands can then be obtained. This type of driver is sometimes termed  
-as a "pass through".  
-In the case of SCSI disks, the block subsystem which is normally used to  
-mount and access a disk, is bypassed permitting low level operations such as  
-formatting to be performed. Various specialized applications for writing  
-CD-Rs and document scanning use the sg driver.  
-  
-  
-  
-Many devices that use other physical buses (e.g. ATAPI cdroms, USB  
-mass storage devices and IEEE 1394 sbp2 devices) utilize the SCSI command  
-set. By using Linux pseudo SCSI device drivers which bridge between  
-the native protocol stack and the SCSI subsystem, the upper level  
-SCSI device drivers, including sg, can be used to control "non-SCSI"  
-devices.  
-  
-  
-  
-This is the third major version of the sg driver.  
-A summary of the sg driver history is as follows:  
-  
-  
-  
-  
-  
-*  
-  
-sg version 1 (original) from 1992 to early 1999  
-(lk 2.2.5) . A copy of the original HOWTO (in plain text) is at  
-www.torque.net/sg/p/original/SCSI-Programming-HOWTO.txt  
-  
-  
-*  
-*  
-  
-sg version 2 from lk 2.2.6 in the 2.2 series. Its  
-documentation is available in abridged form  
- [[www.torque.net/sg/p/scsi-generic.txt ]  
-and a longer form  
-[[www.torque.net/sg/p/scsi-generic_long.txt].  
-  
-  
-*  
-*  
-  
-sg version 3 in the linux kernel 2.4 series.  
-  
-  
-*  
-This document can be found at the Linux Documentation Project's site at  
-www.linuxdoc.org/HOWTO/SCSI-Generic-HOWTO/ .  
-It is available in plain text and pdf renderings at that site.  
-A (possibly later) version of this document can be found at  
-www.torque.net/sg/p/sg_v3_ho.html.  
-That is a single html page; drop the ".html" extension for multi-page  
-html. There are also postscript, pdf and rtf renderings from the original  
-SGML (docbook) file at the same location.  
-  
-  
-  
-A more general description of the Linux SCSI subsystem of which sg is a  
-part can be found in the  
-  
-SCSI-2.4-HOWTO.  
-  
-  
-  
-This document was last modified on 3rd May 2002.  
-  
-----  
-!!!Chapter 2. What the sg driver does  
-  
-The sg driver permits user applications to send SCSI commands to devices  
-that understand them. SCSI commands are 6, 10, 12 or 16 bytes long  
-[[1].  
-The SCSI disk driver (sd), once device initialization is complete, only  
-sends SCSI READ and WRITE commands. There a several other interesting  
-things one might want to do, for example, perform a low level format or turn  
-on write caching.  
-  
-  
-  
-Associated with some SCSI commands there is data to be written to the device.  
-A SCSI WRITE command is one obvious example. When instructed, the sg driver  
-arranges for data to be transferred to the device along with the SCSI  
-command. It is possible that the lower level driver (often known as  
-the "Host Bus Adapter" [[HBA] or simply "adapter" driver) is unable to  
-send the command to the device. An example of this occurs when the device does  
-not respond in which case a 'host_status' or 'driver-status' error will  
-be conveyed back to the user application.  
-  
-  
-  
-All going well the SCSI command (and optionally some data) are conveyed  
-to the device. The device will respond with a single byte value called  
-the 'scsi_status'. GOOD is the scsi status indicating everything has  
-gone well. The most common other status is CHECK CONDITION. In this  
-latter case, the SCSI mid level issues a REQUEST SENSE SCSI command  
-The response of the REQUEST SENSE is 18 bytes or more in length and is  
-called the "sense buffer". It will indicate why the original command  
-may not have been executed. It is important to realize that a CHECK  
-CONDITION may vary in severity from informative (e.g. command needed to  
-be retried before succeeding) to fatal (e.g. "medium error" which often  
-indicates it is time to replace the disk).  
-  
-  
-  
-So in all cases a user application should check the various status values.  
-If necessary the "sense buffer" will be copied back to the user  
-application. SCSI commands like READ convey data back to the user application  
-(if they succeed). The sg driver arranges for this data transfer from the  
-device to the user space, if necessary.  
-  
-  
-  
-The description so far has concentrated on a disk device, but in reality  
-the sg driver is not needed very often for disks because there already  
-is a purpose built device driver for that: sd. The same is true of reading  
-audio and data CDs (sr [[scd]) and tapes (st). However scanners that  
-understand the SCSI command set and CDR "burning" programs tend to use  
-the sg driver. Other applications include tape "robots" and music  
-CD "ripping".  
-  
-  
-  
-To find out more about SCSI (draft) standards and resources visit  
-www.t10.org.  
-To use the sg device driver you should be familiar with the  
-SCSI commands supported by the device that you wish to control.  
-Getting hold of such information for devices like scanners can be  
-quite challenging (if the vendor does not provide it).  
-  
-  
-  
-The first SCSI command sent to a SCSI device when it is initialized  
-is an INQUIRY. All SCSI devices should respond promptly to an INQUIRY  
-supplying information such as the vendor, product designation and revision.  
-Appendix C shows the sg driver being used  
-to send an INQUIRY and print out some of the information in the response.  
-  
-----  
-!!!Chapter 3. Identifying the version of the SG driver  
-  
-Earlier versions of the sg device driver either have no version number  
-(e.g. the original driver) or a version number starting with "2". The  
-drivers that support this new interface have a major version number of  
-"3". The sg version numbers are of the form "x.y.z" and the single number  
-given by the SG_GET_VERSION_NUM ioctl() is calculated by  
-(x * 10000 + y * 100 + z). The sg driver discussed here will yield a  
-number greater than or equal to 30000 from SG_GET_VERSION_NUM. The version  
-number can also be seen using __cat /proc/scsi/sg/version__  
-in the new driver. This document describes sg version 3.1.24 for the  
-lk 2.4 series. Where some facility has been added during the lk 2.4  
-series (e.g. mmap-ed IO) and hence is not available in all versions  
-of the lk 2.4 series, this is noted.  
-[[2]  
-  
-  
-  
-Here is a list of sg versions that have appeared to date during the  
-lk 2.4 series.  
-  
-  
-  
-  
-  
-*  
-  
-lk 2.4.0 : sg version 3.1.17  
-  
-  
-*  
-*  
-  
-lk 2.4.7 : sg version 3.1.19 [[see include/scsi/sg.h in  
-that or a later version for the changelog]  
-  
-  
-*  
-*  
-  
-lk 2.4.10 : sg version 3.1.20 [[This version had several changes put into  
-it by third parties over the next 6 release kernel versions.]  
-  
-  
-*  
-*  
-  
-lk 2.4.17 : sg version 3.1.22  
-  
-  
-*  
-*  
-  
-lk 2.4.19 : sg version 3.1.24 [[lk 2.4.19 hasn't been released at the time  
-of writing. It will most likely contains sg version 3.1.24 .]  
-  
-  
-*  
-  
-----  
-!!!Chapter 4. Interface  
-  
-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.  
-  
-----  
-!!!Chapter 5. Theory of operation  
-  
-The path of a request through the sg driver can be broken into 3  
-distinct stages:  
-  
-  
-  
-  
-  
-#  
-  
-The request is received from the user, resources are  
-reserved as required (e.g. kernel buffer for indirect IO). If  
-necessary, data in the user space is transferred into kernel buffers.  
-Then the request is submitted to the SCSI mid level (and then onto  
-the adapter) for  
-execution. The SCSI mid level maintains a queue so the request may have  
-to wait. If a SCSI device supports command queuing then it may be able to  
-accommodate multiple outstanding requests.  
-  
-  
-#  
-#  
-  
- Assuming the SCSI adapter supports interrupts, then an interrupt  
-is received when the request is completed. When this interrupt arrives  
-the data transfer is complete. This means that if the SCSI command was  
-a READ then the data is in kernel buffers (indirect IO) or in user  
-buffers (direct or mmap-ed IO). The sg driver is informed of this  
-interrupt via a kernel mechanism called a "bottom half" handler. Some  
-kernel resources are freed up.  
-  
-  
-#  
-#  
-  
- The user makes a call to fetch the result of the request. If necessary,  
-data in kernel buffers is transferred to the user space. If necessary,  
-the sense buffer is written out to the user space. The remaining  
-kernel resources associated with this request are freed up.  
-  
-  
-#  
-  
-  
-  
-The write() call performs stage 1 while the read() call performs stage 3.  
-If the read() call is made before stage 2 is complete then it will either  
-wait or yield EAGAIN (depending on whether the file descriptor is blocking  
-or not). If asynchronous notification is being used then stage 2 will send  
-a SIGPOLL signal to the user process. The poll() system call will show this  
-file descriptor is now readable (unless it was sent by the SG_IO ioctl()).  
-  
-  
-  
-The SG_IO ioctl() performs stage 1, waits for stage 2 and then  
-performs stage 3. If the file descriptor in question is set O_NONBLOCK  
-then SG_IO will ignore this and still block! Also a SG_IO call will not  
-effect the poll() state nor cause a SIGPOLL signal to be sent. If you  
-really want non-blocking operation (e.g. for command queuing) then don't  
-use SG_IO; use the write() read() sequence instead.  
-  
-  
-  
-For more information about normal (or indirect), direct and mmap-ed IO  
-see Chapter 9 .  
-  
-  
-  
-Currently the sg driver uses one Linux major device number (char 21)  
-which in the lk 2.4 series limits it to handling 256 SCSI devices.  
-Any attempt to attach more than this number will rejected with a  
-message being sent to the console and the log file.  
-[[3]  
-  
-----  
-!!!Chapter 6. The sg_io_hdr_t structure in detail  
-  
-The main control structure for the version 3 SCSI generic driver has  
-a struct tag name of "sg_io_hdr" and a typedef name of "sg_io_hdr_t".  
-The structure is shown in abridged form below. The "[[i]" notation  
-indicates an input value while "[[o]" indicates a value that is output.  
-The "[[i-bo]" indicates a value that is conveyed from input to output and  
-apart from one special case, is not used by the driver. The "[[i-bo]" members  
-are meant to aid an application matching the request sent to a write()  
-to the corresponding response received by a read(). For pointers the  
-"[[*i]" indicates a pointer that is used for reading from user memory into  
-the driver, "[[*o]" is a pointer used for writing, and "[[*io]" indicates  
-a pointer used for either reading or writing.  
-  
-typedef struct sg_io_hdr  
-{  
-int interface_id; /* [[i] 'S' (required) */  
-int dxfer_direction; /* [[i] */  
-unsigned char cmd_len; /* [[i] */  
-unsigned char mx_sb_len; /* [[i] */  
-unsigned short iovec_count; /* [[i] */  
-unsigned int dxfer_len; /* [[i] */  
-void * dxferp; /* [[i], [[*io] */  
-unsigned char * cmdp; /* [[i], [[*i] */  
-unsigned char * sbp; /* [[i], [[*o] */  
-unsigned int timeout; /* [[i] unit: millisecs */  
-unsigned int flags; /* [[i] */  
-int pack_id; /* [[i-bo] */  
-void * usr_ptr; /* [[i-bo] */  
-unsigned char status; /* [[o] */  
-unsigned char masked_status;/* [[o] */  
-unsigned char msg_status; /* [[o] */  
-unsigned char sb_len_wr; /* [[o] */  
-unsigned short host_status; /* [[o] */  
-unsigned short driver_status;/* [[o] */  
-int resid; /* [[o] */  
-unsigned int duration; /* [[o] */  
-unsigned int info; /* [[o] */  
-} sg_io_hdr_t; /* 64 bytes long (on i386) */  
-  
-----  
-!!!6.1. interface_id  
-  
- This must be set to 'S' (capital ess). If not, the ENOSYS error  
-message is placed in errno. The idea is to allow interface variants  
-in the future that identify themselves with a different value.  
-[[The parallel port generic driver (pg) uses the letter 'P' to  
-identify itself.]  
-The type of interface_id is int.  
-  
-----  
-!!!6.2. dxfer_direction  
-  
-The type of dxfer_direction is int.  
-This is required to be one of the following:  
-  
-  
-  
-  
-  
-*  
-  
-SG_DXFER_NONE /* e.g. a SCSI Test Unit Ready command */  
-  
-  
-*  
-*  
-  
-SG_DXFER_TO_DEV /* e.g. a SCSI WRITE command */  
-  
-  
-*  
-*  
-  
-SG_DXFER_FROM_DEV /* e.g. a SCSI READ command */  
-  
-  
-*  
-*  
-  
-SG_DXFER_TO_FROM_DEV  
-  
-  
-*  
-*  
-  
-SG_DXFER_UNKNOWN  
-  
-  
-*  
-The value SG_DXFER_NONE should be used when there is no data transfer  
-associated with a command (e.g. TEST UNIT READY). The value  
-SG_DXFER_TO_DEV should be used when data is being moved from user  
-memory towards the device (e.g. WRITE). The value SG_DXFER_FROM_DEV  
-should be used when data is being moved from the device towards user  
-memory (e.g. READ).  
-  
-  
-  
- The value SG_DXFER_TO_FROM_DEV is only relevant to indirect IO  
-(otherwise it is treated like SG_DXFER_FROM_DEV). Data is moved from  
-the user space to the kernel buffers. The command is then performed and  
-most likely a READ-like command transfers data from the device into the  
-kernel buffers. Finally the kernel buffers are copied back into the user  
-space. This technique allows application writers to initialize the  
-buffer and perhaps deduce the number of bytes actually read from the  
-device (i.e. detect underrun). This is better done by using 'resid' if  
-it is supported.  
-  
-  
-  
- The value SG_DXFER_UNKNOWN is for those (rare) situations where the  
-data direction is not known. It may be useful for backward  
-compatibility of existing applications when the relevant direction  
-information is not available in the sg interface layer. There is  
-a (minor) performance "hit" associated with choosing this  
-option (e.g. on the PCI bus). Some recent pseudo device drivers (e.g.  
-USB mass storage) may have problems handling this value (especially  
-on vendor-specific SCSI commands).  
-  
-  
-  
- N.B. 'dxfer_direction' must have one of the five indicated values  
-and cannot be uninitialized or zero.  
-  
-  
-  
- If 'dxfer_len' is zero then all values are treated like SG_DXFER_NONE.  
-  
-----  
-!!!6.3. cmd_len  
-  
- This is the length in bytes of the SCSI command that 'cmdp' points  
-to. As a SCSI command is expected an EMSGSIZE error number is  
-produced if the value is less than 6 or greater than 16. Further,  
-if the SCSI mid level has a further limit then EMSGSIZE is produced  
-in this case as well.  
-[[4]  
-The type of cmd_len is unsigned char.  
-  
-----  
-!!!6.4. mx_sb_len  
-  
- This is the maximum size that can be written back to the 'sbp' pointer  
-when a sense_buffer is output which is usually in an error situation.  
-The actual number written out is given by 'sb_len_wr'. In all cases  
-'sb_len_wr' `= 'mx_sb_len' .  
-The type of mx_sb_len is unsigned char.  
-  
-----  
-!!!6.5. iovec_count  
-  
- This is the number of scatter gather elements in an array pointed  
-to by 'dxferp'. If the value is zero then scatter gather (in the  
-user space) is _not_ being used and 'dxferp' points to the data  
-transfer buffer. If the value is greater than zero then each  
-element of the array is assumed to be of the form:  
-  
- typedef struct sg_iovec  
-{  
-void * iov_base; /* starting address */  
-size_t iov_len; /* length in bytes */  
-} sg_iovec_t;  
-Note that this structure has been named and defined in such a way to  
-parallel "struct iovec" used by the readv() and writev() system calls  
-in Linux. See "man 2 readv".  
-  
-  
-  
-Note that the scatter gather capability offered by 'iovec_count' is unrelated  
-to the scatter gather capability (often associated with DMA) offered by  
-most modern SCSI adapters. Furthermore iovec_count's variety of scatter  
-gather (into the user space) is only available when normal (or "indirect")  
-IO is being used. Hence when the SG_FLAG_DIRECT_IO or SG_FLAG_MMAP_IO are  
-set in 'flags' then 'iovec_count' should be zero.  
-  
-  
-  
-The type of iovec_count is unsigned short.  
-  
-----  
-!!!6.6. dxfer_len  
-  
- This is the number of bytes to be moved in the data transfer  
-associated with the command. The direction of the transfer is indicated  
-by 'dxfer_direction'. If 'dxfer_len' is zero then no data transfer  
-takes place.  
-[[5]  
-  
-  
-  
- If iovec_count is non-zero then 'dxfer_len' should be equal to the sum  
-of iov_len lengths. If not, the minimum of the two is the transfer length.  
-The type of dxfer_len is unsigned int.  
-  
-----  
-!!!6.7. dxferp  
-  
- If 'iovec_count' is zero then this value is a pointer to user memory  
-of at least 'dxfer_len' bytes in length. If there is a data transfer  
-associated with the command then the data will be transferred to or  
-from this user memory.  
-If 'iovec_count' is greater than zero then this value points to a  
-scatter-gather array in user memory. Each element of this array  
-should be an object of type sg_iovec_t.  
-Note that data is sometimes written to user memory (e.g. from a failed  
-SCSI READ) even when an error has occurred.  
-  
-  
-  
-If mmap-ed IO is selected then the value in 'dxferp' is ignored and any  
-data transfers will be to and from the address returned by the prior  
-mmap() call.  
-  
-  
-  
-The type of dxferp is void * .  
-  
-----  
-!!!6.8. cmdp  
-  
- This value points to the SCSI command to be executed. The command is  
-assumed to be 'cmd_len' bytes long. If cmdp is NULL then the system  
-call yields an EMSGSIZE error number. The user memory pointed to is  
-only read (not written to).  
-The type of cmdp is unsigned char * .  
-  
-----  
-!!!6.9. sbp  
-  
- This value points to user memory of at least 'mx_sb_len' bytes length  
-where the SCSI sense buffer will be output. Most successful commands  
-do not output a sense buffer and this will be indicated by  
-'sb_len_wr' being zero. Note that there are error conditions that  
-don't result in a sense buffer be generated. The sense buffer results  
-from the "auto-sense" mechanism in the SCSI mid-level driver. This  
-mechanism detects a CHECK_CONDITION status and issues a REQUEST SENSE  
-command and conveys its response back as the "sense buffer".  
-The type of sbp is unsigned char * .  
-  
-----  
-!!!6.10. timeout  
-  
-This value is used to timeout the given command. The units of this  
-value are milliseconds. The time being measured is from when a command  
-is sent until when sg is informed the request has been completed. A  
-following read() can take as long as the user likes. Timeouts are best  
-avoided, especially if SCSI bus resets will adversely effect other  
-devices on that SCSI bus. When the timeout expires, the SCSI mid level  
-attempts error recovery. Error recovery completes when the first action  
-in the following list is successful. Note that a more extreme measure  
-is being taken at each step.  
-  
-  
-  
-  
-  
-*  
-  
-  
-the SCSI command that has timed out is aborted  
-[[6]  
-  
-  
-*  
-*  
-  
-  
-a SCSI device reset is attempted  
-  
-  
-*  
-*  
-  
-  
-a SCSI bus reset is attempted. Note this may have an adverse effect on  
-other devices sharing that SCSI bus.  
-  
-  
-*  
-*  
-  
-  
-a SCSI host (bus adapter) reset is attempted. This is an attempt to  
-re-initialize the adapter card associated with the SCSI device that  
-has the timed out command.  
-  
-  
-*  
-If all these fail then the device may be set "offline" which means that  
-it is no longer accessible (except by this driver when open()-ed  
-O_NONBLOCK) until the machine is rebooted. Offline devices still  
-appear in the __cat /proc/scsi/scsi__ listing. The  
-last column of the __cat /proc/scsi/sg/devices__  
-listing shows the online/offline status of a device ("1" means online  
-while "" is offline). The exact status returned depends on which  
-level of error recovery succeeded. Most likely the 'host_status' will be  
-set to DID_ABORT or DID_RESET.  
-  
-  
-  
-The two error statuses containing the word "TIME(_)OUT" are typically  
-_not_ related to a command timing out. DID_TIME_OUT in the 'host_status'  
-usually means an (unexpected) device selection timeout. DRIVER_TIMEOUT in  
-the 'driver_status' byte means the SCSI adapter is unable to control the  
-devices on its SCSI bus (and has given up).  
-  
-  
-  
-The type of timeout is unsigned int (and it represents milliseconds).  
-  
-----  
-!!!6.11. flags  
-  
- These are single or multi-bit values that can be "or-ed" together:  
-  
-  
-  
-  
-  
-*  
-  
- __SG_FLAG_DIRECT_IO__  
-This is a request for direct IO on the data transfer. If it cannot  
-be performed then the driver automatically performs indirect IO  
-instead. If it is important to find out which type of IO was  
-performed then check the values from the SG_INFO_DIRECT_IO_MASK in  
-'info' when the request packet is completed (i.e. after read() or  
-ioctl(,SG_IO,) ). The default action is to do indirect IO.  
-  
-  
-*  
-*  
-  
- __SG_FLAG_LUN_INHIBIT__  
-The default action of the sg driver to overwrite internally the top  
-3 bits of the second SCSI command byte with the LUN associated with  
-the file descriptor's device. To inhibit this action set this flag.  
-For SCSI 3 (or later) devices, this internal LUN overwrite does not  
-occur.  
-  
-  
-*  
-*  
-  
- __SG_FLAG_MMAP_IO__  
-When set the driver will attempt to procure the reserved buffer. If  
-the reserved buffer is occupied (EBUSY) or too small (ENOMEM) then  
-the operation (write() or ioctl(SG_IO)) fails. No data transfers occur  
-between the dxferp pointer and the reserved buffer (dxferp is ignored).  
-In order for a user application to access mmap-ed IO, it must have  
-successfully executed an appropriate mmap() system call on this sg  
-file descriptor. This precondition is not checked by write() or  
-ioctl(SG_IO) when this flag is set. Setting this flag and  
-SG_FLAG_DIRECT_IO results in a EINVAL error.  
-  
-  
-*  
-*  
-  
- __SG_FLAG_NO_DXFER__  
-When set user space data transfers to or from the kernel buffers do  
-not take place. This only has effect during indirect IO. This flag  
-is for testing bus speed (e.g. the "sg_rbuf" utility uses it).  
-  
-  
-*  
-The type of flags is unsigned int.  
-  
-----  
-!!!6.12. pack_id  
-  
- This value is not normally acted upon by the sg driver. It is provided  
-so the user can identify the request. This is useful when command queuing  
-is being used.  
-The "abnormal" case is when SG_SET_FORCE_PACK_ID is set and a 'pack_id'  
-other than -1 is given to read(). In this case the read() will wait  
-to fetch a request that matches this 'pack_id'. If this mode is used  
-be careful to set 'dxfer_direction' to a valid value (actually any of  
-the SG_DXFER_* values will do) on input to the read(), together with  
-the wanted pack_id.  
-The type of pack_id is int.  
-  
-----  
-!!!6.13. usr_ptr  
-  
- This value is not acted upon by the sg driver. It is meant to allow the  
-user to associate some object with this request (e.g. to maintain state  
-information).  
-The type of usr_ptr is void * .  
-  
-----  
-!!!6.14. status  
-  
- This is the SCSI status byte as defined by the SCSI standard. Note that  
-it can have vendor information set in bits , 6 and 7 (although this  
-is uncommon).  
-Further note that this 'status' data does _not_ match the definitions in  
-`scsi/scsi.hb (e.g. CHECK_CONDITION). The following 'masked_status'  
-does match those definitions.  
-[[7]  
-The type of status is unsigned char .  
-  
-----  
-!!!6.15. masked_status  
-  
- Logically: masked_status == ((status 8 0x3e) bb 1) .  
-So 'masked_status' strips the vendor information bits off 'status'  
-and then shifts it right one position. This makes it easier to do  
-things like "if (CHECK_CONDITION == masked_status) ..." using the  
-definitions in `scsi/scsi.hb. The defined values in this file are:  
-  
-  
-  
-  
-  
-*  
-  
- GOOD [[0x00]  
-  
-  
-*  
-*  
-  
- CHECK_CONDITION [[0x01]  
-  
-  
-*  
-*  
-  
- CONDITION_GOOD [[0x02]  
-  
-  
-*  
-*  
-  
- BUSY 0x04  
-  
-  
-*  
-*  
-  
- INTERMEDIATE_GOOD 0x08  
-  
-  
-*  
-*  
-  
- INTERMEDIATE_C_GOOD 0x0a  
-  
-  
-*  
-*  
-  
- RESERVATION_CONFLICT 0x0c  
-  
-  
-*  
-*  
-  
- COMMAND_TERMINATED 0x11  
-  
-  
-*  
-*  
-  
- QUEUE_FULL 0x14  
-  
-  
-*  
-N.B. 1 bit offset from usual SCSI status values  
-  
-  
-  
- Note that SCSI 3 defines some additional status codes.  
-[[8]  
-The type of masked_status is unsigned char .  
-  
-----  
-!!!6.16. msg_status  
-  
- The messaging level in SCSI is under the command level and knowledge  
-of what is happening at the messaging level is very rarely needed.  
-Furthermore most modern chip-sets used in SCSI adapters completely  
-hide this value. Nearly all adapters will return zero in 'msg_status'  
-all the time.  
-The type of msg_status is unsigned char .  
-  
-----  
-!!!6.17. sb_len_wr  
-  
- This is the actual number of bytes written to the user memory pointed  
-to by 'sbp'. 'sb_len_wr' is always `= 'mx_sb_len'. Linux 2.2 series  
-kernels (and earlier) truncate this value to a maximum of 16 bytes.  
-The actual number of bytes written will not exceed the length  
-indicated by "Additional Sense Length" field (byte 7) of the Request  
-Sense response.  
-The type of sb_len_wr is unsigned char .  
-  
-----  
-!!!6.18. host_status  
-  
- These codes potentially come from the firmware on a host adapter  
-or from one of several hosts that an adapter driver controls.  
-The 'host_status' field has the following values whose #defines mimic  
-those which are only visible within the kernel (with the "SG_ERR_"  
-removed from the front of each define). A copy of these defines can be  
-found in sg_err.h (see Appendix A):  
-  
-  
-  
-  
-  
-*  
-  
- SG_ERR_DID_OK [[0x00] NO error  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_NO_CONNECT [[0x01] Couldn't connect before timeout period  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_BUS_BUSY [[0x02] BUS stayed busy through time out period  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_TIME_OUT [[0x03] TIMED OUT for other reason (often this  
-an unexpected device selection timeout)  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_BAD_TARGET [[0x04] BAD target, device not responding?  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_ABORT [[0x05] Told to abort for some other reason. From  
-lk 2.4.15 the SCSI subsystem supports 16 byte commands however few  
-adapter drivers do. Those HBA drivers that don't support 16 byte  
-commands will yield this error code if a 16 byte command is passed to  
-a SCSI device they control.  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_PARITY [[0x06] Parity error. Older SCSI parallel buses  
-have a parity bit for error detection. This probably indicates  
-a cable or termination problem.  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_ERROR [[0x07] Internal error detected in the host adapter.  
-This may not be fatal (and the command may have succeeded). The  
-aic7xxx and sym53c8xx adapter drivers sometimes report this for  
-data underruns or overruns.  
-[[9]  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_RESET [[0x08] The SCSI bus (or this device) has been reset.  
-Any SCSI device on a SCSI bus is capable of instigating a reset.  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_BAD_INTR [[0x09] Got an interrupt we weren't expecting  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_PASSTHROUGH [[0x0a] Force command past mid-layer  
-  
-  
-*  
-*  
-  
- SG_ERR_DID_SOFT_ERROR [[0x0b] The low level driver wants a retry  
-  
-  
-*  
-The type of host_status is unsigned short .  
-  
-----  
-!!!6.19. driver_status  
-  
-One driver can potentially control several host adapters. For example  
-Advansys provide one Linux adapter driver that controls all adapters made  
-by that company - if 2 of more Advansys adapters are in 1 machine, then 1  
-driver controls both.  
-When ('driver_status' 8 SG_ERR_DRIVER_SENSE) is true the 'sense_buffer'  
-is also output. The 'driver_status' field has the following values whose  
-#defines mimic those which are only visible within the kernel (with the  
-"SG_ERR_" removed from the front of each define). A copy of these defines  
-can be found in sg_err.h (see the utilities section):  
-  
-  
-  
-  
-  
-*  
-  
- SG_ERR_DRIVER_OK [[0x00] Typically no suggestion  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_BUSY [[0x01]  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_SOFT [[0x02]  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_MEDIA [[0x03]  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_ERROR [[0x04]  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_INVALID [[0x05]  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_TIMEOUT [[0x06] Adapter driver is unable to control  
-the SCSI bus to its is setting its devices offline (and giving up)  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_HARD [[0x07]  
-  
-  
-*  
-*  
-  
- SG_ERR_DRIVER_SENSE [[0x08] Implies sense_buffer output  
-  
-  
-*  
-*  
-  
- above status 'or'ed with one of the following suggestions  
-  
-  
-*  
-*  
-  
- SG_ERR_SUGGEST_RETRY [[0x10]  
-  
-  
-*  
-*  
-  
- SG_ERR_SUGGEST_ABORT [[0x20]  
-  
-  
-*  
-*  
-  
- SG_ERR_SUGGEST_REMAP [[0x30]  
-  
-  
-*  
-*  
-  
- SG_ERR_SUGGEST_DIE [[0x40]  
-  
-  
-*  
-*  
-  
- SG_ERR_SUGGEST_SENSE [[0x80]  
-  
-  
-*  
-The type of driver_status is unsigned short .  
-  
-----  
-!!!6.20. resid  
-  
-This is the residual count from the data transfer. It is 'dxfer_len'  
-less the number of bytes actually transferred. In practice it only  
-reports underruns (i.e. positive number) as data overruns should  
-never happen. This value will be zero if there was no underrun or  
-the SCSI adapter doesn't support this feature.  
-[[10]  
-The type of resid is int .  
-  
-----  
-!!!6.21. duration  
-  
- This value will be the number of milliseconds from when a SCSI  
-command was sent until sg is informed that it is complete. For i386  
-machines the granularity is 10ms while on alpha machines it is 1ms.  
-This value is rounded toward zero.  
-The type of duration is unsigned int .  
-  
-----  
-!!!6.22. info  
-  
- This value is designed to convey useful information back to the user  
-about the associated request. This information does not necessarily  
-indicate an error. Several single bit and multi-bit fields are "or-ed"  
-together to make this value.  
-  
-  
-  
- A single bit component contained in SG_INFO_OK_MASK indicates whether  
-some error or status field is non-zero. If either 'masked_status',  
-'host_status' or 'driver_status' are non-zero then SG_INFO_CHECK is  
-set. The associated values are:  
-  
-  
-  
-  
-  
-*  
-  
- SG_INFO_OK_MASK [[0x1]  
-  
-  
-*  
-*  
-  
- SG_INFO_OK [[0x0] no sense, host nor driver "noise"  
-  
-  
-*  
-*  
-  
- SG_INFO_CHECK [[0x1] something abnormal happened. In most but not all  
-cases, the sense buffer will be written. If the sense buffer has  
-not been written than 'sb_len_wr' will be zero. This flag indicates  
-either 'masked_status', 'host_status' or 'driver_status' is  
-non-zero.  
-  
-  
-*  
-  
-  
-  
- A multi bit component contained in SG_INFO_DIRECT_IO_MASK indicates  
-what type of data transfer has just taken place. If indirect IO (or  
-no data transfer) has taken place then SG_INFO_INDIRECT_IO is matched.  
-Note that even if direct IO was requested in 'flags' the driver may  
-choose to do indirect IO instead. If direct IO was requested and  
-performed then SG_INFO_DIRECT_IO will be matched. Currently  
-SG_INFO_MIXED_IO is never set. The associated values are:  
-  
-  
-  
-  
-  
-*  
-  
- SG_INFO_DIRECT_IO_MASK [[0x6]  
-  
-  
-*  
-*  
-  
- SG_INFO_INDIRECT_IO [[0x0] data xfer via kernel buffers (or no xfer)  
-  
-  
-*  
-*  
-  
- SG_INFO_DIRECT_IO [[0x2]  
-  
-  
-*  
-*  
-  
- SG_INFO_MIXED_IO [[0x4] part direct, part indirect IO  
-  
-  
-*  
-The type of info is unsigned int .  
-  
-----  
-!!!Chapter 7. System calls  
-  
-System calls that can be used on sg devices are discussed in this chapter.  
-The ioctl() system call is discussed in the following chapter [[ see  
-Chapter 8 ].  
-  
-  
-  
-Successfully opening a sg device file name (e.g. /dev/sg0) establishes a link between a file descriptor and an attached  
-SCSI device. The sg driver maintains state information and resources at  
-both the SCSI device (e.g. exclusive lock) and the file descriptor (e.g.  
-reserved buffer) levels.  
-  
-  
-  
-A SCSI device can be detached while an application has a sg file  
-descriptor open. An example of this is a "hotplug" device such as a USB  
-mass storage device that has just been unplugged. Most subsequent system  
-calls that attempt to access the detached SCSI device will yield ENODEV.  
-The close() call will complete silently while the poll() call will  
-"or" in POLLHUP to its result. A subsequent attempt to open() that  
-device name will yield ENODEV.  
-  
-----  
-!!!7.1. open()  
-  
-__open(const char * filename, int flags). __The filename should be a sg device file name as discussed in the  
-Chapter 4.  
-Flags can be a number of the following or-ed together:  
-  
-  
-  
-  
-  
-*  
-  
-O_RDONLY restricts operations to read()s and ioctl()s  
-(i.e. can't use write() ).  
-  
-  
-*  
-*  
-  
-O_RDWR permits all system calls to be executed.  
-  
-  
-*  
-*  
-  
-O_EXCL waits for other opens on the associated SCSI device to be closed  
-before proceeding. If O_NONBLOCK is set then yields EBUSY when someone  
-else has the SCSI device open. The combination of O_RDONLY and O_EXCL is  
-disallowed.  
-  
-  
-*  
-*  
-  
-O_NONBLOCK Sets non-blocking mode. Calls that would otherwise block  
-yield EAGAIN (e.g. read() ) or EBUSY (e.g. open() ). This flag is ignored by  
-ioctl(SG_IO) .  
-  
-  
-*  
-Either O_RDONLY or O_RDWR must be set in flag. Either of the other 2  
-flags (but not both) can be or-ed in.  
-  
-  
-  
-Note that multiple file descriptors may be open to the same SCSI device.  
-[[This is a way of side stepping the SG_MAX_QUEUE limit.] At the sg level  
-separate state information is maintained. This means that even if  
-multiple file descriptors are open to a single SCSI device their  
-write() read() sequences are essentially independent.  
-  
-  
-  
-Open() calls may be blocked due to exclusive locks (i.e. O_EXCL). An  
-exclusive lock applies to a single SCSI device and only to sg's  
-use of that device (i.e. it has no effect on access via sd, sr or st  
-to that device). If the O_NONBLOCK flag is used then open() calls  
-that would have otherwise blocked, yield EBUSY. Applications that  
-scan sg devices trying to determine their identity (e.g. whether  
-one is a scanner) should use the O_NONBLOCK flag otherwise they  
-run the risk of blocking.  
-  
-  
-  
-The driver will attempt to reserve SG_DEF_RESERVED_SIZE bytes (32KBytes in  
-the current sg.h) on open(). The size of this reserved buffer can  
-subsequently be modified with the SG_SET_RESERVED_SIZE ioctl(). In both  
-cases these are requests subject to various dynamic constraints. The actual  
-amount of memory obtained can be found by the SG_GET_RESERVED_SIZE ioctl().  
-The reserved buffer will be used if:  
-  
-  
-  
-  
-  
-*  
-  
-it is not already in use (e.g. when command queuing is in use)  
-  
-  
-*  
-*  
-  
-a write() or ioctl(SG_IO) requests a data transfer size that is less  
-than or equal to the reserved buffer size.  
-  
-  
-*  
-  
-  
-  
-Returns a file descriptor if b= 0 , otherwise -1 implies an error.  
-  
-----  
-!!!7.2. write()  
-  
-__write(int sg_fd, const void * buffer, size_t count). __The action of write() with a control block based on struct sg_header is  
-discussed in the earlier document:  
-www.torque.net/sg/p/scsi-generic.txt  
-(i.e the sg version 2 documentation). This section describes the action of  
-write() when it is given a control block based on struct sg_io_hdr.  
-  
-  
-  
-The 'buffer' should point to an object of type sg_io_hdr_t and 'count'  
-should be sizeof(sg_io_hdr_t) [[it can be larger but the excess is ignored].  
-If the write() call succeeds then the 'count' is returned as the result.  
-  
-  
-  
-Up to SG_MAX_QUEUE (16) write()s can be queued up before any finished  
-requests are completed by read(). An attempt to queue more than that will  
-result in an EDOM error.  
-[[11]  
-The write() command should return more or  
-less immediately.  
-[[12]  
-  
-  
-  
-The version 2 sg driver defaulted the maximum queue length to 1 (and  
-made available the SG_SET_COMMAND_Q ioctl() to switch it to SG_MAX_QUEUE).  
-So for backward compatibility a file descriptor that only receives  
-sg_header structures in its write() will have a default "max" queue length  
-of 1. As soon as a sg_io_hdr_t structure is seen by a write() then the  
-maximum queue length is switched to SG_MAX_QUEUE on that file descriptor.  
-  
-  
-  
-The "const" on the 'buffer' pointer is respected by the sg driver. Data  
-is read in from the sg_io_hdr object that is pointed to. Significantly  
-this is when the 'sbp' and the 'dxferp' are recorded internally (i.e.  
-not from the sg_io_hdr object given to the corresponding read() ).  
-  
-----  
-!!!7.3. read()  
-  
-__read(int sg_fd, void * buffer, size_t count). __The action of read() with a control block based on struct sg_header is  
-discussed in the earlier document:  
-www.torque.net/sg/p/scsi-generic.txt  
-(i.e. the sg version 2 documentation). This section describes the action of  
-read() when it is given a control block based on struct sg_io_hdr.  
-  
-  
-  
-The 'buffer' should point to an object of type sg_io_hdr_t and 'count'  
-should be sizeof(sg_io_hdr_t) [[it can be larger but the excess is ignored].  
-If the read() call succeeds then the 'count' is returned as the result.  
-  
-  
-  
-By default, read() will return the oldest completed request that is  
-queued up. A read() will not interfere with any request associated  
-with the SG_IO ioctl() on this file descriptor except in a special  
-case when a SG_IO ioctl() is interrupted by a signal.  
-  
-  
-  
-If the SG_SET_FORCE_PACK_ID,1 ioctl() is active then read() will attempt  
-to fetch the packet whose pack_id (given earlier to write()) matches the  
-sg_io_hdr_t::pack_id given to this read(). If not available it will either  
-wait or yield EAGAIN. As a special case, -1 in sg_io_hdr_t::pack_id given  
-to read() will match the request whose response has been waiting for  
-the longest time. Take care to also set 'dxfer_direction' to any valid  
-value (e.g. SG_DXFER_NONE) when in this mode. The 'interface_id' member  
-should also be set appropriately.  
-  
-  
-  
-Apart from the SG_SET_FORCE_PACK_ID case (and then only for the 3 indicated  
-fields), the sg_io_hdr_t object given to read() can be uninitialized. Note  
-that the 'sbp' pointer value for optionally outputting a sense buffer was  
-recorded from the earlier, corresponding write().  
-  
-----  
-!!!7.4. poll()  
-  
-__poll(struct pollfd *ufds, unsigned int nfds,  
-int timeout). __This call can be used to check the state of a sg file descriptor. It  
-will always respond immediately. Typical usages are to periodically  
-poll the state of a sg file descriptor and to determine why a SIG_IO  
-signal was received.  
-  
-  
-  
-For file descriptors associated with sg devices:  
-  
-  
-  
-  
-  
-*  
-  
- POLLIN one or more responses is awaiting a read()  
-  
-  
-*  
-*  
-  
- POLLOUT command can be sent to write() without causing an EDOM  
-error (i.e. sufficient space on sg's queues)  
-  
-  
-*  
-*  
-  
- POLLHUP SCSI device has been detached, awaiting cleanup  
-  
-  
-*  
-*  
-  
- POLLERR internal structures are inconsistent  
-  
-  
-*  
-  
-  
-  
-POLLOUT indicates the sg will not block a new write() or SG_IO ioctl().  
-However it is still possible (but unlikely) that the mid level or an  
-adapter may block (or yield EAGAIN).  
-  
-----  
-!!!7.5. close()  
-  
-__close(int sg_fd). __Preferably a close() should be done after all issued write()s have had  
-their corresponding read() calls completed. Unfortunately this is not  
-always possible (e.g. the user may choose to send a kill signal to a  
-running process). The sg driver implements "fast" close semantics and thus  
-will return more or less immediately (i.e. not wait on any event). This  
-is application friendly but requires the sg driver to arrange for an  
-orderly cleanup of those packets that are still "in flight".  
-  
-  
-  
-When close() leaves outstanding SCSI commands still awaiting responses,  
-the sg driver maintains its internal structures for the now defunct  
-file descriptor. These internal structures are maintained until all  
-outstanding responses (some might be timeouts) are received. When the  
-sg driver is loaded as a module and has any open file descriptors or  
-"defunct" file descriptors then it cannot be unloaded. An attempt to  
-call __rmmod sg__ will report the driver is busy. Defunct  
-file descriptors that remain for some time, perhaps awaiting a timeout,  
-can be observed with the __cat /proc/scsi/sg/debug__  
-command. In this case "closed=1" will be set on the defunct file descriptor  
-[[see Section 11.1]. Defunct file descriptors do not impede  
-attempts by applications to open() new file descriptors on the same SCSI  
-device.  
-  
-  
-  
-The kernel arranges for only the last close() on a file descriptor to be  
-seen by a driver (and to emphasize this, the corresponding sg driver call  
-is named sg_release() rather than sg_close()). This is only significant when  
-an application uses fork() or dup().  
-  
-  
-  
-Returns 0 if successful, otherwise -1 implies an error.  
-  
-----  
-!!!7.6. mmap()  
-  
-__mmap(void * start, size_t length, int prot,  
-int flags, int sg_fd, off_t offset). __This system call returns a pointer to the beginning of the reserved buffer  
-associated with the sg file descriptor 'sg_fd'. The 'start' argument is  
-a hint to the kernel and is ignored by this driver; best set it to .  
-The 'length' argument should be less than or equal to the size of the  
-reserved buffer associated with 'sg_fd'. If it exceeds the  
-reserved buffer size (after 'length' has been rounded up to a page size  
-multiple) then MAP_FAILED is returned and ENOMEM is placed in errno. The  
-'prot' argument should either be PROT_READ or (PROT_READ | PROT_WRITE).  
-The 'flags' argument should contain MAP_SHARED. In a sense, the user  
-application is "sharing" data with the sg driver. The MAP_PRIVATE flag  
-does not play well with compiler optimization flags such as '-O2'.  
-The 'offset' argument must be set to 0 (or NULL).  
-  
-  
-  
-The mmap() system call can be made multiple times on the same sg_fd.  
-The munmap() system call is not required if close() is called on  
-sg_fd. Mmap-ed IO is well-behaved when a process is fork()-ed  
-(or the equivalent finer grained clone() system call is made).  
-In the case of a fork(), 2 processes will be sharing the same memory mapped  
-area together with the sg driver for a sg_fd and the last one to  
-close the sg_fd (or exit) will cause the shared memory to be freed.  
-  
-  
-  
-It is assumed that if the default reserved buffer size of 32 KB is  
-not sufficient then a ioctl(SG_SET_RESERVED_SIZE) call is made  
-prior to any calls to mmap(). If the required size is not a multiple  
-of the kernel's page size (returned by getpagesize() system call) then  
-the size passed to ioctl(SG_SET_RESERVED_SIZE) should be rounded up  
-to the next page size multiple.  
-  
-  
-  
-Mmap-ed IO is requested by setting (or or-ing in) the SG_FLAG_MMAP_IO  
-constant into the flag member of the the sg_io_hdr structure prior to  
-a call to write() or ioctl(SG_IO). The logic to do mmap-ed IO _assumes_  
-that an appropriate mmap() call has been made by the application. In  
-other words it does not check.  
-[[13]  
-  
-----  
-!!!7.7. fcntl(sg_fd, F_SETFL, oflags | FASYNC)  
-  
-__fcntl(int sg_fd, int cmd, long arg). __There are several uses for this system call in association with a sg  
-file descriptor. The following pseudo code shows code that is useful for  
-scanning the sg devices, taking care not to be caught in a wait for  
-an O_EXCL lock by another process, and when the appropriate device is  
-found, switching to normal blocked io. A working example of this logic  
-is in the sg_scan utility program.  
-  
-open("/dev/sg0", O_RDONLY | O_NONBLOCK)  
-/* check device, EBUSY means some other process has O_EXCL lock on it */  
-/* when the device you want is found then ... */  
-flags = fcntl(sg_fd, F_GETFL)  
-fcntl(sg_fd, F_SETFL, flags 8 (~ O_NONBLOCK))  
-/* since, with simple apps, it is easier to use normal blocked io */  
-  
-  
-  
-The sg driver supports asynchronous notification.  
-This is a non-blocking mode of operation in which, when the driver receives  
-data back from a device so that a read() can be done, it sends a SIGPOLL  
-(aka SIGIO) signal to the owning process. Here is a code snippet from  
-the sg_poll test program.  
-  
-sigemptyset(8sig_set)  
-sigaddset(8sig_set, SIGPOLL)  
-sigaction(SIGPOLL, 8s_action, )  
-fcntl(sg_fd, F_SETOWN, getpid())  
-flags = fcntl(sg_fd, F_GETFL);  
-fcntl(sg_fd, F_SETFL, flags | O_ASYNC)  
-  
-----  
-!!!7.8. Errors reported in errno  
-  
-With the original interface almost any string could be accidentally  
-given to write() and potentially (but rarely) something nasty could happen.  
-If some error was detected then more than likely EIO was placed in errno.  
-  
-  
-  
-Unfortunately this can still happen with write() since it can accept  
-both the original struct sg_header or the newer sg_io_hdr_t described in  
-this note. However since the SG_IO ioctl() will only accept the sg_io_hdr_t  
-structure there is less chance of a random string being interpreted  
-as a command. Since the sg_io_hdr_t interface does a lot more error  
-checking, it attempts to give out more precise errno values to help  
-the user pinpoint the problem. [[Admittedly some of these errno values  
-are picked in an arbitrary way from the large set of available values.]  
-  
-  
-  
-In most cases when a system call on a sg file descriptor fails, the call  
-in question will return -1. After an application detects that a system  
-call has failed it should read the value in the "errno" variable (prior  
-to do any more system calls). Applications should include the `errno.hb  
-header.  
-  
-  
-  
-Below is a table of errno values indicating which calls to sg will  
-generate them and the meaning of the error. A write() call is indicated by  
-"w", a read() call by "r" and an open() call by "o".  
-  
-  
-  
-  
-errno which_calls Meaning  
------ ----------- ----------------------------------------------  
-EACCES `some ioctlsb Root permission (more precisely CAP_SYS_ADMIN  
-or CAP_SYS_RAWIO) required. Also may occur during  
-an attempted write to /proc/scsi/sg files.  
-EAGAIN r The file descriptor is non-blocking and the request  
-has not been completed yet.  
-EAGAIN w,SG_IO SCSI sub-system has (temporarily) run out of  
-command blocks.  
-EBADF w File descriptor was not open()ed O_RDWR.  
-EBUSY o Someone else has an O_EXCL lock on this device.  
-EBUSY w With mmap-ed IO, the reserved buffer already in use.  
-EBUSY `some ioctlsb Attempt to change something (e.g. reserved buffer  
-size) when the resource was in use.  
-EDOM w,SG_IO Too many requests queued against this file  
-descriptor. Limit is SG_MAX_QUEUE active requests.  
-If sg_header interface is being used then the  
-default queue depth is 1. Use SG_SET_COMMAND_Q  
-ioctl() to increase it.  
-EFAULT w,r,SG_IO Pointer to user space invalid.  
-`most ioctlsb  
-EINVAL w,r Size given as 3rd argument not large enough for the  
-sg_io_hdr_t structure. Both direct and mmap-ed IO  
-selected.  
-EIO w Size given as 3rd argument less than size of old  
-header structure (sg_header). Additionally a write()  
-with the old header will yield this error for most  
-detected malformed requests.  
-EIO r A read() with the older sg_header structure yields  
-this value for some errors that it detects.  
-EINTR o While waiting for the O_EXCL lock to clear this call  
-was interrupted by a signal.  
-EINTR r,SG_IO While waiting for the request to finish this call  
-was interrupted by a signal.  
-EINTR w [[Very unlikely] While waiting for an internal SCSI  
-resource this call was interrupted by a signal.  
-EMSGSIZE w,SG_IO SCSI command size ('cmd_len') was too small  
-(i.e. ` 6) or too large  
-ENODEV o Tried to open() a file with no associated device.  
-[[Perhaps sg has not been built into the kernel or  
-is not available as a module?]  
-ENODEV o,w,r,SG_IO SCSI device has detached, awaiting cleanup.  
-User should close fd. Poll() will yield POLLHUP.  
-ENOENT o Given filename not found.  
-ENOMEM o [[Very unlikely] Kernel was not even able to find  
-enough memory for this file descriptor's context.  
-ENOMEM w,SG_IO Kernel unable to find memory for internal buffers.  
-This is usually associated with indirect IO.  
-For mmap-ed IO 'dxfer_len' greater than reserved  
-buffer size.  
-Lower level (adapter) driver does not support enough  
-scatter gather elements for requested data transfer.  
-ENOSYS w,SG_IO 'interface_id' of a sg_io_hdr_t object was _not_ 'S'.  
-ENXIO o "remove-single-device" may have removed this device.  
-ENXIO o, w,r,SG_IO Internal error (including SCSI sub-system busy doing  
-error processing - e.g. SCSI bus reset). When a  
-SCSI device is offline, this is the response. This  
-can be bypassed by opening O_NONBLOCK.  
-EPERM o Can't use O_EXCL when open()ing with O_RDONLY  
-EPERM w,SG_IO File descriptor open()-ed O_RDONLY but O_RDWR  
-`some ioctlsb access mode needed for this operation.  
-  
-----  
-!!!Chapter 8. Ioctl()s  
-  
-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.  
-  
-----  
-!!!8.1. 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.  
-  
-----  
-!!!8.2. SG_GET_ACCESS_COUNT  
-  
-__SG_GET_ACCESS_COUNT 0x2289. __This ioctl() yields the access count maintained by the mid level  
-for this SCSI device. This number is incremented by each open()  
-call done by the upper level SCSI drivers (i.e. sd, sr, st and sg)  
-and decremented by those drivers' release(). [[A driver's release()  
-corresponds to the last close() on a file descriptor, or is  
-supplied by the kernel when a process is aborted.] Each SCSI  
-device has a separate access count.  
-  
-----  
-!!!8.3. SG_SET_COMMAND_Q (and _GET_)  
-  
-__SG_SET_COMMAND_Q 0x2271 [[_GET_ 0x2270] . __The default it the original sg driver was not to allow commands to be  
-queued on the same file descriptor (actually it was more restrictive,  
-commands could not be queued on a SCSI device). The version 2 sg driver  
-kept this action as its default (for backward compatibility) and offered  
-these ioctl()s to change and monitor the command queuing state.  
-  
-----  
-!!!8.4. SG_SET_DEBUG  
-  
-__SG_SET_DEBUG 0x227e. __The third argument is assumed to point to an int. The default value is .  
-If this call is made pointing to an int greater than 0 then any SCSI  
-request that is issued that results in the SCSI status of CHECK_CONDITION  
-(or COMMAND_TERMINATED) will cause a message to be sent to the log (and  
-perhaps the console). The message is information derived from the sense  
-buffer (i.e. the SCSI error message) and it is prefixed with  
-"sg_cmd_done_bh".  
-  
-  
-  
-The other actions of debug mode performed in version 2 of the sg driver  
-have been removed as they are no longer needed. The internal state  
-of the sg driver can now be found by viewing the output of  
-__cat /proc/scsi/sg/debug__.  
-  
-----  
-!!!8.5. SG_EMULATED_HOST  
-  
-__SG_EMULATED_HOST 0x2203. __Assumes 3rd argument points to an int and outputs a flag indicating  
-whether the host (adapter) is connected to a "real" SCSI bus or is an  
-emulated one (e.g. ide-scsi or usb storage device driver). A value of 1  
-means emulated while 0 is not. [[To check: is IEEE1394 a "real" SCSI serial  
-bus?]  
-  
-----  
-!!!8.6. SG_SET_KEEP_ORPHAN (and _GET_)  
-  
-__SG_SET_KEEP_ORPHAN 0x2287 [[_GET_ 0x2288]. __These ioctl()s allow the setting and reading of the "keep_orphan"  
-flag. This controls what happens to the request associated with a  
-SG_IO ioctl() that is interrupted (i.e. errno is EINTR). The  
-default action is to drop the response as soon as it is received.  
-This corresponds to the "keep_orphan" flag being . When the  
-"keep_orphan" flag is 1 then the response is transformed in such  
-a way that it can be fetched by a read(). This is the only  
-circumstance in which a request sent by a SG_IO ioctl() can have  
-the associated response fetched by a read().  
-  
-----  
-!!!8.7. SG_SET_FORCE_LOW_DMA  
-  
-__SG_SET_FORCE_LOW_DMA 0x2279. __Assumes 3rd argument points to an int containing 0 or 1. 0 (default)  
-means sg decides whether to use memory above 16 Mbyte level (on i386)  
-based on the host adapter being used by this SCSI device. Typically  
-PCI SCSI adapters will indicate they can DMA to the whole 32 bit address  
-space.  
-If 1 is given then the host adapter is overridden and only memory below  
-the 16MB level is used for DMA. A requirement for this should be  
-extremely rare. If the "reserved" buffer allocated on open() is not in  
-use then it will be de-allocated and re-allocated under the 16MB level  
-(and the latter operation could fail yielding ENOMEM).  
-Only the current file descriptor is affected.  
-  
-----  
-!!!8.8. SG_GET_LOW_DMA  
-  
-__SG_GET_LOW_DMA 0x227a. __Assumes 3rd argument points to an int and places 0 or 1 in it.  
-indicates the whole 32 bit address space is being used for DMA transfers  
-on this file descriptor. 1 indicates the memory below the 16MB level  
-(on i386) is being used (and this may be the case because the host  
-adapters setting has been overridden by SG_SET_FORCE_LOW_DMA,1 .  
-  
-----  
-!!!8.9. SG_NEXT_CMD_LEN  
-  
-__SG_NEXT_CMD_LEN 0x2283. __This ioctl() is not required with sg_io_hdr structure since command length  
-is set explicitly for every command.  
-Assumes 3rd argument is pointing to an int. The value of the int (if b )  
-will be used as the SCSI command length of the next SCSI command sent to  
-a write() using the sg_header interface. After that write() the SCSI  
-command length logic is reset to use automatic length detection (i.e.  
-depending on SCSI command group and the 'twelve_byte' field). If the  
-current SCSI command length maximum of 16 is exceeded then the affected  
-write() will yield an EDOM error. Giving this ioctl() a value of 0 will  
-set automatic length detection for the next write(). N.B. Only the following  
-write() on this fd is affected by this ioctl().  
-  
-----  
-!!!8.10. SG_GET_NUM_WAITING  
-  
-__SG_GET_NUM_WAITING 0x227d. __Assumes 3rd argument points to an int and places the number of packets  
-waiting to be read in it. Only those requests that have been issued by  
-a write() and are now available to be read() are counted. In other words  
-any ioctl(SG_IO) operations underway on this file descriptor will not  
-effect this count  
-[[14].  
-  
-----  
-!!!8.11. SG_SET_FORCE_PACK_ID  
-  
-__SG_SET_FORCE_PACK_ID 0x227b. __Assumes 3rd argument is pointing to an int. 0 (default) instructs read()  
-to return the oldest (written) packet if multiple packets are  
-waiting to be read. 1 instructs read() to view the sg_io_hdr::pack_id  
-(or sg_header::pack_id) as input and return the oldest packet matching  
-that pack_id or wait until it arrives. If the file descriptor is in  
-O_NONBLOCK state, rather than wait this ioctl() will yield EAGAIN.  
-As a special case the pack_id of -1  
-given to read() in the mode will match the oldest packet.  
-Only the current file descriptor is affected by this command.  
-  
-----  
-!!!8.12. SG_GET_PACK_ID  
-  
-__SG_GET_PACK_ID 0x227c. __Assumes 3rd argument points to an int and places the pack_id of the  
-oldest (written) packet in it. If no packet is waiting to be read then  
-yields -1.  
-  
-----  
-!!!8.13. SG_GET_REQUEST_TABLE  
-  
-__SG_GET_REQUEST_TABLE 0x2286. __This ioctl outputs an array of information about the status of  
-requests associated with the current file descriptor. Its 3rd  
-argument should point to memory large enough to receive SG_MAX_QUEUE  
-objects of the sg_req_info_t structure. This structure has the  
-following members:  
-  
- req_state  
-0 -b request not in use  
-1 -b request has been sent, but is not finished (i.e. it is  
-between stages 1 and 2 in the "theory of operation")  
-2 -b request is ready to be read() (i.e. it is between stages  
-2 and 3 in the "theory of operation")  
-orphan  
-0 -b normal request  
-1 -b request sent by SG_IO ioctl() which has been interrupted  
-by a signal  
-sg_io_owned  
-0 -b request sent by a write()  
-1 -b request sent by a SG_IO ioctl()  
-problem  
-0 -b no problem (or 1 == req_state)  
-1 -b req_state is 2 and either masked_status, host_status or  
-driver_status is non-zero  
-duration  
-[[if 1 == req_state] time since request was sent (in millisecs)  
-[[if 2 == req_state] duration of request (in millisecs). Clock  
-is stopped when stage 2 in "theory of operation" is  
-reached  
-pack_id  
-usr_ptr  
-these are user provided values in the sg_io_hdr_t (or  
-struct sg_header) that sent the request  
-  
-----  
-!!!8.14. SG_SET_RESERVED_SIZE (and _GET_ )  
-  
-__SG_SET_RESERVED_SIZE 0x2275 [[_GET_ 0x2272]. __Both ioctl()s assume the 3rd argument is pointing to an int.  
-  
-  
-  
-For ioctl(SG_SET_RESERVED_SIZE) the value will be used to  
-request a new reserved buffer of that size. The previous reserved buffer  
-is freed (if it is not in use; if it was in use then the ioctl() fails and  
-EBUSY is placed in errno).  
-A new reserved buffer is then allocated and its actual size can be found by  
-calling the ioctl(SG_GET_RESERVED_SIZE). The reserved buffer is then used  
-for DMA purposes by subsequent write() and ioctl(SG_IO) commands if it is  
-not already in use and if the write() is not calling for a buffer size  
-larger than that reserved. The reserved buffer may well be a series of  
-kernel buffers if the adapter supports scatter-gather. Large buffers can  
-be requested (e.g. 4 MB) but not necessarily granted. Once a mmap() call  
-has been made on a sg file descriptor, subsequent calls to this ioctl()  
-will fail with EBUSY placed in errno.  
-  
-  
-  
-In the case of ioctl(SG_GET_RESERVED_SIZE) the size in bytes of  
-the reserved buffer from open() or the most recent SG_SET_RESERVED_SIZE  
-ioctl() call on this fd. The result can be 0 if memory is very tight. In  
-this case it may not be wise to attempt something like burning a CD on  
-this file descriptor.  
-  
-----  
-!!!8.15. SG_SCSI_RESET  
-  
-__SG_SCSI_RESET 0x2284. __Assumes 3rd argument points to an int. That int should be one of the  
-following defined in the sg.h header:  
-  
-  
-  
-  
-  
-*  
-  
-SG_SCSI_RESET_NOTHING (0x0): can be used to poll the device  
-after a reset has been issued to see if it has returned to the normal  
-state. If it is still being reset or it is offline then EBUSY will be  
-placed in errno,  
-  
-  
-*  
-*  
-  
-SG_SCSI_RESET_DEVICE (0x1): issues a reset to the SCSI  
-device associated with the current sg file descriptor,  
-  
-  
-*  
-*  
-  
-SG_SCSI_RESET_BUS (0x2): issues a reset to the SCSI  
-bus that contains the device associated with the current sg file descriptor.  
-This will usually have an adverse effect on any other SCSI device sharing  
-this SCSI bus, especially if it was in the middle of an operation,  
-  
-  
-*  
-*  
-  
-SG_SCSI_RESET_HOST (0x3): issues a reset to the host that  
-controls the SCSI bus that contains the device associated with the  
-current sg file descriptor. This operation can have an adverse effect  
-on any SCSI device that is connected to this host.  
-  
-  
-*  
-The reset options are in ascending order of severity. Not all levels  
-are supported by all linux lower level drivers. Most lower level  
-(adapter) drivers support the SCSI bus reset. These boards often issue  
-a SCSI bus reset during their initialization.  
-  
-  
-  
-Unfortunately this ioctl() doesn't currently do much (but may in the  
-future after other issues are resolved). Yields an EBUSY error if the  
-SCSI bus or the associated device is being reset when this ioctl() is  
-called, otherwise returns .  
-N.B. In some recent distributions there is a patch to the SCSI mid level  
-code that activates this ioctl. Check your distribution.  
-  
-----  
-!!!8.16. SG_GET_SCSI_ID  
-  
-__SG_GET_SCSI_ID 0x2276. __Assumes 3rd argument is pointing to an object of type Sg_scsi_id (see  
-sg.h) and populates it. That structure contains ints for host_no,  
-channel, scsi_id, lun, scsi_type, allowable commands per lun and  
-queue_depth. Most of this information is available from other sources  
-(e.g. SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER) but tends to be  
-awkward to collect.  
-Allowable commands per lun and queue_depth give an insight to the  
-command queuing capabilities of the adapters and the device. The latter  
-overrides the former (logically) and the former is only of interest  
-if it is equal to queue_depth which probably indicates the device  
-does not support queuing commands (e.g. most scanners).  
-  
-typedef struct sg_scsi_id { /* used by SG_GET_SCSI_ID ioctl() */  
-int host_no; /* as in "scsi`nb" where 'n' is one of , 1, 2 etc */  
-int channel;  
-int scsi_id; /* scsi id of target device */  
-int lun;  
-int scsi_type; /* TYPE_... defined in scsi/scsi.h */  
-short h_cmd_per_lun;/* host (adapter) maximum commands per lun */  
-short d_queue_depth;/* device (or adapter) maximum queue length */  
-int unused[[2]; /* probably find a good use, set 0 for now */  
-} sg_scsi_id_t;  
-  
-----  
-!!!8.17. SG_GET_SG_TABLESIZE  
-  
-__SG_GET_SG_TABLESIZE 0x227F. __Assumes 3rd argument points to an int and places the maximum number of  
-scatter gather elements supported by the host adapter associated with  
-the current SCSI device. 0 indicates that the adapter does support scatter  
-gather.  
-  
-----  
-!!!8.18. SG_GET_TIMEOUT  
-  
-__SG_GET_TIMEOUT 0x2202. __Ignores its 3rd argument and _returns_ the timeout value (which will be  
-b= 0 ). The unit of this timeout is "jiffies" which are currently 10  
-millisecond intervals on i386 (less on an alpha). Linux supplies  
-a manifest constant HZ which is the number of "jiffies" in 1 second.  
-This ioctl() is not relevant to the sg version 3 driver because timeouts  
-are specified explicitly for each command in the sg_io_hdr structure.  
-  
-----  
-!!!8.19. SG_SET_TIMEOUT  
-  
-__SG_SET_TIMEOUT 0x2201. __Assumes 3rd argument points to an int containing the new timeout value  
-for this file descriptor. The unit is a "jiffy". Packets that are  
-already "in flight" will not be affected. The default value is set  
-on open() and is SG_DEFAULT_TIMEOUT (defined in sg.h). This default is  
-currently 1 minute and may not be long enough for formats. Negative  
-values will yield an EIO error.  
-This ioctl() is not relevant to the sg version 3 driver because timeouts  
-are specified explicitly for each command in the sg_io_hdr structure.  
-Only when the sg_header structure is used is the timeout inherited from  
-this value (help on a per file descriptor basis).  
-  
-----  
-!!!8.20. SG_SET_TRANSFORM  
-  
-__SG_SET_TRANSFORM 0x2204. __Only is meaningful when SG_EMULATED host has yielded 1 (i.e. the low-level  
-is the ide-scsi device driver); otherwise an EINVAL error occurs. The  
-default state is to _not_ transform SCSI commands to the corresponding  
-ATAPI commands but pass them straight through as is. [[Only certain classes  
-of SCSI commands need to be transformed to their ATAPI equivalents.]  
-The third argument is interpreted as an integer. When it is non-zero then  
-a flag is set inside the ide-scsi driver that transforms subsequent  
-commands sent to this driver. When zero is passed as the 3rd argument to  
-this ioctl then the flag within the ide-scsi driver is cleared and  
-subsequent commands are not transformed. Beware, this state will affect  
-all devices (and hence all related sg file descriptors) associated with  
-this ide-scsi "bus".  
-  
-----  
-!!!8.21. SG_GET_TRANSFORM  
-  
-__SG_GET_TRANSFORM 0x2205. __Third argument is ignored. Only is meaningful when SG_EMULATED host has  
-yielded 1 (i.e. the low-level is the ide-scsi device driver); otherwise  
-an EINVAL error occurs. Returns 0 to indicate _not_ transforming SCSI  
-to ATAPI commands (default). Returns 1 when it is transforming them.  
-  
-----  
-!!!8.22. Sg ioctls removed in version 3  
-  
-Some seldom used ioctl()s introduced in the sg 2.x series drivers have  
-been withdrawn. They are:  
-  
-  
-  
-  
-  
-*  
-  
-SG_SET_UNDERRUN_FLAG (and _GET_) [[use 'resid' in this new  
-interface]  
-  
-  
-*  
-*  
-  
-SG_SET_MERGE_FD (and _GET) [[added complexity with little  
-benefit]  
-  
-  
-*  
-  
-----  
-!!!8.23. SCSI_IOCTL_GET_IDLUN  
-  
-__SCSI_IOCTL_GET_IDLUN 0x5382. __This ioctl takes a pointer to a "struct scsi_idlun" object as its third  
-argument. The "struct scsi_idlun" is not visible to user applications.  
-To use this, that structure needs to be replicated in  
-the user's program. Something like:  
-  
-typedef struct my_scsi_idlun {  
-int four_in_one; /* 4 separate bytes of info compacted into 1 int */  
-int host_unique_id; /* distinguishes adapter cards from same supplier */  
-} My_scsi_idlun;  
-"four_in_one" is made up as follows:  
-  
-(scsi_device_id | (lun `` 8) | (channel `` 16) | (host_no `` 24))  
-These 4 components are assumed (or masked) to be 1 byte each. These are  
-the four numbers that the SCSI subsystem uses to index devices, often  
-written as "`host_no, channel, scsi_id, lunb".  
-The 'host_unique_id' assigns a different number to each controller from the  
-same manufacturer/low-level device driver. Most of the information  
-provided by this command is more easily obtained from SG_GET_SCSI_ID.  
-  
-  
-  
-The 'host_no' element is a change in lk 2.4 kernels. [[In the lk 2.2 series  
-and earlier, it was 'low_inode 8 0xff' from the procfs entry  
-corresponding to the host.] This change makes the use of the  
-SCSI_IOCTL_GET_BUS_NUMBER ioctl() superfluous.  
-  
-  
-  
-The advantage of this ioctl() is that it can be called on any SCSI file  
-descriptor.  
-  
-----  
-!!!8.24. SCSI_IOCTL_GET_PCI  
-  
-__SCSI_IOCTL_GET_PCI 0x5387. __Yields the PCI slot name (pci_dev::slot_name) associated with the lower  
-level (adapter) driver that controls the current device. Up to 8 characters  
-are output to the location pointed to by 'arg'. If the current device  
-is not controlled by a PCI device then errno is set to ENXIO.  
-[[This ioctl() was introduced in lk 2.4.4]  
-  
-----  
-!!!8.25. SCSI_IOCTL_PROBE_HOST  
-  
-__SCSI_IOCTL_PROBE_HOST 0x5385. __This command should be given a pointer to a 'char' array as its 3rd  
-argument. That array should be at least sizeof(int) long and have the  
-length of the array as an 'int' at the beginning of the array! An ASCII  
-string of no greater than that length containing "information" (or the  
-name) of SCSI host (i.e. adapter) associated with this file descriptor is  
-then placed in the given byte array. N.B. A trailing '\' may need to  
-be put on the output string if it has been truncated by the input  
-length. Returns 1 if host is present, 0 if it is not and a negative  
-value if there is an error.  
-  
-----  
-!!!8.26. SCSI_IOCTL_SEND_COMMAND  
-  
-__SCSI_IOCTL_SEND_COMMAND 0x1. __This ioctl() also offers a "pass through" SCSI command capability  
-which is a subset of what is offered by the sg driver.  
-  
-  
-  
-The structure that we are passed should look like:  
-  
- struct sdata {  
-unsigned int inlen; [[i] Length of data written to device  
-unsigned int outlen; [[i] Length of data read from device  
-unsigned char cmd[[x]; [[i] SCSI command (6 `= x `= 16)  
-[[o] Data read from device starts here  
-[[o] On error, sense buffer starts here  
-unsigned char wdata[[y]; [[i] Data written to device starts here  
-};  
-Notes:  
-  
-  
-  
-  
-  
-*  
-  
- The SCSI command length is determined by examining the 1st byte of the  
-given command  
-[[15]  
-. There is no way to override this.  
-  
-  
-*  
-*  
-  
-Data transfers are limited to PAGE_SIZE (4K on i386, 8K on alpha).  
-  
-  
-*  
-*  
-  
-The length (x + y) must be at least OMAX_SB_LEN bytes long to accommodate  
-the sense buffer when an error occurs. The sense buffer is truncated to  
-OMAX_SB_LEN (16) bytes so that old code will not be surprised.  
-  
-  
-*  
-*  
-  
-If a Unix error occurs (e.g. ENOMEM) then the user will receive a  
-negative return and the Unix error code in 'errno'. If the SCSI command  
-succeeds then 0 is returned. Positive numbers returned are the compacted  
-SCSI error codes (4 bytes in one int) where the lowest byte is the SCSI  
-status. See the drivers/scsi/scsi.h file for more information on this.  
-  
-  
-*  
-  
-----  
-!!!Chapter 9. Direct and Mmap-ed IO  
-  
-The normal action of the sg driver for a read operation (from a device)  
-is to request the lower level (adapter) driver to DMA  
-[[16]  
-data into kernel buffers that the sg driver manages. The sg driver will  
-then copy the contents of its buffers into the user space. [[This sequence  
-is reversed for a write operation (towards a device)]. While this double  
-handling of data is obviously inefficient it does decouple some hardware  
-issues from user applications. For these and historical reasons the  
-"double-buffered" IO remains the default for the sg driver.  
-  
-  
-  
-Both "direct" and "mmap-ed" IO are techniques that permit the data  
-to be DMA-ed directly from the lower level (adapter) driver into  
-the user application (vice versa for write operations). Both techniques  
-result in faster speed, smaller latencies and lower CPU utilization  
-but come at the expense of complexity (as always). For example the Linux  
-kernel must not attempt to swap out pages in a user application that a  
-SCSI adapter is busy DMA-ing data into.  
-  
-----  
-!!!9.1. Direct IO  
-  
-Direct IO uses the kiobuf mechanism [[see the Linux  
-Device Drivers book] to manipulate memory  
-allocated within the user space so that a lower level (adapter) driver  
-can DMA directly to or from that user space memory. Since the user  
-can give a different data buffer to each SCSI command passed through  
-the sg interface then the kiobuf mechanism needs to setup its structures  
-(and undo that setup) for each SCSI command.  
-[[17]  
-Direct IO is available as an option in sg 3.1.18 (before that the sg driver  
-needed to be recompiled with an altered define). Direct IO support is  
-designed in such a way that if it is requested and cannot be performed  
-then the command will still be performed using indirect IO. If direct IO  
-is requested and has been performed then the SG_INFO_DIRECT_IO bit will  
-be set in the 'info' member of the sg_io_hdr_t control structure after  
-the request has been completed. Direct IO is not supported on ISA SCSI  
-adapters since they only can address a 24 bit address space.  
-  
-  
-  
-One limit on direct IO is that sg_io_hdr_t::iovec_count==. So the user  
-cannot (currently) use application level scatter gather and direct IO on  
-the same request.  
-  
-  
-  
-For direct IO to be worthwhile, a reasonable amount of data should be  
-requested for data transfer. For transfers less than 8 KByte it is  
-probably not worth the trouble. On the other hand "locking down" a  
-multiple 512 KB blocks of data for direct IO could adversely impact  
-overall system performance. Remember that for the duration of a direct  
-IO request, the data transfer buffer is mapped to a fixed memory location  
-and locked in such a way that it won't be swapped out. This can "cramp  
-the style" of the kernel if it is overdone.  
-  
-  
-  
-Prior to sg 3.1.18 the direct IO code was commented out with the  
-"SG_ALLOW_DIO" define. In sg 3.1.18 (available for lk 2.4.2 and later)  
-the direct IO code is active but is defaulted off by a run time value.  
-This value can be accessed via the "proc" file system at  
-/proc/scsi/sg/allow_dio . Direct IO is enabled when  
-a user with root permissions writes "1" to that file:  
-__echo 1 b /proc/scsi/sg/allow_dio__ . If SG_FLAG_DIRECT_IO  
-is set in sg_io_hdr::flags but /proc/scsi/sg/allow_dio  
-holds "" then indirect IO will be performed (and this is indicated by  
-((sg_io_hdr::info 8 SG_INFO_DIRECT_IO_MASK) == SG_INFO_INDIRECT_IO)  
-after the request is completed).  
-  
-----  
-!!!9.2. Mmap-ed IO  
-  
-Memory-mapped IO takes a different approach from direct IO to removing  
-the extra data copy performed by normal ("indirect") IO. With mmap-ed  
-IO the application calls the mmap() system call to memory map sg's reserved  
-buffer. The sg driver maintains one reserved buffer per file descriptor.  
-The default size of the reserved buffer is 32 KB and it can be changed  
-with the ioctl(SG_SET_RESERVED_SIZE). The mmap() system call only needs  
-to be called once prior  
-[[18]  
-to doing mmap-ed IO. For more details on the mmap() see  
-Section 7.6. An application indicates that it wants mmap-ed on  
-a SCSI request by setting the SG_FLAG_MMAP_IO value in 'flags'.  
-  
-  
-  
-Since there is only reserved buffer per sg file descriptor then only one  
-mmap-ed IO command can be active at one time. In order to perform command  
-queuing with mmap-ed IO, an application will need to open() multiple  
-file descriptors to the same SCSI device.  
-With mmap-ed IO the various status values and the sense buffer (if  
-required) are conveyed back to an application in the same fashion as  
-normal ("indirect") IO.  
-  
-  
-  
-Mmap-ed has very low per command latency since the reserved buffer mapping  
-only needs to be done once per file descriptor. Also the reserved buffer  
-is set up by the sg driver to aid the efficient construction of the  
-internal scatter gather list used by the lower level (adapter) driver for  
-DMA purposes. This tends to be more efficient than the user memory that  
-direct IO requires the sg driver to process into an internal scatter  
-gather list. So on both these counts, mmap-ed IO has the edge over direct IO.  
-  
-----  
-!!!Chapter 10. Driver and module initialization  
-  
-The size of the default reserved buffer can be specified when the  
-sg driver is loaded. If it is built into the kernel then use:  
-  
- sg_def_reserved_size=`nb  
-on the boot line (only supported in 2.4 kernels).  
-  
-  
-  
-If sg is a module, it can be loaded with __modprobe__  
-in either manner:  
-  
- modprobe sg  
-modprobe sg def_reserved_size=`nb  
-In the second case "`nb" is an integer (non negative). The default  
-value is the value of the SG_DEF_RESERVED_SIZE defined in sg.h .  
-This is currently 32768.  
-  
-  
-  
-If sg is a module, it can be unloaded with __rmmod__  
-like this:  
-  
- rmmod sg  
-However if there is a file descriptor still open with the sg driver  
-(or there is an outstanding request awaiting a response) then the  
-sg module is considered to be busy and can't be unloaded.  
-  
-----  
-!!!Chapter 11. Sg and the "proc" file system  
-  
-The sg driver provides information about the SCSI subsystem and the current  
-internal state of the sg driver in the /proc/scsi/sg  
-directory. Some sg driver defaults can be changed by super user writing values  
-to these "pseudo" files  
-[[19].  
-  
-  
-  
-The following files which are readable by all:  
-  
-allow_dio 0 indicates direct IO disable, 1 for enabled  
-debug debug information including active request data  
-def_reserved_size default buffer size reserved for each file descriptor  
-devices one line of numeric data per device  
-device_hdr single line of column names corresponding to 'devices'  
-device_strs one line of vendor, product and rev info per device  
-hosts one line of numeric data per host  
-host_hdr single line of column names corresponding to 'hosts'  
-host_strs one line of host information (string) per host  
-version sg version as a number followed by a string representation  
-  
-  
-  
-Each line in 'devices' and 'device_strs' corresponds to an sg device. For  
-example the first line corresponds to /dev/sg0. The line  
-number (origin ) also corresponds to the sg minor device number. This  
-mapping is local to sg and is normally the same as given by th  
-__cat /proc/scsi/scsi__ command which is reported by the SCSI  
-mid level driver. The two mappings may diverge when 'remove-single-device'  
-and 'add-single-device' are used (see the SCSI-2.4-HOWTO for more information).  
-  
-  
-  
-Each line in 'hosts' and 'host_strs' corresponds to a SCSI host. For example  
-the first line corresponds to the host normally represented as "scsi0".  
-This mapping is invariant across the SCSI sub system. [[So these entries  
-could arguably be migrated to the mid level.]  
-  
-  
-  
-The column headers in 'device_hdr' are given below. If the device is not  
-present (and one is present after it) then a line of "-1" entries is  
-output. Each entry is separated by a whitespace (currently a tab):  
-  
-host host number (indexes 'hosts' table, origin )  
-chan channel number of device  
-id SCSI id of device  
-lun Logical Unit number of device  
-type SCSI type (e.g. -bdisk, 5-bcdrom, 6-bscanner)  
-opens number of opens (by sd, sr, sr and sg) at this time  
-depth maximum queue depth supported by device  
-busy number of commands being processed by host for this device  
-online 1 indicates device is in normal online state, -boffline  
-A SCSI device is set offline by the SCSI mid level when it decides that  
-a device is no longer responding (e.g. the device does not respond to  
-an SCSI INQUIRY command after it has been reset).  
-  
-  
-  
-The column headers in 'host_hdr' are given below. Each entry is separated  
-by a whitespace (currently a tab):  
-  
-uid unique id (non-zero if multiple hosts of same type)  
-busy number of commands being processed for this host  
-cpl maximum number of command per lun (may be 0 if "device depth"  
-is given  
-sgat maximum elements of scatter gather the adapter (pseudo)  
-DMA can accommodate  
-isa 0 -b non-ISA adapter, 1 -b ISA adapter. ISA adapters are  
-assumed to have a 24 bit address bus limit (16 MB).  
-emu 0 -b real SCSI adapter, 1 -b emulated SCSI adapter  
-(e.g. ide-scsi device driver)  
-  
-  
-  
-The 'def_reserved_size' is both readable and writable. It is only writable  
-by root. It is initialized to the value of DEF_RESERVED_SIZE in the "sg.h"  
-file. Values between 0 and 1048576 (which is 2 ** 20) are accepted and can  
-be set from the command line with the following syntax:  
-  
-$ echo "262144" b /proc/scsi/sg/def_reserved_size  
-Note that the actual reserved buffer associated with a file descriptor could  
-be less than 'def_reserved_size' if appropriate memory is not available. If  
-the sg driver is compiled into the kernel (but not when it is a module)  
-this value can also be read at /proc/sys/kernel/sg-big-buff . This latter  
-feature is deprecated.  
-  
-  
-  
-The 'allow_dio' is both readable and writable. It is only writable by  
-root. When it is 0 (default) any request to do direct IO (i.e. by  
-setting SG_FLAG_DIRECT_IO) will be ignored and indirect IO will be done  
-instead.  
-  
-----  
-!!!11.1. /proc/scsi/sg/debug  
-  
-This appendix explains the output from the /proc/scsi/sg/debug which is typically viewed by the command  
-__cat /proc/scsi/sg/debug__. Below is the (slightly  
-abridged) output while this command: __sgp_dd if=/dev/sg0  
-of=/dev/null bs=512__ is executing on the system. That sgp_dd  
-command is using command queuing to read a disk (and the data is  
-written to /dev/null which forgets it).  
-  
-$ cat /proc/scsi/sg/debug  
-dev_max(currently)=7 max_active_device=1 (origin 1)  
-scsi_dma_free_sectors=416 sg_pool_secs_aval=320 def_reserved_size=32768  
-bbb device=sg0 scsi0 chan=0 id=0 lun=0 em=0 sg_tablesize=255 excl=  
-FD(1): timeout=60000ms bufflen=65536 (res)sgat=2 low_dma=  
-cmd_q=1 f_packid=1 k_orphan=0 closed=  
-fin: id=3949312 blen=65536 dur=10ms sgat=2 op=0x28  
-act: id=3949440 blen=65536 t_o/elap=60000/10ms sgat=2 op=0x28  
-rbbb act: id=3949568 blen=65536 t_o/elap=60000/10ms sgat=2 op=0x28  
-act: id=3949696 blen=65536 t_o/elap=60000/0ms sgat=2 op=0x28  
-Those items output above that are significant to user applications  
-are described below.  
-  
-  
-  
-Broadly speaking the above output shows everything is going fine.  
-Four SCSI READ(10) commands (SCSI opcode 0x28) for different ids  
-are underway. Three commands are active while one is finished with its  
-status and data read() and the request structure is pending deletion.  
-The "id" corresponds to the pack_id given in the sg_io_hdr structure  
-(or the sg_header structure). In the case if sgp_dd the pack_id  
-value is the block number being given to the SCSI READ (or WRITE).  
-You will notice the 4 ids are 128 apart.  
-  
-  
-  
-The "bbb" line shows the sg device name followed by the linux scsi  
-adapter, channel, scsi id and lun numbers. The "em=" argument indicates  
-whether the driver emulates a SCSI HBA. The ide-scsi driver would  
-set "em=1". The "sg_tablesize" is the maximum number of scatter gather  
-elements supported by the adapter driver. The "excl=" indicates no  
-sg open() on this device is currently using the O_EXCL flag.  
-  
-  
-  
-The next two lines starting with "FD(1)" supply data about the first  
-(and only in this case) open file descriptor on /dev/sg0. The default timeout is 60 seconds however this is only  
-significant if the sg_header interface is being used since the  
-sg_io_hdr interface explicits sets the timeout on a per command basis.  
-"bufflen=65536" is the reserved buffer size for this file descriptor.  
-The "(res)sgat=2" indicates that this reserved buffer requires 2  
-scatter gather elements. The "low_dma" will be set to 1 for ISA HBAs  
-indicating only the bottom 16 MB of RAM can be used for its kernel  
-buffers. The "cmd_q=1" indicates command queuing is being allowed.  
-The "f_packid=1" indicates the SG_SET_FORCE_PACK_ID mode is on.  
-The "k_orphan" value is 1 in the rare cases when a SG_IO is interrupted  
-while a SCSI command is "in flight". The "closed" value is 1 in the  
-rare cases the file descriptor has been closed while a SCSI command  
-is "in flight".  
-  
-  
-  
-Each line indented with 5 spaces represents a SCSI command. The state  
-of the command is either:  
-  
-  
-  
-  
-  
-*  
-  
-prior: command hasn't been sent to mid level (rare)  
-  
-  
-*  
-*  
-  
-act: mid level (adapter driver or device) has command  
-  
-  
-*  
-*  
-  
-rcv: sg bottom half handler has received response to this  
-command (awaiting read() or SG_IO ioctl to complete  
-  
-  
-*  
-*  
-  
-fin: SCSI response (and optionally data) has been or is  
-being read but the command data structures have not been removed  
-  
-  
-*  
-These states can be optionally prefixed by "rbbb" which means the reserved  
-buffer is being used, "diobb" which means this command is using direct IO,  
-or "mmapbb" which means that mmap-ed IO is being used by this command.  
-The "id" is the pack_id from this command's interface structure. The "blen"  
-is the buffer length used by the data transfer associated with this command.  
-For commands that a response has been received "dur" shows its duration  
-in milliseconds. For commands still "in flight" an indication of  
-"t_o/elap=60000/10ms" means this command has a timeout of 60000 milliseconds  
-of which 10 milliseconds has already elapsed. The "sgat=2" argument  
-indicates that this command's "blen" requires 2 scatter gather elements.  
-The "op" value is the hexadecimal value of the SCSI command being executed.  
-  
-  
-  
-If sg has lots of activity then the "debug" output may span many lines  
-and in some cases appear to be corrupted. This occurs because procfs requests  
-fixed buffer sizes of information and, if there is more data to output,  
-returns later to get the remainder. The problem with this strategy is that  
-sg's internal state may have changed. Rather than double buffering, the sg  
-driver just continues from the same offset. While procfs is very useful,  
-ioctl()s (such as SG_GET_REQUEST_TABLE) still have their place.  
-  
-----  
-!!!Chapter 12. Asynchronous usage of sg  
-  
-It is recommended that synchronous sg-based applications use the new  
-SG_IO ioctl() command. Existing applications (which are mainly synchronous)  
-can continue to use the older sg_header based interface which is still  
-supported.  
-  
-  
-  
-Asynchronous usage allows multiple SCSI commands to be queued up to the  
-device. If the device supports command queuing then there can be a major  
-performance gain. Even if the device doesn't support command queuing (or  
-is temporarily busy) then queuing up commands in the mid level or the host  
-driver can be a minor performance win (since there will be a lower latency  
-to transmit the next command when the device becomes free).  
-  
-  
-  
-Asynchronous usage usually starts with setting the O_NONBLOCK flag on open()  
-[[or thereafter by using the fcntl(fd, SETFD, old_flags | O_NONBLOCK)  
-system call]. A similar effect can be obtained without using O_NONBLOCK  
-when POSIX threads are used. There are several strategies that can then  
-be followed:  
-  
-  
-  
-  
-  
-#  
-  
-set O_NONBLOCK and use a poll() loop  
-  
-  
-#  
-#  
-  
-set O_NONBLOCK and use SIGPOLL signal to alert app when readable  
-  
-  
-#  
-#  
-  
-use POSIX threads and a single sg file descriptor  
-  
-  
-#  
-#  
-  
-use POSIX threads and multiple sg file descriptors to same device  
-  
-  
-#  
-  
-  
-  
-The O_NONBLOCK flag also permits open(), write() and read() [[but not  
-the ioctl(SG_IO)] to access a SCSI device even though it has been  
-marked offline. SCSI devices are marked offline when they are detected  
-and don't respond to the initial SCSI commands as expected, or,  
-some SCSI error condition is detected on that device and the  
-mid level error recovery logic is unable to "resurrect" the device.  
-A SCSI device that is being reset (and still settling) could be  
-accessed during this period by using the O_NONBLOCK flag; this  
-could lead to unexpected behaviour so the sg user should take care.  
-  
-  
-  
-In Linux SIGIO and SIGPOLL are the same signal. If POSIX real time  
-signals are used (e.g. when SA_SIGINFO is used with sigaction() and  
-fcntl(fd, F_SETSIG, SIGRTMIN + `nb) ) then the file descriptor with which  
-the signal is associated is available to the signal handler. The  
-associated file descriptor is in the si_fd member of the siginfo_t  
-structure. The poll() system call that is often used after a signal  
-is received can thus be bypassed.  
-  
-----  
-!!!Appendix A. Sg3_utils package  
-  
-The sg3_utils package is a collection of programs that use the sg interface.  
-The utilities can be categorized as follows:  
-  
-  
-  
-  
-  
-*  
-  
-variants of the Unix __dd__ command: sg_dd, sgp_dd, sgq_dd  
-and sgm_dd,  
-  
-  
-*  
-*  
-  
-scanning and mapping utilities: sg_scan, sg_map and scsi_devfs_scan,  
-  
-  
-*  
-*  
-  
-SCSI support: sg_inq, scsi_inquiry, sginfo, sg_readcap, sg_start and sg_reset,  
-  
-  
-*  
-*  
-  
-timing and testing: sg_rbuf, sg_test_rwbuf, sg_read, sg_turs and sg_debug,  
-  
-  
-*  
-*  
-  
-example programs: sg_simple1..4 and sg_simple16,  
-  
-  
-*  
-  
-  
-  
-The "dd" family of utilities take a sg device file name as input (i.e.  
-if=`sg_dev_filen_nameb), as output of both. They can also take raw  
-device file names  
-[[20]  
-instead of sg device file names. One important difference from the  
-standard __dd__ command is that the value given to  
-the block size (bs=) argument must be the exact block size of that device  
-and not a integral multiple as allowed by __dd__.  
-These "dd" variants are suitable for SCSI Direct Access Devices such  
-as disk and CDROMs (but are not suitable for SCSI tape devices).  
-  
-  
-  
-The sg3_utils package is designed to be used with the sg version 3  
-driver found in the lk 2.4 series. There is also a sg_utils package  
-that supports a subset of these commands for the sg version 2 driver  
-(with some support for the original sg driver) which is found in  
-the lk 2.2 series (from and after lk 2.2.6). There are links to  
-the most recent sg3_utils (and sg_utils) packages at the sg website  
-at  
-www.torque.net/sg. There are tarballs and  
-both source and binary rpm packages. At the time of writing the latest  
-sg3_utils tarball is at  
-  
-www.torque.net/sg/p/sg3_utils-.97.tgz.  
-There is a README file in that tarball that should be examined for  
-up to date information. The more important utility commands (e.g.  
-sg_dd) have "man" pages.  
-[[21]  
-  
-  
-  
-Almost all of the sg device driver capabilities discussed in this  
-document appear in code in one or more of these programs. For example  
-the recently added mmap-ed IO can be found in sgm_dd, sg_read and  
-sg_rbuf.  
-  
-  
-  
-The sg3_utils package also provides some functions that may be useful for  
-applications that use sg. The functions declared in sg_err.h and defined in sg_err.c  
-categorize SCSI subsystem errors that are returned to an application  
-in a read() or a ioctl(SG_IO). In the case of sense buffers, they  
-are decoded into text message (as per SCSI 2 definitions). There is  
-also a function to do a 64 bit seek (llseek.h).  
-  
-----  
-!!!Appendix B. sg_header, the original sg control structure  
-  
-Following is the original interface structure of the sg driver that  
-dates back to 1991. Those field elements with a "[[o]+" are added by  
-the sg version 2 driver which was first placed in lk 2.2.6 in April  
-1999.  
-  
-struct sg_header  
-{  
-int pack_len; /* [[o] */  
-int reply_len; /* [[i] */  
-int pack_id; /* [[i-bo] */  
-int result; /* [[o] */  
-unsigned int twelve_byte:1; /* [[i] */  
-unsigned int target_status:5; /* [[o]+ */  
-unsigned int host_status:8; /* [[o]+ */  
-unsigned int driver_status:8; /* [[o]+ */  
-unsigned int other_flags:10; /* unused */  
-unsigned char sense_buffer[[SG_MAX_SENSE]; /* [[o] */  
-}; /* This structure is 36 bytes long on i386 */  
-SCSI commands are sent via write() calls to an sg device name (e.g. /dev/sg0).  
-The data written to write() is of the form  
-`a_sg_header_obj + scsi_command [[ + data_to_write]b. The "data_to_write"  
-component is only needed for SCSI commands that transfer data towards the  
-SCSI device. The corresponding read() to the sg device name will yield  
-data of the form `a_sg_header_obj [[ + data_to_read]b.  
-  
-  
-  
-This interface is fully described in the  
-www.torque.net/sg/p/scsi-generic.txt  
-file which documents the sg version 2 driver.  
-  
-  
-  
-Since many Linux applications use this interface, it is still supported  
-in this version (i.e. version 3) of the driver. Only its most perverse  
-idiosyncrasies have been modified and no major applications have reported  
-any problems running old applications atop this newer driver.  
-  
-----  
-!!!Appendix C. Programming example  
-  
-This appendix contains an example program. It is an abridged version of  
-sg_simple2.c found in the sg3_utils  
-package. It send a SCSI INQUIRY command to the nominated sg device and  
-prints out some of the response or outputs error information. Hopefully  
-showing the error processing does not cloud what is being illustrated.  
-  
-#include `unistd.hb  
-#include `fcntl.hb  
-#include `stdio.hb  
-#include `string.hb  
-#include `errno.hb  
-#include `sys/ioctl.hb  
-#include `scsi/sg.hb /* take care: fetches glibc's /usr/include/scsi/sg.h */  
-/* This is a simple program executing a SCSI INQUIRY command using the  
-sg_io_hdr interface of the SCSI generic (sg) driver.  
-* Copyright (C) 2001 D. Gilbert  
-* This program is free software. Version 1.01 (20020226)  
-*/  
-#define INQ_REPLY_LEN 96  
-#define INQ_CMD_CODE 0x12  
-#define INQ_CMD_LEN 6  
-int main(int argc, char * argv[[])  
-{  
-int sg_fd, k;  
-unsigned char inqCmdBlk[[INQ_CMD_LEN] =  
-{INQ_CMD_CODE, , , , INQ_REPLY_LEN, };  
-/* This is a "standard" SCSI INQUIRY command. It is standard because the  
-* CMDDT and EVPD bits (in the second byte) are zero. All SCSI targets  
-* should respond promptly to a standard INQUIRY */  
-unsigned char inqBuff[[INQ_REPLY_LEN];  
-unsigned char sense_buffer[[32];  
-sg_io_hdr_t io_hdr;  
-if (2 != argc) {  
-printf("Usage: 'sg_simple0 `sg_deviceb'\n");  
-return 1;  
-}  
-if ((sg_fd = open(argv[[1], O_RDONLY)) ` ) {  
-/* Note that most SCSI commands require the O_RDWR flag to be set */  
-perror("error opening given file name");  
-return 1;  
-}  
-/* It is prudent to check we have a sg device by trying an ioctl */  
-if ((ioctl(sg_fd, SG_GET_VERSION_NUM, 8k) ` ) || (k ` 30000)) {  
-printf("%s is not an sg device, or old sg driver\n", argv[[1]);  
-return 1;  
-}  
-/* Prepare INQUIRY command */  
-memset(8io_hdr, , sizeof(sg_io_hdr_t));  
-io_hdr.interface_id = 'S';  
-io_hdr.cmd_len = sizeof(inqCmdBlk);  
-/* io_hdr.iovec_count = ; */ /* memset takes care of this */  
-io_hdr.mx_sb_len = sizeof(sense_buffer);  
-io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;  
-io_hdr.dxfer_len = INQ_REPLY_LEN;  
-io_hdr.dxferp = inqBuff;  
-io_hdr.cmdp = inqCmdBlk;  
-io_hdr.sbp = sense_buffer;  
-io_hdr.timeout = 20000; /* 20000 millisecs == 20 seconds */  
-/* io_hdr.flags = ; */ /* take defaults: indirect IO, etc */  
-/* io_hdr.pack_id = ; */  
-/* io_hdr.usr_ptr = NULL; */  
-if (ioctl(sg_fd, SG_IO, 8io_hdr) ` ) {  
-perror("sg_simple0: Inquiry SG_IO ioctl error");  
-return 1;  
-}  
-/* now for the error processing */  
-if ((io_hdr.info 8 SG_INFO_OK_MASK) != SG_INFO_OK) {  
-if (io_hdr.sb_len_wr b ) {  
-printf("INQUIRY sense data: ");  
-for (k = ; k ` io_hdr.sb_len_wr; ++k) {  
-if ((k b ) 88 (0 == (k % 10)))  
-printf("\n ");  
-printf("0x%02x ", sense_buffer[[k]);  
-}  
-printf("\n");  
-}  
-if (io_hdr.masked_status)  
-printf("INQUIRY SCSI status=0x%x\n", io_hdr.status);  
-if (io_hdr.host_status)  
-printf("INQUIRY host_status=0x%x\n", io_hdr.host_status);  
-if (io_hdr.driver_status)  
-printf("INQUIRY driver_status=0x%x\n", io_hdr.driver_status);  
-}  
-else { /* assume INQUIRY response is present */  
-char * p = (char *)inqBuff;  
-printf("Some of the INQUIRY command's response:\n");  
-printf(" %.8s %.16s %.4s\n", p + 8, p + 16, p + 32);  
-printf("INQUIRY duration=%u millisecs, resid=%d\n",  
-io_hdr.duration, io_hdr.resid);  
-}  
-close(sg_fd);  
-return ;  
-}  
-  
-  
-  
-The sg_simple4.c program is an example of using mmap-ed IO in the sg3_utils  
-package. An example of using direct IO can be found in sg_rbuf.c in the  
-same package.  
-  
-----  
-!!!Appendix D. Debugging  
-  
-There are various ways to debug what is happening with the sg driver.  
-The information provided in the /proc/scsi/sg  
-directory can be useful, especially the debug  
-pseudo file. It outputs the state of the sg driver when it is called.  
-Invoking it at the right time can be a challenge. One approach (used in  
-SANE) is to invoke the system() system call like this:  
-  
- system("cat /proc/scsi/sg/debug");  
-at appropriate times within an application that is using the sg driver.  
-  
-  
-  
-Another debugging technique is to trace all system calls a program makes  
-with the __strace__ command (see its "man" page). This  
-command can also be used to obtain timing information (with the  
-"-r" and "t" options).  
-  
-  
-  
-To debug the sg driver itself then the kernel needs to be built with  
-CONFIG_SCSI_LOGGING selected. Then copious output will be sent by the sg  
-driver whenever it is invoked to the log (normally  
-/var/log/messages) and/or the console.  
-This debug output is turned on by:  
-  
- $ echo "scsi log timeout 7" b /proc/scsi/scsi  
-As the number (i.e. 7) is reduced, less output is generated. To turn off  
-this type of debugging use:  
-  
- $ echo "scsi log timeout " b /proc/scsi/scsi  
-  
-  
-  
-If you want the system to log SCSI (CHECK_CONDITION related) errors that  
-sg detects rather than process them within the application using sg  
-then set ioctl(SG_SET_DEBUG) to a value greater than zero.  
-Processing SCSI errors within the application using sg is my preference.  
-  
-----  
-!!!Appendix E. Other references  
-  
-The primary site for SCSI information, standards (draft and emerging) and  
-related reseources is  
-www.t10.org.  
-  
-  
-  
-The most recent news on the sg driver can be found at:  
-www.torque.net/sg .  
-  
-  
-  
-Some notes on the sg v3 driver can be found at:  
-www.torque.net/sg/s_packet.html .  
-For some timings (and CPU utilizations) comparisons between direct and  
-indirect IO see:  
-www.torque.net/sg/rbuf_tbl.html  
-  
-  
-  
-  
-The Linux Documentation Project's SCSI-2.4-HOWTO may help to put this  
-driver into perspective:  
-linuxdoc.org/HOWTO/SCSI-2.4-HOWTO .  
-The most recent version of that document can be found at  
-www.torque.net/scsi/SCSI-2.4-HOWTO .  
-  
-  
-  
-  
-To understand the inner workings of device drivers there is a fine book  
-called "Linux Device Drivers", second edition by Alessandro Rubini and  
-Jonathan Corbet published by O'Reilly [[ISBN -596-00008-1]. The authors  
-and the publisher have unselfishly made this book available under the GNU  
-Free Documentation License (version 1.1). It can be found in html at  
-www.oreilly.com/catalog/linuxdrive2/chapter/book .  
-  
-  
-!Notes  
-[[1]  
-  
-SCSI command opcode 0x7f does allow for variable length commands but  
-that is not supported in Linux currently.  
-  
-[[2]  
-  
-There is an sg version 3..19 which is an optional driver for the lk 2.2  
-series. It has the following limitations:  
-  
-  
-  
-  
-  
-*  
-  
-maximum size of SCSI commands is 12 bytes  
-  
-  
-*  
-*  
-  
-sense buffer limited to 16 bytes  
-  
-  
-*  
-*  
-  
-resid (residual data transfer count) is always  
-  
-  
-*  
-*  
-  
-direct and mmap-ed IO not supported (defaults to indirect IO)  
-  
-  
-*  
-  
-[[3]  
-  
-Patches exist for sg to extend the number of SCSI devices past the  
-256 limit when the device file system (devfs) is being used.  
-  
-[[4]  
-  
-Linux kernel prior to 2.4.15 limited SCSI commands to a length of 12  
-bytes. In lk 2.4.15 this was raised to 16 bytes. However unless lower  
-level drivers (e.g. aic7xxx) indicate that they can handle 16 byte  
-commands (and few currently do) then the command is aborted with a  
-DID_ABORT host status.  
-  
-[[5]  
-  
-Some HBA - SCSI device combinations have difficulties with an odd valued  
-dxfer_len . In some cases the operation succeeds but a DID_ERROR host status  
-is returned. So unless there is a good reason, applications that want  
-maximum portability should avoid an odd valued dxfer_len .  
-  
-[[6]  
-  
-Whether aborting individual commands is supported or not is left to  
-the adapter. Many adapters are unable to abort SCSI commands "in flight"  
-because these details are handled in silicon by embedded processors  
-in hardware. SCSI device or bus resets are required.  
-  
-[[7]  
-  
-Some lower level drivers (e.g. ide-scsi) clear this status field  
-even when a CHECK_CONDITION or COMMAND_TERMINATED status has  
-occurred. However they do set DRIVER_SENSE in driver_status field.  
-Also a (sb_len_wr b ) indicates there is a sense buffer.  
-  
-[[8]  
-  
-Some lower level drivers (e.g. ide-scsi) clear this masked_status field  
-even when a CHECK_CONDITION or COMMAND_TERMINATED status has  
-occurred. However they do set DRIVER_SENSE in driver_status field.  
-Also a (sb_len_wr b ) indicates there is a sense buffer.  
-  
-[[9]  
-  
-In some cases the sym53cxx driver reports a DID_ERROR when it internally  
-rounds up an odd transfer length by 1. This is an example of a "non-error".  
-  
-[[10]  
-  
-Unfortunately some adapters drivers report an incorrect number for 'resid'.  
-This is due to some "fuzziness" in the internal interface definitions within  
-the Linux scsi subsystem concerning the _exact_ number of bytes to be  
-transferred. Therefore only applications tied to a specific adapter that  
-is known to give the correct figure should use this feature. Hopefully  
-this will be cleared up in the near future.  
-  
-[[11]  
-  
-The command queuing capabilities of the SCSI device and the adapter driver  
-should also be taken into account. To this end the sg_scsi_id::h_cmd_per_lun  
-and sg_scsi_id::d_queue_depth values returned bu ioctl(SG_GET_SCSI_ID) may  
-be useful. Also some devices that indicate in their INQUIRY response that  
-they can accept command queuing react badly when queuing is actually  
-attempted.  
-  
-[[12]  
-  
-There is a small probability it will spend some time waiting for a  
-command block to become available. In this case the wait is interruptible.  
-If O_NONBLOCK is active then this scenario will cause a EAGAIN.  
-  
-[[13]  
-  
-The sg driver does record that the mmap() system call has been invoked  
-at least once on a file descriptor. This is not sufficient because the  
-given 'length' may be too short for the current IO. Also the driver is  
-unaware of munmap() calls so it could easily be tricked.  
-  
-[[14]  
-  
-If ioctl(SG_SET_KEEP_ORPHAN) is set to 1 and a ioctl(SG_IO) operation  
-is interrupted (e.g. by control-C by the user) then when the response  
-arrives then the "num_waiting" will be incremented to indicate a  
-read() can now pick up the response.  
-  
-[[15]  
-  
-Here is the mapping from the SCSI opcode "group" (top 3 bits of opcode)  
-to the assumed length (in lk 2.4.15):  
-  
-unsigned char scsi_command_size[[8] =  
-{  
-6, 10, 10, 12,  
-16, 12, 10, 10  
-};  
-The assumed length of group 4 commands changed from 12 to 16 in lk 2.4.15  
-reflecting support for 16 byte SCSI commands being added to the kernel.  
-  
-[[16]  
-  
-Older SCSI adapters and some pseudo adapter drivers don't have DMA  
-capability in which case the CPU is used to copy the data.  
-  
-[[17]  
-  
-Unfortunately that setup time is large enough in some versions of  
-the lk 2.4 series to adversely impact direct IO performance.  
-Also memory malloc()-ed in the user space tends to be made up of  
-discontinuous pages seen from the SCSI adapter. This requires the  
-sg driver to build heavily splintered scatter gather lists which  
-is less than desirable. This limits the maximum transfer size to  
-[[(max_scsi_adapter_scatter_gather_elements - 1) * PAGE_SIZE].  
-[[This is a _different_ scatter gather mechanism to that which the user  
-sees in the sg interface based on iovec.]  
-  
-[[18]  
-  
-When a write() or ioctl(SG_IO) attempts mmap-ed IO there is no check  
-performed that a prior mmap() system call has been performed. If no  
-mmap() has been issued then random data is written to the device or data  
-read from the device in inaccessible. Also once mmap() has been called  
-on a file descriptor then all subsequent calls to ioctl(SG_SET_RESERVED_SIZE)  
-will yield EBUSY.  
-  
-[[19]  
-  
-One strange quirk is that the /proc/scsi/sg directory  
-will not appear if there are no SCSI devices (or pseudo devices such as  
-USB mass storage) attached to the system. The reason for this is that  
-in the absence of SCSI devices, the SCSI mid level does not initialize  
-the sg driver (even if it has been loaded as a module).  
-When the sg driver is a module and the __rmmod sg__ is  
-successfully executed then the /proc/scsi/sg directory  
-and its contents are removed.  
-  
-[[20]  
-  
-Raw device names are of the form /dev/raw/raw`nb  
-and can be bound to block devices (e.g. an IDE disk partition  
-such as /dev/hda3). The binding is done with the  
-__raw__ command (see "man raw").  
-  
-[[21]  
-  
-Although the author wrote most of these programs, initially to test  
-facilities within the sg driver, some have been contributed by others.  
-See www.torque.net/sg/u_index.html  
-for more information
+Describe [HowToSCSIGenericHOWTO ] here.