Pilote de périphérique du client de bande USB

Objectif

Prend en charge le protocole USB (Universal Serial Bus) pour le pilote de périphérique de bande à accès séquentiel.

Syntaxe

#include <sys/devinfo.h>
#include <sys/usb.h>
#include <sys/tape.h>
#include <sys/usbdi.h>

Sous-programmes dépendant de l'unité

La plupart des opérations sur bande sont implémentées à l'aide des sous-routines open, close, readet write . Toutefois, la sous-routine openx doit être utilisée si l'unité doit être ouverte en mode Diagnostic .

Sous-routines ouvertes et proches

La sous-routine openx est principalement utilisée pour les commandes de diagnostic et les utilitaires. Vous devez disposer des droits appropriés pour exécuter le sous-programme. Si vous exécutez leopenx sous-programme sans l’autorité requise, le sous-programme renvoie une valeur de-1 et définit le numéro d'erreur variable globale à une valeur deEPERM .

La sous-routine openx active le mode Diagnostic pour le pilote de périphérique et désactive la logique de relance de commande. Cette action permet aux opérations ioctl d'exécuter des fonctions spéciales associées au traitement des diagnostics. La sous-routine openx peut également forcer l'ouverture et la conservation des réservations.

La sous-routine open applique une règle de réservation basée sur l'attribut Object Data Manager (ODM) reserve_policy . Les unités de bande USB peuvent ne pas prendre en charge la commande de réservation SCSI (Small Computer System Interface) et, par conséquent, ces commandes peuvent être ignorées.

Le paramètre ext transmis à la sous-routine openx sélectionne l'opération à utiliser pour l'unité cible. Le fichier /usr/include/sys/scsi.h définit les valeurs possibles pour le paramètre ext .

Le paramètre Ext peut contenir n'importe quelle combinaison logique des valeurs d'indicateur suivantes:

Article Descriptif
SC_FORCED_OPEN Force l'accès à un périphérique en supprimant tout type de réservation sur le périphérique qui peut empêcher l'accès. Le type d'action à effectuer pour supprimer la réservation dépend du type spécifique de la réservation établie. Si cette option est spécifiée, une commande de réinitialisation de mémoire de masse est émise pour une bande USB, qui est un périphérique de stockage de masse.
SC_DIAGNOSTIC Place le périphérique sélectionné en mode Diagnostic . Ce mode est singulièrement entrant. Cela signifie que lorsqu'une unité est en mode Diagnostic , les opérations SCSI sont effectuées pendant les opérations open ou close et la consignation des erreurs est désactivée. En mode Diagnostic , seules les opérations close et ioctl sont acceptées. Tous les autres sous-programmes pris en charge par le périphérique renvoient une valeur de-1 et réglez le numéro d'erreur variable globale à une valeur deEACCES .

Une unité peut être ouverte en mode Diagnostic uniquement si l'unité cible n'est pas ouverte actuellement. Si vous ouvrez un appareil dans leDiagnostic mode et que le périphérique cible est déjà ouvert, le sous-programme renvoie une valeur de-1 et définit le numéro d'erreur variable globale à une valeur deEACCES .

Sous-routine ioctl

Les opérations ioctl suivantes sont prises en charge sur les unités de bande USB:

Opération Descriptif
INFOS Remplit l'argument devinfo transmis par l'appelant avec les valeurs suivantes:
        devinfo.devtype           = DD_SCTAPE;
        devinfo.flags             = 0;
        devinfo.devsubtype        = 0x00;
        devinfo.un.scmt.type      = DT_STREAM;
        devinfo.un.scmt.blksize   = Block Size Set for the Tape Device;
STIOCTOP Indique l'adresse d'une structure d'arrêt définie dans le fichier src/bos/usr/include/sys/tape.h . L'opération détectée dans la zone st_op de la structure d'arrêt est exécutée st_count fois, à l'exception des opérations de rembobinage, d'effacement et de conservation.

Cette commande ioctl prend en charge les opérations suivantes avec les détails d'implémentation respectifs:

