Multi-Media Commands - 6 Kapitel 6.10. Das MECHANISM STATUS Command ruft den gegenwärtigen Status des Mechanismus, einschließlich der Wechslermechanismen, welche den Standard unterstützt, ab. Der Befehl wurde bereits im Kapitel Mechanik - Status der Schublade benutzt.
Der MECHANISM STATUS Command Descriptor Block:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
| 0 | Operation Code ($BD) | |||||||
| 1 | Reserviert | |||||||
| 2 | ||||||||
| 3 | ||||||||
| 4 | ||||||||
| 5 | ||||||||
| 6 | ||||||||
| 7 | ||||||||
| 8 | Allocation Length | |||||||
| 9 | ||||||||
| 10 | Reserved | |||||||
| 11 | Control | |||||||
Byte 0: Operation Code - $BD
Byte 8 und 9: Länge der Antwortstruktur (SizeOf(TMechanismStatusHeader))
const
SCSIOP_MECHANISM_STATUS = $BD;
type
TMECHANISM_STATUS_CDB = record
OperationCode : Byte;
AllocationLength : Word;
Control : Byte;
end;
...
begin
...
{
* Den Command Descriptor Block füllen.
}
ZeroMemory(@MECHANISM_STATUS_CDB, SizeOf(MECHANISM_STATUS_CDB));
MECHANISM_STATUS_CDB.OperationCode := SCSIOP_MECHANISM_STATUS;
MECHANISM_STATUS_CDB.AllocationLength := SizeOf(TMECHANISM_STATUS);
{
* Den Command Descriptor Block übertragen.
}
SetLength(aCDB, 12);
aCDB[0] := MECHANISM_STATUS_CDB.OperationCode;
aCDB[8] := HiByte(MECHANISM_STATUS_CDB.AllocationLength);
aCDB[9] := LoByte(MECHANISM_STATUS_CDB.AllocationLength);
...
end;
Auf acht Byte Mechanism Stauts Header folgen die Slot tables. Hier der Techanism Status Header:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
| 0 | Fault | Changer State | Current Slot (Low order)) | |||||
| 1 | Mechanism State | Door Open | Reserviert | Current Slot (High order) | ||||
| 2 | Current LBA (Legacy) | |||||||
| 3 | ||||||||
| 4 | ||||||||
| 5 | Number of Slots Available | |||||||
| 6 | Length of Slot Tables | |||||||
| 7 | ||||||||
Fault
Gibt an, ob die Ausführung der Aktion, welche im Changer State angegeben ist, scheiterte.
Changer State
| Changer State | Definition |
| $0 | Ready |
| $1 | Load in Progress |
| $2 | Unload in Progress |
| $3 | Initialisierung |
Current Slot
Gibt den aktuell ausgewählten Slot an. Bei Geräten, welche bootfähig sind, sollte dies nach der Initialisierung
der Slot 0 sein. Wenn das Gerät kein Wechsler ist, ist das Feld reserviert.
Mechanism State
| Mechanism State | Definition |
| $0 | Idle |
| $1 | Legacy definition - Playing (Audio or Data) |
| $2 | Legacy definition - Scanning |
| $3 | Legacy definition - Active with Host, Composite or Other Ports in use (zB READ) |
| $4 - $6 | Reserviert |
| $7 | No State Information Available |
Door open
Wenn das Bit gesetzt ist, ist die Tür/Schublade offen oder das Magazin nicht eingesetzt.
Current LBA
LBA (Logical Block Addressing) gibt den Sektor an, von welchem zuletzt gelesen wurde.
Number of Slots
Anzahl der verfügbaren Slots.
Length of Slot Tables
Gibt die Anzahl der Bytes an, welche mit Slot Informationen belegt sind. Sie berägt ein Vielfaches von vier.
Eine Slot Table:
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
| 0 | Disc Present | Reserved | Change | |||||
| 1 | Reserved | CWP_V | CWPt | |||||
| 2 | Reserved | |||||||
| 3 | ||||||||
Disc Present
Gibt an, ob eine Disc eingelegt ist.
Change
Gibt an, ob die Disc seit den letzten Laden geändert wurde. Das Flag ist obligatorisch.
CWP_V
Gibt an, das die Media Cartridge Write Protection in diesem Slot geprüft wurde und das Flag CWP gültig ist.
CWP
Gibt an, ob die Media Cartridge Write Protection für den Slot aktiv ist.
type
TMECHANISM_STATUS_HEADER = record
Fault_ChangerState_CurrSlot : Byte;
MechState_DoorOpen_CurrSlot : Byte;
CurrentLBA : array[0..2] of Byte;
NumberOfSlots : Byte;
LengthOfSlot : Word;
end;
TSLOT_TABLE = record
DiscPresent_Change : Byte;
CWPV_CWP : Byte;
Reserved1 : Byte;
Reserved2 : Byte;
end;
TMECHANISM_STATUS = record
MechStatusHeader : TMECHANISM_STATUS_HEADER;
SlotTable : Array [0..9] of TSLOT_TABLE;
end;
Nach der Ausführung wird die Antwortstruktur ausgewertet.
type
TMechanismStatusHeader = record
CurrentSlot : Byte;
Fault : Boolean;
ChangerState : Byte;
MechanismState : Byte;
DoorOpen : Boolean;
CurrentLBA : array[0..2] of Byte;
NumberOfSlots : Byte;
LengthOfSlot : Word;
end;
TSlotTable = record
DiscPresent : Boolean;
Change : Boolean;
CWP_V : Boolean;
CWP : Boolean;
end;
TMechanismStatus = record
MechanismStatusHeader : TMechanismStatusHeader;
SlotTable : Array [0..9] of TSlotTable;
end;
...
begin
...
{
* Befehl ausführen
}
ZeroMemory(@MECHANISM_STATUS, SizeOf(MECHANISM_STATUS));
if GET_SCSI_PASS_THROUGH_DIRECT(aDrive, aCDB,
@MECHANISM_STATUS, SizeOf(TMECHANISM_STATUS))
then begin
MechStatus.MechanismStatusHeader.CurrentSlot
:= MECHANISM_STATUS.MechStatusHeader.Fault_ChangerState_CurrSlot and $15 or
MECHANISM_STATUS.MechStatusHeader.MechState_DoorOpen_CurrSlot and $07 shl 5;
MechStatus.MechanismStatusHeader.Fault
:= MECHANISM_STATUS.MechStatusHeader.Fault_ChangerState_CurrSlot and $80 > 0;
MechStatus.MechanismStatusHeader.ChangerState
:= MECHANISM_STATUS.MechStatusHeader.Fault_ChangerState_CurrSlot and $60 shr 5;
MechStatus.MechanismStatusHeader.MechanismState
:= MECHANISM_STATUS.MechStatusHeader.MechState_DoorOpen_CurrSlot shr 6;
MechStatus.MechanismStatusHeader.DoorOpen
:= MECHANISM_STATUS.MechStatusHeader.MechState_DoorOpen_CurrSlot and $10 > 0;
MechStatus.MechanismStatusHeader.CurrentLBA[0]
:= MECHANISM_STATUS.MechStatusHeader.CurrentLBA[0];
MechStatus.MechanismStatusHeader.CurrentLBA[1]
:= MECHANISM_STATUS.MechmStatusHeader.CurrentLBA[1];
MechStatus.MechanismStatusHeader.CurrentLBA[2]
:= MECHANISM_STATUS.MechStatusHeader.CurrentLBA[2];
MechStatus.MechanismStatusHeader.NumberOfSlots
:= MECHANISM_STATUS.MechStatusHeader.NumberOfSlots;
MechStatus.MechanismStatusHeader.LengthOfSlot
:= MECHANISM_STATUS.MechStatusHeader.LengthOfSlot;
end;
...
end;
CD-Wechsler dürften in PCs selten sein. Somit dürften eigentlich nur die Informationen Door_Open und eventuell
CurrentLBA, welcher sich bei jedem Dateizugriff ändert, interessant sein. Das Laufwerk G:\ ist ein virtuelles
Laufwerk, in welchem kein Image gemountet ist.
Demo, welche diese Funktion nutzt:

Hardware Mechanismus (podHardMech.7z - 267 kb) MD5 (1 kb). Stand: 3. Januar 2012
Fr_An - Letzte Änderung: 3. Januar 2012
seit 28. Juli 2010