diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /Documentation/scsi-generic.txt | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'Documentation/scsi-generic.txt')
-rw-r--r-- | Documentation/scsi-generic.txt | 636 |
1 files changed, 636 insertions, 0 deletions
diff --git a/Documentation/scsi-generic.txt b/Documentation/scsi-generic.txt new file mode 100644 index 000000000..17822c4ad --- /dev/null +++ b/Documentation/scsi-generic.txt @@ -0,0 +1,636 @@ + Notes on Linux's SG driver version 2.1.30 + ----------------------------------------- + 990328 + +Introduction +============ +These are notes on the Linux SCSI generic packet device driver (sg) +describing version 2.1.30 . The original driver was written by Lawrence +Foard and has remained in place with minimal changes since circa 1992. +Version 2 of this driver remains backward compatible (binary and +source **) with the original. It adds scatter gather, command queuing, +per file descriptor sequencing, asynchronous notification and better +error reporting. + +Sg is one of the four "high level" SCSI device drivers along with +sd, st and sr (disk, tape and CDROM respectively). Sg is more generalized +(but lower level) than its sibling and tends to be used on SCSI devices +that don't fit into the already serviced categories. Thus sg is used for +scanners, cd writers and reading audio cds amongst other things. + +The interface and usage of the original sg driver has been documented +by Heiko Eissfeldt in a HOWTO called SCSI-Programming-HOWTO. My copy +of the document is version 1.5 dated 7th May 1996. It can found at +ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/SCSI-Programming-HOWTO . +Amongst other things it has a lot of tables from the SCSI-2 standard +that are very useful for programming this interface. + +** It is possible to write applications that perform differently +depending on whether they are using the original or this version of +the sg device driver. The author is not aware of any useful applications +that have problems with version 2 (yet). + + +Architecture +============ +The SCSI generic packet device driver (sg) is a character based device. +It is one of the four high level device driver in the SCSI sub-system; +the others are sd (for direct-access devices - disks), st (for tapes) +and sr (for data cdroms). The other three devices are block devices. + +The unifying layer of the SCSI sub-system in the so-called mid-level. +Below that are all the drivers for the various adapters supported by +Linux. + +Since sg is a character device it supports the traditional Unix +system calls of open(), close(), read(), write() and ioctl(). Two other +related system calls: poll() and fcntl() are added to this list and +how they interact with the sg device driver is documented later. + +An SG device is accessed by write()ing SCSI commands plus any associated +outgoing data to it; the resulting status codes and any incoming data are +then obtained by a read() call. The device can be opened O_NONBLOCK +(non-blocking) and poll() used to monitor its progress. The device may be +opened O_EXCL which excludes other "sg" users from this device (but not +"sd", "st" or "sr" users). The buffer given to the write() call is made +up as follows: + - struct sg_header image (see below) + - scsi command (6, 10 or 12 bytes long) + - data to be written to the device (if any) + +The buffer received from the corresponding read() call contains: + - struct sg_header image (check status/errors + sense_buffer) + - data read back from device (if any) + +The given SCSI command has its LUN field overwritten by the LUN value of +the associated sg device that has been open()ed. + + +sg_header +========= +This is the name of the control structure that conveys information +about the length of data to be read/written by the associated SCSI +command. It also conveys error and status information from the +read() call. An instance of this structure is the first thing that +is placed in the data buffers of both write() and read(). + +In its original form it looked like this: +struct sg_header { + int pack_len; + int reply_len; + int pack_id; + int result; + unsigned int twelve_byte:1; + unsigned int other_flags:31; + unsigned char sense_buffer[16]; +}; /* this structure is 36 bytes long */ + +The 'pack_len' is bizzare and ends up having the 'reply_len' put in it +(perhaps it had a use at some stage). + +The 'reply_len' is the length of the data the corresponding read() +will/should request (including the sg_header). + +The 'pack_id' is not acted upon by the sg device driver but is conveyed +back to the corresponding read() so it can be used for sequencing by an +application. + +The 'result' is also bizzare, turning certain types of host codes it 0 (no +error), EBUSY or EIO. With better error reporting now available, the +'result' is best ignored. + +The 'twelve_byte' field overrides the internal SCSI command length "guessing" +algorithm for group 6 and 7 commands (ie when 1st byte >= 0xc0) and forces +a command lenth of 12 bytes. +The command length "guessing" algorithm is as follows: +Group: 0 1 2 3 4 5 6 7 +Length: 6 10 10 12 12 12 10 10 + +'other_flags' was originally documented as "not used" but some current +applications assume it has 0 placed in it. + +The 'sense_buffer' is the first 16 bytes of SCSI sense buffer that is +returned when the target returns a SCSI status code of CHECK_CONDITION +or COMMAND_TERMINATED [or (driver_status & DRIVER_SENSE) is true]. This +buffer should be at least 18 bytes long and arguably 32 bytes; unfortunately +this is unlikely to happen in the 2.2.x series of kernels. + +The new sg_header offered in this driver is: +#define SG_MAX_SENSE 16 +struct sg_header +{ + int pack_len; /* [o] reply_len (ie useless) ignored as input */ + int reply_len; /* [i] max length of expected reply (inc. sg_header) */ + int pack_id; /* [io] id number of packet (use ints >= 0) */ + int result; /* [o] 0==ok, else (+ve) Unix errno code (e.g. EIO) */ + unsigned int twelve_byte:1; + /* [i] Force 12 byte command length for group 6 & 7 commands */ + unsigned int target_status:5; /* [o] scsi status from target */ + unsigned int host_status:8; /* [o] host status (see "DID" codes) */ + unsigned int driver_status:8; /* [o] driver status+suggestion */ + unsigned int other_flags:10; /* unused */ + unsigned char sense_buffer[SG_MAX_SENSE]; /* [o] when target_status is + CHECK_CONDITION or COMMAND_TERMINATED this is output. */ +}; /* This structure is 36 bytes long on i386 */ + +Firstly the new header is binary compatible with the original. This is +important for keeping existing apps working without recompilation. + +Only those elements (or fields) that are new or in some way different +from the original are documented below. + +'pack_id' becomes input to a read() when ioctl(sg_fd, SG_SET_FORCE_PACK_ID, +&one) is active. A 'pack_id' of -1 is interpreted as fetch the oldest +waiting packet; any other value will cause the read() to wait (or yield +EAGAIN) until a packet with that 'pack_id' becomes available. In all cases +the value of 'pack_id' available after a read() is the value given to that +variable in the prior, corresponding write(). + +The 'target_status' field is always output and is the (masked and shifted +1 bit right) SCSI status code from the target device. The allowable +values are (found in <scsi/scsi.h>): +/* N.B. 1 bit offset from usual SCSI status values */ +#define GOOD 0x00 +#define CHECK_CONDITION 0x01 +#define CONDITION_GOOD 0x02 +#define BUSY 0x04 +#define INTERMEDIATE_GOOD 0x08 +#define INTERMEDIATE_C_GOOD 0x0a +#define RESERVATION_CONFLICT 0x0c +#define COMMAND_TERMINATED 0x11 +#define QUEUE_FULL 0x14 +When the 'target_status' is CHECK_CONDITION or COMMAND_TERMINATED the +'sense_buffer' is output. Note that when (driver_status & DRIVER_SENSE) +is true then the 'sense_buffer' is also output (this seems to occur when +the scsi ide emulation is used). When the 'sense_buffer' is output the +SCSI Sense Key can be found at (sense_buffer[2] & 0x0f) . + +The 'host_status' field is always output and has the following values +whose "defines" are not visible outside the kernel (unfortunately): +#define DID_OK 0x00 /* NO error */ +#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */ +#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */ +#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */ +#define DID_BAD_TARGET 0x04 /* BAD target. */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody. */ +#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */ +#define DID_PASSTHROUGH 0x0a /* Force command past mid-layer */ +#define DID_SOFT_ERROR 0x0b /* The low level driver just wish a retry */ + +The 'driver_status' field is always output. When ('driver_status' & +DRIVER_SENSE) is true the 'sense_buffer' is also output. The following +values whose "defines" are not visible outside the kernel (unfortunately) +can occur: +#define DRIVER_OK 0x00 /* Typically no suggestion */ +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 +/* above status 'or'ed with one of the following suggestions */ +#define SUGGEST_RETRY 0x10 +#define SUGGEST_ABORT 0x20 +#define SUGGEST_REMAP 0x30 +#define SUGGEST_DIE 0x40 +#define SUGGEST_SENSE 0x80 + +'other_flags' still remains as a 10 bit field, so code that places 0 in it +will still be happy. It is not used. + + +memory +====== +Memory is a scarce resource in any computer. Sg needs to reserve memory +suitable for DMA roughly equal in size to the maximum of the write and +read data buffers for each packet. This DMA memory is obtained at the time +of a write() and released when the corresponding read() is called (although +if memory is tight it may be using the buffer reserved by the open() ). + +Linux obtaining memory a challenge for several reasons. The memory pool +that sg uses is in common with all other device drivers and all user +processes. In this environment the only way to 99.9% guarantee a driver +will have memory in Linux is to build it into the kernel (ie not as a +module) and then reserve it on initialization before user processes get +a chance. [Of course, another driver initialized before sg could take +all available memory ...] Another problem is the biggest contiguous +chunk of memory that can be obtained from the kernel is 32 * PAGE_SIZE +(which is 128KBytes on i386). As memory gets "splintered" there is a good +chance that buffers won't be available (my machine has 64 MBytes of RAM +and has 3 available at the moment). + +The original sg driver used the following technique: grab a SG_BIG_BUFF +sized buffer at driver initialization and use it for all requests greater +than PAGE_SIZE (4096 bytes on i386). By default SG_BIG_BUFF is set to +32 KBytes in the origianl driver but many applications suggest that the +user increases this number. Linux limits the biggest single buffer of +this type to 32 * PAGE_SIZE (128KBytes on i386). Unfortunately if the +sg driver is a module then there is a high chance a contiguous block of +that large size will not be available at module initialization. + +The author has found no "silver bullet" solution but uses multiple +techniques hoping that at least one is able provide memory at the critical +time. Listed below are some of these techniques: + - use scatter gather: then instead of one large buffer needing to + be found, multiple smaller buffer can be used + - use memory above the 16MByte level: the original driver limited + itself to obtaining memory below the 16MByte level (on the i386) + due to the shortcomings of DMA on ISA adapters. Yet more and more + people use PCI adapters that don't have this problem. So make + the decision based on the capabilities of the host adpater + associated with the current SCSI device + - reserve some memory at open() for emergencies but otherwise + fetch and release it on a per packet basis + - if the kernel is short of memory then dip into the SCSI DMA + pool (maintained by the mid-level driver) to a limited amount + + + +System Calls +============ +What follows are descriptions of the characteristics of the standard +Unix operating system calls when applied to a SCSI generic device +using this version of the device driver. + +open +---- +The filename should be an 'sg' device such as +/dev/sg[a-z] +/dev/sg[0,1,2,...] +or a symbolic link to one of these. [Devfs has its own sub-directory for +sg devices.] It seems as though SCSI devices are allocated to sg minor +numbers in the same order as they appear in 'cat /proc/scsi/scsi'. +Sg is a "character" based Linux device driver. This means it has an +open/close/read/write/ioctl type interface. + +Flags can be either O_RDONLY or O_RDWR or-ed with either +O_EXCL waits for other opens on sg device to be closed before + proceeding. If O_NONBLOCK is set then yields EBUSY when + someone else has the sg 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 (eg read() ) or EBUSY (eg open() ). + +The original version of sg did not allow the O_RDONLY (yielding a EACCES +error). This version allows it for accessing ioctls (e.g. doing an sg +device scan with the SG_GET_SCSI_ID ioctl) but write()s will not be +allowed. + +By default, sequencing is per file descriptor in this version of sg. This +means, for example that 2 processes can independently manipulate the same +sg device at the same time. This may or may not make sense depending on +the application: 2 processes (logically) reading from the same direct access +device (ie a disk) is ok while running 2 instances of cd writing software +on the same device at the same time probably wouldn't be a good idea. The +previous version of sg supported only per device sequencing and this can +still be selected with the SG_SET_MERGE_FD,1 ioctl(). + +The driver will attempt to reserve SG_SCATTER_SZ bytes (32KBytes in the +current sg.h) on open() for "emergency" situations. If this is unavailable +it will halve its request and try again. It gives up if PAGE_SIZE bytes +(4096 bytes on i386) cannot be obtained so no memory is reserved. In this +case open() will still return successfully. The actual amount of memory +reserved can be found with the SG_GET_RESERVED_SIZE ioctl(). + +Returns a file descriptor if >= 0 , otherwise -1 implies an error. + +Error codes (value in 'errno' after -1 returned): +ENODEV sg not compiled into kernel or the kernel cannot find the + sg module (or it can't initialize itself (low memory??)) +ENXIO either scsi sub-system is currently processing some error + (eg doing a device reset) or the sg driver/module removed + or corrupted +EBUSY O_NONBLOCK set and some user of this sg device has O_EXCL + set while someone is already using this device +EINTR while waiting for an "exclusive" lock to clear, a signal + is received, just try again ... +ENOMEM An attempt to get memory to store this open's context + failed (this was _not_ a request to reserve DMA memory) +EACCES An attempt to use both O_RDONLY and O_EXCL + + +write +----- +Even though sg is a character-based device driver it sends and receives +packets to/from the associated scsi device. Write() is used to send a +packet containing 2 mandatory parts and 1 optional part. The mandatory +parts are: + - a control block (an instance of struct sg_header) + - a SCSI command (6, 10 or 12 bytes long) +The optional part is: + - outgoing data (eg if a SCSI write command is being sent) +These should appear as one contiguous string in the buffer given to +write() in the above order with no pad characters. + +If a write() accepts this packet then at some later time the user should +call a read() to get the result of the SCSI command. The previous sg +driver enforced a strict write()/read()/write()/read() regime so that a +second write() would block until first read() was finished. This sg +driver relaxes that condition and thereby allows command queuing +(limit is SG_MAX_QUEUE (16) outstanding packets per file descriptor). +However, for backward compatibility, command queuing is turned off +by default (#define SG_DEF_COMMAND_Q 0 in sg.h). This can be changed +via the the SG_SET_COMMAND_Q ioctl() [or by recompiling after changing +the above define to 1]. + +In this sg driver a write() should return more or less immediately. + +Returns number of bytes written if > 0 , otherwise -1 implies an error. + +Error codes (value in 'errno' after -1 returned): +ENXIO either scsi sub-system is currently processing some error + (eg doing a device reset) or the sg driver/module removed + or corrupted +EACCES opened with RD_ONLY flag +EIO incoming buffer too short. It should be at least (6 + + sizeof(struct sg_header))==42 bytes long +EDOM a) command queuing off: a packet is already queued + b) command queuing on: too many packets queued + (SG_MAX_QUEUE exceeded) +EAGAIN SCSI mid-level out of command blocks (rare), try again. + This is more likely to happen when queuing commands, + so wait a bit (eg usleep(10000) ) before trying again +ENOMEM can't get memory for DMA. Take evasive action ... + (see section on memory) + + +read +---- +Read() is used to receive a packet containing 1 mandatory part and 1 +optional part. The mandatory part is: + - a control block (an instance of struct sg_header) +The optional part is: + - incoming data (eg if a SCSI read command was sent by earlier write() ) +The buffer given to a read() and its corresponding count should be +sufficient to accommodate this packet to avoid truncation. Truncation has +occurred if count < sg_header::replylen . + +By default, read() will return the oldest packet queued up. 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_header::pack_id given to this read(). If not available it will either +wait or yield EAGAIN. As a special case, -1 in sg_header::pack_id given +to read() will match the oldest packet. + + +Returns number of bytes read if > 0 , otherwise -1 implies an error. +Unfortunately the return value in the non-error case is simply the +same as the count argument. It is not the actual number of bytes +DMA-ed by the SCSI device. This driver is currently unable to provide +such an underrun indication. + +Error codes (value in 'errno' after -1 returned): +ENXIO either scsi sub-system is currently processing some error + (eg doing a device reset) or the sg driver/module removed + or corrupted +EAGAIN either no waiting packet or requested packet is not + available while O_NONBLOCK flag was set +EINTR while waiting for a packet, a signal is received, just + try again ... +EIO if the 'count' given to read() is < sizeof(struct sg_header) + and the 'result' element in sg_header is non-zero. Not a + recommended error reporting technique + + +close +----- +Preferably a close() should be done after all issued write()s have had +their corresponding read() calls completed. Unfortunately this is not +always possible. The semantics of close() in Unix are to return more +or less immediately (ie not wait on any event) so the driver needs to +arrange to an orderly cleanup of those packets that are still "in +flight". + +A process that has an open file descriptor to an sg device may be aborted +(eg by a kill signal). In this case, the kernel automatically calls close +(which is called 'sg_release()' in the version 2 driver) to facilitate +the cleanup mentioned above. + +A problem persists in version 2.1.8 if the sg driver is a module and is +removed while packets are still "in flight". Hopefully this will be soon +fixed. + +Returns 0 if successful, otherwise -1 implies an error. + +Error codes (value in 'errno' after -1 returned): +ENXIO sg driver/module removed or corrupted + +ioctl (sg specific) +------------------- +Ken Thompson (or perhaps some other Unix luminary) described ioctl() as +the "garbage bin of Unix". This driver compounds the situation by adding +around 18 more commands. These commands either yield state information (10 +of them), change the driver's characteristics (8 of them) or allow direct +communication with the common SCSI mid-level driver. + +Those commands with an appended "+" are new in version 2. + +Those commands with an appended "W" are only accessible from file +descriptors opened with O_RDWR. They will yield EACCES otherwise. + +SG_GET_TIMEOUT: +Ignores its 3rd argument and _returns_ the timeout value (which will be +>= 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. + +SG_SET_TIMEOUT: +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 effected. The default value is set +on open() and is SG_DEFAULT_TIMEOUT (defined in sg.h). + +SG_EMULATED_HOST: +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 +emulated one (eg ide-scsi device driver). A value of 1 means emulated +while 0 is not. + +SG_SET_FORCE_LOW_DMA +: +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 "reserve" 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 effected. + +SG_GET_LOW_DMA +: +Assumes 3rd argument points to an int and places 0 or 1 in it. 0 +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 . + +SG_GET_SCSI_ID +: +Assumes 3rd argument is pointing to an object of type Sg_scsi_id and +populates it. That structure contains ints for host_no, channel, +scsi_id, lun and scsi_type. Most of this information is available from +other sources (eg SCSI_IOCTL_GET_IDLUN and SCSI_IOCTL_GET_BUS_NUMBER) +but tends to be awkward to collect. + +SG_SET_FORCE_PACK_ID +: +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 (when command queuing is being used). +1 instructs read() to view the sg_header::pack_id as input and return the +oldest packet matching that pack_id or wait until it arrives (or yield +EAGAIN if O_NONBLOCK is in force). 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 effected by this command. + +SG_GET_LOW_DMA +: +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. + +SG_GET_NUM_WAITING +: +Assumes 3rd argument points to an int and places the number of packets +waiting to be read in it. + +SG_GET_SG_TABLESIZE +: +Assumes 3rd argument points to an int and places the maximum number of +scatter gather elements supported by the host adapter. 0 indicates that +the adapter does support scatter gather. + +SG_SET_RESERVED_SIZE +W: +This is not currently implemented. It is intended for reserving either a +large buffer or scatter gather list that will be available until the +current file descriptor is closed. The requested amount of memory may +not be available so SG_GET_RESERVED_SIZE should be used after this call +to see how much was reserved. (EBUSY error possible) + +SG_GET_RESERVED_SIZE +: +Assumes 3rd argument points to an int and places the size in bytes of +the DMA buffer reserved on open() for emergencies. If this is 0 then it +is probably not wise to attempt on operation like burning a CD on this +file descriptor. + +SG_SET_MERGE_FD +W: +Assumes 3rd argument is pointing to an int. 0 (the default) causes all +subsequent sequencing to be per file descriptor. 1 causes all subsequent +sequencing to be per device. If this command tries to change the current +state and the is one or more _other_ file descriptors using this sg +device then an EBUSY error occurs. Also if this file descriptor was not +open()ed with the O_RDWR flag then an EACCES error occurs. +Per device sequencing was the original semantics and allowed, for example +different processes to "share" the device, one perhaps write()ing with +the other one read()ing. This command is supplied if anyone needs those +semantics. Per file descriptor sequencing, perhaps with the usage of +the O_EXCL flag, seems more sensible. + +SG_GET_MERGE_FD +: +Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies +sequencing is per file descriptor. 1 implies sequencing is per device +(original sg driver's semantics). + +SG_SET_COMMAND_Q +: +Assumes 3rd argument is pointing to an int. 0 (current default, set by +SG_DEF_COMMAND_Q in sg.h) disables command queuing. Attempts to write() +a packet while one is already queued will result in a EDOM error. +1 turns command queuing on. +Changing the queuing state only effects write()s done after the change. +Only the current file descriptor is effected by this command. + +SG_GET_COMMAND_Q +: +Assumes 3rd argument points to an int and places 0 or 1 in it. 0 implies +that command queuing is off on this file descriptor. 1 implies command +queuing is on. + +SG_SET_DEBUG +: +Assumes 3rd argument is pointing to an int. 0 (default) turns debugging +off. Values > 0 cause the SCSI sense buffer to be decoded and output +to the console/log when a SCSI device error occurs. Values > 8 cause +the current sg device driver's state to be output to the console/log +(this is a "one off" effect). +If you need a _lot_ of the SCSI sub-system debug information (mainly from +the mid-level) then try 'echo "scsi dump 0" > /proc/scsi/scsi' and lots of +debug will appear in your console/log. + +ioctl (in common with sd, st + sr) +---------------------------------- +The following ioctl()s can be called from any high-level scsi device +driver (ie sd, st, sr + sg). Access permissions may differ a bit from +one device to another, the access information given below is specific to +the sg device driver. + +SCSI_IOCTL_GET_IDLUN: +SCSI_IOCTL_GET_BUS_NUMBER: + +SCSI_IOCTL_SEND_COMMAND: W +If open()ed O_RDONLY yields an EACCESS error. Otherwise is forwarded onto +the SCSI mid-level driver for processing. +Don't know much about this one but it looks pretty powerful and +dangerous. Some comments says it is also deprecated. + +<any_command_not matching_above>: W +If open()ed O_RDONLY yields an EACCESS error. Otherwise is forwarded onto +the SCSI mid-level driver for processing. + + +poll +---- +This is a native call in Linux 2.2 but most of its capabilities are available +through the older select() call. Given a choice poll() should probably be +used. Typically poll() is used when a sg scsi device is open()ed O_NONBLOCK +for polling; or alternatively with asynchronous notification using the +fcntl() system call (below) and the SIGPOLL (aka SIGIO) signal. +Only if something drastically is wrong (eg file handle gone stale) will +POLLERR ever be set. POLLPRI, POLLHUP and POLLNVAL are never set. +POLLIN is set when there is one or more packets waiting to be read. +When POLLIN is set it implies that a read() will not block (or yield +EAGAIN in non-blocking mode) but return a packet immediately. +POLLOUT (aka POLLWRNORM) is set when write() is able to accept a packet +(ie will _not_ yield an EDOM error). The setting of POLLOUT is effected +by the SG_SET_COMMAND_Q state: if the state is on then POLLOUT will remain +set until the number of queued packets reaches SG_MAX_QUEUE, if the +state is off then POLLOUT is only set when no packets are queued. +Note that a packet can be queued after write()ing but not available to be +read(); this typically happens when a SCSI read command is issued while +the data is being retreaved. +Poll() is per file descriptor unless SG_SET_MERGE_FD is set in which case +it is per device. + + +fcntl +----- +There are several uses for this system call in association with a sg +file descriptor. The first 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.c utility program. + +open("/dev/sga", O_RDONLY | O_NONBLOCK) +/* check device, EBUSY means some other process has O_EXCL lock on it */ +/* one the device you want is found then ... */ +flags = fcntl(sg_fd, F_GETFL) +fcntl(sg_fd, F_SETFL, flags & (~ O_NONBLOCK)) +/* for simple apps is is easier to use normal blocked io */ + + +Some work has to be done in Linux to set up for 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. A working example of this logic +is in the sg_poll.c test program. + +sigemptyset(&sig_set) +sigaddset(&sig_set, SIGPOLL) +sigaction(SIGPOLL, &s_action, 0) +fcntl(sg_fd, F_SETOWN, getpid()) +flags = fcntl(sg_fd, F_GETFL); +fcntl(sg_fd, F_SETFL, flags | O_ASYNC) + + +Utility and Test Programs +========================= |