[LINUX] Traduction de scsi_mid_low_api.txt

J'ai traduit scsi_mid_low_api.txt pour ma propre étude, alors prenez note. Introduction Ce document décrit l'interface entre le pilote de niveau intermédiaire Linux SCSI et le pilote de niveau inférieur SCSI. Les pilotes de niveau inférieur (ci-après LLD) sont appelés par diverses choses telles que le pilote d'adaptateur de bus hôte (ci-après HBA) et le pilote d'hôte (ci-après HD). Dans ce contexte, «hôte» signifie le pont qui connecte le bus IO (par exemple PCI ou ISA) à un seul port initiateur SCSI qui réside sur le transport SCSI. Le port «initiateur» (un terme SCSI, voir SAM-3) envoie des commandes SCSI au port SCSI «cible» (par exemple, disque). Il peut y avoir de nombreux LLD dans un système en cours d'exécution, mais un seul par type de matériel s'applique. La plupart des LLD peuvent contrôler un ou plusieurs HBA SCSI. Certains HBA contiennent plusieurs hôtes.

Le transport SCSI peut également être un bus externe qui possède déjà son propre sous-système sous Linux. (Exemple: USB et ieee1394.) Dans de tels cas, le LLD du sous-système SCSI devient un pont logiciel vers les sous-systèmes des autres pilotes. Des exemples sont le pilote de stockage USB (situé dans dirvers / usb / storage) et le pilote iee1394 / sbp2 (situé dans drivers / ieee1394).

Par exemple, l'aic7xxx LLD contrôle le contrôleur d'interface parallèle SCSI Adaptec (SPI) qui utilise la série de puces 7xxx de la société. Aic7xxx LLD peut être intégré au noyau ou chargé en tant que module. Un seul LLD aic7xxx fonctionne sur un système Linux, mais il peut contrôler de nombreux HBA. Ces HBA peuvent exister en tant que cartes filles PCI ou être intégrés à la carte mère (ou les deux). Certains HBA basés sur aic7xxx sont des contrôleurs doubles. Par conséquent, il représente deux hôtes. Comme le dernier HBA, chaque hôte de aic7xxx possède sa propre adresse de périphérique PCI. [La correspondance un à un entre l'hôte SCSI et le périphérique PCI est courante, mais pas obligatoire. (Exemple: lors de l'utilisation d'un adaptateur ISA)]

La couche intermédiaire SCSI isole le LLD des autres couches telles que le pilote de couche supérieure SCSI et le pilote de couche de bloc.

Ce document est à peu près cohérent avec la version 2.6.8 du noyau Linux.

Documentation Le répertoire de documentation SCSI se trouve dans l'arborescence des sources Linxu, généralement Documentation / scsi. La plupart des documents sont en texte brut (c'est-à-dire ASCII). Ce fichier est nommé scsi_mid_low_api.txt et se trouve dans ce répertoire. Une copie plus récente de ce document http://web.archive.org/web/20070107183357rn_1/sg.torque.net/scsi/ Vous pouvez le trouver sur. De nombreux LLD y sont documentés. (Exemple: Aic7xxx.txt). Le niveau intermédiaire SCSI est brièvement mentionné dans scsi.txt, qui contient une URL vers un document décrivant la famille Linux Kernel 2.4 de sous-systèmes SCSI. Les deux pilotes de niveau supérieur ont des documents dans ce répertoire. Autrement dit, st.txt (pilote de bande SCSI) et scsi-generic.txt (pour pilote sg).

Les documents ou les URL concernant certains LLD peuvent être trouvés dans le code source C ou dans le même répertoire que le code source C. Par exemple, pour trouver l'URL du pilote de stockage de masse USB, regardez dans le répertoire / usr / src / linux / drivers / usb / storage.

Driver structure Traditionnellement, les LLD pour les sous-systèmes SCSI se composent d'au moins deux fichiers dans le répertoire drivers / scsi. Par exemple, un pilote appelé xyz a un fichier d'en-tête xyz.h et un fichier source xyz.c. [En fait, il n'y a aucune raison claire pour laquelle vous ne pouvez pas tous les écrire dans un seul fichier. Le fichier d'en-tête peut être supplémentaire]. Certains pilotes qui sont portés sur différents systèmes d'exploitation ont plusieurs fichiers. Par exemple, le pilote aic7xxx a des fichiers séparés pour les génériques et spécifiques au système d'exploitation (par exemple FreeBSD et Linux). Ces pilotes ont tendance à créer leurs propres répertoires sous le répertoire drivers / scsi.

