Avatar
www.fr-an.de

Medieninformationen

Lese- und Schreibgeschwindigkeiten

MODE SENSE (10) Command - Operation Code $5A
CD Capabilities and Mechanical Status - Page Code $2A

Dafür kann man auf die Capabilities zurückgreifen und das MODE SENSE (10) Command verwenden. Der MODE SENSE (10) Command Descriptor Block:

  7 6 5 4 3 2 1 0
0 Operation Code ($5A)
1 Reserviert LLBAA DBD Reserviert
2 PC PAGE CODE
3 SUBPAGE CODE
4 Reserviert
5
6
7 Allocation Length
8
9 Control

 

Zu setzende Werte:

Byte 0: Operation Code - $5A

Byte 1: $00.

Byte 2: 00b - Current values

Byte 2 und 3: $2A00 - Page Code und Subpage Code

Byte 7 und 8: $FF - Länge der Antwortstruktur, der vom Gerätetyp, dem unterstützten Multi Media Command Standard und dem eingelegten Medium abhängigen Mode Parameter Liste. Diese beginnt mit dem Mode Parameter (10) Header:

  7 6 5 4 3 2 1 0
0 Mode Data Length
1
2 Reserviert
3
4
5
6 Block Descriptor Length = 0
7

 
Mode Data Length
Gibt in Bytes an, wie lang die folgende Datenstruktur ist.

Block Descriptor Length
Die Länge ist 0, da Multimediageräte keine Block Descriptors unterstützen. Für ältere SCSI logical Units sind es 8.

CD/DVD Capabilities and Mechanical Status Page (Page Code 2Ah)
Die Beschreibung der CD/DVD Capabiblities and Mechanical Status Page (Page Code $2A) findet sich in den SCSI Multimedia Commands – 3 (MMC-3) in Kapitel 6.3.11. Hier auf die interessierenden Felder reduziert:

  7 6 5 4 3 2 1 0
0 PS Reserviert Page Code ($2A)
1 Page Length (28 + 4 * (maximum number of n))
2..7 Verschiedene Felder siehe Capabilities
8 Maximum Read Speed Supported (Veraltet)
9
10..17 Verschiedene Felder siehe Capabilities
18 Maximum Write Speed (Veraltet)
19
20 Current Write Speed Selected (Veraltet)
21
22..26 Verschiedene Felder siehe Capabilities
27 Reserved Rotation Control Selected
28 Current Write Speed Selected
29
30 Number of Logical Unit Write Speed Performance Descriptor Tables (n)
31
32 Logical Unit Write Speed Performance Descriptor Block #1
33
34
35
36 Logical Unit Write Speed Performance Descriptor Block #2
37
38
39
.
.
 
n * 4 + 28 Logical Unit Write Speed Performance Descriptor Block #n
n * 4 + 29
n * 4 + 30
n * 4 + 31
  Padding

 

Page Code: Code der zurückgegebenenen Seite.

Page Length: Gibt die noch folgenden Bytes an.

Maximum Read Speed Supported: Die höchste unterstützte Lesegeshwindigkeit. Sie ist vom eingelegten Medium abhängig. Obwohl als veraltet bezeichnet, wird sie meist noch angegeben.

Maximum Write Speed: Die höchste unterstützte Schreibgeschwindigkeit. Sie ist vom eingelegten Medium abhängig. Obwohl als veraltet bezeichnet, wird sie meist noch angegeben.

Rotation Control Selected: Gibt an, wie die Rotation controlliert wird:

Wert Beschreibung
00b Media default rotation control
01b CAV
Andere Reserviert

 
Current Write Speed Selected: Die gegenwärtig eingelegte Schreibgeschwindigkeit. Sie ist vom eingelegten Medium abhängig. In der alten Version der Code Page belegt das Feld die Bytes 20 und 21. In der neuen Version wird es als veraltet bezeichnet, wird jedoch meist angegeben. In der neuen Version belegt das Feld die Bytes 28 und 29. Hinzu ist das Feld Rotation Control Selected in Byte 27 gekommen.

Number of Logical Unit Write Speed Performance Descriptor Tables (n): Gibt die Anzahl der folgenden Logical Unit Write Speed Performance Descriptor Blocks an.

Logical Unit Write Speed Performance Descriptor Block - Struktur:

  7 6 5 4 3 2 1 0
0 Reserved
1 Reserved Rotation Control
2 Write Speed Supported (kbytes/sec)
3

 
Hier bedeutet die Rotation Control:

Wert Beschreibung
00b CLV
01b CAV
10b Reserviert
11b

 

Deklarationen

 
  {
  *  Für die Auswertung.
  }

  type
    TModeParameterHeader = record
      ModeDataLength  : Word;
      BlockDescLength : Word;
    end;
 
  type
    TLogUnitWriteSpeedPerfDescBlock = record
      Rotation   : Byte;
      WriteSpeed : Word;
    end;
 
  type
    TCapabilities = record
      PageCode      : Byte;
      PageLength    : Byte;
      RotCtrlSel    : Byte;
      CurWriSpeSel  : Word;
      NumLUWSPDT    : Word;
      LUWSPDBlock   : array of TLogUnitWriteSpeedPerfDescBlock;
      SpeedReadMax  : Word;
      SpeedReadCur  : Word;
      SpeedWriteMax : Word;
      SpeedWriteCur : Word;
    end;
 
    TCapabilitiesMechStatus = record
      ModeParameterHeader : TModeParameterHeader;
      Capabilities        : TCapabilities;
    end;
 
    ...
 
  {
  *  Für den Befehl.
  }
 
  const
    SCSIOP_MODE_SENSE10 = $5A;
    SCSIPC_CAPABILITIES = $2A;
 
  type
    TMODE_SENSE10_CDB = record
      OperationCode    : Byte;
      PC_PageCode      : Byte;
      SubpageCode      : Byte;
      AllocationLength : Word;
    end;
 
  type
    TCAPABILITIES_MECHSTATUS = record
      ModeParameterHeader : array[0..7] of Byte;
      Data                : array[0..$FF] of Byte;
    end;
 
        

 

