Next Previous Contents

## 6. Overview Of Device Programming

The header file `include/scsi/sg.h` contains a description of the interface (this is based on kernel version 1.3.98):

> `

>     struct sg_header
>      {
>       int pack_len;
>                        /* length of incoming packet (including header) */
>       int reply_len;   /* maximum length of expected reply */
>       int pack_id;     /* id number of packet */
>       int result;      /* 0==ok, otherwise refer to errno codes */
>       unsigned int twelve_byte:1;
>                    /* Force 12 byte command length for group 6 & 7 commands  */
>       unsigned int other_flags:31;                  /* for future use */
>       unsigned char sense_buffer[16]; /* used only by reads */
>       /* command follows then data for command */
>      };

> `

This structure describes how a SCSI command is to be processed and has room to hold the results of the execution of the command. The individual structure components will be discussed later in section sec-header .

The general way of exchanging data with the generic driver is as follows: to send a command to an opened generic device, `write()` a block containing these three parts to it:

> `

>     struct sg_header
>     SCSI command
>     data to be sent with the command

> `

To obtain the result of a command, `read()` a block with this (similar) block structure:

> `

>     struct sg_header
>     data coming from the device

> `

This is a general overview of the process. The following sections describe each of the steps in more detail.

NOTE: Up to recent kernel versions, it is necessary to block the SIGINT signal between the `write()` and the corresponding `read()` call (i.e. via `sigprocmask()`). A return after the `write()` part without any `read()` to fetch the results will block on subsequent accesses. This signal blocking has not yet been included in the example code. So better do not issue SIGINT (a la ^C) when running these examples.

Next Previous Contents