Les fichiers suivants (trouvés dans le répertoire drivers / scsi) doivent être notés lors de l'ajout d'un nouveau LLD à Linux. Makefile et Kconfig. Il est probablement préférable de savoir comment votre LLD existant est configuré.

Des changements ont été introduits dans cette interface à mesure que le noyau de développement de la série 2.5 évoluait vers la série de production de la série 2.6. Un exemple de ceci est le code d'initialisation du pilote qui active les deux modèles. L'ancienne initialisation est basée sur l'hôte trouvé lors du chargement du pilote HBA. On en trouve des similaires dans la série 2.4. C'est ce qu'on appelle le modèle d'initialisation "passif". Le nouveau modèle permet le branchement à chaud et le débranchement du HBA pendant la durée de vie du LLD. Et c'est ce qu'on appelle le modèle d'initialisation "hotplug". Le nouveau modèle est préféré car il traite à la fois les périphériques SCSI traditionnels qui sont connectés en permanence et les périphériques SCSI modernes qui sont branchés à chaud (par exemple, les appareils photo numériques connectés par USB ou IEEE1394) de la même manière. Les deux modèles d'initialisation sont décrits dans les sections ci-dessous.

Il existe différentes manières d'interfacer le LLD avec le sous-système SCSI: a) Exécuter la fonction directement à partir du niveau intermédiaire b) Via le pointeur de fonction pour l'enregistrement des fonctions fourni par le niveau intermédiaire. Le niveau intermédiaire exécutera ces fonctions à un moment donné dans le futur. LLD fournit des implémentations de ces fonctions. c) Accès direct aux instances de structures de données bien connues maintenues par le niveau intermédiaire

a) Les fonctions de groupe sont répertoriées dans le chapitre «Fonctions fournies de niveau intermédiaire» ci-dessous.

b) Les fonctions de groupe sont répertoriées dans le chapitre «Fonctions d'interface» ci-dessous. Ces pointeurs de fonction existent dans "struct scsi_host_template" et sont passés par scsi_host_alloc () (* Note 1). Les interfaces de fonction que LLD ne souhaite pas fournir définissent les membres correspondants de scsi_host_template sur NULL. La définition d'une instance de scsi_host_template dans la portée du fichier définit un pointeur de fonction qui n'a pas été explicitement initialisé à NULL.

c) Soyez prudent lorsque vous utilisez des groupes, en particulier dans un environnement «hotplug». Le LLD doit être conscient de la durée de vie de l'instance partagée avec le niveau intermédiaire et d'autres couches.

Toutes les fonctions définies dans le LLD et toutes les données définies dans la portée du fichier doivent être statiques. Par exemple, la fonction slave_alloc () définie dans le LLD nommé xxx peut être définie comme "static int xxx_slave_alloc (struct scsi_device * sdev) {/ * code * /}".

(* Note 1) La fonction scsi_host_alloc () est presque toujours remplacée par la fonction scsi_register (). Les fonctions scsi_register () et scsi_unregister () restent pour maintenir le support du modèle d'initialisation passive.

Hotplug initialization model Ce modèle contrôle le moment où le LLD introduit et supprime l'hôte SCSI du sous-système SCSI. L'hôte est installé aussi vite que l'initialisation du pilote et est supprimé dès que le pilote est arrêté. Le pilote répond généralement à un rappel de sonde sysfs () indiquant qu'un HBA a été détecté. Après avoir vérifié que le nouveau périphérique est ce que le LLD veut contrôler, le LLD initialise le HBA puis enregistre le nouvel hôte au niveau intermédiaire SCSI.

Lors de l'initialisation du LLD, le pilote doit s'enregistrer sur le bus IO approprié où il s'attend à ce que le HBA soit découvert. (Exemple: bus PCI). Ceci est probablement possible via sysfs. Certains paramètres du pilote, en particulier ceux qui sont accessibles en écriture après le chargement du pilote, peuvent également être enregistrés avec sysfs à ce stade. Le niveau intermédiaire SCSI reconnaît le LLD lorsqu'il enregistre le premier HBA.

