
                    Le HOWTO Linux de la programmation SCSI

Heiko Eifeldt heiko@colossus.escape.de (version franaise : Thierry Danis
thierry.danis@hol.fr, le 26 Janvier 1998, largement base sur la traduction de
la version v1.4 faite par Bernard Choppy choppy@imaginet.fr).

   v1.5, 7 Juin 1996
     _________________________________________________________________

   _Ce document traite de la programmation de l'interface SCSI gnrique
   de Linux._
     _________________________________________________________________

Appendix

1. Les nouveauts

   Les interfaces des nouveaux noyaux ont un peu chang. Le chapitre
   'rescrutation des priphriques' est concern par ces changements. Il
   est maintenant possible d'ajouter et d'enlever des priphriques SCSI
    chaud et  la vole.

   A partir de la version 1.3.98, certains fichiers d'inclusion
   importants ont t dplacs ou dcoups (sg.h and scsi.h).

   Quelques bugs idiots ont t remplacs par d'autres.

2. Introduction

   Ce document est un guide d'installation et de programmation de
   l'interface gnrique SCSI de Linux.

   Il traite des prrequis du noyau, de l'organisation des priphriques,
   et de l'interaction de base avec ces derniers. Quelques exemples
   simples de programmation en C sont inclus. Pour de plus amples dtails
   sur la norme SCSI et les informations associes, reportez-vous 
   l'annexe de ce document.

   Note : la version texte simple de ce document ne dispose pas de
   rfrnces croises (indiques par ``'').

3. Qu'est-ce que l'interface SCSI gnrique ?

   L'interface gnrique SCSI a t faite pour fournir un accs gnral 
   des priphriques SCSI (ventuellement exotiques). Elle a t
   dveloppe par Lawrence Foard ( entropy@world.std.com) et sponsorise
   par Killy Corporation (voir les commentaires du fichier
   drivers/scsi/sg.h).

   Cette interface permet  des programmes applicatifs (c'est--dire hors
   du noyau) d'accder aux fonctionnalits de certains priphriques. Le
   dveloppement de pilotes dans le noyau, plus risqus et difficiles 
   mettre au point, n'est ainsi plus ncessaire.

   Nanmoins, si le priphrique n'est pas correctement programm, il est
   possible de bloquer le bus SCSI, le pilote, ou le noyau. C'est
   pourquoi il est important de programmer correctement le pilote
   gnrique, et de commencer par sauvegarder tous les fichiers afin
   d'viter une perte de donnes. Une autre prcaution utile est de faire
   un sync avant de lancer vos programmes pour garantir l'criture de
   tous les tampons sur le disque ; cela limitera la perte de donnes en
   cas de blocage du systme.

   Un autre avantage du pilote gnrique est que, aussi longtemps que
   l'interface elle-mme ne change pas, toutes les applications restent
   indpendantes des nouveaux dveloppements du noyau. En comparaison,
   les pilotes de bas niveau du noyau doivent suivre les volutions
   internes de celui-ci.

   Typiquement, le pilote gnrique est utilis pour communiquer avec les
   nouveaux quipements SCSI qui exigent l'criture d'applications
   utilisateur spcifiques pour tirer avantage de leurs fonctionalits
   (par exemple les scanners, les imprimantes, le juke-boxes de CDROM).
   L'interface gnrique permet un dveloppement rapide de ces
   applications.

4. Que faut-il pour l'utiliser ?

4.1 Configuration du noyau

   Il vous faut videmment un adapteur SCSI reconnu. De plus, votre noyau
   doit tre compil avec le support du pilote gnrique, en plus de
   celui pour votre adapteur. La configuration du noyau Linux (par make
   config sous /usr/src/linux) doit ressembler  :

 ...
*
* SCSI support
*
SCSI support? (CONFIG_SCSI) [n] y
*
* SCSI support type (disk, tape, CDrom)
*
 ...
Scsi generic support (CONFIG_CHR_DEV_SG) [n] y
*
* SCSI low-level drivers
*
 ...

   Si le noyau est modulable, vous pouvez tout aussi bien utiliser les
   modules.

4.2 Fichiers spciaux

   Le pilote gnrique utilise ses propres fichiers spciaux. Ils peuvent
   tre crs par le script MAKEDEV, que l'on trouve habituellement dans
   le rpertoire /dev. La commande MAKEDEV sg cre les fichiers suivants
   :

crw-------   1 root     system    21,   0 Aug 20 20:09 /dev/sga
crw-------   1 root     system    21,   1 Aug 20 20:09 /dev/sgb
crw-------   1 root     system    21,   2 Aug 20 20:09 /dev/sgc
crw-------   1 root     system    21,   3 Aug 20 20:09 /dev/sgd
crw-------   1 root     system    21,   4 Aug 20 20:09 /dev/sge
crw-------   1 root     system    21,   5 Aug 20 20:09 /dev/sgf
crw-------   1 root     system    21,   6 Aug 20 20:09 /dev/sgg
crw-------   1 root     system    21,   7 Aug 20 20:09 /dev/sgh
                                   |    |
                       numros majeur, mineur

   Notez que ces fichiers sont des fichiers en mode caractre pour
   permettre les accs directs. Sur certains systmes, ces fichiers
   peuvent s'appeler /dev/{sg0,sg1,...}, en fonction de votre
   installation. Vous devrez donc adapter les exemples qui suivant en
   consquence.

4.3 Organisation des priphriques

   Les fichiers spciaux sont affects dynamiquement aux ID/LUN (LUN :
   Unit logique) du bus SCSI. Les priphriques sont conscutivement
   allous selon les units logiques de chaque priphrique dtect lors
   de la scrutation du bus, les plus petits LUN/ID/BUS tant allous en
   premier. Le noyau commence par le premier contrleur SCSI et continue
   sans interruption avec tous les autres adapteurs. Cette tape est
   actuellement ralise lors de l'initialisation du pilote SCSI.

   Par exemple, si vous avez trois priphriques SCSI configurs avec les
   ID 1, 3 et 5 sur le premier bus SCSI (chacun avec une seule unit
   logique), l'affectation sera la suivante :

/dev/sga -> SCSI id 1
/dev/sgb -> SCSI id 3
/dev/sgc -> SCSI id 5

   Si vous ajoutez maintenant un nouveau priphrique d'identificateur 4,
   l'organisation aprs la prochaine scrutation du bus sera :

/dev/sga -> SCSI id 1
/dev/sgb -> SCSI id 3
/dev/sgc -> SCSI id 4
/dev/sgd -> SCSI id 5

   Notez le changement pour l'identificateur 5 - le priphrique
   correspondant n'est plus affect  /dev/sgc, mais  /dev/sgd.

   Les noyaux plus rcents permettent de changer cet ordre.

  Insertion et retrait dynamiques de priphriques SCSI

   Dans les noyaux rcents avec un systme de fichier /proc mont, il est
   possible de retirer et d'ajouter un priphrique libre (non-busy)  la
   vole.

   Pour enlever un priphrique SCSI :

echo "scsi remove-single-device a b c d" > /proc/scsi/scsi

   De la mme manire, ajouter un priphrique SCSI se fera par :

echo "scsi add-single-device a b c d" > /proc/scsi/scsi

   Ici, a, b, c et d sont dfinis de la faon suivante :

      a == identificateur de l'adapteur (le premier a l'id 0)
      b == canal SCSI sur l'adapteur (le premier a le numro 0)
      c == ID
      d == LUN (la premire ayant le numro 0)

   Ainsi, si nous dsirons intervertir l'affectation des fichiers
   /dev/sgc et /dev/sgd de l'exemple prcdent, nous pouvons faire :

echo "scsi remove-single-device 0 0 4 0" > /proc/scsi/scsi
echo "scsi remove-single-device 0 0 5 0" > /proc/scsi/scsi
echo "scsi add-single-device 0 0 5 0" > /proc/scsi/scsi
echo "scsi add-single-device 0 0 4 0" > /proc/scsi/scsi

   puisque les priphriques gnriques sont allous dans leur ordre
   d'insertion.

   Si vous voulez ajouter de nouveaux priphriques sur le bus SCSI,
   gardez  l'esprit qu'un nombre limit d'entres supplmentaires a t
   attribu. La mmoire a t alloue au dmarrage, et il n'y a de place
   que pour 2 entres supplmentaires.