Ausführung und Auswertung

Nach dem Ausfüllen des Command Descriptors Blockes wird die Abfrage ausgeführt und die Antwort ausgewertet. Es werden auch die als veraltet bezeichneten Felder ausgewertet.

 
    ...
 
  begin
 
    ...
 
    {
    *  Den Command Descriptor Block füllen.
    }
    ZeroMemory(@MODE_SENSE10_CDB, SizeOf(MODE_SENSE10_CDB));
    MODE_SENSE10_CDB.OperationCode    := SCSIOP_MODE_SENSE10;
    MODE_SENSE10_CDB.PC_PageCode      := SCSIPC_CAPABILITIES;
    MODE_SENSE10_CDB.AllocationLength := SizeOf(TMODE_SENSE10_DATA);
    {
    *  Den Command Descriptor Block übertragen.
    }
    SetLength(aCDB, 10);
    aCDB[0] := MODE_SENSE10_CDB.OperationCode;
    aCDB[2] := MODE_SENSE10_CDB.PC_PageCode;
    aCDB[3] := MODE_SENSE10_CDB.SubpageCode;
    aCDB[7] := HiByte(MODE_SENSE10_CDB.AllocationLength);
    aCDB[8] := LoByte(MODE_SENSE10_CDB.AllocationLength);
    {
    *  Befehl ausführen
    }
    ZeroMemory(@CAPABILITIES_MECHSTATUS, SizeOf(CAPABILITIES_MECHSTATUS));
    if GET_SCSI_PASS_THROUGH_DIRECT(aDrive, aCDB, @CAPABILITIES_MECHSTATUS,
                                    SizeOf(TCAPABILITIES_MECHSTATUS))
    then begin
      with Capabilities.ModeParameterHeader
      do begin
        ModeDataLength  := CAPABILITIES_MECHSTATUS.ModeParameterHeader[0] shl 8 or
                           CAPABILITIES_MECHSTATUS.ModeParameterHeader[1];
        BlockDescLength := CAPABILITIES_MECHSTATUS.ModeParameterHeader[6] shl 8 or
                           CAPABILITIES_MECHSTATUS.ModeParameterHeader[7];
      end;
      with Capabilities.Capabilities
      do begin
        PageCode      := CAPABILITIES_MECHSTATUS.Data[0] and $3F;
        PageLength    := CAPABILITIES_MECHSTATUS.Data[1];
        SpeedReadMax  := CAPABILITIES_MECHSTATUS.Data[8] shl 8 or
                         CAPABILITIES_MECHSTATUS.Data[9];
        SpeedReadCur  := CAPABILITIES_MECHSTATUS.Data[14] shl 8 or
                         CAPABILITIES_MECHSTATUS.Data[15];
        SpeedWriteMax := CAPABILITIES_MECHSTATUS.Data[18] shl 8 or
                         CAPABILITIES_MECHSTATUS.Data[19];
        SpeedWriteCur := CAPABILITIES_MECHSTATUS.Data[20] shl 8 or
                         CAPABILITIES_MECHSTATUS.Data[21];
        RotCtrlSel    := CAPABILITIES_MECHSTATUS.Data[27] and $03;
        CurWriSpeSel  := CAPABILITIES_MECHSTATUS.Data[28] shl 8 or
                         CAPABILITIES_MECHSTATUS.Data[29];
        NumLUWSPDT    := CAPABILITIES_MECHSTATUS.Data[30] shl 8 or
                         CAPABILITIES_MECHSTATUS.Data[31];
        {
        *  Blöcke
        }
        if NumLUWSPDT > 0
        then begin
          SetLength(LUWSPDBlock, NumLUWSPDT);
          for n := 1 to NumLUWSPDT
          do begin
            LUWSPDBlock[n - 1].Rotation
                 := CAPABILITIES_MECHSTATUS.Data[n * 4 + 29] and $07;
            LUWSPDBlock[n - 1].WriteSpeed
                 := CAPABILITIES_MECHSTATUS.Data[n * 4 + 30] shl 8 or
                    CAPABILITIES_MECHSTATUS.Data[n * 4 + 31];
          end;
        end;
      end;
    end;
 
    ...
 
  end;
        

 
Hier könnte man noch einige Plausibilitätsprüfungen einbauen. Zum Beispiel kann man die Werte für die Mode Data Length, den Page Code und die Page Length überprüfen.

 

Demo, welche diese Funktion nutzt:

Medien Disc Speed (podDiscSpeed.7z - 267 kb) MD5 (1 kb). Stand: 26. Februar 2012

Änderungen an der Demo

26.02.2012 -
Aktualisiert: Groupbox "Optische Laufwerke".
18.02.2012 -
Fehler: Profilbezeichnung für $001A DVD+R und $001B DVD+RW korrigiert.

 

Fr_An - Erstellt: 30. Januar 2012 - Letzte Änderung: 26. Februar 2012

seit 28. Juli 2010