Après un certain temps, le LLD reconnaît le HBA et la séquence d'appel générale suivante entre le LLD et le niveau intermédiaire. Cet exemple montre le niveau intermédiaire qui recherche les HBA nouvellement introduits où seuls les deux premiers des trois périphériques SCSI renvoient une réponse.

        HBA PROBE: assume 2 SCSI devices found in scan
LLD                   mid level                    LLD
===-------------------=========--------------------===------
scsi_host_alloc()  -->
scsi_add_host()  ---->
scsi_scan_host()  -------+
                         |
                slave_alloc()
                slave_configure() -->  scsi_adjust_queue_depth()
                         |
                slave_alloc()
                slave_configure()
                         |
                slave_alloc()   ***
                slave_destroy() ***
------------------------------------------------------------

Si LLD veut ajuster les paramètres par défaut de la file d'attente, il invoque scsi_adjust_queue_depth () dans la routine slave_configure ().

*** Les paires Slave_alloc (), slave_destroy () sont appelées pour les périphériques scsi où le niveau intermédiaire ne répond pas après avoir essayé un scan.

Lorsque le HBA est supprimé, il peut faire partie du processus d'arrêt normal associé au module LLD déchargé, ou il peut être une réponse au "hot unplug" prévu en invoquant le rappel sysfs remove (). Peut être. Dans les deux cas, la séquence est la même.

    HBA REMOVE: assume 2 SCSI devices attached
LLD                      mid level                 LLD
===----------------------=========-----------------===------
scsi_remove_host() ---------+
                            |
                     slave_destroy()
                     slave_destroy()
scsi_host_put()
------------------------------------------------------------

Il peut être utile pour LLD de suivre une instance de la structure Scsi_Host (un pointeur vers la valeur de retour de scsi_host_alloc ()). Ces instances appartiennent au niveau intermédiaire. Les instances de la structure Scsi_Host sont libérées via scsi_host_put () lorsque le nombre de références atteint zéro.

Le débranchement à chaud du HBA qui contrôle le disque traitant les commandes SCSI sur le système de fichiers monté est une situation intéressante. Une logique de comptage des références a été introduite au niveau intermédiaire pour résoudre de nombreux problèmes liés au niveau intermédiaire. Voir le chapitre sur le décompte des références ci-dessous.

Le concept de hotplug peut être étendu aux périphériques SCSI. Actuellement, lorsque le HBA est ajouté, la fonction scsi_scan_host () analyse le périphérique SCSI connecté au transport SCSI du HBA. Avec les transports SCSI plus récents, le HBA peut prendre connaissance de nouveaux périphériques SCSI une fois le processus d'analyse terminé. Le LLD peut utiliser la séquence suivante pour rendre le niveau intermédiaire conscient du périphérique SCSI.

             SCSI DEVICE hotplug
LLD                   mid level                    LLD
===-------------------=========--------------------===------
scsi_add_device()  ------+
                         |
                    slave_alloc()
                    slave_configure()   [--> scsi_adjust_queue_depth()]
------------------------------------------------------------

De la même manière, le LLD peut prendre conscience que le périphérique SCSI a été supprimé ou que la connexion au périphérique SCSI a été interrompue. Certains transports SCSI existants (par exemple SPI) peuvent ne pas savoir que le périphérique SCSI a été supprimé tant que la commande SCSI de mise hors ligne du périphérique SCSI émise par le niveau intermédiaire échoue. Le LLD qui détecte la suppression du périphérique SCSI peut démarrer la suppression de la couche supérieure selon la séquence suivante.

              SCSI DEVICE hot unplug
LLD                      mid level                 LLD
===----------------------=========-----------------===------
scsi_remove_device() -------+
                            |
                     slave_destroy()
------------------------------------------------------------

Il peut être utile pour LLD de suivre une instance de la structure scsi_device (les pointeurs sont passés comme paramètres aux rappels slave_alloc () et slave_configure ()). Ces instances appartiennent au niveau intermédiaire. La structure scsi_device est libérée après slave_destroy ().