5. Le guide du programmeur

   Les sections qui suivent s'adressent aux programmeurs dsireux
   d'utiliser l'interface gnrique SCSI dans leurs propres applications.
   Nous allons donner un exemple permettant d'accder  un priphrique
   SCSI par le biais des commandes INQUIRY et TESTUNITREADY.

   Lors de l'utilisation de ces exemples, prenez garde  ce qui suit :
     * l'emplacement des fichiers d'inclusion sg.h et scsi.h a chang 
       partir du noyau 1.3.98. Ces fichiers se trouvent maintenant 
       /usr/src/linux/include/scsi, qui devrait tre un lien vers
       /usr/include/scsi. Dans les versions prcdentes, ils se
       trouvaient dans /usr/src/linux/drivers/scsi. Nous supposerons dans
       la suite que vous utilisez un de ces noyaux rcents.
     * l'interface gnrique SCSI a t tendue dans la version 1.1.68 du
       noyau. Les exemples ncessitent au moins cette version. En
       revanche, vitez d'utiliser les noyaux de 1.1.77  1.1.89 qui
       disposent d'une interface gnrique SCSI dfectueuse.
     * la constante DEVICE de la section qui dcrit le priphrique
       accd doit tre positionne en fonction de vos priphriques
       disponibles (reportez-vous au chapitre La structure d'en-tte).

6. Vue d'ensemble de la programmation des priphriques

   Le fichier d'inclusion include/scsi/sg.h contient une description de
   l'interface (celle du noyau 1.3.98) :

struct sg_header
 {
                        /*
                         * longueur du paquet entrant (y compris en-tte)
                         */
  int pack_len;
                        /*
                         * taille max de la rponse attendue
                         */
  int reply_len;
                        /*
                         * numro d'id du paquet
                         */
  int pack_id;
                        /*
                         * 0 == ok,
                         * pour les autres, voir les codes pour errno
                         */
  int result;
                        /*
                         * Force la longueur a 12 pour les commandes des
                         * groupes 6 & 7
                         */
  unsigned int twelve_byte:1;
                        /*
                         * pour utilisation future
                         */
  unsigned int other_flags:31;
                        /*
                         * uniquement utilis lors des lectures
                         */
  unsigned char sense_buffer[16];
                        /*
                         * la commande suit puis les donnes de la
                         * commande
                         * .............
                         */

   Cette structure dcrit comment une commande SCSI doit tre traite et
   disposer de place pour le rsultat de son excution. Les composants
   individuels de la structure seront abords plus loin  la section La
   structure d'en-tte.

   La mthode gnrale pour changer des donnes avec le pilote gnrique
   est la suivante : pour envoyer une commande  un priphrique
   gnrique ouvert, il faut crire (write()) un bloc compos des trois
   parties suivantes :

                             struct sg_header
                               commande SCSI
                     donnes envoyes avec la commande

   Pour obtenir le rsultat d'une commande, il faut lire (read()) un bloc
   composs des parties suivantes (similaires  l'criture) :

                             struct sg_header
                             donnes en entre

   Il s'agit d'une vue gnrale de la procdure. Les sections qui suivent
   dcrivent chaque tape en dtail.

   NOTE : jusqu' de rcentes versions du noyau, il tait ncessaire de
   bloquer le signal SIGINT entre les appels write() et le read()
   correspondant (par exemple, par sigprocmask()). Un retour aprs la
   partie criture sans lecture pour rcuprer les rsultats va bloquer
   les accs suivants. Le blocage du signal n'a pas encore t inclus
   dans le code des exemples. Evitez donc d'envoyer un SIGINT (par ^C,
   par exemple) lors du test de ceux-ci.

7. Ouverture du priphrique

   Un priphrique gnrique doit tre ouvert avant tout accs en lecture
   ou en criture :

        int fd = open(nom_du_priphrique, O_RDWR);

   (ce qui prcde s'applique aussi pour les matriels en lecture seule
   comme les lecteurs de CDROM).

   Il faut excuter un write pour envoyer la commande et un read pour en
   lire le rsultat. En cas d'erreur, le code de retour est ngatif (se
   reporter  la section Traitement d'erreurs pour la liste complte des
   codes de retour).

8. La structure d'en-tte

   La structure d'en-tte struct sg_header est utilise comme couche de
   contrle entre l'application et le pilote du noyau. Abordons
   maintenant le dtail de ses composants.

   _int pack_len_
          dfinit la taille du bloc envoy au pilote. Cette valeur est
          dfinie dans le noyau pour une utilisation interne.

   _int reply_len_
          dfinit la taille du bloc accept en rponse. Cette valeur est
          dfinie du ct application.

   _int pack_id_
          Ce champ facilite l'appariement des rponses aux requtes.
          L'application peut fournir un identifiant unique  chaque
          requte. Supposons que vous ayez crit un certain nombre de
          commandes (disons 4) pour un priphrique. Celles-ci peuvent
          fonctionner en parallle, l'une d'entre elles tant la plus
          rapide. Lors de la lecture des rponses par quatre "read",
          celles-ci ne sont pas forcment dans l'ordre des requtes. Pour
          identifier la rponse correcte pour une requte, on peut
          utiliser le champ pack_id. Habituellement, cette valeur est
          incrmente aprs chaque requte (et boucle ventuellement). Le
          nombre maximum de requtes mises simultanment est limit par
          le noyau  SG_MAX_QUEUE (en gnral, quatre).

   _int result_
          C'est la valeur du rsultat d'un appel  read ou  write. Elle
          est (parfois) dfinie par la le pilote gnrique (partie
          noyau). Il est plus prudent de le positionner  9 avant l'appel
           write. Ces codes sont dclars dans le fichier errno.h (0
          indique un rsultat correct).

   _unsigned int twelve_byte:1_
          Ce champ n'est ncessaire que lors de l'utilisation de
          commandes spcifiques non standard (dans la plage 0xc0  0xff).
          Lorsque la longueur de ces commandes est de 12 octets au lieu
          de 10, il faut positionner ce champ  1 avant l'appel  write.
          D'autres longueurs de commandes ne peuvent tre utilises. Ce
          champ est positionn par l'application.

   _unsigned char sense_buffer[16]_
          Ce tampon est positionn aprs l'excution d'une commande
          (aprs un appel  read()) et contient le code de "sensation"
          SCSI (SCSI send code. NdT. : dans le reste du document, on
          utilisera simplement la formule "tampon SCSI"). Certains
          rsultats de commandes doivent tre lus  cet emplacement (par
          exemple pour TESTUNITREADY). Il ne contient habituellement que
          des octets nuls. La valeur de ce champ est positionne par le
          pilote gnrique (partie noyau).

   L'exemple de fonction qui suit s'interface directement avec le pilote
   gnrique du noyau. Il dfinit la structure d'en-tte, envoie la
   commande par write, lit le rsultat par read et effectue un nombre
   (limit) de contrles d'erreurs. Les donnes du tampon SCSI sont
   disponibles dans le tampon de sortie (sauf si un pointeur nul a t
   fourni, auquel cas elles se trouvent dans le tampon d'entre). Nous
   l'utiliserons dans les exemples qui suivent.

   Note : positionnez la valeur de DEVICE  celle qui correspond  votre
   matriel.

#define DEVICE "/dev/sgc"

/* Programme d'exemple utilisant l'interface SCSI gnrique */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/sg.h>


#define SCSI_OFF sizeof(struct sg_header)
static  unsigned char cmd[SCSI_OFF + 18];       /* tampon de commande SCSI */
int     fd;                                     /*
                                                 * descripteur de peripherique/
                                                 * fichier SCSI
                                                 */
/* traite une commande SCSI complte. Utilise l'interface gnrique */
static int handle_SCSI_cmd(unsigned cmd_len,     /* longueur de commande  */
                           unsigned in_size,     /* taille data en entre */
                           unsigned char *i_buff,/* tampon d'entre       *//
                           unsigned out_size,    /* taille data en sortie */
                           unsigned char *o_buff /* tampon de sortie      */
                           )
{
    int status = 0;
    struct sg_header *sg_hd;

    /* vrifications de scurit */
    if (!cmd_len) return -1;            /* ncessite que cmd_len != 0 */
    if (!i_buff) return -1;             /* ncessite que i_buff != NULL */

#ifdef SG_BIG_BUFF
    if (SCSI_OFF + cmd_len + in_size > SG_BIG_BUFF) return -1;
    if (SCSI_OFF + out_size > SG_BIG_BUFF) return -1;
#else
    if (SCSI_OFF + cmd_len + in_size > 4096) return -1;
    if (SCSI_OFF + out_size > 4096) return -1;
#endif

    if (!o_buff) out_size = 0;          /* pas de tampon de sortie, pas de */
                                        /* taille                          */

    /* construction de l'en-tte gnrique de priphrique */
    sg_hd = (struct sg_header *) i_buff;
    sg_hd->reply_len   = SCSI_OFF + out_size;
    sg_hd->twelve_byte = cmd_len == 12;
    sg_hd->result = 0;
#if     0
    sg_hd->pack_len    = SCSI_OFF + cmd_len + in_size; /* non indispensable */
    sg_hd->pack_id;     /* inutilise */
    sg_hd->other_flags; /* inutilise */
#endif

    /* envoi de la commande */
    status = write( fd, i_buff, SCSI_OFF + cmd_len + in_size );
    if ( status < 0 || status != SCSI_OFF + cmd_len + in_size ||
                       sg_hd->result ) {
        /* condition d'erreur */
        fprintf( stderr, "write(generic) resultat = 0x%x cmd = 0x%x\n",
                    sg_hd->result, i_buff[SCSI_OFF] );
        perror("");
        return status;
    }

    if (!o_buff) o_buff = i_buff; /* contrle du pointeur du tampon */

    /* rcupration du rsultat */
    status = read( fd, o_buff, SCSI_OFF + out_size);
    if ( status < 0 || status != SCSI_OFF + out_size || sg_hd->result ) {
        /* condition d'erreur */
        fprintf( stderr, "read(generic) statut = 0x%x, resultat = 0x%x, "
                         "cmd = 0x%x\n",
                         status, sg_hd->result, o_buff[SCSI_OFF] );
        fprintf( stderr, "read(generic) tampon SCSI "
                "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
                sg_hd->sense_buffer[0],         sg_hd->sense_buffer[1],
                sg_hd->sense_buffer[2],         sg_hd->sense_buffer[3],
                sg_hd->sense_buffer[4],         sg_hd->sense_buffer[5],
                sg_hd->sense_buffer[6],         sg_hd->sense_buffer[7],
                sg_hd->sense_buffer[8],         sg_hd->sense_buffer[9],
                sg_hd->sense_buffer[10],        sg_hd->sense_buffer[11],
                sg_hd->sense_buffer[12],        sg_hd->sense_buffer[13],
                sg_hd->sense_buffer[14],        sg_hd->sense_buffer[15]);
        if (status < 0)
            perror("");
    }
    /* A-t-on ce qu'on attendait ? */
    if (status == SCSI_OFF + out_size) status = 0; /* on a tout */

    return status;  /* 0 indique que tout est bon */
}

   Bien que cela puisse sembler quelque peu complexe au premier abord,
   une grande partie du code est ddie aux contrle et dtection
   d'erreurs (ce qui est utile mme une fois que le code fonctionne
   correctement).

   Handle_SCSI_cmd prsente une forme gnralise pour tous les types de
   commandes SCSI, qui correspondent  l'une des catgories qui suivent :

     Mode de donnes            |    Exemple de commande
=============================================================
ni entre ni sortie de donnes  |     test d'unite prte
pas d'entre, sortie de donnes |      requte, lecture
entre de donnes, pas de sortie| selection de mode, criture
  entre et sortie de donnes   |     dtection de mode

9. Exemple de commande de requte

   L'une des commandes SCSI de base est INQUIRY, utilise pour identifier
   les type et constructeur du priphrique. Voici la dfinition issue de
   la spcification SCSI-2 (se reporter au standard SCSI-2 pour les
   dtails).

                            Table 44: Commande INQUIRY
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Octet|        |        |        |        |        |        |        |        |
|=====+=======================================================================|
| 0   |                           Code opration (12h)                        |
|-----+-----------------------------------------------------------------------|
| 1   |Numro d'unit logique    |                  Rserv          |  EVPD  |
|-----+-----------------------------------------------------------------------|
| 2   |                           Code page                                   |
|-----+-----------------------------------------------------------------------|
| 3   |                           Rserv                                     |
|-----+-----------------------------------------------------------------------|
| 4   |                           Taille d'allocation                         |
|-----+-----------------------------------------------------------------------|
| 5   |                           Contrle                                    |
+=============================================================================+

   Les donnes en sortie ont l'allure suivante :

                   Table 45: Format standard de donnes INQUIRY
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Octet|        |        |        |        |        |        |        |        |
|=====+==========================+============================================|
| 0   | Qualificateur de priph. |           Type de priphrique             |
|-----+-----------------------------------------------------------------------|
| 1   |  RMB   |                  Modificateur de type de priphrique        |
|-----+-----------------------------------------------------------------------|
| 2   |   Version ISO   |       Version ECMA       |  Version approuve ANSI  |
|-----+-----------------+-----------------------------------------------------|
| 3   |  AENC  | TrmIOP |     Rserv     |   Format de donnes en rponse    |
|-----+-----------------------------------------------------------------------|
| 4   |                    Longueur additionnelle (n-4)                       |
|-----+-----------------------------------------------------------------------|
| 5   |                           Rserv                                     |
|-----+-----------------------------------------------------------------------|
| 6   |                           Rserv                                     |
|-----+-----------------------------------------------------------------------|
| 7   | RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserve | CmdQue | SftRe  |
|-----+-----------------------------------------------------------------------|
| 8   | (MSB)                                                                 |
|- - -+---                      Identification de constructeur             ---|
| 15  |                                                                 (LSB) |
|-----+-----------------------------------------------------------------------|
| 16  | (MSB)                                                                 |
|- - -+---                      Identification de produit                  ---|
| 31  |                                                                 (LSB) |
|-----+-----------------------------------------------------------------------|
| 32  | (MSB)                                                                 |
|- - -+---                      Niveau de rvision du produit              ---|
| 35  |                                                                 (LSB) |
|-----+-----------------------------------------------------------------------|
| 36  |                                                                       |
|- - -+---                      Spcifique constructeur                    ---|
| 55  |                                                                       |
|-----+-----------------------------------------------------------------------|
| 56  |                                                                       |
|- - -+---                        Rserv                                  ---|
| 95  |                                                                       |
|=====+=======================================================================|
|     |                       Paramtres spcifiques constructeur             |
|=====+=======================================================================|
| 96  |                                                                       |
|- - -+---                      Spcifique constructeur                    ---|
| n   |                                                                       |
+=============================================================================+

   L'exemple qui suit utilise la fonction de bas niveau handle_SCSI_cmd
   pour effectuer la commande SCSI INQUIRY.

   Tout d'abord, nous ajoutons le bloc de commande  l'en-tte gnrique,
   puis appelons handle_SCSI_cmd. Notez que l'argument taille de tampon
   en sortie de l'appel handle_SCSI_cmd exclut la taille de l'en-tte
   gnrique. Aprs l'excution de la commande, le tampon de sortie
   contient les informations, sauf si une erreur s'est produite.

#define INQUIRY_CMD     0x12
#define INQUIRY_CMDLEN  6
#define INQUIRY_REPLY_LEN 96
#define INQUIRY_VENDOR  8       /* dcalage vers le nom du constructeur */

/* recherche du constructeur et du modle */
static unsigned char *Inquiry ( void )
{
  unsigned char Inqbuffer[ SCSI_OFF + INQUIRY_REPLY_LEN ];
  unsigned char cmdblk [ INQUIRY_CMDLEN ] =
      { INQUIRY_CMD,  /* commande                 */
                  0,  /* lun/rserv              */
                  0,  /* code de page             */
                  0,  /* rserv                  */
  INQUIRY_REPLY_LEN,  /* longueur allocation      */
                  0 };/* rserv / drapeau / lien */

  memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );

  /*
   * +------------------+
   * | struct sg_header | <- commande
   * +------------------+
   * | copie de cmdblk  | <- commande + SCSI_OFF
   * +------------------+
   */

  if (handle_SCSI_cmd(sizeof(cmdblk), 0, cmd,
                      sizeof(Inqbuffer) - SCSI_OFF, Inqbuffer )) {
      fprintf( stderr, "La requete a echoue\n" );
      exit(2);
  }
  return (Inqbuffer + SCSI_OFF);
}

   L'exemple ci-dessus suit cette structure. La fonction Inquiry recopie
   son bloc de commande aprs l'en-tte gnrique (donn par SCSI_OFF).
   Les donnes en entre sont absentes de cette commande. handle_SCSI_cmd
   dfinit la structure d'en-tte. Nous pouvons maintenant implmenter la
   fonction main qui complte ce programme d'exemple fonctionnel.

