9. Exemple de commande de requête

Contenu de cette section

L'une des commandes SCSI de base est INQUIRY, utilisée pour identifier les type et constructeur du périphérique. Voici la définition issue de la spécification SCSI-2 (se reporter au standard SCSI-2 pour les détails).

                            Table 44: Commande INQUIRY
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Octet|        |        |        |        |        |        |        |        |
|=====+=======================================================================|
| 0   |                           Code operation (12h)                        |
|-----+-----------------------------------------------------------------------|
| 1   |Numero d'unite logique    |                  Reserve          |  EVPD  |
|-----+-----------------------------------------------------------------------|
| 2   |                           Code page                                   |
|-----+-----------------------------------------------------------------------|
| 3   |                           Reserve                                     |
|-----+-----------------------------------------------------------------------|
| 4   |                           Taille d'allocation                         |
|-----+-----------------------------------------------------------------------|
| 5   |                           Controle                                    |
+=============================================================================+

Les données en sortie ont l'allure suivante :

                   Table 45: Format standard de donnees INQUIRY
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Octet|        |        |        |        |        |        |        |        |
|=====+==========================+============================================|
| 0   | Qualificateur de periph. |           Type de peripherique             |
|-----+-----------------------------------------------------------------------|
| 1   |  RMB   |                  Modificateur de type de peripherique        |
|-----+-----------------------------------------------------------------------|
| 2   |   Version ISO   |       Version ECMA       |  Version approuvee ANSI  |
|-----+-----------------+-----------------------------------------------------|
| 3   |  AENC  | TrmIOP |     Reserve     |   Format de donnees en reponse    |
|-----+-----------------------------------------------------------------------|
| 4   |                    Longueur additionnelle (n-4)                       |
|-----+-----------------------------------------------------------------------|
| 5   |                           Reserve                                     |
|-----+-----------------------------------------------------------------------|
| 6   |                           Reserve                                     |
|-----+-----------------------------------------------------------------------|
| 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 revision du produit              ---|
| 35  |                                                                 (LSB) |
|-----+-----------------------------------------------------------------------|
| 36  |                                                                       |
|- - -+---                      Specifique constructeur                    ---|
| 55  |                                                                       |
|-----+-----------------------------------------------------------------------|
| 56  |                                                                       |
|- - -+---                        Reserve                                  ---|
| 95  |                                                                       |
|=====+=======================================================================|
|     |                       Parametres specifiques constructeur             |
|=====+=======================================================================|
| 96  |                                                                       |
|- - -+---                      Specifique 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-tête générique, 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-tête générique. Après l'exécution 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       /* decalage vers le nom du constructeur */

/* recherche du constructeur et du 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 de page             */
                  0,  /* reserve                  */
  INQUIRY_REPLY_LEN,  /* longueur allocation      */
                  0 };/* reserve / 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 après l'en-tête générique (donné par SCSI_OFF). Les données en entrée sont absentes de cette commande. handle_SCSI_cmd définit la structure d'en-tête. Nous pouvons maintenant implémenter la fonction main qui complète 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 resultat de Inquiry() */
  printf( "%s\n", Inquiry() + INQUIRY_VENDOR );
}

Tout d'abord, nous ouvrons le périphérique, contrôlons l'absence d'erreur, puis appelons la fonction de haut niveau. Ensuite, nous affichons des résultats sous une forme lisible, dont le constructeur, le produit et la version.

Note : il y a plus d'informations dans le résultat de "Inquiry" que ce que fournit ce petit programme. Il vous est loisible d'étendre celui-ci au type de périphérique, version ANSI, etc. Le type de périphérique a une importance particulière, puisqu'il détermine les jeux de commandes obligatoires et facultatives pour celui-ci. Si vous ne souhaitez pas le programmer vous-même, Eric Youngdale a réalisé le programme scsiinfo, qui fournit à peu près toute information disponible pour un périphérique SCSI. Cherchez sur tsx-11.mit.edu dans pub/Linux/ALPHA/scsi (NdT : on trouvera ce programme sur les sites miroirs français, comme ftp.ibp.fr, à un emplacement similaire).


Chapitre suivant, Chapitre Précédent

Table des matières de ce chapitre, Table des matières générale

Début du document, Début de ce chapitre