[an error occurred while processing this directive]
diff logo Informatica e sistemi alternativi
su questo sito sul Web
    Home   Chi siamo    Contattaci    Scrivi per diff    Proponi un argomento 20/04/24
    Cos'è diff    Come accedere    F.A.Q.    Promuovi    Dicono di diff    Amici di diff    
AmigaOS
Linux
FreeBSD
BeOS
OpenSource
Java
Database
Informatica
Hardware
E-Commerce
Narrativa

La programmazione sotto SCSI
di Andrea Vallinotto


Secondo esempio: INQUIRY

Il secondo esempio è un po' più complesso, e comporta la lettura dei dati di Inquiry. Questi sono i dati fondamentali di un dispositivo, che riportano una 'fotografia' in generale dell'unità in questione. I vari campi che si possono leggere sono descritti in dettaglio nello standard: in questo caso nell'SPC, perché questo, come il precendente TEST_UNIT_READY, è un comando che si applica a tutti i tipi di periferiche. Anzi: è il comando che viene sempre inviato all'inizializzazione della catena; serve all'host adapter per riconoscere quali unità sono presenti, e comportarsi di conseguenza.

Come sempre, c'è una versione "ridotta all'osso" del comando, quella che devono seguire tutti i prodotti. Poi alcuni dispositivi con un ricco set di comandi e con una buona implementazione, ritornano (se richiesti) alcune notizie addizionali: alcuni hard-disk IBM ad esempio, dicono anche il ... luogo di nascita, ovvero il nome dello stabilimento che li ha prodotti. Nello SCSI-3 (SPC-2) inoltre, questo comando è stato esteso per ritornare in maniera opportuna l'elenco di tutti i comandi che l'unità supporta. Questo è veramente molto utile per gli implementatori di software di alto livello. Purtroppo, essendo questa feature di recente creazione, bisognerà attendere ancora qualche tempo per poterla vedere nei prodotti in commercio.

In ogni caso, anche con una risposta minima, dai dati di Inquiry si ottengono tutte le inforazioni essenziali su un device, ed anche un po' di più.
Dal punto di vista della programmazione, ciò che cambia è che dobbiamo riservare uno spazio per i dati in entrata - e poi interpretarli, se vogliamo. La documentazione SCSI del comando Inquiry dà tutte le informazioni necessarie per l'interpretazione dei dati ritornati. La dimensione da riservare la ricaviamo dai nostri abituali libri delle magie: in questo caso, l'SPC (o SPC-2). Il numero minimo di bytes ritornati in questo caso è 36.

inquiry.c

Terzo esempio: uso della doppia lettura per READ_DEFECT_DATA

Il prossimo esempio illustra una tecnica spesso usata: la doppia lettura. Questo genere di tecnica (che in effetti porta a dare due comandi), serve quando si vuole effettuare una lettura di cui non si conosce la dimensione a priori.
Questo accade spesso, e a ben vedere anche l'esempio precedente poteva beneficiare di questa tecnica (perché i dati di Inquiry sono al minimo 36, ma spesso di più).

Come si procede? Tutti i comandi che possono ritornare una lunghezza non stimabile prima della chiamata, contengono nei primi bytes ritornati un campo detto Additional length o List length. In questo campo (che può essere di 8, 16 o più bit) viene ritornata la lunghezza complessiva dei dati disponibili. Non a caso, lo SCSI permette che se la dimensione di RAM allocata in memoria centrale è minore dei dati teoricamente disponibili, vengano trasmessi solo quei dati per i quali è stato riservato lo spazio (il campo scsi_Length). Riassumendo:

  1. Si invia un primo comando, avendo allocato la lunghezza necessaria per arrivare a leggere il campo Additional length.
  2. Si legge il campo relativo e di conseguenza si rialloca il buffer dati e si cambia il CDB (perché contiene Allocation Length!!).
  3. Si effettua la seconda lettura, e questa volta i dati saranno trasferiti per intero.

Questa tecnica è da utilizzarsi quando la dimensione dei dati è molto variabile: infatti nell'esempio precedente dell'Inquiry, per essere sicuri di prendere tutti i dati, bastava allocare 252 miseri bytes. Al contrario, per letture più grandi (come la defect list dell'esempio che segue, o le mode pages) è meglio usare questo sistema, e non basarsi su una sovrastima mal fatta (del genere "640k basteranno per tutti").

getd.c

Dare un SENSE ai nostri errori

ovvero come leggere i dati di SENSE

In caso di errore, se l'opportuno flag di AUTOSENSE è stato configurato, in sensebuffer->buf troviamo il già menzionato buffer di sense, corrispondente ai dati in risposta al comando REQUEST_SENSE (vedi SPC o SPC-2). È una sequenza di byte di lunghezza minima (e spesso massima) di 18 bytes. In questi bytes è contenuta una descrizione minuziosa del tipo di errore riscontrato. Anche in questo caso sta al buon cuore del produttore dotare la periferica di un più o meno adeguato set di codici d'errore. Lo standard di suo ce la mette tutta, definendo qualcosa come più di 300 codici d'errore diversi (a fondo dell'articolo si trova un breve elenco dei più strani).

La decodifica dei codici d'errori è pressochè gerarchica: l'errore viene definito in maniera via via più precisa. Il primo campo da leggere è il primo byte che può avere valori 0x70 o 0x71: in caso contrario il dispositivo ha risposto in maniera non standard, e quindi il resto dei dati ha una sintassi "vendor specific", cioè non standard (buona fortuna, e ricordatevi dei carboni ardenti).