void main( void )
{
  fd = open(DEVICE, O_RDWR);
  if (fd < 0) {
    fprintf( stderr, "Il faut les permissions lecture/ecriture pour "DEVICE".\n
" );
    exit(1);
  }

  /* affiche certains champs du rsultat de Inquiry() */
  printf( "%s\n", Inquiry() + INQUIRY_VENDOR );
}

   Tout d'abord, nous ouvrons le priphrique, contrlons l'absence
   d'erreur, puis appelons la fonction de haut niveau. Ensuite, nous
   affichons des rsultats sous une forme lisible, dont le constructeur,
   le produit et la version.

   Note : il y a plus d'informations dans le rsultat de "Inquiry" que ce
   que fournit ce petit programme. Il vous est loisible d'tendre
   celui-ci au type de priphrique, version ANSI, etc. Le type de
   priphrique a une importance particulire, puisqu'il dtermine les
   jeux de commandes obligatoires et facultatives pour celui-ci. Si vous
   ne souhaitez pas le programmer vous-mme, Eric Youngdale a ralis le
   programme scsiinfo, qui fournit  peu prs toute information
   disponible pour un priphrique SCSI. Cherchez sur tsx-11.mit.edu dans
   pub/Linux/ALPHA/scsi (NdT : on trouvera ce programme sur les sites
   miroirs franais, comme ftp.ibp.fr,  un emplacement similaire).

10. Le "tampon SCSI"

   Les commandes qui ne renvoient pas de donnes peuvent fournir des
   informations d'tat  l'aide du tampon SCSI (qui fait partie
   intgrante de la structure d'en-tte). Les donnes d'tat sont
   disponibles lorsque la commande prcdente s'est termine avec un
   statut "CHECK CONDITION". Dans ce cas, le noyau rapatrie
   automatiquement les donnes d'tat  l'aide d'une commande "REQUEST
   SENSE". Sa structure est la suivante :

+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Octet|        |        |        |        |        |        |        |        |
|=====+========+==============================================================|
| 0   | Valide |                  Code d'erreur (70h ou 71h)                  |
|-----+-----------------------------------------------------------------------|
| 1   |                           Numro de segment                           |
|-----+-----------------------------------------------------------------------|
| 2   |Filemark|  EOM   |  ILI   |Rserv |         Clef d'tat               |
|-----+-----------------------------------------------------------------------|
| 3   | (MSB)                                                                 |
|- - -+---                        Information                              ---|
| 6   |                                                                 (LSB) |
|-----+-----------------------------------------------------------------------|
| 7   |                           Longueur additionnelle d'tat (n-7)         |
|-----+-----------------------------------------------------------------------|
| 8   | (MSB)                                                                 |
|- - -+---                        Information spcifique de la commande    ---|
| 11  |                                                                 (LSB) |
|-----+-----------------------------------------------------------------------|
| 12  |                           Code d'tat additionnel                     |
|-----+-----------------------------------------------------------------------|
| 13  |                           Qualificateur de code d'tat additionnel    |
|-----+-----------------------------------------------------------------------|
| 14  |                           Code d'unit de champ remplaable           |
|-----+-----------------------------------------------------------------------|
| 15  |  SKSV  |                                                              |
|- - -+------------               Spcifique clef d'tat                   ---|
| 17  |                                                                       |
|-----+-----------------------------------------------------------------------|
| 18  |                                                                       |
|- - -+---                        Octets supplmentaires d'tat            ---|
| n   |                                                                       |
+=============================================================================+

   Note : les champs les plus utiles sont la clef d'tat (cf. section
   Clefs du buffer SCSI), le code d'tat additionnel et le qualificateur
   de code d'tat additionnel (cf. section Codes et qualificateurs du
   buffer SCSI additionnels). Les deux derniers sont utiliss en
   combinaison l'un avec l'autre.

11. Exemple d'utilisation du tampon SCSI

   Nous allons utiliser ici la commande "TEST UNIT READY" pour contrler
   si un support est charg dans notre priphrique. Les dclarations
   d'en-tte et la fonction handle_SCSI_cmd de l'exemple de "Inquiry"
   seront aussi ncessaires.

                        Table 73: Commande TEST UNIT READY
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Octet|        |        |        |        |        |        |        |        |
|=====+=======================================================================|
| 0   |                           Code opration (00h)                        |
|-----+-----------------------------------------------------------------------|
| 1   |Numero d'unit logique LUN|                  Rserv                   |
|-----+-----------------------------------------------------------------------|
| 2   |                           Rserv                                     |
|-----+-----------------------------------------------------------------------|
| 3   |                           Rserv                                     |
|-----+-----------------------------------------------------------------------|
| 4   |                           Rserv                                     |
|-----+-----------------------------------------------------------------------|
| 5   |                           Contrle                                    |
+=============================================================================+

   Voici la fonction qui l'implmente :

#define TESTUNITREADY_CMD 0
#define TESTUNITREADY_CMDLEN 6

#define ADD_SENSECODE 12
#define ADD_SC_QUALIFIER 13
#define NO_MEDIA_SC 0x3a
#define NO_MEDIA_SCQ 0x00

int TestForMedium ( void )
{
  /* demande le statut READY */
  static unsigned char cmdblk [TESTUNITREADY_CMDLEN] = {
      TESTUNITREADY_CMD, /* commande */
                      0, /* lun/rserv */
                      0, /* rserv */
                      0, /* rserv */
                      0, /* rserv */
                      0};/* contrle */

  memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );

  /*
   * +------------------+
   * | struct sg_header | <- commande
   * +------------------+
   * | copie de cmdblk  | <- commande + SCSI_OFF
   * +------------------+
   */

  if (handle_SCSI_cmd(sizeof(cmdblk), 0, cmd,
                            0, NULL)) {
      fprintf (stderr, "Unite non prete\n");
      exit(2);
  }

  return
   *(((struct sg_header*)cmd)->sense_buffer +ADD_SENSECODE) !=
                                                        NO_MEDIA_SC ||
   *(((struct sg_header*)cmd)->sense_buffer +ADD_SC_QUALIFIER) !=
                                                        NO_MEDIA_SCQ;
}

   Nous pouvons maintenant raliser le contrle  l'aide de la fonction
   main :

void main( void )
{
  fd = open(DEVICE, O_RDWR);
  if (fd < 0) {
    fprintf( stderr, "Il faut les permissions lecture/ecriture pour "DEVICE".\n
"
 );
    exit(1);
  }

  /* on regarde si le support est charge */

  if (!TestForMedium()) {
    printf("le support n'est pas charge\n");
  } else {
    printf("le support est charge\n");
  }
}

   Le fichier generic_demo.c en annexe contient les deux exemples.

12. Fonctions ioctl

   Deux fonctions ioctl sont disponibles :
     * ioctl(fd, SG_SET_TIMEOUT, &Timeout); dfinit la valeur du timeout
        Timeout * 10 millisecondes. Timeout doit tre dclar en tant
       qu'entier (int).
     * ioctl(fd, SG_GET_TIMEOUT, &Timeout); lit la valeur du timeout en
       cours. Timeout doit tre dclar en tant qu'entier (int).

13. Valeurs par dfaut du pilote

