Forum: PC-Programmierung Linux und sg_utils für Vendor Specific ATA Command


von Andreas F. (andreasfrieser)


Lesenswert?

Hallo,
ich verwende sg3_utils 1.30-1 um unter Ubuntu 11.04 ATA Kommandos an 
SATA Platten zu verschicken. Die SATA Platten sind an einen 
AHCI-Hostcontroller (Intel H67) angeschlossen. Der Zugriff auf die 
Platten erfolgt über libsgutils2, bei der Erstellung der Programm habe 
ich mich an sg_sat_identify.c aus dem /src-Verzeichnis von sg3_utils 
orientiert.
Der Zugriff auf die Geräte funktioniert für ATA Identify Device, ATA 
Read Sector, ATA Write Sector und die SMART Kommandos ohne Probleme. Ich 
muss aber einige Vendor Specific Commands verwenden. Hier beginnt das 
Problem.
Die Kommandos basieren auf ATA Set Features und verwenden den 
Subcommandcode 0x59. Es werden keinerlei Daten übertragen und ich möchte 
die Antwort der Platten (ATA Status Register, ATA Error Register) 
auswerten.
Folgender Codeausschnitt zeigt Zusammenbau und Senden des Kommandos:
1
int sgLibDevDescriptor;
2
3
unsigned char scsiAtaCommand[12];  // SCSI ATA PASS-THROUGH (12) command
4
unsigned char scsiAtaReturnDescriptor[16];
5
unsigned char scsiSenseBuffer[64]; // hold SCSI command sense data
6
int           scsiResourceId =  0; // returned by SCSI command
7
8
// open device
9
sgLibDevDescriptor = sg_cmds_open_device("/dev/sdc", 0, 0);
10
11
// build command
12
memset(scsiAtaCommand, 0, sizeof(scsiAtaCommand));
13
scsiAtaCommand[ 0] = 0xA1;
14
scsiAtaCommand[ 1] = 0x06; // non-data protocol
15
scsiAtaCommand[ 2] = 0x20; // ck_cond
16
scsiAtaCommand[ 3] = 0x59; // vendor specific command
17
scsiAtaCommand[ 4] = 0xAA; // vendor specific command
18
scsiAtaCommand[ 8] = 0xE0; // device register
19
scsiAtaCommand[ 9] = 0xEF; // ATA Set Features
20
21
// process command
22
ataReturnCode = sg_ll_ata_pt(sgLibDevDescriptor,
23
                             scsiAtaCommand,
24
                             sizeof(scsiAtaCommand),
25
                             20,
26
                             NULL,
27
                             NULL,
28
                             0,
29
                             scsiSenseBuffer,
30
                             sizeof(scsiSenseBuffer),
31
                             scsiAtaReturnDescriptor,
32
                             sizeof(scsiAtaReturnDescriptor),
33
                             &scsiResourceId,
34
                             0);
sg_ll_ata_pt kommt immer mit einem Fehlercode zurück. Vorrangegangenes 
ATA Identify Device und ATA Write Sector waren erfolgreich. Schaue ich 
mir den SATA Bus mit einem Busanalyzer an, sehe ich das der H2D Register 
FIS mit dem Kommando und der D2H Register FIS mit der erfolgreichen 
Antwort der SATA Platte komplett und ohne Fehler übertraen werden. 
Innerhalb der Firmware der SATA Platte treten ebenfalls keine Fehler 
auf.
Ich bin im Moment dabei, den Zusatnd des SATA Link nach Auftreten des 
beschriebenen Problems genauer zu unutersuchen.
Hat jemand eine Idee oder einen Anhaltspunkt für die weitere 
Fehlersuche?

Grüsse vom Bodensee,

Andreas

von Andreas F. (andreasfrieser)


Lesenswert?

Zur weiteren Information: sg_pll_ata_pt() kehrt, nach Ablaufen des 
Timeouts und Auswerten der Fehlerinformation mit command aborted zurück.
Der SATA Link ist gestört, da die Festplatte intern die Fehlermeldung 
PHY not connected generiert. Die Konfiguration von PHY und SATA 
Interface der Festplatte ist in Ordnung.

Grüsse vom Bodensee,

Andreas

von Tobi (Gast)


Lesenswert?

Moin Andreas,

ich mache das ganze so wir hier für data-in, data-out und no-data 
Commands beschrieben.
Funktioniert bei mir alles prima.

http://www.jukie.net/bart/blog/ata-via-scsi

Gruss,
Tobi

von Andreas F. (andreasfrieser)


Lesenswert?

Hallo Tobi,

Danke für den Hinweis. Habe die von Bart beschriebene Variante 
implementiert und durchgetestet - gleiches Verhalten und Fehlerbild. 
Werde weitersuchen!

Gruss vom Bodensee,

Andreas

von Andreas F. (andreasfrieser)


Lesenswert?

Weitere Erkenntnis: der Fehler tritt unabhängig von der Verwendung des 
SCSI-Gerätes oder des HDD-Gerätes auf.
1
// open device
2
sgLibDevDescriptor = sg_cmds_open_device("/dev/sg3", 0, 0); // SCSI
3
sgLibDevDescriptor = sg_cmds_open_device("/dev/sdc", 0, 0); // HDD
Werde das Programm mal auf einem anderen Rechner testen.

Gruss vom Bodensee,

Andreas

von Tobi (Gast)


Lesenswert?

Hallo Andreas,

hmm, was soll denn SET Features mit Subcode 0x59 bei welchem Vendor 
bewirken ?
Ich habe hier einige Platten liegen und könnte es mal hier ausprobieren.

Wie sieht es aus wenn du mal den sg_sat_set_features Befehl aus den 
sg3_utils verwendest ?

Gruss,
Tobi

von Andreas F. (andreasfrieser)


Lesenswert?

Moin, Moin,

Problem hat sich erledigt - Fehler gefunden! Die SATA SSD hat beim 
Antwort-FIS ein Flag falsch gesetzt (I-Flag, FIS Wort 0, Byte 1), 
welches im AHCI Controller des Hosts einen Schluckauf verursacht hat. 
War auf dem Analyzer nicht ohne weiteres zu sehen.

@Tobi: Danke für Hinweise und Hilfe. Ich will die grundlegende 
Befehlsbehandlung möglichst universell halten und nicht für jede 
Befehlsgrupe eigene Funktionen implementieren.

Gruss vom Bodensee,

Andreas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.