Passive initialization model Ces anciens LLD contiennent un fichier appelé "scsi_module.c" dans leur code source. Pour que ce fichier fonctionne, vous devez définir une instance de la structure scsi_host_template appelée driver_template. Voici une utilisation typique de la séquence de code pour ce modèle: static struct scsi_host_template driver_template = { ... }; #include "scsi_module.c" Le fichier Scsi_module.c contient deux fonctions: --Init_this_scsi_driver () Exécuté lorsque LLD est initialisé (c'est-à-dire au démarrage ou au chargement du module) --Exit_this_scsi_driver () Exécuté lorsque LLD est arrêté (lorsque le module est déchargé) Remarque: Ces fonctions sont balisées avec les modificateurs __init et __exit, donc LLD ne doit pas être appelé explicitement. (Parce que le noyau fonctionne)

Voici un exemple où deux hôtes sont reconnus (detect () renvoie 2) et une analyse de bus SCSI est effectuée sur chaque hôte pour découvrir un périphérique SCSI. (Le deuxième périphérique SCSI n'a pas répondu).

LLD                      mid level                 LLD
===----------------------=========-----------------===------
init_this_scsi_driver() ----+
                            |
                         detect()  -----------------+
                             |                       |
                            |                scsi_register()
                            |                scsi_register()
                            |
                      slave_alloc()
                      slave_configure()  -->  scsi_adjust_queue_depth()
                      slave_alloc()   ***
                      slave_destroy() ***
                            |
                      slave_alloc()
                      slave_configure()
                      slave_alloc()   ***
                      slave_destroy() ***
------------------------------------------------------------

Le niveau intermédiaire désactive la mise en file d'attente étiquetée, appelle scsi_adjust_queue_depth () et définit "cmd_per_lun" comme longueur de file d'attente pour cet hôte. Ces paramètres peuvent être remplacés par slave_configure () fourni par LLD. *** Une paire de slave_alloc () et slave_detroy () est appelée pour les périphériques SCSI dont le niveau intermédiaire a tenté de scanner et n'a pas répondu.

Voici la séquence dans laquelle le LLD s'arrête.

LLD                      mid level                 LLD
===----------------------=========-----------------===------
exit_this_scsi_driver() ----+
                            |
                     slave_destroy()
                         release()   -->   scsi_unregister()
                            |
                     slave_destroy()
                        release()   -->   scsi_unregister()
------------------------------------------------------------

LLD n'a pas besoin de définir slave_destroy () (c'est-à-dire qu'il est facultatif).

L'inconvénient du modèle «d'initialisation passive» est que l'enregistrement et la désinscription des hôtes est lié à l'initialisation et à l'arrêt du LLD. Une fois le LLD initialisé, il n'est pas facile d'ajouter un hôte nouvellement émergent (via par exemple hotplug) sans éteindre ou réinitialiser le pilote. Il peut être possible d'écrire un LLD pour les deux modèles d'initialisation.

Reference Counting Une infrastructure de comptage de références a été ajoutée à la structure Scsi_Host. Cela étend efficacement la propriété de l'instance Scsi_Host via les différentes couches SCSI qui les utilisent. Auparavant, ces instances appartenaient exclusivement au niveau intermédiaire. Les LLD n'ont généralement pas besoin de manipuler directement ces comptages de références, mais dans certains cas, ils le font.

Il existe trois fonctions de comptage de références intéressantes liées à la structure Scsi_Host. --scsi_host_alloc (): renvoie un pointeur vers une nouvelle instance de la structure Scsi_Host avec le nombre de références défini sur 1. ^^ --scsi_host_get (): Ajoute 1 au nombre de références pour une instance donnée. --scsi_host_put (): Diminue le nombre de références pour une instance donnée de 1. Si le nombre de références atteint 0, libérez l'instance donnée

Une infrastructure de comptage de références a été ajoutée à la structure Scsi_device. La propriété des instances Scsi_device est effectivement étendue à travers les différentes couches SCSI qui les utilisent. Auparavant, ces instances appartenaient exclusivement au niveau intermédiaire. Regardez les fonctions d'accès déclarées vers la fin de Include / scsi / scsi_device.h. Si le LLD veut conserver une copie du pointeur vers l'instance Scsi_device, il doit utiliser scsi_device_get () pour augmenter son nombre de références. Lorsque le pointeur est terminé, vous pouvez utiliser scsi_device_put () pour réduire son nombre de références (et éventuellement le supprimer).

^^ La structure Scsi_Host a en fait deux comptages de références qui sont manipulés en parallèle par ces fonctions. (Shost_dev et host_gendev?)

Conventions Tout d'abord, vous pouvez trouver des idées sur le style de codage de Linus Tobals C dans le fichier Documentation / CodingStyle.

Ensuite, il y a un mouvement pour interdire les typedefs qui introduisent des synonymes pour les balises struct. Les deux peuvent toujours être trouvés dans le sous-système SCSI, mais ces typedefs ont été déplacés vers un seul fichier scsi_typedefs.h pour faciliter la suppression future. Par exemple: "typedef struct scsi_cmnd Scsi_Cmnd;"

De plus, la plupart des améliorations de C99 encouragent les extensions pour lesquelles elles sont prises en charge par le compilateur gcc associé. Par conséquent, la structure de style C99 et les initialiseurs de séquence sont encouragés en cas de besoin. N'en faites pas trop, les VLA ne sont pas encore correctement pris en charge. L'exception à cela est d'utiliser des commentaires de style "//". / * * / Les commentaires de style sont toujours préférés sous Linux.

Un code bien écrit, testé et documenté n'a pas besoin d'être reformulé pour suivre les conventions ci-dessus. Par exemple, le pilote aic7xxx est fourni sous Linux par les laboratoires FreeBSD et Adaptec. FreeBSD et Adaptec ont sûrement leurs propres conventions de codage.

Mid level supplied functions Ces fonctions sont fournies par le niveau intermédiaire SCSI pour être utilisées par LLD. Les noms de ces fonctions (c'est-à-dire les points d'entrée) sont exportés afin que le LLD puisse y accéder. Le noyau charge et prépare le niveau intermédiaire SCSI pour l'initialisation avant l'initialisation de tout LLD. Les fonctions suivantes sont répertoriées par ordre alphabétique et tous leurs noms de fonction commencent par "scsi_".

Summary:
scsi_activate_tcq - turn on tag command queueing
scsi_add_device - creates new scsi device (lu) instance
scsi_add_host - perform sysfs registration and set up transport class
scsi_adjust_queue_depth - change the queue depth on a SCSI device
scsi_bios_ptable - return copy of block device's partition table
scsi_block_requests - prevent further commands being queued to given host
scsi_deactivate_tcq - turn off tag command queueing
scsi_host_alloc - return a new scsi_host instance whose refcount==1
scsi_host_get - increments Scsi_Host instance's refcount
scsi_host_put - decrements Scsi_Host instance's refcount (free if 0)
scsi_partsize - parse partition table into cylinders, heads + sectors
scsi_register - create and register a scsi host adapter instance.
scsi_remove_device - detach and remove a SCSI device
scsi_remove_host - detach and remove all SCSI devices owned by host
scsi_report_bus_reset - report scsi _bus_ reset observed
scsi_scan_host - scan SCSI bus
scsi_track_queue_full - track successive QUEUE_FULL events 
scsi_unblock_requests - allow further commands to be queued to given host
scsi_unregister - [calls scsi_host_put()]

Details:

réduction

Interface Functions Les fonctions d'interface sont définies par LLD et leurs pointeurs de fonction sont placés sur des instances de la structure scsi_host_template assignée par scsi_host_alloc () [ou scsi_register () / init_this_scsi_driver ()]. Certains sont obligatoires. Les fonctions d'interface doivent être déclarées statiques. La convention acceptée est que le pilote "xyz" déclare sa fonction slave_configure () comme statique int xyz_slave_configure (struct scsi_device * sdev). Et toutes les fonctions d'interface sont listées ci-dessous.

Un pointeur vers cette fonction doit être placé dans le membre slave_configure de l'instance de structure scsi_host_template. Un pointeur vers une telle instance doit être passé au niveau intermédiaire scsi_host_alloc () [ou scsi_register () / init_this_scsi_driver ()].

Les fonctions d'interface sont également écrites juste au-dessus de la définition de la structure scsi_host_template dans le fichier include / scsi / scsi_host.h. Dans certains cas, les détails peuvent être trouvés ci-dessous que dans scsi_host.h.

Les fonctions de l'interface sont répertoriées ci-dessous par ordre alphabétique.

Summary:
bios_param - fetch head, sector, cylinder info for a disk
detect - detects HBAs this driver wants to control
eh_timed_out - notify the host that a command timer expired
eh_abort_handler - abort given command
eh_bus_reset_handler - issue SCSI bus reset
eh_device_reset_handler - issue SCSI device reset
eh_host_reset_handler - reset host (host bus adapter)
info - supply information about given host
ioctl - driver can respond to ioctls
proc_info - supports /proc/scsi/{driver_name}/{host_no}
queuecommand - queue scsi command, invoke 'done' on completion
release - release all resources associated with given host
slave_alloc - prior to any commands being sent to a new device 
slave_configure - driver fine tuning for given device after attach
slave_destroy - given device is about to be shut down
Details:

réduction

Data Structures struct scsi_host_template Il existe un "struct scsi_host_template" par LLD **. Il est initialisé en tant que portée de fichier statique dans le fichier d'en-tête du pilote. Les membres qui ne sont pas explicitement initialisés de cette façon sont définis sur 0 ou NULL. Les membres d'intérêt sont: name - Nom du pilote (espaces autorisés, mais jusqu'à 80 caractères) proc_name - Utilisé par sysfs dans l'un des répertoires <proc_name> et "drivers" dans "/ proc / scsi / <proc_name> / <host_no>". De plus, "proc_name" ne doit contenir que des caractères acceptés par les noms de fichiers Unix. ( queueecommand) () --mid level est le principal callback utilisé pour injecter des commandes SCSI dans le LLD. La structure scsi_host_template est définie et commentée dans include / scsi / scsi_host.h.

*** Dans des situations extrêmes, un pilote peut avoir plusieurs instances si un pilote contrôle plusieurs classes différentes de matériel. (par exemple, LLD gère à la fois les cartes ISA et PCI et a une structure scsi_host_template distincte pour chaque classe).

struct Scsi_Host Il existe une structure Scsi_Host pour chaque hôte (HBA) contrôlé par le LLD. La structure Scsi_Host a de nombreux membres en commun avec la "struct scsi_host_template". Lorsqu'une nouvelle instance de structure Scsi_Host est créée (créée par scsi_host_alloc () dans hosts.c), leurs membres communs sont initialisés à partir de l'instance de structure scsi_host_template du pilote. Les membres d'intérêt sont:

host_no - Le seul numéro à l'échelle du système pour identifier cet hôte. Les valeurs sont attribuées par ordre croissant à partir de 0. can_queue - doit être supérieur à 0. N'envoyez pas plus de commandes à l'adaptateur que la valeur de can_queue. this_id --Représente l'ID de l'hôte SCSI (initiateur). Mis à -1 si inconnu. sg_tablesize --Nombre maximum d'éléments de collecte de dispersion autorisés par l'hôte. Si 0, cela signifie que l'hôte ne prend pas en charge la collecte de dispersion. max_sectors --Le nombre maximum de secteurs autorisés par une seule commande SCSI (généralement 512 octets). La valeur initiale de 0 conduit au paramétrage de SCSI_DEFAULT_MAX_SECTORS (défini dans scsi_host.h), qui définit actuellement 1024. Jusqu'à présent, la longueur de transfert maximale d'un disque est de 512 Ko lorsque max_sectors n'est pas défini. Veuillez noter que cette taille peut ne pas être assez grande pour les téléchargements de micrologiciels de disque. cmd_per_lun --Nombre maximum de commandes pouvant être mises en file d'attente sur un périphérique contrôlé par l'hôte. Écraser par LLD en appelant scsi_adjust_queue_depth (). Lorsque unchecked_isa_dma -1 =>, seuls les 16 Mo inférieurs de RAM sont utilisés (limite d'adressage ISA DMA), et lorsque 0> =, un espace d'adressage DMA de 32 bits ou plus peut être pleinement utilisé. use_clustering --1 => les commandes SCSI de niveau intermédiaire peuvent être fusionnées, 0 => La fusion de commandes SCSI n'est pas autorisée hostt - Un pointeur vers la structure scsi_host_template du pilote à partir de l'instance de structure Scsi_Host générée. Le nom de hostt-> proc_name -LLD. C'est le nom du pilote utilisé par sysfs. transportt --Un pointeur vers l'instance scsi_transport_template (le cas échéant). Les transports FC et SPI sont actuellement pris en charge. sh_list-Une liste liée bidirectionnelle à toutes les instances Scsi_Host. (Actuellement et dans l'ordre croissant de host_no). my_devices --Une liste liée bidirectionnelle vers les structures scsi_device appartenant à cet hôte. hostdata [0] - Zone réservée pour LLD à la fin de la structure Scsi_Host. La taille est définie par le deuxième argument de scsi_host_alloc () ou scsi_register (). vendor_id: valeur unique qui identifie le LLD fourni par le fournisseur pour Scsi_Host. Principalement utilisé pour valider la demande de message du fournisseur d'eau chaude spéciale. La valeur se compose du type d'identifiant et de la valeur spécifique au fournisseur. Voir scsi_netlink.h pour une description des formats valides.