13.1 Tailles de transfert

   Actuellement (au moins jusqu'au noyau version 1.1.68), les tailles
   d'entre et de sortie doivent tre infrieures ou gales  4096
   octets, sauf si le noyau a t compil avec la constante SG_BIG_BUFF
   dfinie, auquel cas elles sont limites  SG_BIG_BUFF (soit 32768)
   octets. Les tailles donnes comprennent l'en-tte gnrique ainsi que
   le bloc de commande fourni en entre. SG_BIG_BUFF peut tre augmente
   sans problme jusqu' (131072 - 512). Pour en bnficier, vous devrez
   bien videmment regnrer un nouveau noyau et redmarrer avec.

13.2 Timeout et valeurs de ressais

   La valeur du timeout par dfaut est d'une minute (Timeout = 6 000).
   Elle peut tre modifie  l'aide d'un appel  ioctl (cf. section
   Fonctions ioctl). Le nombre de ressais par dfaut est un.

14. Comment obtenir les spcifications SCSI ?

   Il existe des normes appeles SCSI-1, SCSI-2 et SCSI-3. Les normes
   assurent  peu de choses prs la compatibilit ascendante.

   Le standard SCSI-1 est (d'aprs l'auteur) en grande partie obsolte,
   et SCSI-2 est celui qui est le plus largement utilis. SCSI-3 est trs
   jeune et trs cher. Ces jeux de commandes normaliss dfinissent des
   commandes obligatoires et facultatives pour les constructeurs de
   matriels SCSI et doivent tre prfres aux extensions spcifiques
   non normalises et pour lesquelles l'information est plus difficile 
   obtenir. Evidemment, il n'y a parfois aucune alternative  ces
   extensions propritaires.

   Des copies lectroniques sont disponibles par FTP anonyme depuis :
     * ftp.cs.tulane.edu:pub/scsi
     * ftp.symbios.com:/pub/standards
     * ftp.cs.uni-sb.de:/pub/misc/doc/scsi

   (J'ai eu mes spcifications SCSI dans le CD-ROM Linux d'Yggdrasil,
   dans le rpertoires /usr/doc/scsi-2 et /usr/doc/scsi-1).

   La FAQ SCSI liste aussi les sources d'information imprime suivantes :

   Les spcifications SCSI - disponible depuis :

      Global Engineering Documents
      15 Inverness Way East
      Englewood Co  80112-5704
      (800) 854-7179
        SCSI-1: X3.131-1986
        SCSI-2: X3.131-199x
        SCSI-3 X3T9.2/91-010R4 Working Draft

(Global Engineering Documentation in Irvine, CA (714)261-1455??)

SCSI-1: Doc \# X3.131-1986 from ANSI, 1430 Broadway, NY, NY 10018

IN-DEPTH EXPLORATION OF SCSI peut tre trouv chez
Solution Technology, Attn: SCSI Publications, POB 104, Boulder Creek,
CA 95006, (408)338-4285, FAX (408)338-4374

THE SCSI ENCYLOPEDIA et SCSI BENCH REFERENCE peuvent tre obtenus chez
ENDL Publishing, 14426 Black Walnut Ct., Saratoga, CA 95090,
(408)867-6642, FAX (408)867-2115

SCSI: UNDERSTANDING THE SMALL COMPUTER SYSTEM INTERFACE est publi chez
Prentice-Hall, ISBN 0-13-796855-8

15. D'autres sources d'information

15.1 HOWTOs et FAQs

   Le _SCSI-HOWTO_ Linux de Drew Eckhardt (NdT : disponible en version
   franaise) traite de tous les contrleurs SCSI reconnus ainsi que des
   questions spcifiques aux priphriques. De nombreux aides pour le
   dpannage sont fournies. Il est disponible sur sunsite.unc.edu dans
   /pub/Linux/docs/LDP et sur ses sites miroirs.

   Les questions gnrales concernant le SCSI ont une rponse dans la FAQ
   SCSI du groupe de news comp.periphs.scsi (disponible sur tsx-11 dans
   /pub/linux/ALPHA/scsi et sur les sites miroirs).

15.2 La liste de messagerie

   Il existe une _liste de messagerie_ qui traite des rapports
   d'anomalies et questions sur le dveloppement SCSI sous Linux. Pour la
   rejoindre, envoyez un courrier  majordomo@vger.rutgers.edu avec la
   ligne subscribe linux-scsi dans le corps du message. Les messages
   doivent tre envoys  linux-scsi@vger.rutgers.edu. Un texte d'aide
   peut tre demand par envoi de la ligne de message "help" 
   majordomo@vger.rutgers.edu.

15.3 Exemples de code

   _sunsite.unc.edu: apps/graphics/hpscanpbm-0.3a.tar.gz_
          Ce paquetage gre un scanner HP scanjet  l'aide de l'interface
          gnrique.

   _tsx-11.mit.edu: BETA/cdrom/private/mkisofs/cdwrite-1.3.tar.gz_
          Le paquetage cdwrite utilise l'interface gnrique pour crire
          une image de CD sur un graveur.

   _sunsite.unc.edu: apps/sound/cds/cdda2wav*.src.tar.gz_
          Un composant pour mes propres applications, qui copie des
          pistes audio de CD sous forme de fichiers wav.

16. Autres choses utiles

   Des choses qui pourraient devenir pratiques. Je n'ai aucune ide de la
   prsence de versions plus rcentes ou meilleures ici ou l. Toute
   information est la bienvenue.

16.1 Aides  l'criture de pilotes de priphriques

   Ces documents peuvent tre trouvs sur le serveur ftp de
   sunsite.unc.edu et sur ses miroirs.

   _/pub/Linux/docs/kernel/kernel-hackers-guide_
          Le guide des stakhanovistes du noyau LDP (NdT : Projet de
          Documentation Linux). Il est peut-tre un peu ancien, mais
          traite les points les plus fondamentaux.

   _/pub/Linux/docs/kernel/drivers.doc.z_
          Ce document traite de l'criture de pilotes caractres.

   _/pub/Linux/docs/kernel/tutorial.doc.z_
          Tutoriel sur l'criture d'un pilote de priphrique caractre
          avec le code.

   _/pub/Linux/docs/kernel/scsi.paper.tar.gz_
          Un document Latex dcrivant comment crire un pilote SCSI.

   _/pub/Linux/docs/hardware/DEVICES_
          Une liste des numros majeurs et mineurs utiliss par Linux.

16.2 Utilitaires

   _tsx-11.mit.edu: ALPHA/scsi/scsiinfo*.tar.gz_
          Programme d'interrogation d'un priphrique SCSI pour obtenir
          ses paramtres d'utilisation, listes de dfauts, etc. Une
          interface X ncessitant Tk/Tcl/wish est disponible. Avec cette
          dernire, vous pouvez facilement modifier la configuration du
          lecteur.

   _tsx-11.mit.edu: ALPHA/kdebug_
          Une extension  pour le dverminage du noyau.

17. Autres interfaces d'accs au SCSI

   Sous Linux, on peut accder diffremment au SCSI via des appels ioctl
   SCSI_IOCTL_SEND_COMMAND qui ncessitent des privilges root. Les
   paquetages "scsiinfos" ainsi que "cdda2wav" les utilisent.

   D'autres interfaces similaires sont utilises dans le monde Unix, mais
   ne sont pas disponibles pour Linux :
    1. CAM (Common Access Method) dveloppe par Future Domain et
       d'autres constructeurs SCSI. Linux dispose maintenant d'un petit
       support pour un systme CAM SCSI (essentiellement pour bouter
       depuis un disque dur). CAM supporte mme le mode "target", qui
       permet de dguiser un ordinateur en priphrique SCSI (c..d.
       raliser un petit rseau SCSI).
    2. ASPI (Advanced SCSI Programming Interface) developpe par Adaptec.
       C'est le standard de facto pour les machines MS-DOS.
    3. ??? est disponible sur NeXTStep.
    4. DSLIB est disponible sur Silicon Graphics.
    5. SCSI... est disponible sur les machines SUN.
    6. SCO Unix a aussi quelque chose.
    7. HPUX utilise des ioctl. -->

   D'autres interfaces applicatives existent aussi chez SCO(TM),
   NeXT(TM), Silicon Graphics(TM) et SUN(TM).

18. Commentaires finals

   L'interface gnrique SCSI jette un pont sur le foss entre les
   applications utilisateur et les priphriques spcifiques. Mais plutt
   que de charger de nombreux programmes avec des jeux similaires de
   fonctions de bas niveau, il serait plus souhaitable de disposer d'une
   bibliothque partage avec un jeu gnralis de fonctions de bas
   niveau pour un usage particulier. Le but principal est de disposer de
   couches d'interfaces indpendantes. Une bonne conception doit sparer
   une application en routines de bas niveau et indpendantes du
   matriel. Celles-ci peuvent tre places dans une bibliothque
   partage et rendues disponibles pour toutes les applications. Ainsi,
   les interfaces standardises doivent tre suivies autant que possible
   avant d'en raliser de nouvelles.

   Vous devriez maintenant en savoir plus que moi sur l'interface
   gnrique SCSI de Linux. Vous pouvez donc commencer  dvelopper de
   puissantes applications pour le plus grand bnfice de la communaut
   Linux...

19. Remerciements

   Un grand merci  Jeff Tranter pour ses corrections et amliorations
   considrables de ce texte, ainsi qu' Carlos Puchol pour ses
   commentaires utiles. L'aide de Drew Eckhardt et Eric Youngdale sur mes
   premires questions (idiotes) sur l'utilisation de cette interface a
   t apprcie.

20. Annexe

21. Traitement d'erreurs

   Les fonctions open, ioctl, write et read peuvent renvoyer des erreurs.
   Dans ce cas, leur valeur de retour est -1 et la variable globale errno
   est positionne au numro d'erreur (ngatif). Les valeurs de errno
   sont dfinies dans /usr/include/errno.h. Les valeurs ngatives
   possibles sont les suivantes :

Fonction | Erreur       | Description
=========|==============|==================================================
open     |  ENXIO       | priphrique invalide
         |  EACCES      | l'accs n'est pas en lecture/criture (O_RDWR)
         |  EBUSY       | le priphrique est accd en mode non bloquant,
         |              | mais il est occup actuellement
         |  ERESTARTSYS | erreur interne. Essayez de la rendre reproductible
         |              | et informez-en le canal SCSI (pour les dtails sur
         |              | le rapport de bogue, se reporter au SCSI-HOWTO de
         |              | Drew Eckhardts).
ioctl    |  ENXIO       | priphrique invalide
read     |  EAGAIN      | le priphrique bloqu. Essayez plus tard.
         |  ERESTARTSYS | erreur interne. Essayez de la rendre reproductible
         |              | et informez-en le canal SCSI (pour les dtails sur
         |              | le rapport de bogue, se reporter au SCSI-HOWTO de
         |              | Drew Eckhardts).
write    |  EIO         | taille trop petite (plus petite que cette de l'en-
         |              | tte gnrique). Attention : il n'y a actuellement
         |              | aucun contrle de dbordement.
         |  EAGAIN      | le priphrique bloqu. Essayez plus tard.
         |  ENOMEM      | la mmoire ncessaire pour cette requte ne peut
         |              | tre alloue. Essayez plus tard sauf si vous depas-
         |              | sez la taille maximale de transfert (cf. ci-dessus).
select   |              | sans description
close    |              | sans description

   Pour la lecture et l'criture, des valeurs de retour positivent
   indiquent comme d'habitude la quantit d'octets transfrs. Cette
   valeur doit correspondre  celle demande.

21.1 Dcodage de l'tat d'erreur

   En plus, une information dtaille est fournie par hd_status du noyau
   et par sense_buffer du priphrique (cf. section ref
   id="sec-sensebuff" name="Le tampon SCSI">), les deux utilisant la
   structure d'en-tte gnrique.

   Les diffrents sens de hd_status peuvent tre trouvs dans
   drivers/scsi/scsi.h. Cet unsigned int est compos de diffrentes
   parties :

  lsb  |    ...    |    ...    | msb
=======|===========|===========|============
status | sense key | host code | driver byte

   Les macros de drivers/scsi/scsi.h sont disponibles, mais elles ne
   peuvent malheureusement pas tre facilement utilises  cause
   d'interdpendances tordues entre fichiers d'en-tte. Il faudrait faire
   une passe sur ces fichiers pour clarifier les choses.

        Macro          | Description
=======================|=================================================
status_byte(hd_status) | Etat du priphrique. cf. section Codes d'etat
msg_byte(hd_status)    | du pripherique. cf. section buffer SCSI
host_byte(hd_status)   | du noyau. cf. section codes hte
driver_byte(hd_status) | du noyau. cf. section codes intermdiaires

21.2 Codes d'tat

   Les codes d'tat de priphrique qui suivent (issus de
   drivers/scsi/scsi.h) sont disponibles :

Valeur | Symbole
=======|=====================
0x00   | GOOD
0x01   | CHECK_CONDITION
0x02   | CONDITION_GOOD
0x04   | BUSY
0x08   | INTERMEDIATE_GOOD
0x0a   | INTERMEDIATE_C_GOOD
0x0c   | RESERVATION_CONFLICT

   On constate que ces valeurs symboliques ont subi un _dcalage droit_.
   Lorsque l'tat indique CHECK_CONDITION, les donnes du buffer SCSI
   sont valides (contrlez en particulier le code d'tat additionnel et
   le qualificateur de code d'tat additionnel).

   Les valeurs qui suivent concernent les spcifications SCSI-2 :


                  Table 27 : Code de l'octet d'tat
+=================================-==============================+
|      Bits de l'octet d'tat     |  Etat                        |
|  7   6   5   4   3   2   1   0  |                              |
|---------------------------------+------------------------------|
|  R   R   0   0   0   0   0   R  |  GOOD                        |
|  R   R   0   0   0   0   1   R  |  CHECK CONDITION             |
|  R   R   0   0   0   1   0   R  |  CONDITION MET               |
|  R   R   0   0   1   0   0   R  |  BUSY                        |
|  R   R   0   1   0   0   0   R  |  INTERMEDIATE                |
|  R   R   0   1   0   1   0   R  |  INTERMEDIATE-CONDITION MET  |
|  R   R   0   1   1   0   0   R  |  RESERVATION CONFLICT        |
|  R   R   1   0   0   0   1   R  |  COMMAND TERMINATED          |
|  R   R   1   0   1   0   0   R  |  QUEUE FULL                  |
|                                 |                              |
|       Tous autres codes         |  Rserv                     |
|----------------------------------------------------------------|
|       R = Bit rserv                                          |
+================================================================+

   La dfinition des codes de l'octet d'tat sont donnes ci-dessous :

   _GOOD._
          Cet tat indique que la cible a correctement excut la
          commande.

   _CHECK CONDITION._
          Cet tat indique qu'une condition de contention s'est produite
          (cf. 6.6).

   _CONDITION MET._
          Cet tat, ou INTERMEDIATE-CONDITION MET est renvoy lorsque les
          conditions de l'opration demande sont satisfaites (cf.
          commandes SEARCH DATA et PRE-FETCH).

   _BUSY._
          Cet tat indique que la cible est occupe. Il peut tre renvoy
          lorsque la cible ne peut accepter de commande depuis un
          initiateur inacceptable par ailleurs (i.e. conflit d'absence de
          rservation). L'action de reprise recommande est une nouvelle
          tentative ultrieure.

   _INTERMEDIATE._
          Cet tat, ou INTERMEDIATE-CONDITION MET doit tre renvoye
          aprs chaque commande russie d'une srie de commandes lies
          (sauf pour la dernire), sauf si celle-ci se termine par un
          CHECK CONDITION, RESERVATION CONFLICT, ou COMMAND TERMINATED.
          Si ni INTERMEDIATE ni INTERMEDIATE-CONDITION MET n'est renvoy,
          la srie de commandes se termine, ainsi que le processus
          d'entres/sorties.

   _INTERMEDIATE-CONDITION MET._
          Cet tat est la combinaison de CONDITION MET et de
          INTERMEDIATE.

   _RESERVATION CONFLICT._
          Cet tat doit tre renvoy lorsqu'un initiateur tente d'accder
           une unit logique ou  un extension  l'intrieur d'une unit
          logique rserve avec un type de rservation en conflit pour un
          autre priphrique SCSI (cf. commandes RESERVE et RESERVE
          UNIT). L'action de reprise recommande est une nouvelle
          tentative ultrieure.

   _COMMAND TERMINATED._
          Cet tat doit tre renvoy lorsque la cible termine le
          processus d'entres/sorties aprs rception d'un message
          TERMINATE I/O PROCESS (cf. 5.6.22). Cet tat indique aussi
          qu'une condition de contention s'est produite (cf. 6.6).

   _QUEUE FULL._
          Cet tat doit tre implment si la file d'attente marque
          (tagged queuing) l'est aussi. Il est renvoy lors de la
          rception d'un message SIMPLE QUEUE TAG, ORDERED QUEUE TAG, ou
          HEAD OF QUEUE TAG et que la file de commandes est pleine. Le
          processus d'entre/sortie n'est alors pas plac dans la file de
          commandes.

