Linux SG FAQ

[0.1] Current Status

[1.1] Why change the SG device driver in Linux kernel 2.2.6?
[1.2] But I have my own mods to sg.c ...
[1.3] Is there a version of this sg driver for 2.0.x ?
[1.4] Scsi device, bus and driver resets
[1.5] How to make an ATAPI cdrom appear as a SCSI device

Problems with SG and other kernel and hardware issues
[2.1] Kernel build dies in sg.c complaining about scsi_logging
[2.2] When I change SG_BIG_BUFF it is not reflected in /proc/sys/kernel/sg-big-buff
[2.3] Foooooooood fight panic from aha1542
[2.4] DMA problems with sym53c416
[2.5] aha152x
[2.6] Agfa SnapScan (scanner under SANE)
[2.7] aic7xxx
[2.9] Canon backend in SANE
[2.10] Sg freezes in early lk 2.4 series
[2.11] Ide-scsi driver continually resets in lk 2.4
[2.12] Sg in Redhat 6.2, 7.0 and Mandrake 7.1
[2.13] Sg in Redhat 7.3

Application related issues
[3.1] The compiler is picking up the wrong sg.h ?
[3.2] Cdrecord
[3.3] Cdrdao
[3.4] SANE
[3.5] Cdparanoia [a.k.a. cdda paranoia or just paranoia]
[3.6] Finding the target id of a scsi device


[0.1]  Current Status

[20011223] The current production version in linux kernel 2.2.20 is sg version 2.1.40 . The current 2.4 series kernel sg driver is version 3.1.22 (lk 2.4.17) . Broadly speaking there are now 3 major versions of the sg driver: The version 3 sg driver adds an additional interface structure and provides information in the "proc" file system in the /proc/scsi/sg directory. More information about it can be found on this page. Recent SANE releases (1.0.3 + 1.0.4) use the version 3 sg interface. There has been one problem (see the SANE item). Users of distributions based on early lk 2.4 series kernels (e.g. RedHat 7.1 and Mandrake 8) should see point 2.10 . This problem is resolved in RH 7.2 and Mandrake 8 (and Suse 7.3).

[1.1]  Why change the SG device driver in Linux kernel 2.2.6?

The original driver was having more and more trouble finding memory in the early 2.2 series of kernels. It would try and obtain a buffer of SG_BIG_BUFF size at driver initialization time as a continuous slab and under the 16MByte level (on i386). Ironically the more memory a machine has the less likely such a continuous slab of memory will be available under the 16MB limit. If sg was being loaded as a module then failure to find such memory would cause a non-fatal oops in the kernel and the sg module could not be loaded henceforth, even if the memory became available. This condition would be cleared when the machine was rebooted. Application writers who use the sg device have often recommended that users change the default value of SG_BIG_BUFF from its default of 32KB to 128KB. This only makes matters worse!

The memory starvation problem has improved since a new kernel memory allocator was included in kernel 2.2.10 .

[1.2]  But I have my own mods to sg.c ...

Then load up the original driver (link on main page) and apply your mods. If those mods have anything to do with the memory management of the original driver then it is very unlikely they will have any direct application to the new sg driver. Also, they may not be needed anymore.

[1.3]  Is there a version of this sg driver for 2.0.x ?

No. There are no current plans to do this.

[1.4]  Scsi device, bus and driver resets

The implementation of SCSI device, bus and driver resets have been put on hold. There is an ioctl() in recent versions of sg to support this but associated changes in the SCSI mid level driver have not been accepted. There is concern that allowing users to instigate SCSI bus resets may interfere with internal SCSI error processing.

The RedHat 6.2 upgrade kernel, RedHat 7.0 and Mandrake 7.1 contain the SCSI mid level patch that activates the sg driver reset capability. As of lk 2.4.0 the required SCSI mid level patch is not in the main kernel tree. However a patch has been posted on the linux-scsi mailing list.

Here is the SCSI mid level patch for lk 2.2.16. This mid level patch for lk 2.2.18 was updated on 2001/3/5. This mid level patch for lk 2.4.2 was updated on 2001/03/21. Here is a more recent 2.4.7 patch.