La structure scsi_host est définie dans include / scsi / scsi_host.h.

struct scsi_device En général, il existe une instance de cette structure pour chaque LU SCSI sur un hôte. Le périphérique SCSI connecté à l'hôte est identifié de manière unique par le numéro de canal, l'ID cible et le numéro d'unité logique (lun). Cette structure est définie dans include / scsi / scsi_device.h.

struct scsi_cmnd Une instance de cette structure propage une commande SCSI vers le LLD et renvoie une réponse au niveau intermédiaire. Le niveau intermédiaire SCSI ne met pas en file d'attente les commandes SCSI vers le LLD au-dessus de la valeur voulue par scsi_adjust_queue_depth () (ou cmd_per_lun dans la structure Scsi_Host). Au moins une instance de la structure scsi_cmnd sera disponible pour chaque périphérique SCSI. Les membres d'intérêt sont:

cmnd - Tableau contenant des commandes SCSI cmnd_len - Longueur du tableau de commandes SCSI (en octets) sc_data_direction --Sens du transfert de données pendant la phase de données. Voir «enum dma_data_direction» dans include / linux / dma-mapping.h request_bufflen --Nombre d'octets de données à transférer (0 signifie pas de données de transfert) use_sg - == 0-> N'utilisez pas la liste de dispersion. Autrement dit, les données transférées depuis / vers le tampon de requête-> 0-> la liste de collecte de dispersion de request_bufffer en utilisant l'élément use_sg (en fait un tableau) laquelle. Les éléments de collecte de dispersion sont définis par la structure scatterlist dans include / asm / scatterlist.h. done - Un pointeur de fonction qui doit être appelé par le LLD lorsque la commande SCSI se termine (avec succès ou autrement). Si le LLD accepte la commande (c'est-à-dire que queuecommand () renvoie ou retourne 0), il ne doit être appelé que par le LLD. LLD peut commencer avant la fin de queuecommand (). LLD doit être défini par avant d'appeler result --done. Une valeur de 0 signifie que la commande a réussi. (Et toutes les données ont été transférées depuis / vers le périphérique cible SCSI.) Le résultat est un entier non signé de 32 bits affiché sous forme de 4 octets associés. La valeur de l'état SCSI est LSB. Voir les constantes associées aux macros status_byte (), msg_byte (), host_byte (), driver_byte () dans Include / scsi / scsi.h. sense_buffer - Le tableau à écrire lorsque l'état SCSI (LSB du résultat) est défini sur CHECK CONDITION (2) (longueur maximale: SCSI_SENSE_BUFFERSIZE octets). Lorsque CHECK CONDITION est défini, si les 4 bits supérieurs de sense_buffer [0] ont une valeur de 7, le niveau intermédiaire suppose que le tableau sense_buffer contient un tampon de détection SCSI valide. Sinon, le niveau intermédiaire émettra la commande REQUESET SENSE SCSI pour obtenir le tampon de détection. Cette dernière stratégie est sujette à des erreurs en présence de la mise en file d'attente des commandes. Donc, LLD devrait toujours être auto-sense. device: pointeur vers l'objet scsi_device associé à cette commande resid --LLD doit être mis à cet entier signé moins la longueur de transfert demandée (c'est-à-dire request_buffer) moins le nombre d'octets réellement transférés. Le resid est préréglé à 0, et si le sous-fonctionnement (le dépassement est rare) ne peut pas être détecté, LLD peut l'ignorer. Si possible, LLD doit définir resid avant le lancement terminé. Le cas le plus intéressant est le transfert de données à partir de périphériques cibles SCSI sous-exécutés (par exemple READ). underflow --LLD doit mettre (DID_ERROR_ << 16) dans result si le nombre d'octets effectivement transférés est inférieur à cette valeur. Peu de LLD implémentent cette vérification et crachent des messages d'erreur dans le journal plutôt que de signaler DID_ERROR. Mieux pour LLD est de mettre en œuvre resid.