Il campo Sense key è un nibble (4 bit) che indica la categoria generica dell'errore; quindi i due campi più specifici sono detti ASC e ASCQ, ovvero Additional Sense Code ed Additional Sense Code Qualifier. Combinando questi due valori, si ottiene il codice specifico dell'errore: l'elenco completo si trova nella documentazione SCSI. L'include accluso (sense_codes.h) definisce tutti i codici SCSI-2; essendo questi due bytes contigui ed allineati, si possono leggere direttamente sulle architetture Big-endian. Per le little-endian invece, c'è un'apposita macro per fare le conversioni.

Il campo Sense-Key specific infine, può contenere dei dati addizionali, nel caso ce ne fosse bisogno.

Qualche altra cosa con cui far colpo sugli amici....

In genere, quando si invia sul bus un determinato comando, si deve attendere fino al suo completamento per poterne inviare un altro (a meno che si stia dialogando in sincorno con riselezione). Questo fatto in alcuni casi può non essere desiderabile; anche nel caso della riselezione infatti, non è possibile inviare un secondo comando allo stesso dispositivo, fin quando il primo non è stato completato. Nel caso di operazioni che richiedono molto tempo, è utile poter sapere come stanno andando le cose. La soluzione sta in un flag che alcuni comandi implementano, detto Immed (= 'immediate'). Per i dispositivi che implementano questo flag (che è sempre opzionale), il comportamento è il seguente: al ricevimento del comando, viene validato il CDB, e l'eventuale lista dei parametri in fase dati, quindi il comando ritorna subito lo stato.
Mentre l'operazione è in corso, il dispositivo risponde solo ad un limitato set di comandi, perché ovviamente è occupato.

Un buon esempio (per gli hard disk) è il comando FORMAT_UNIT, che effettua la formattazione a basso livello - "Kids, don't try this at home".

In un'operazione così lunga (e delicata), sarebbe bello poter aver indicazione se tutto sta procedendo per il verso giusto, ed a che punto è l'operazione.
Impostando a 1 il flag di Immed (che in questo specifico caso si trova nella parameter list), possiamo avere l'indicazione del progresso inviando successivi comandi REQUEST_SENSE: durante la formattazione il disco risponderà con dei valori ASC - ASCQ corrispondenti a LOGICAL UNIT NOT READY FORMAT IN PROGRESS ; il campo Sense-key specific avrà un progress indicator codificato in maniera particolare.

ASSIGN_FAILURE_OCCURRED
Assign Diff: NIL:
AUTOMATIC_DOCUMENT_FEEDER_LIFT_UP
Chiudi 'sto coso!
BLOCK_NOT_COMPRESSIBLE
È inutile che ti ostini.
CANNOT_WRITE_MEDIUM_UNKNOWN_FORMAT
Banana in disk drive.
CLEANING_REQUESTED
Mi insaponi?
COMMANDS_CLEARED_BY_ANOTHER_INITIATOR
Questa catena è troppo piccola per due controller.
COPY_PROT_KEY_EXCH_FAIL_AUTHENTICATION_FAILURE
La chiave pirata non funziona...
DOCUMENT_JAM_IN_AUTOMATIC_DOCUMENT_FEEDER
E adesso chi lo sblocca?
ERROR_TOO_LONG_TO_CORRECT
È una storia troppo lunga...
EXCHANGE_OF_LOGICAL_UNIT_FAILED
Mai giocare al gioco delle tre carte.
FAILED_TO_SENSE_TOP_OF_FORM
Ma quant'è lungo il foglio?
GENERATION_DOES_NOT_EXIST
La generazione X
INSUFFICIENT_REGISTRATION_RESOURCES
Shareware di poco successo.
INVALID_COMBINATION_OF_WINDOWS_SPECIFIED
Windows'98 e X-Windows
LAMP_FAILURE
Hanno spento la luce al fondo del tunnel.
LOGICAL_UNIT_NOT_READY_MANUAL_INTERVENTION_REQUIRED
Dagli un calcio e riparte.
OUT_OF_FOCUS
Oggi vedo doppio.
PACKET_DOES_NOT_FIT_IN_AVAILABLE_SPACE
Allargare il deposito, please.
TOO_MANY_WINDOWS_SPECIFIED
Windows'95, Windows'98, Windows NT, etc...
WARNING_SPECIFIED_TEMPERATURE_EXCEEDED
Ho il cervello arrosto. Meglio piantarla qui.


Andrea Vallinotto
Studente di Informatica all'Universtità degli Studi di Torino.
Utente e sviluppatore Amiga, programma, quando ha tempo, in C e ARexx.
Collabora come free-lance (senza sapere dove poi atterra) alla rivista francese AmigaNews.
Altri hobby: subacquea e viaggi.

Puoi contattare l'autore scrivendo a:
avallino@diff.org


Articoli dello stesso autore:
Annuncio AmigaOS 5 (DevCon '98)
Reportage dalla fiera di Colonia '98
Clickboom
Signorina, mi scusi lo SCSI
Introduzione alla programmazione
AmigaOS 3.5 è realtà
Utility ed inutilities per la rete e per Internet
I Love You: cronache del dopobomba
I Love You ed i sistemi nostrani


 


  Indice dell'articolo:
Introduzione
Parte 1
Parte 2

Documenti collegati all'articolo:
scsidisk.h
send_scsi_cmd.h
send_scsi_cmd.c
scsi/test_unit_ready.c
<commands.h>
<sense_codes.h>
<status.h>
inquiry.c
getd.c

Link esterni citati:
la Home Page del TX310, cioè il comitato che definisce lo SCSI-3

Per informazioni circa il bus SCSI si rimanda all'articolo già pubblicato sul primo numero Signorina, mi scusi lo SCSI.


© 1999,2000,2001,2002 NonSoLoSoft di Ferruccio Zamuner (Italia)- tutti i diritti sono riservati