21.3 Clefs du buffer SCSI

   Les clefs rsultantes peuvent tre rapatries  l'aide de la macro
   msg_byte (cf. section Dcodage de l'tat d'erreur). Les symboles du
   noyau qui suivent sont prdfinis dans drivers/scsi/scsi.h :

Valeur | Symbole
=======|================
0x00   | NO_SENSE
0x01   | RECOVERED_ERROR
0x02   | NOT_READY
0x03   | MEDIUM_ERROR
0x04   | HARDWARE_ERROR
0x05   | ILLEGAL_REQUEST
0x06   | UNIT_ATTENTION
0x07   | DATA_PROTECT
0x08   | BLANK_CHECK
0x0a   | COPY_ABORTED
0x0b   | ABORTED_COMMAND
0x0d   | VOLUME_OVERFLOW
0x0e   | MISCOMPARE

   Une liste extraite de la doc SCSI-2 suit (issue de la section
   7.2.14.3) :

        Table 69: Description des clefs (0h-7h) du buffer SCSI
+========-====================================================================+
|  Clef  |  Description                                                       |
|--------+--------------------------------------------------------------------|
|   0h   |  NO SENSE.  Indique qu'aucune information spcifique n'est         |
|        |  disponible pour l'unit logique dsigne. C'est le cas pour les   |
|        |  commandes russies ou celles dont l'tat est CHECK CONDITION ou   |
|        |  COMMAND TERMINATED  cause de l'un des bits filemark, EOM ou ILI. |
|--------+--------------------------------------------------------------------|
|   1h   |  RECOVERED ERROR.  Indique que la russite de la dernire commande |
|        |  fut conditionne par une action de rparation effectue par la    |
|        |  cible. Les octets additionnels peuvent fournir des dtails, ainsi |
|        |  que le champ information. Lorsque plusieurs erreurs rpares se   |
|        |  produisent durant une commande, le choix de celle indique        |
|        |  (premire, dernire, plus svre, etc.) dpend du priphrique.   |
|--------+--------------------------------------------------------------------|
|   2h   |  NOT READY.  Indique que l'unit logique est inaccessible. Une     |
|        |  intervention manuelle peut tre ncessaire.                       |
|--------+--------------------------------------------------------------------|
|   3h   |  MEDIUM ERROR.  Indique la fin d'une commande sur une erreur non-  |
|        |  rcuprable, cause probablement par un dfaut du support ou une  |
|        |  erreur de donnes. Cette clef peut aussi tre renvoye si la      |
|        |  cible ne peut faire la distinction entre un dfaut du support et  |
|        |  un dfaut spcifique du matriel (clef 4h).                       |
|--------+--------------------------------------------------------------------|
|   4h   |  HARDWARE ERROR.  Indique que la cible a dtect une erreur mat-  |
|        |  rielle irrcuprable (dfaut du contrleur, du priphrique, er-  |
|        |  reur de parit, etc.) lors de l'excution de la commande ou d'un  |
|        |  auto-test.                                                        |
|--------+--------------------------------------------------------------------|
|   5h   |  ILLEGAL REQUEST.  Indique qu'un paramtre illgal a t dtect   |
|        |  dans le bloc de description de commande ou dans les paramtres    |
|        |  additionnels (pour certaines commandes : FORMAT UNIT, SEARCH DATA,|
|        |  etc.). Si la cible dtecte un paramtre incorrect, il doit termi- |
|        |  ner celle-ci sans modifier le contenu du support. Si le paramtre |
|        |  incorrect se trouve dans les paramtres additionnels, la cible    |
|        |  peut avoir dj modifi le support. Cette clef est aussi renvoye |
|        |  lors de la rception d'un message IDENTIFY invalide (5.6.7).      |
|--------+--------------------------------------------------------------------|
|   6h   |  UNIT ATTENTION.  Indique que le support amovible a pu tre chang |
|        |  ou que la cible a t rinitialise. Cf. 6.9 pour d'autres infor- |
|        |  mation sur cette condition.                                       |
|--------+--------------------------------------------------------------------|
|   7h   |  DATA PROTECT.  Indique qu'une commande de lecture ou d'criture a |
|        |  t tente sur un bloc protg contre cette opration. Celle-ci   |
|        |  n'est pas effectue.                                              |
+=============================================================================+

        Table 70: Description des clefs (8h-Fh) du buffer SCSI
+========-====================================================================+
|  Clef  |  Description                                                       |
|--------+--------------------------------------------------------------------|
|   8h   |  BLANK CHECK.  Indique qu'un priphrique  criture unique ou     |
|        |  squentiel a trouv un support vierge ou une indication de fin de |
|        |  donnes de formatage lors de la lecture, ou qu'un support non     |
|        |  vierge  criture seule a t trouv pendant l'criture.          |
|--------+--------------------------------------------------------------------|
|   9h   |  Vendor Specific.  Cette clef est disponible pour indiquer des     |
|        |  cas particuliers spcifiques du constructeur.                     |
|--------+--------------------------------------------------------------------|
|   Ah   |  COPY ABORTED.  Indique qu'une commande COPY, COMPARE ou COPY AND  |
|        |  VERIFY a echou  cause d'une condition d'erreur sur le priph-  |
|        |  rique source, destination ou les deux (cf. 7.2.3.2 pour plus de   |
|        |  dtails).                                                         |
|--------+--------------------------------------------------------------------|
|   Bh   |  ABORTED COMMAND.  Indique que la cible a abandonn la commande.   |
|        |  L'initiateur peut ventuellement corriger le problme par une     |
|        |  nouvelle tentative.                                               |
|--------+--------------------------------------------------------------------|
|   Ch   |  EQUAL.  Indique qu'une commande SEARCH DATA a satisfait une con-  |
|        |  dition d'galit.                                                 |
|--------+--------------------------------------------------------------------|
|   Dh   |  VOLUME OVERFLOW.  Indique qu'un priphrique  mmoire-tampon a   |
|        |  atteint la fin de partition et que des donnes non crites sur le |
|        |  support peuvent rester dans le tampon. Une (ou plusieurs) commande|
|        |  RECOVER BUFFER DATA peut tre tente pour lire les donnes non    |
|        |  crites depuis le tampon.                                         |
|--------+--------------------------------------------------------------------|
|   Eh   |  MISCOMPARE.  Indique que les donnes source ne correspondent pas  |
|        |   celles lues sur le support.                                     |
|--------+--------------------------------------------------------------------|
|   Fh   |  RESERVE.                                                          |
+=============================================================================+

21.4 Codes hte

   Les codes htes qui suivent sont dfinis au niveau de
   drivers/scsi/scsi.h. Ils sont positionns par le pilote du noyau et
   doivent tre utiliss avec la macro host_byte (cf. section Dcodage de
   l'tat d'erreur) :

Valeur | Symbole        | Description
=======|================|========================================
0x00   | DID_OK         | Pas d'erreur
0x01   | DID_NO_CONNECT | Connexion impossible avant le timeout
0x02   | DID_BUS_BUSY   | BUS occup durant la priode de timeout
0x03   | DID_TIME_OUT   | Timeout atteint pour une autre raison
0x04   | DID_BAD_TARGET | Mauvaise cible
0x05   | DID_ABORT      | Arrt effectu pour une autre raison
0x06   | DID_PARITY     | Erreur de parit
0x07   | DID_ERROR      | Erreur interne
0x08   | DID_RESET      | Rinitialis par quelqu'un
0x09   | DID_BAD_INTR   | Interruption inattendue reue

21.5 Codes du pilote

   Le pilote de niveau intermdiaire catgorise l'tat renvoy par le
   pilote de bas niveau en fonction du buffer SCSI du priphrique. Il
   suggre certaines actions pouvant tre tentes comme un ressai, un
   abandon ou un changement de topographie. La routine scsi_done de
   scsi.c effectue un travail trs diffrenci fond sur host_byte(),
   status_byte(), msg_byte() et la suggestion prcdente. Ensuite, il
   positionne l'octet du pilote afin d'indiquer ce qui a t ralis.
   L'octet du pilote est en deux parties : l'tat du pilote et la
   suggestion. Chaque moiti est compose des valeurs suivantes (de
   scsi.h) combines par un OR :

Valeur | Symbole        | Description ou tat du pilote
=======|================|========================================
0x00   | DRIVER_OK      | pas d'erreur
0x01   | DRIVER_BUSY    | inutilis
0x02   | DRIVER_SOFT    | inutilis
0x03   | DRIVER_MEDIA   | inutilis
0x04   | DRIVER_ERROR   | erreur interne du pilote
0x05   | DRIVER_INVALID | termin (DID_BAD_TARGET ou DID_ABORT)
0x06   | DRIVER_TIMEOUT | termin avec timeout
0x07   | DRIVER_HARD    | termin avec une erreur fatale
0x08   | DRIVER_SENSE   | buffer SCSI disponible pour informations

Valeur | Symbole        | Description de la suggestion
=======|================|========================================
0x10   | SUGGEST_RETRY  | ressayer la requte SCSI
0x20   | SUGGEST_ABORT  | abandonner la requte
0x30   | SUGGEST_REMAP  | remape le bloc (non encore implement)
0x40   | SUGGEST_DIE    | laisser le noyau tomber en "panic"
0x80   | SUGGEST_SENSE  | lire le buffer SCSI du priphrique
0xff   | SUGGEST_IS_OK  | rien  faire

22. Codes et qualificateurs du buffer SCSI additionnels

   Lorsque l'tat de la commande SCSI excute est CHECK_CONDITION, des
   donnes sont disponibles dans le buffer SCSI. Les code et
   qualificateur additionnels se trouvent dans ce tampon.

   Je joins ici deux tables issues des spcifications SCSI-2. La premire
   est trie alphabtiquement, la seconde, numriquement (NdT : la
   traduction ayant un tantinet boulevers l'ordre alphabtique, seule la
   table trie par numros a t conserve. Le lecteur pourra se reporter
    la version originale en amricain pour la liste alphabtique).