LLD recommande de définir resid pour le transfert de données à partir de périphériques cibles SCSI (par exemple READs). La définition du resid est particulièrement importante pour les transferts de données qui ont une clé de détection MEDIUM_ERROR et HARDWARE ERROR (RECOVERD ERROR si possible). Dans ces cas, vous ne savez pas dans quelle mesure le LLD acceptera les données et l'approche la plus sûre est de ne pas accepter les données. Par exemple: LLD peut utiliser ces fonctions d'assistance pour indiquer qu'aucune donnée valide n'a été reçue:

scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));

SCpnt est un pointeur vers l'objet scsi_cmnd. Le resid est défini de cette manière pour indiquer que seuls trois blocs de 512 octets ont été reçus.

scsi_set_resid(SCpnt, scsi_bufflen(SCpnt) - (3 * 512));

La structure scsi_cmnd est définie dans include / scsi / scsi_cmnd.h.

Locks Une instance de la structure Scsi_Host a un spin_lock appelé Scsi_Host :: default_lock qui est initialisé avec scsi_host_alloc (). Dans la même fonction, le pointeur Scsi_Host :: host_lock est initialisé pour pointer vers default_lock. Les opérations de verrouillage et de déverrouillage sont ensuite effectuées par le niveau intermédiaire à l'aide du pointeur Scsi_Host :: host_lock. Le pilote précédent pouvait remplacer host_lock, mais ce n'est plus autorisé.