STREW
Exécute la commande REWIND sur l'unité de bande pour rembobiner la bande.
STÉRASE
Exécute la commande SCSI ERASE pour effacer le contenu du support de bande. L'effacement n'est pas autorisé avec une bande en lecture seule.
STRETEN ou STINSRT
Exécute la commande SCSI LOAD avec les bits Load et Reten définis dans l'octet 4 de la commande.
STWEOF
Ecrit la marque de fin de fichier sur la bande. L'opération Write End-of-Filemark n'est pas autorisée avec une bande en lecture seule.  
STDÉDE
Désactive la commande de vérification de fin de bande.
STFSF
Exécute la commande Forward Space File . La zone st_count indique le nombre de marques de fichier que la bande avance.
STFSR
Exécute la commande Forward Space Record . La zone st_count indique le nombre d'enregistrements que la bande avance.
STRSF
Exécute la commande Reverse Space File . La zone st_count indique le nombre de marques de fichier que la bande inverse.
STRSR
Exécute la commande Reverse Space Record . La zone st_count indique le nombre d'enregistrements que la bande inverse.
STOFFL ou STEJECT
Ejecte la bande de l'unité de bande. Cette opération émet la commande SCSI LOAD avec le bit Load de l'octet 4 du bloc de descripteur de commande (CDB) qui est défini sur zéro.
STIOCHGP
Définit la commande ioctl pour modifier dynamiquement la taille de bloc de cette unité de bande. La taille de bloc est modifiée pour la longueur de l'opération d'ouverture et est renvoyée aux valeurs d'origine lors de la prochaine opération d'ouverture. La bande est forcée à BOT (début-de-bande) lors de l'exécution de cette opération.

Le paramètre de cette commande ioctl spécifie l'adresse d'une structure stchgp définie dans le fichier src/bos/usr/include/sys/tape.h . La zone st_blksize de la structure indique la valeur de taille de bloc à définir.

STIOCTOP (suite)
STIOCMD
Lorsque l'unité est correctement ouverte, l'opération STIOCMD exécute une commande SCSI sur l'unité de bande spécifiée.

L'octet de statut SCSI et les octets de statut de l'adaptateur sont renvoyés via le paramètre arg qui contient l'adresse d'une structure scsi_iocmd . Cette structure est définie dans le fichier /usr/include/sys/scsi_buf.h . L'opération STIOCMD reçoit la commande SCSI dans la section scsi_cdb de la structure scsi_iocmd et l'envoie à l'unité de bande USB. Si laSTIOCMD l'opération échoue, le sous-programme renvoie une valeur de-1 et définit le numéro d'erreur variable globale à une valeur non nulle. Dans ce cas, l'appelant doit évaluer les octets d'état renvoyés pour déterminer la cause de l'échec de l'opération et les actions de reprise.

Les valeurs version, command_lengthet timeout_value transmises par l'utilisateur sont validées et la valeur d'erreur EINVAL est renvoyée si elles ne sont pas valides.

Si vous transférez plus de 1 Mo de la taille maximale de transfert d'E/S, le sous-programme renvoie une valeur de-1 et définit le numéro d'erreur variable globale à une valeur deEINVAL .

Dans une condition de vérification, les valeurs de statut d'erreur suivantes sont définies dans la structure sc_passthru :

    status_validity  = SC_SCSI_ERROR
    scsi_bus_status = SC_CHECK_CONDITION
    adap_set_flags will have SC_AUTOSENSE_DATA_VALID flag set.

L'exemple suivant est un pseudo-code permettant d'exécuter l'opération STIOCMD sur la bande USB pour émettre une commande INQUIRY SCSI :

    struct scsi_iocmd cmd;
    char inq_data[255];
    char sense_data[255];
..
    fd = open(“/dev/rmt0”, O_RDWR);