22.1 ASC et ASCQ dans l'ordre numrique

   La table qui suit fournit une liste de descriptions avec les
   priphriques auxquels elles s'appliquent.

                       Table 364 : Assignements ASC et ASCQ

+=============================================================================+
|           D - priphrique  accs Direct (Disque)                          |
|           .T - priphrique  accs squenTiel (bande magnTique)           |
|           . I - Imprimante                                                  |
|           .  P - Processeur                                                 |
|           .  .W -WORM (CD-ROM inscriptible une fois)                        |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
| ASC ASCQ  DTIPWRSOMC  DESCRIPTION                                           |
| --- ----              ----------------------------------------------------- |
|  00  00   DTIPWRSOMC  pas d'information additionnelle                       |
|  00  01    T          marque de fichier dtecte                            |
|  00  02    T    S     fin de partition/mdium dtecte                      |
|  00  03    T          marque de jeu dtecte                                |
|  00  04    T    S     dbut de partition/mdium dtect                     |
|  00  05    T    S     fin de donnes dtecte                               |
|  00  06   DTIPWRSOMC  fin du processus d'E/S                                |
|  00  11   R           lecture audio en cours                                |
|  00  12   R           lecture audio suspendue                               |
|  00  13   R           lecture audio termine avec succs                    |
|  00  14   R           lecture audio stoppe pour cause d'erreur             |
|  00  15   R           pas d'tat audio en cours  retourner                 |
|  01  00   DW  O       pas de signal d'index/de secteur                      |
|  02  00   D   WR OM   dplacement incomplet                                 |
|  03  00   DTI W SO    chec d'criture sur le priphrique                  |
|  03  01    T          pas d'criture en cours                               |
|  03  02    T          trop d'erreurs d'criture                             |
|  04  00   DTIPWRSOMC  unit logique non prte, cause inconnue               |
|  04  01   DTIPWRSOMC  unit logique en prparation                          |
|  04  02   DTIPWRSOMC  unit logique non prte, commande d'init ncessaire   |
|  04  03   DTIPWRSOMC  unit logique non prte, intervention manuelle ncess.|
|  04  04   DTI    O    unit logique non prte, formatage en cours           |
|  05  00   DTI WRSOMC  l'unit logique ne rpond pas  la slection          |
|  06  00   D   WR OM   pas de position de rfrence trouve                  |
|  07  00   DTI WRSOM   slection de plusieurs priphriques                  |
|  08  00   DTI WRSOMC  chec de communication avec l'unit logique           |
|  08  01   DTI WRSOMC  timeout de communication avec l'unit logique         |
|  08  02   DTI WRSOMC  erreur de parit en communication avec l'unit logique|
|  09  00   DT  WR O    erreur de suivi de piste                              |
|  09  01       WR O    dfaillance du servo de suivi de piste                |
|  09  02       WR O    dfaillance du servo de focalisation                  |
|  09  03       WR O    dfaillance du servo de SPINDLE                       |
+=============================================================================+

Table 364 : (suite)
+=============================================================================+
|           D - priphrique  accs Direct (Disque)                          |
|           .T - priphrique  accs squenTiel (bande magnTique)           |
|           . I - Imprimante                                                  |
|           .  P - Processeur                                                 |
|           .  .W -WORM (CD-ROM inscriptible une fois)                        |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
| ASC ASCQ  DTIPWRSOMC  DESCRIPTION                                           |
| --- ----              ----------------------------------------------------- |
|  0A  00   DTIPWRSOMC  dbordement de la trace d'erreur                      |
|  0B  00                                                                     |
|  0C  00    T     S    erreur d'criture                                     |
|  0C  01   D   W  O    erreud d'criture corrige par auto-rallocation      |
|  0C  02   D   W  O    erreur d'criture - auto-rallocation impossible      |
|  0D  00                                                                     |
|  0E  00                                                                     |
|  0F  00                                                                     |
|  10  00   D   W  O    erreur ID, CRC ou ECC                                 |
|  11  00   DT  WRSO    erreur de lecture irrcuprable                       |
|  11  01   DT  W SO    nombre d'essais atteint                               |
|  11  02   DT  W SO    erreur trop longue  corriger                         |
|  11  03   DT  W SO    erreurs de lecture multiples                          |
|  11  04   D   W  O    erreur de lecture - auto-rallocation impossible      |
|  11  05       WR O    erreur irrcuprable L-EC                             |
|  11  06       WR O    erreur irrcuprable CIRC                             |
|  11  07       W  O    erreur de resynchronisation de donnes                |
|  11  08    T          lecture de bloc incomplte                            |
|  11  09    T          pas de brche trouve                                 |
|  11  0A   DT     O    erreur mal corrige                                   |
|  11  0B   D   W  O    erreur de lecture - rassignement recommand          |
|  11  0C   D   W  O    erreur de lecture - recriture recommande            |
|  12  00   D   W  O    marque d'adresse introuvable pour le champ ID         |
|  13  00   D   W  O    marque d'adresse introuvable pour le champ donnes    |
|  14  00   DTI WRSO    identit enregistre introuvable                      |
|  14  01   DT  WR O    enregistrement introuvable                            |
|  14  02    T          marque de fichier ou de jeu introuvable               |
|  14  03    T          fin de donnes introuvable                            |
|  14  04    T          erreur de squence de bloc                            |
|  15  00   DTI WRSOM   erreur de positionnement alatoire                    |
|  15  01   DTI WRSOM   erreur de positionnement mcanique                    |
|  15  02   DT  WR O    erreur de positionnement dtecte par la lecture      |
|  16  00   DW     O    erreur de marque de synchronisation de donnes        |
|  17  00   DT  WRSO    donnes recupres sans correction d'erreur           |
|  17  01   DT  WRSO    donnes recupres aprs plusieurs essais             |
|  17  02   DT  WR O    donnes recupres avec un dcalage de tte positif   |
|  17  03   DT  WR O    donnes recupres avec un dcalage de tte negatif   |
|  17  04       WR O    donnes recupres avec plusieurs essais et/ou CIRC   |
|  17  05   D   WR O    donnes recupres sur l'ID de secteur prcdent      |
|  17  06   D   W  O    donnes recupres sans ECC - donnes auto-ralloues |
|  17  07   D   W  O    donnes recupres sans ECC - rassignement recommand|
|  17  08   D   W  O    donnes recupres sans ECC - recriture rcommande  |
|  18  00   DT  WR O    donnes recupres avec correction d'erreur           |
|  18  01   D   WR O    donnes recupres avec correction & plusieurs essais |
|  18  02   D   WR O    donnes recupres - donnes auto-ralloues          |
|  18  03        R      donnes recupres avec CIRC                          |
|  18  04        R      donnes recupres avec LEC                           |
|  18  05   D   WR O    donnes recupres - rassignement recommand         |
|  18  06   D   WR O    donnes recupres - recriture recommande           |
+=============================================================================+

Table 364 : (suite)
+=============================================================================+
|           D - priphrique  accs Direct (Disque)                          |
|           .T - priphrique  accs squenTiel (bande magnTique)           |
|           . I - Imprimante                                                  |
|           .  P - Processeur                                                 |
|           .  .W -WORM (CD-ROM inscriptible une fois)                        |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
| ASC ASCQ  DTIPWRSOMC  DESCRIPTION                                           |
| --- ----              ----------------------------------------------------- |
|  19  00   D      O    erreur de liste de dfauts                            |
|  19  01   D      O    liste de dfauts indisponible                         |
|  19  02   D      O    erreur de liste de dfauts en liste primaire          |
|  19  03   D      O    erreur de liste de dfauts en liste secondaire (grown)|
|  1A  00   DTIPWRSOMC  erreur de taille de la liste de dfauts               |
|  1B  00   DTIPWRSOMC  erreur de transfert de donnes synchrone              |
|  1C  00   D      O    liste de dfauts introuvable                          |
|  1C  01   D      O    liste de dfauts primaire introuvable                 |
|  1C  02   D      O    liste de dfauts secondaire (grown) introuvable       |
|  1D  00   D   W  O    erreur de comparaison durant la vrification          |
|  1E  00   D   W  O    ID rcupr avec ECC                                  |
|  1F  00                                                                     |
|  20  00   DTIPWRSOMC  code d'opration de commande incorrect                |
|  21  00   DT  WR OM   adresse du bloc logique hors limites                  |
|  21  01           M   adresse d'lment incorrecte                          |
|  22  00   D           fonction illegale (seulement 20 00, 24 00 ou 26 00)   |
|  23  00                                                                     |
|  24  00   DTIPWRSOMC  champ incorrect en CDB                                |
|  25  00   DTIPWRSOMC  unit logique non supporte                           |
|  26  00   DTIPWRSOMC  champ incorrect en liste de paramtres                |
|  26  01   DTIPWRSOMC  paramtre non support                                |
|  26  02   DTIPWRSOMC  valeur de paramtre incorrecte                        |
|  26  03   DTIPWRSOMC  paramtres de seuil non supports                     |
|  27  00   DT  W  O    protection en criture                                |
|  28  00   DTIPWRSOMC  transition non-prt/prt (changement de mdium ?)     |
|  28  01           M   accs  un lment import ou export                   |
|  29  00   DTIPWRSOMC  allumage, rinit. ou rinit. du bus a eu lieu         |
|  2A  00   DTI WRSOMC  paramtres changs                                    |
|  2A  01   DTI WRSOMC  paramtres de mode changs                            |
|  2A  02   DTI WRSOMC  paramtres de trace changs                           |
|  2B  00   DTIPWRSO C  copie impossible : dconnexion du host impossible     |
|  2C  00   DTIPWRSOMC  erreur de squence de commandes                       |
|  2C  01         S     trop de fentres spcifies                           |
|  2C  02         S     combinaison de fentres incorrecte spcifie          |
|  2D  00    T          erreur d'criture en crasement de donnes            |
|  2E  00                                                                     |
|  2F  00   DTIPWRSOMC  commandes annules par un autre initiateur            |
|  30  00   DT  WR OM   mdium incompatible prsent                           |
|  30  01   DT  WR O    mdium illisible - format inconnu                     |
|  30  02   DT  WR O    mdium illisible - format incompatible                |
|  30  03   DT          cartouche de nettoyage prsente                       |
|  31  00   DT  W  O    format du mdium endommage                            |
|  31  01   D I    O    chec de la commande de format                        |
|  32  00   D   W  O    plus d'emplacement de dfaut disponible               |
|  32  01   D   W  O    chec de mise a jour de la liste de dfauts           |
|  33  00    T          erreur de longueur de bande                           |
|  34  00                                                                     |
|  35  00                                                                     |
|  36  00     I         manque d'encre, de ruban ou de toner                  |
+=============================================================================+