[1.5]  How to make an ATAPI cdrom appear as a SCSI device

Various applications based on cd writers and readers (e.g. cdrecord and cdparanoia) use the sg driver to access ATAPI IDE devices. This requires some reconfiguration because Linux will typically set up such devices within the IDE subsystem. For example a cd writer on the second IDE controller set as a slave will normally appear as device /dev/hdd . A 2 stage process is required to make an ATAPI device appear as a SCSI device:
  1. stop the IDE subsystem claiming the ATAPI device
  2. load the ide-scsi driver so the SCSI subsytem finds it
On some recent distributions there may be a very quick solution:
    rmmod ide-cd
    modprobe ide-scsi

This works if both ide-cd and ide-scsi are modules. If not what follows is a more detailed approach.

Stage 1 can be accomplished by rebuilding the kernel with CONFIG_BLK_DEV_IDECD deselected. Perhaps a simpler technique (that only affects 1 device) is to add the following line in the appropriate place of the file /etc/lilo.conf :
    append="hdd=ide-scsi" .

Stage 2 can be accomplished by rebuilding the kernel to include a SCSI subsytem and with CONFIG_BLK_DEV_SR built in or a module. Most distributions come with the SCSI subsystem (and its cdrom driver) built in. Further, the ide-scsi driver (called CONFIG_BLK_DEV_IDESCSI needs to be built in or be a module. Most distributions come with the ide-scsi module available. The simplest way to find out is to write:
    modprobe ide-scsi
[The /etc/modules.conf file can be tweaked to make this module load automatically as required.] If this has worked then the following line should output data describing your cdrom device:
    cat /proc/scsi/scsi

If so, then try cdrecord (xcdroast or whatever) again and it should be happy.

[2.1]  Kernel build dies in sg.c complaining about scsi_logging_level ...

Take a copy of your ".config" file (placing it, for example, in /tmp) and then run make mrproper. Restore your ".config" file and revisit the configuration with make config | menuconfig | xconfig then "exit and save". [There is no need to change any of the configuration.] Next do a full kernel build (e.g. make dep; make clean; make bzImage; make modules; make modules_install, etc). This should fix the problem. This only occurs when sg is made as a module, versioning is used on modules, CONFIG_SCSI_LOGGING is selected and there is some "crap" laying around from previous builds. I don't fully understand why it happens but I suspect a tweak in a Makefile is needed.

[2.2]  When I change SG_BIG_BUFF it is not reflected in /proc/sys/kernel/sg-big-buff

The SG_BIG_BUFF define exists only for backward compatibility. Some applications act on it or worse, suggest that users change it in the kernel then rebuild and reload the kernel. The latter approach is playing with fire, especially on the original sg driver when used in 2.2 . See the "SG_BIG_BUFF and friends" and the "Memory issues" sections in the full documentation which has a link to it from the main page.

If you can't use the recommended ioctls() (e.g. not visible) then increase the value of the SG_DEF_RESERVED_SIZE define to get a similar effect.

As for /proc/sys/kernel/sg-big-buff, it is only visible when sg is built into the kernel (i.e. not when sg is a module). If available, it yields the size of the reserved buffer of the most recently opened sg device. It is only readable. If the lk 2.4 series is being used then /proc/scsi/sg/def_reserved_size contains the same information, is visible whenever sg is built in or loaded as a module and is writeable.

[2.3]  "Foooooooood fight" panic from aha1542

There is a bug in the sg driver (lk 2.2.14+15) when it is used with the aha1542 driver (and perhaps some other adapter drivers modelled on it). It occurs when commands with data transfer lengths that are either odd or zero length, are sent while scatter gather is being used for the default buffer. The latter condition will usually only occur when "reserved size" buffer is increased beyond its default value of 32 KB. SANE 1.0.2 users are most effected by this. This is fixed by a change to the sg driver (sg 2.1.37) in lk 2.2.16. It can also be circumvented by setting the environment variable SANE_SG_BUFFERSIZE to 32768.

[2.4]  DMA problems with sym53c416

The fix for the aha1542 in lk 2.2.16 (see [2.3]) had the unfortunate side effect of causing problems for the sym53c416 driver! This problem also occurs with SANE 1.0.2 and can be circumvented by setting the environment variable SANE_SG_BUFFERSIZE to 32768. This is fixed in lk 2.2.17 .

[2.5] aha152x

The aha152x driver was a source of some concern. Something happened to it in the transition from 2.2.5 to 2.2.6 (interrupt code changes that were not performed by the maintainer). The nett effect is that the cdrecord, sg, aha152x combination often lead to a machine lock up in 2.2.5-15 (the kernel version shipped with Redhat 6.0) .One solution is to regress the aha152x driver to the one found in the original 2.2.5 kernel. Here is a tarball of it. Since this problem has not been reported recently it seems as though changes to the aha152x driver between 2.2.10 and 2.2.12 fixed this problem.

Problems seem to have re-emerged with this driver (or the way sg uses it) in lk 2.4.0-test9 (or kernel around that time) and they are now fixed in lk 2.4.0-test11

[2.6] Agfa SnapScan (scanner under SANE)

The Agfa SnapScan driver within SANE found a way to upset the current production sg driver (version 2.1.34). The SANE driver in question has been changed to fix this problem. See Kevin Charter's SnapScan page . A test version of sg that fixed this problem (2.1.35) was available for a while but that "fix" has been reversed out in 2.1.36. The reason for this was the complexity that it introduced in sg and that the 2 fixes were not needed for the same problem. This is fixed in SANE 1.0.2 .

[2.7]  aic7xxx

On certain hardware this driver seems prone to going into infinite bus reset mode. It (or adaptec hardware) seems very sensitive to the SCSI bus termination arrangements. New versions of this driver are being released that alleviate some of these problems. There is now another aic7xxx adapter driver available, this one is provided by Adaptec and is currently in beta test. It may be worth trying.

There is a new aic7xxx driver which is sponsored by adaptec. It is currently in beta test and there have been favourable reports. It can be found at .


This is an ioctl() offered by the SCSI mid-level and hence is available to all file descriptors obtained from SCSI devices. It is deprecated and its interface structure is "hidden" from the user space. Still it is useful in some contexts. What follows is a summary of its interface structure (which users need to replicate in their programs):

 * struct sdata {
 *  unsigned int inlen;      [i] Length of data to be written to device
 *  unsigned int outlen;     [i] Length of data to be read from device
 *  unsigned char cmd[x];    [i] SCSI command (6 <= x <= 12).
 *                           [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. 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.

[2.9]  Canon backend in SANE

The Canon backend in SANE requires a patch to be applied to the sg driver. See this following url: . This is required due to a design limitation in the original sg driver interface. An additional interface has been added in the version 3 sg driver which is now available in lk 2.4.0 . Since recent versions of SANE (e.g. 1.0.4) detect and use the version 3 sg driver interface, then the above patch should no longer be needed. I would like someone with a Canon scanner to confirm this.

[2.10] Sg freezes in early lk 2.4 series

The sg driver (version 3.1.17) found in the early lk 2.4 series in distributions such as RedHat 7.1 and Mandrake 8 has the tendency to lock up when a large amount of memory is requested. Recent versions of cdda2wav (and some other apps) request a 100 MB "reserved" buffer from sg. This was a little larger than I expected and due to a bug in sg can cause the driver to lockup (or at least wait for a long time) in the hope that that much memory (that is, _real_ RAM) will become available. The process in question will be unkillable and ps's WCHAN usually shows "-". The solution is to go to the main page and fetch sg version 3.1.19 (or later) and rebuild your kernel (or the sg  module). The fixed driver is found in lk 2.4.7 .

[2.11] Ide-scsi driver continually resets in lk 2.4

Try this command: "hdparm -d0 /dev/hdc" to turn off DMA on the device before using something like cdrecord. [The assumes your cd writer is attached to the second IDE channel as the master: /dev/hdc ]. The continual reset problem with an IDE cd writer together with ide-scsi, sg and cdrecord is being reported a lot with early versions of lk 2.4 .

[2.12] Sg in Redhat 6.2, 7.0 and Mandrake 7.1

Various distributions have slightly modified sg drivers in the lk 2.2 series. The change arises due to a "sigio" patch that has been applied. [The sigio patch backports some new lk 2.4 functionality for POSIX real time signals into the lk 2.2 series.] This patch effects sg because it changes the number of arguments to the kill_fasync() call. This call is found at line 834 in sg version 2.1.39 and looks like this in the standard kernels:
       kill_fasync(sfp->async_qp, SIGPOLL);
If compiling this line gives an error (usually "too few arguments to kill_fasync") then it can safely be changed to this:
       kill_fasync(sfp->async_qp, SIGPOLL, POLL_IN);

This problem only impacts sg 2.1.x versions of sg (and sg version 3.0.17).

[2.13] Sg in Redhat 7.3

Redhat 7.3 breaks the "standard" sg driver in the lk 2.4 series. There are two minor compile problems which are easily fixed. They are in the sg_proc_dev_info() and sg_proc_host_info() functions towards the end of the driver source code (around line 3000). The macro argument:
needs to be changed to
Also a few lines further on the macro argument:
needs to be changed to

It is regrettable that such issues arise, but from a technical viewpoint it is a wise change.

[3.1] The compiler is picking up the wrong sg.h

User applications need to find the correct "sg.h" header file matching their kernel in order to write code using the sg device driver. This is sometimes more difficult than it should be. The correct "sg.h" will usually be found at /usr/src/linux/include/scsi/sg.h . Another important header file is "scsi.h" which will be in the same directory.

glibc comes with it's own headers for these files in /usr/include/scsi - but they're not currently synched.  When "#include <scsi/sg.h>" is written in an application then this refers to the file /usr/include/scsi/sg.h . Glibc 2.1.3 and later versions should get it right (but will probably be out of sync again when lk 2.4 is released).

The fact the /usr/include/linux is a symbolic link opens up the following solution proposed by the author of cdparanoia (Monty): #include <linux/../scsi/sg.h> .

[I would like to thank Andreas Jaeger <> for his contributions on this subject.]

[3.2] Cdrecord

This application has taken over from cdwrite as the primary, general purpose cd writing tool for Linux. It is ported to many other platforms as well. It is written and maintained by Jörg Schilling and further information can be found at its home site .
Cdrecord has a transport layer library called libscg that isolates the bulk of the application from the OS on which it is running. Jörg Schilling maintains his own Linux sg driver for the Linux 2.2 series of kernels and has changed libscg to take advantage of those non-standard changes. This improves error reporting a little at the expense of the error fixes and enhancements that have been placed in the standard sg driver in the last 12 months. [Jörg Schilling's sg driver implementation is a modified copy from March 1999 of the what was to become the standard sg driver.] The impact on cdrecord users is minor and they can safely use the standard sg device driver found in recent Linux distributions.

There is a mailing list that covers cdrecord, cdrdao and cdparanoia issues at . You can  subscribe by sending mail to containing only the word subscribe in the body. Please do not send subscription requests directly to the main list.

Cdrecord uses the sg interface to access IDE ATAPI cd writers. See FAQ 1.5 .

In the linux 2.4 kernel series there has been an increase in problems when the ide-scsi driver is used so that cdrecord can control ATAPI (IDE) cd writers. The problem may be related to the aggressive manner in which the IDE subsystem attempts to optimize the speed of transfers to devices it controls. Some people experiencing timeouts and machine lockups have found that reducing the DMA setting via the hdparm command has fixed the problem. If the cd writer is connected to /dev/hdd then users have reported success with these 2 commands:
    hdparm -d0 -c1 /dev/hdd
    hdparm -d 1 -X 34 /dev/hdd
The first one turns off DMA completely while the second one sets it "multiword DMA mode 2". Cd writers do not need the types of speeds that modern disks utilize. Even burning at "x16" implies a sustained transfer rate of 16 times 150 KB/sec which is approximately 2.4 MB/sec, not really that fast. There has also been a report that moving a cd writer off a high speed IDE controller (Promise) and back to the motherboard's lower speed IDE controllers has fixed a random IDE bus reset problem. Another report suggests reducing (or turning off) the DMA on the IDE hard disk can also stop lockups. Jörg Schilling states that DMA should be used for burn speeds greater tha "x12". The lowest IDE DMA speed of 33 MB/sec should be sufficient for the foreseeable future.

[3.3] Cdrdao

Cdrdao records audio/data CD-Rs in disk-at-once (DAO) mode based on a textual description of the CD contents (toc-file). This is its home site . It uses the same transport layer library as cdrecord (namely libscg) however its author ( Andreas Müller ) has experimented with direct support for Linux (i.e. by-passing libscg).
There are no known "sg" related issues with cdrdao.

[3.4] SANE

SANE stands for "Scanner Access Now Easy" and is an application programming interface (API) that provides standardized access to any raster image scanner hardware (flatbed scanner, hand-held scanner, video- and still-cameras, frame-grabbers, etc.). This is its home site . SANE is a multi platform application that uses a transport layer to isolate the bulk of its logic from the OS specifics (e.g. the sg device driver). Some changes have been made to take advantage of relatively new sg features.

If things are failing with SANE then defining various environment variables may help. For Bourne derived shells 'export SANE_DEBUG_SANEI_SCSI=127' and 'export SANE_DEBUG_<BACKEND_NAME>=127' will provide output that may help those trying to trace the problem.

There is a problem with SANE 1.0.3 and 1.0.4 when used with the version 3 sg driver found in the lk 2.4 series. The default timeout of 10 seconds is too short and causes SCSI bus resets on many scanners. In the SANE source this change from Abel Deuring is required:
Try to change the following line in sanei/sanei_scsi.c
      req->sgdata.sg3.hdr.timeout = 10000;
(line 1892 in Sane 1.0.4) to:
      req->sgdata.sg3.hdr.timeout = 1000 * 10 * 60;
The SANE CVS has been updated so SANE version 1.0.5 won't have this problem. Also major Linux distributions that will be based on early versions of lk 2.4 will most likely include this patch in their SANE packages.

The above problem is fixed in SANE 1.0.5 . Some SCSI (pseudo) adapters (e.g. usb/microtek currently but may soon be fixed) do not support scatter gather at the device level. In such cases set the environment variable SANE_SG_BUFFERSIZE to 32768. When using the bash shell this can be done with "export SANE_SG_BUFFERSIZE=32768".

[3.5] Cdparanoia [a.k.a. cdda paranoia or just "paranoia"]

Cdparanoia retrieves audio tracks from CDDA capable  CDROM drives.   The  data  can be saved to a file or directed to standard output in WAV, AIFF, AIFF-C or raw format.   Most ATAPI,  SCSI and several proprietary CDROM drive makes are supported; cdparanoia can determine if the target drive is CDDA capable. In  addition  to  simple  reading,  cdparanoia adds extra- robust data verification, synchronization, error  handling and scratch reconstruction capability. This is its home site .
Some of the notes about cdroms in the cdrecord section (e.g. disabling or reducing IDE DMA) are also relevant.

[3.6] Finding the target id of a scsi device

This is an edited answer to this question from the mailing list. Some of the answer is only relevant to lk 2.4 :

> How can I translate between BUS,ID,LUN <-> sg <-> sr (hd)?

The answer depends on what size of "hammer" you wish to use on this problem.

At one extreme is the device pseudo file system (devfs) which is included in 2.4 kernels (but not usually the default). It makes both the host/channel/target/lun hierarchy and (when devfsd is used) the linux traditional "sda"-like device names available. To get your mapping may require a fair amount of directory scanning.

Next there is scsidev ( see ). Once this utility is run it adds a /dev/scsi directory that looks like this on my system:

$ ls -l /dev/scsi
brw-------    1 root     root       8,   0 Aug 12 11:04 sdh1-0c0i0l0
crw-------    1 root     root      21,   0 Aug 12 10:48 sgh1-0c0i0l0
crw-------    1 root     root      21,   1 Aug 12 10:48 sgh2-0c0i2l0
crw-------    1 root     root      21,   3 Aug 12 11:04 sgh2-0c0i5l0
crw-------    1 root     root      21,   2 Aug 12 10:48 sgh2-0c0i6l0
br--------    1 root     root      11,   0 Aug 12 10:48 srh2-0c0i2l0
br--------    1 root     root      11,   1 Aug 12 10:48 srh2-0c0i6l0

This time a relatively simple directory scan should answer your question. [Even though devfs introduces a /dev/scsi directory, it and scsidev do seem to happily co-exist.]

Another approach is to parse the output of 'cat /proc/scsi/scsi'. It is not pretty but some applications do it:
$ cat /proc/scsi/scsi
Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: IBM      Model: DNES-309170W     Rev: SA30
  Type:   Direct-Access                    ANSI SCSI revision: 03
Host: scsi2 Channel: 00 Id: 02 Lun: 00
  Vendor: PIONEER  Model: DVD-ROM DVD-303  Rev: 1.10
  Type:   CD-ROM                           ANSI SCSI revision: 02
Host: scsi2 Channel: 00 Id: 06 Lun: 00
  Vendor: YAMAHA   Model: CRW4416S         Rev: 1.0g
  Type:   CD-ROM                           ANSI SCSI revision: 02
Host: scsi2 Channel: 00 Id: 05 Lun: 00
  Vendor: UMAX     Model: Astra 1220S      Rev: V1.2
  Type:   Scanner                          ANSI SCSI revision: 02

Then there is the SCSI_IOCTL_GET_IDLUN ioctl(). It does some awkward bit stuffing and be careful with the hostnumber (because in lk 2.2 and earlier you will need to call the additional SCSI_IOCTL_GET_BUS_NUMBER ioctl() to get that number). It can applied to all SCSI device names.

Finally the sg driver tries to make this a bit simpler with the SG_GET_SCSI_ID ioctl(). See sg's documentation. It should be simple enough to see what it does from /usr/src/linux/include/scsi/sg.h :
typedef struct sg_scsi_id {
    int host_no;        /* as in "scsi<n>" where 'n' is one of 0, 1, 2 etc */
    int channel;
    int scsi_id;        /* scsi id of target device */
    int lun;
    int scsi_type;      /* TYPE_... defined in scsi/scsi.h */
    /* ...... */
} Sg_scsi_id;

For examples of this see the sg web site and the sg utilities. The best example is a program called sg_map (another is sg_scan). The output of sg_map for my system looks like:

$ sg_map
/dev/sg0  /dev/sda
/dev/sg1  /dev/sr0
/dev/sg2  /dev/sr1

Note that /dev/sg3 doesn't "map" because it is a scanner. With this extra "x" option this becomes:

$ sg_map -x
/dev/sg0  1 0 0 0  0  /dev/sda
/dev/sg1  2 0 2 0  5  /dev/sr0
/dev/sg2  2 0 6 0  5  /dev/sr1
/dev/sg3  2 0 5 0  6

The numbers are host_number, channel, id, lun and scsi device type (where "6" is a scanner). With the sg driver in lk 2.4 similar information is provided via the "proc" file system. After the header line each row corresponds to an sg device starting at /dev/sg0.

$ cd /proc/scsi/sg ;  cat device_hdr devices
host    chan    id      lun     type    bopens  qdepth  busy
1       0       0       0       0       4       63      3
2       0       2       0       5       0       4       0
2       0       6       0       5       0       4       0
2       0       5       0       6       0       4       0

If a device has been removed the a row of "-1"s is output. A device can be removed with a line like 'echo "scsi remove-single-device 2 0 6 0" > /proc/scsi/scsi'. Also "-1"s are only output (indicating a "hole" in the mapping) if there is a following device.

If the ide-scsi pseudo driver is being used I know of no way to establish the sr <-> hd mapping after the fact. Suggestions?

Return to main page.

Douglas Gilbert can be emailed at this address.
Last updated: 14th June 2002, 23:00