Autosense La détection automatique (ou détection automatique) est définie dans la documentation SAM-2 selon laquelle lorsque l'état CHECK_CONDITION se produit, la réponse automatique des données de détection au client d'application coïncide avec l'exécution de la commande SCSI. Les LLD doivent lire la détection automatique. Cela doit être fait lorsque le LLD détecte une CONDITION DE VÉRIFICATION par chacun: a) Demandez au protocole SCSI de lire plus de données dans une telle réponse. b) Alternativement, le LLD émet la commande REQUEST SENSE à lui-même.

Dans tous les cas, lorsque CHECK CONDITION est reconnu, le niveau intermédiaire vérifie struct scsi_cmnd :: sense_buffer [0] pour déterminer si LLD lit la détection automatique. Si cet octet a les 4 bits supérieurs de 7 (signifiant 0b0111? Ou 0xf), alors on suppose que l'auto-détection s'est produite. S'il a une valeur différente (et que cet octet est initialisé à 0 avant chaque commande), le niveau intermédiaire émet la commande REQUESET SENSE.

Si une commande en file d'attente existe, le lien qui conserve les données du tampon de détection de la commande qui échoue jusqu'au prochain REQUESET SENSE peut être désynchronisé. C'est la meilleure raison pour laquelle LLD joue la détection automatique.

Recommended Posts

Traduction de scsi_mid_low_api.txt
Traduction japonaise du manuel sysstat
Traduction japonaise du manuel Linux
Traduction japonaise du manuel e2fsprogs
[Français] Table des matières du didacticiel scikit-learn 0.18
Tutoriel TensorFlow - Représentation vectorielle des mots (traduction)
Traduction japonaise du manuel man-db
Traduction japonaise appropriée de pytorch tensor_tutorial
Traduction japonaise du manuel util-linux
Traduction japonaise du manuel iproute2
[Français] scikit-learn 0.18 Guide de l'utilisateur Table des matières
Traduction japonaise: PEP 20 - Le Zen de Python
[Français] scikit-learn 0.18 Introduction de l'apprentissage automatique par le didacticiel scikit-learn