Table 364 : (suite)
+=============================================================================+
|           D - priphrique  accs Direct (Disque)                          |
|           .T - priphrique  accs squenTiel (bande magnTique)           |
|           . I - Imprimante                                                  |
|           .  P - Processeur                                                 |
|           .  .W -WORM (CD-ROM inscriptible une fois)                        |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
| ASC ASCQ  DTIPWRSOMC  DESCRIPTION                                           |
| --- ----              ----------------------------------------------------- |
|  37  00   DTI WRSOMC  paramtre arrondi                                     |
|  38  00                                                                     |
|  39  00   DTI WRSOMC  sauvegarde de paramtres non supporte                |
|  3A  00   DTI WRSOM   pas de mdium                                         |
|  3B  00    TI         erreur de positionnement squentiel                   |
|  3B  01    T          erreur de positionnement de la bande au dbut         |
|  3B  02    T          erreur de positionnement de la bande  la fin         |
|  3B  03     I         bande ou feuille--feuille non prt                   |
|  3B  04     I         erreur de SLEW (NdT : !?)                             |
|  3B  05     I         bourrage papier                                       |
|  3B  06     I         haut de page non dtect                              |
|  3B  07     I         bas  de page non dtect                              |
|  3B  08    T          erreur de repositionnement                            |
|  3B  09         S     lecture aprs la fin du mdium                        |
|  3B  0A         S     lecture avant le debut du mdium                      |
|  3B  0B         S     position aprs la fin du mdium                       |
|  3B  0C         S     position avant le debut du mdium                     |
|  3B  0D           M   emplacement de destination occup                     |
|  3B  0E           M   emplacement d'origine vide                            |
|  3C  00                                                                     |
|  3D  00   DTIPWRSOMC  bits incorrects dans le message d'identification      |
|  3E  00   DTIPWRSOMC  auto-configuration de l'unit non encore ralise     |
|  3F  00   DTIPWRSOMC  les conditions de fonctionnement ont chang           |
|  3F  01   DTIPWRSOMC  le micro-code a t chang                            |
|  3F  02   DTIPWRSOMC  dfinition de fonctionnement modifie                 |
|  3F  03   DTIPWRSOMC  les donnes de requte ont chang                     |
|  40  00   D           dfaillance RAM (40nn obligatoire)                    |
|  40  NN   DTIPWRSOMC  chec de diagnostic du composant nn (80h-FFh)         |
|  41  00   D           chec du chemin de donnes (40nn obligatoire)         |
|  42  00   D           chec d'alllumage ou d'auto-test (40nn obligatoire)   |
|  43  00   DTIPWRSOMC  erreur de message                                     |
|  44  00   DTIPWRSOMC  dfaillance de cible interne                          |
|  45  00   DTIPWRSOMC  chec de slection ou de reslection                  |
|  46  00   DTIPWRSOMC  chec de la rinitialisation logicielle               |
|  47  00   DTIPWRSOMC  erreur de parit SCSI                                 |
|  48  00   DTIPWRSOMC  rception de message d'erreur dtect par initiateur  |
|  49  00   DTIPWRSOMC  erreur message incorrect                              |
|  4A  00   DTIPWRSOMC  erreur de phase de commande                           |
|  4B  00   DTIPWRSOMC  erreur de phase de donnes                            |
|  4C  00   DTIPWRSOMC  chec de l'auto-configuration de l'unit logique      |
|  4D  00                                                                     |
|  4E  00   DTIPWRSOMC  commandes en recouvrement                             |
|  4F  00                                                                     |
|  50  00    T          erreur d'criture en ajout                            |
|  50  01    T          erreur de positionnement en ajout                     |
|  50  02    T          erreur de positionnement par rapport au timing        |
|  51  00    T     O    erreur d'effacement                                   |
|  52  00    T          dfaut de cartouche                                   |
+=============================================================================+

Table 364 : (suite)
+=============================================================================+
|           D - priphrique  accs Direct (Disque)                          |
|           .T - priphrique  accs squenTiel (bande magnTique)           |
|           . I - Imprimante                                                  |
|           .  P - Processeur                                                 |
|           .  .W -WORM (CD-ROM inscriptible une fois)                        |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
| ASC ASCQ  DTIPWRSOMC  DESCRIPTION                                           |
| --- ----              ----------------------------------------------------- |
|  53  00   DTI WRSOM   chec de chargement ou d'jection du mdium           |
|  53  01    T          chec de dchargement de la bande                     |
|  53  02   DT  WR OM   priphrique protg contre le changement de mdium   |
|  54  00      P        dfaillance de l'interface host-SCSI                  |
|  55  00      P        dfaut de ressources systme                          |
|  56  00                                                                     |
|  57  00        R      impossible de rcuprer la table du contenu           |
|  58  00          O    la gnration n'existe pas                            |
|  59  00          O    lecture de bloc mis a jour                            |
|  5A  00   DTIPWRSOM   requte oprateur ou demande de changement d'tat     |
|  5A  01   DT  WR OM   requte oprateur d'extraction du mdium              |
|  5A  02   DT  W  O    l'oprateur a slectionn la protection en criture   |
|  5A  03   DT  W  O    l'oprateur a slectionn l'autorisation d'criture   |
|  5B  00   DTIPWRSOM   exception de trace                                    |
|  5B  01   DTIPWRSOM   condition de seuil remplie                            |
|  5B  02   DTIPWRSOM   compteur de trace au maximum                          |
|  5B  03   DTIPWRSOM   plus de code pour la liste de trace                   |
|  5C  00   D      O    changement d'tat RPL                                 |
|  5C  01   D      O    SPINDLES synchronises                                |
|  5C  02   D      O    SPINDLES non synchronises                            |
|  5D  00                                                                     |
|  5E  00                                                                     |
|  5F  00                                                                     |
|  60  00         S     dfaillance de la lampe                               |
|  61  00         S     erreur d'acquisition vido                            |
|  61  01         S     impossible de capturer la vido                       |
|  61  02         S     hors de la zone focalise                             |
|  62  00         S     erreur de positionnement de la tte de digitalisation |
|  63  00        R      fin de zone utilisateur sur cette piste               |
|  64  00        R      mode illgal pour cette piste                         |
|  65  00                                                                     |
|  66  00                                                                     |
|  67  00                                                                     |
|  68  00                                                                     |
|  69  00                                                                     |
|  6A  00                                                                     |
|  6B  00                                                                     |
|  6C  00                                                                     |
|  6D  00                                                                     |
|  6E  00                                                                     |
|  6F  00                                                                     |
+=============================================================================+

Table 364 : (fin)
+=============================================================================+
|           D - priphrique  accs Direct (Disque)                          |
|           .T - priphrique  accs squenTiel (bande magnTique)           |
|           . I - Imprimante                                                  |
|           .  P - Processeur                                                 |
|           .  .W -WORM (CD-ROM inscriptible une fois)                        |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
| ASC ASCQ  DTIPWRSOMC  DESCRIPTION                                           |
| --- ----              ----------------------------------------------------- |
|  70  00                                                                     |
|  71  00                                                                     |
|  72  00                                                                     |
|  73  00                                                                     |
|  74  00                                                                     |
|  75  00                                                                     |
|  76  00                                                                     |
|  77  00                                                                     |
|  78  00                                                                     |
|  79  00                                                                     |
|  7A  00                                                                     |
|  7B  00                                                                     |
|  7C  00                                                                     |
|  7D  00                                                                     |
|  7E  00                                                                     |
|  7F  00                                                                     |
|                                                                             |
|  80  xxh \                                                                  |
|   jusqu'a >  spcifique constructeur                                        |
|  FF  xxh /                                                                  |
|                                                                             |
|  xxh 80 \                                                                   |
|  jusqu'a >  qualification du standard ASC spcifique constructeur           |
|  xxh FF /                                                                   |
|              TOUS LES CODES VIDES OU NON MONTRES SONT RESERVES              |
+=============================================================================+

23. Rfrence rapide des commandes SCSI

   La table 365 est une liste ordonne numriquement des codes opration
   des commandes.

                        Table 365 : Codes operations SCSI-2

+=============================================================================+
|           D - priphrique  accs Direct               Clef de colonne     |
|           .T - priphrique  accs squenTiel          N = Ncessaire      |
|           . I - Imprimante                              O = Optionnel       |
|           .  P - Processeur                             C = Constructeur    |
|           .  .W -WORM (CD-ROM inscriptible une fois)    R = Rserv         |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
|        OP DTIPWRSOMC Description                                            |
|----------+----------+-------------------------------------------------------|
|        00 NNNNNNNNNN test d'unit prte                                     |
|        01  N         rembobinage                                            |
|        01 O C OO OO  remise  zro de l'unit                               |
|        02 CCCCCC  C                                                         |
|        03 NNNNNNNNNN requte de buffer SCSI                                 |
|        04   O        formatage                                              |
|        04 N      O   formatage de l'unite                                   |
|        05 CNCCCC  C  lecture des limites de bloc                            |
|        06 CCCCCC  C                                                         |
|        07         O  initialisation de l'tat d'un lment                  |
|        07 OCC O  OC  rassignation de blocs                                 |
|        08          N lecture de message (06)                                |
|        08 ONC OO OC  lecture (06)                                           |
|        08    O       rception                                              |
|        09 CCCCCC  C                                                         |
|        0A   N        impression                                             |
|        0A          N mission de message (06)                               |
|        0A    N       mission (06)                                          |
|        0A ON  O  OC  criture (06)                                          |
|        0B O   OO OC  dplacement (06)                                       |
|        0B   O        SLEW et impression                                     |
|        0C CCCCCC  C                                                         |
|        0D CCCCCC  C                                                         |
|        0E CCCCCC  C                                                         |
|        0F COCCCC  C  lecture inverse                                       |
|        10   O O      synchronisation du tampon                              |
|        10 CN CCC     criture de marques de fichiers                        |
|        11 CNCCCC     espace                                                 |
|        12 NNNNNNNNNN requte                                                |
|        13 COCCCC     vrification (06)                                      |
|        14 COOCCC     rcupration des donnes bufferises                   |
|        15 ONO OOOOOO slection de mode (06)                                 |
|        16 N   NN NO  rservation                                            |
|        16  NN   N    rservation d'unit                                    |
|        17 N   NN NO  libration                                             |
|        17  NN   N    libration d'unit                                     |
|        18 OOOOOOOO   copie                                                  |
|        19 CNCCCC     effacement                                             |
|        1A ONO OOOOOO lecture du buffer SCSI (06)                            |
|        1B  O         chargement dchargement                                |
|        1B       O    digitalisation                                         |
|        1B   O        arrt d'impression                                     |
|        1B O   OO O   arrt dmarrage de l'unit                             |
+=============================================================================+

Table 365 : (suite)
+=============================================================================+
|           D - priphrique  accs Direct               Clef de colonne     |
|           .T - priphrique  accs squenTiel          N = Ncessaire      |
|           . I - Imprimante                              O = Optionnel       |
|           .  P - Processeur                             C = Constructeur    |
|           .  .W -WORM (CD-ROM inscriptible une fois)    R = Rserv         |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
|        OP DTIPWRSOMC Description                                            |
|----------+----------+-------------------------------------------------------|
|        1C OOOOOOOOOO rception des rsultats du diagnostic                  |
|        1D NNNNNNNNNN mission de diagnostic                                 |
|        1E OO  OO OO  protection contre l'enlvement du mdium               |
|        1F                                                                   |
|        20 C   CC C                                                          |
|        21 C   CC C                                                          |
|        22 C   CC C                                                          |
|        23 C   CC C                                                          |
|        24 C   CCN    dfinition de fentre                                  |
|        25       O    lecture de fentre                                     |
|        25 N   N  N   lecture de capacit                                    |
|        25      N     lecture de capacit de cd-rom                          |
|        26 C   CC                                                            |
|        27 C   CC                                                            |
|        28          O lecture de message (10)                                |
|        28 N   NNNN   lecture (10)                                           |
|        29 C   CC O   lecture de gnration                                  |
|        2A          O mission de message (10)                               |
|        2A       O    mission (10)                                          |
|        2A N   N  N   criture (10)                                          |
|        2B  O         localisation                                           |
|        2B         O  positionnement sur lment                             |
|        2B O   OO O   dplacement (10)                                       |
|        2C C      O   effacement (10)                                        |
|        2D C   O  O   lecture de bloc mis  jour                             |
|        2E O   O  O   lecture et vrification (10)                           |
|        2F O   OO O   vrification (10)                                      |
|        30 O   OO O   lecture de donne haute (10)                           |
|        31       O    position d'objet                                       |
|        31 O   OO O   recherche de donne gale (10)                         |
|        32 O   OO O   recherche de donne basse (10)                         |
|        33 O   OO O   dfinition de limites (10)                             |
|        34       O    lecture de l'tat du tampon de donnes                 |
|        34 O   OO O   pr-lecture                                            |
|        34  O         lecture de position                                    |
|        35 O   OO O   synchronisation du cache                               |
|        36 O   OO O   verrouillage/dverrouillage du cache                   |
|        37 O      O   lecture de donnes dfectueuses (10)                   |
|        38     O  O   digitalisation du mdium                               |
|        39 OOOOOOOO   comparaison                                            |
|        3A OOOOOOOO   copie et vrification                                  |
|        3B OOOOOOOOOO criture de tampon                                     |
|        3C OOOOOOOOOO lecture de tampon                                      |
|        3D     O  O   mise  jour de bloc                                    |
|        3E O   OO O   lecture longue                                         |
|        3F O   O  O   criture longue                                        |
+=============================================================================+