..
    memset(&cmd, '\0', sizeof(struct sc_passthru));
    cmd.version = SCSI_VERSION_1;
    cmd.timeout_value = 30;
    cmd.command_length = 6;
    cmd.autosense_length = 255;
    cmd.autosense_buffer_ptr = &sense_data[0];
    cmd.data_length = 0xFF;
    cmd.buffer = inq_data;

   cmd.flags = B_READ;

   cmd.scsi_cdb[0] = SCSI_INQUIRY;
    cmd.scsi_cdb[1] = (0x00 | vpd);  /* Standard Inquiry - vpd=1 
                 for Extended Inquiry */
    cmd.scsi_cdb[2] = page_code;    /* Page Code - valid if vpd=1 */
    cmd.scsi_cdb[3] = 0x00;
    cmd.scsi_cdb[4] = 0xFF;
    cmd.scsi_cdb[5] = 0x00;

   if ((rc=ioctl(fd, STIOCMD, &cmd)) != 0){
         if (cmd.adap_set_flags & SC_AUTOSENSE_DATA_VALID) { 
        /* look at sense data */
         } /* end SC_AUTOSENSE_DATA_VALID */

         printf("STPASSTHRU: Ioctl FAIL errno %d\n",errno);
         printf("status_validity: %x, scsi_status: %x, adapter_status:%x\n", 
      cmd.status_validity, cmd.scsi_bus_status, cmd.adapter_status);
         printf("Residual: %x\n", cmd.residual);
         exit(-1);
     } else {
         printf("STPASSTHRU : Ioctl PASS\n");
         printf("status_validity: %x, scsi_status: %x, adapter_status:%x\n", 
      cmd.status_validity, cmd.scsi_bus_status, cmd.adapter_status);     }
STPASSTHRU Prend la commande SCSI dans la section scsi_cdb de la structure sc_passthru et l'envoie au pilote de bande USB. Cette opération est similaire à l'opération STIOCMD ioctl , à la seule exception des zones d'informations supplémentaires dans la structure sc_passthru qui fournit plus d'informations sur l'erreur.

L'exemple suivant est un pseudo-code permettant d'exécuter l'opération STPASSTHRU sur la bande USB pour émettre une commande INQUIRY SCSI :

    struct sc_passthru cmd;
    char inq_data[255];
    char sense_data[255];
..
    fd = open(“/dev/rmt0”, O_RDWR);
..
    memset(&cmd, '\0', sizeof(struct sc_passthru));
    cmd.version = SCSI_VERSION_1;
    cmd.timeout_value = 30;
    cmd.command_length = 6;
    cmd.autosense_length = 255;
    cmd.autosense_buffer_ptr = &sense_data[0];
    cmd.data_length = 0xFF;
    cmd.buffer = inq_data;

   cmd.flags = B_READ;

   cmd.scsi_cdb[0] = SCSI_INQUIRY;
    cmd.scsi_cdb[1] = (0x00 | vpd);  /* Standard Inquiry - vpd=1
                                 for Extended Inquiry */
    cmd.scsi_cdb[2] = page_code;      /* Page Code - valid if vpd=1 */
    cmd.scsi_cdb[3] = 0x00;
    cmd.scsi_cdb[4] = 0xFF;
    cmd.scsi_cdb[5] = 0x00;

   if ((rc=ioctl(fd, STPASSTHRU, &cmd)) != 0){
       if (cmd.adap_set_flags & SC_AUTOSENSE_DATA_VALID) {
             /* look at sense data */
         } /* end SC_AUTOSENSE_DATA_VALID */

         printf("STPASSTHRU: Ioctl FAIL errno %d\n",errno);
         printf("status_validity: %x, scsi_status: %x, adapter_status:%x\n", 
       cmd.status_validity, cmd.scsi_bus_status, cmd.adapter_status);
         printf("Residual: %x\n", cmd.residual);
         exit(-1);
     } else {
         printf("STPASSTHRU : Ioctl PASS\n");
         printf("status_validity: %x, scsi_status: %x, adapter_status:%x\n", 
       cmd.status_validity, cmd.scsi_bus_status, cmd.adapter_status);
     }