Table 365 : (suite)
+=============================================================================+
|           D - priphrique  accs Direct               Clef de colonne     |
|           .T - priphrique  accs squenTiel          N = Ncessaire      |
|           . I - Imprimante                              O = Optionnel       |
|           .  P - Processeur                             C = Constructeur    |
|           .  .W -WORM (CD-ROM inscriptible une fois)    R = Rserv         |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
|        OP DTIPWRSOMC Description                                            |
|----------+----------+-------------------------------------------------------|
|        40 OOOOOOOOOO changement de dfinition                               |
|        41 O          criture identique                                     |
|        42      O     lecture de sous-canal                                  |
|        43      O     lecture du TOC                                         |
|        44      O     lecture d'en-tte                                      |
|        45      O     lecture audio (10)                                     |
|        46                                                                   |
|        47      O     lecture audio MSF                                      |
|        48      O     lecture d'index de piste audio                         |
|        49      O     lecture de piste relative (10)                         |
|        4A                                                                   |
|        4B      O     reprise de pause                                       |
|        4C OOOOOOOOOO trace de slection                                     |
|        4D OOOOOOOOOO trace du buffer SCSI                                   |
|        4E                                                                   |
|        4F                                                                   |
|        50                                                                   |
|        51                                                                   |
|        52                                                                   |
|        53                                                                   |
|        54                                                                   |
|        55 OOO OOOOOO mode de slection (10)                                 |
|        56                                                                   |
|        57                                                                   |
|        58                                                                   |
|        59                                                                   |
|        5A OOO OOOOOO mode du buffer SCSI (10)                               |
|        5B                                                                   |
|        5C                                                                   |
|        5D                                                                   |
|        5E                                                                   |
|        5F                                                                   |
+=============================================================================+

Table 365 : (fin)
+=============================================================================+
|           D - priphrique  accs Direct               Clef de colonne     |
|           .T - priphrique  accs squenTiel          N = Ncessaire      |
|           . I - Imprimante                              O = Optionnel       |
|           .  P - Processeur                             C = Constructeur    |
|           .  .W -WORM (CD-ROM inscriptible une fois)    R = Rserv         |
|           .  . R - CD-ROM (lecture seule)                                   |
|           .  .  S - Scanner ou numriseur                                   |
|           .  .  .O - mmoire Optique                                        |
|           .  .  . M - changeur de Mdia                                     |
|           .  .  .  C - priphrique de Communications                       |
|           .  .  .  .                                                        |
|        OP DTLPWRSOMC Description                                            |
|----------+----------+-------------------------------------------------------|
|        A0                                                                   |
|        A1                                                                   |
|        A2                                                                   |
|        A3                                                                   |
|        A4                                                                   |
|        A5         N  dplacement de mdium                                  |
|        A5      O     lecture audio (12)                                     |
|        A6         O  changement de mdium                                   |
|        A7                                                                   |
|        A8          O lecture de message (12)                                |
|        A8     OO O   lecture (12)                                           |
|        A9      O     lecture de piste relative (12)                         |
|        AA          O mission de message (12)                               |
|        AA     O  O   criture (12)                                          |
|        AB                                                                   |
|        AC        O   effacement (12)                                        |
|        AD                                                                   |
|        AE     O  O   criture et vrification (12)                          |
|        AF     OO O   vrification (12)                                      |
|        B0     OO O   recherche de donne haute (12)                         |
|        B1     OO O   recherche de donne egale (12)                         |
|        B2     OO O   recherche de donne basse (12)                         |
|        B3     OO O   dfinition des limites (12)                            |
|        B4                                                                   |
|        B5                                                                   |
|        B5         O  demande d'adresse d'lment volume                     |
|        B6                                                                   |
|        B6         O  mission de TAG de volume                              |
|        B7        O   lecture des donnes de dfauts (12)                    |
|        B8                                                                   |
|        B8         O  lecture de l'tat d'lment                            |
|        B9                                                                   |
|        BA                                                                   |
|        BB                                                                   |
|        BC                                                                   |
|        BD                                                                   |
|        BE                                                                   |
|        BF                                                                   |
+=============================================================================+

24. Programmes d'exemple

   Voici le programme exemple en C qui demande le constructeur et le
   modle et indique si un medium est charg dans le priphrique.

#define DEVICE "/dev/sgc"
/* Programme de demonstration de l'interface SCSI generique */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/sg.h>

#define SCSI_OFF sizeof(struct sg_header)
static unsigned char cmd[SCSI_OFF + 18];        /* tampon de commandes SCSI */
int     fd;                          /* descripteur de periph./fichier SCSI */

/* traite une commande SCSI complete. Utilise l'interface SCSI generique */

static int handle_scsi_cmd(unsigned cmd_len,         /* longueur */
                           unsigned in_size,         /* taille data IN */
                           unsigned char *i_buff,    /* tampon IN */
                           unsigned out_size,        /* taille data OUT */
                           unsigned char *o_buff     /* tampon OUT */
                           )
{
    int status = 0;
    struct sg_header *sg_hd;

    /* quelques controles de routine */
    if (!cmd_len) return -1;            /* cmd_len doit etre != 0 */
    if (!i_buff) return -1;             /* tampon IN doit etre != NULL */
#ifdef SG_BIG_BUFF
    if (SCSI_OFF + cmd_len + in_size > SG_BIG_BUFF) return -1;
    if (SCSI_OFF + out_size > SG_BIG_BUFF) return -1;
#else
    if (SCSI_OFF + cmd_len + in_size > 4096) return -1;
    if (SCSI_OFF + out_size > 4096) return -1;
#endif

    if (!o_buff) out_size = 0;

    /* construction de l'en-tete du pilote generique */
    sg_hd = (struct sg_header *) i_buff;
    sg_hd->reply_len   = SCSI_OFF + out_size;
    sg_hd->twelve_byte = cmd_len == 12;
    sg_hd->result = 0;
#if     0
    sg_hd->pack_len    = SCSI_OFF + cmd_len + in_size; /* pas indispensable */
    sg_hd->pack_id;     /* inutilise */
    sg_hd->other_flags; /* inutilise */
#endif

    /* envoi de la commande */
    status = write( fd, i_buff, SCSI_OFF + cmd_len + in_size );
    if ( status < 0 || status != SCSI_OFF + cmd_len + in_size ||
                       sg_hd->result ) {
        /* une erreur s'est produite */
        fprintf( stderr, "ecriture (generique) resultat = 0x%x cmd = 0x%x\n",
                    sg_hd->result, i_buff[SCSI_OFF] );
        perror("");
        return status;
    }

    if (!o_buff) o_buff = i_buff;       /* controle du pointeur du tampon */

    /* recuperation du resultat */
    status = read( fd, o_buff, SCSI_OFF + out_size);
    if ( status < 0 || status != SCSI_OFF + out_size || sg_hd->result ) {
        /* une erreur s'est produite */
        fprintf( stderr, "lecture (generique) resultat = 0x%x cmd = 0x%x\n",
                sg_hd->result, o_buff[SCSI_OFF] );
        fprintf( stderr, "read(generic) sense "
                "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
                sg_hd->sense_buffer[0],         sg_hd->sense_buffer[1],
                sg_hd->sense_buffer[2],         sg_hd->sense_buffer[3],
                sg_hd->sense_buffer[4],         sg_hd->sense_buffer[5],
                sg_hd->sense_buffer[6],         sg_hd->sense_buffer[7],
                sg_hd->sense_buffer[8],         sg_hd->sense_buffer[9],
                sg_hd->sense_buffer[10],        sg_hd->sense_buffer[11],
                sg_hd->sense_buffer[12],        sg_hd->sense_buffer[13],
                sg_hd->sense_buffer[14],        sg_hd->sense_buffer[15]);
        if (status < 0)
            perror("");
    }
    /* Voyons si nous avons ce que nous attendions */
    if (status == SCSI_OFF + out_size) status = 0; /* on a tout */

    return status;  /* 0 indique que tout est OK */
}

#define INQUIRY_CMD     0x12
#define INQUIRY_CMDLEN  6
#define INQUIRY_REPLY_LEN 96
#define INQUIRY_VENDOR  8    /* Decalage sur le constructeur dans la reponse */

/* On demande le constructeur et le modele */
static unsigned char *Inquiry ( void )
{
  unsigned char Inqbuffer[ SCSI_OFF + INQUIRY_REPLY_LEN ];
  unsigned char cmdblk [ INQUIRY_CMDLEN ] =
      { INQUIRY_CMD,  /* commande */
                  0,  /* lun/reserve */
                  0,  /* code page */
                  0,  /* reserve */
  INQUIRY_REPLY_LEN,  /* longueur d'allocation */
                  0 };/* reserve/drapeau/lien */

  memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );

  /*
   * +------------------+
   * | struct sg_header | <- cmd
   * +------------------+
   * | copie de cmdblk  | <- cmd + SCSI_OFF
   * +------------------+
   */

  if (handle_scsi_cmd(sizeof(cmdblk), 0, cmd,
                      sizeof(Inqbuffer) - SCSI_OFF, Inqbuffer )) {
      fprintf( stderr, "Echec de la demande\n" );
      exit(2);
  }
  return (Inqbuffer + SCSI_OFF);
}

#define TESTUNITREADY_CMD 0
#define TESTUNITREADY_CMDLEN 6

#define ADD_SENSECODE 12
#define ADD_SC_QUALIFIER 13
#define NO_MEDIA_SC 0x3a
#define NO_MEDIA_SCQ 0x00
int TestForMedium ( void )
{
  /* demande de l'etat READY */
  static unsigned char cmdblk [TESTUNITREADY_CMDLEN] = {
      TESTUNITREADY_CMD, /* commande */
                      0, /* lun/reserve */
                      0, /* reserve */
                      0, /* reserve */
                      0, /* reserve */
                      0};/* reserve */

  memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );

  /*
   * +------------------+
   * | struct sg_header | <- cmd
   * +------------------+
   * | copie de cmdblk  | <- cmd + SCSI_OFF
   * +------------------+
   */

  if (handle_scsi_cmd(sizeof(cmdblk), 0, cmd,
                            0, NULL)) {
      fprintf (stderr, "Echec du test d'unite prete\n");
      exit(2);
  }

  return
   *(((struct sg_header*)cmd)->sense_buffer +ADD_SENSECODE) !=
                                                        NO_MEDIA_SC ||
   *(((struct sg_header*)cmd)->sense_buffer +ADD_SC_QUALIFIER) !=
                                                        NO_MEDIA_SCQ;
}

void main( void )
{
  fd = open(DEVICE, O_RDWR);
  if (fd < 0) {
    fprintf( stderr, "Il faut les droits lecture/ecriture sur "DEVICE".\n" );
    exit(1);
  }

  /* on ecrit quelques champs du resultat de la requete */
  printf( "%s\n", Inquiry() + INQUIRY_VENDOR );

  /* on regarde si le medium est charge */
  if (!TestForMedium()) {
    printf("pas de medium charge\n");
  } else {
    printf("un medium est present\n");
  }
}
