← ST-Computer 10 / 1997

Ein generischer SCSI-Treiber (2)

Grundlagen

Weder TOS selbst noch die TOS-kompatiblen Betriebssysteme bieten von sich aus die Möglichkeit zur direkten Kommunikation mit SCSI-PeripheriegerÀten.

FĂŒr den ATARI gibt es mehrere Möglichkeiten, ein SCSI-GerĂ€t zum Medienauswurf zu bewegen. Wenn es um Wechselplatten geht, kann man sich vorteilhaft eines XHDI-kompatiblen Treibers bedienen, der von Hause aus eine entsprechende Funktion bereitstellt. Bei anderen GerĂ€ten, insbesondere bei Streamern und CD-ROM-Laufwerken, kommt man auf diesem Weg allerdings nicht weiter. Hier bietet sich die Nutzung des SCSIDRV-Interfaces an.

Wie man das SCSI-Kommando EJECT zum Medienauswurf ĂŒber den generi-schen SCSI-Treiber an alle angeschlossenen SCSI-GerĂ€te schickt, soll Thema dieser Ausgabe sein. Die Grundlagen wurden bereits in [1] gelegt. Dort wurden die wichtigsten Aufrufe des SCSIDRV vorgestellt, wie er in [2] und [3] implementiert ist.

ErlÀuterungen Programmlisting

Das Listing zum Programm EJEC-TALL.TOS ist ausfĂŒhrlich dokumentiert, daher möchte ich hier nur die wesentlichen Operationen ansprechen. Um EJECTALL.C compilieren zu können, sind die Headerfiles zum SCSIDRV erforderlich, wie sie in [2] enthalten sind.

Nun zum Programmablauf: ZunĂ€chst wird nach dem cookie "SCSI" gesucht, wie er vom SCSIDRV angelegt wird. Der Parameter zu diesem cookie ist ein Pointer auf eine Liste aller Routinen, die vom SCSIDRV bereitgestellt werden. Zu diesen Routinen zĂ€hlen auch InquireSCSIO und InquireBusQ. Mit diesen Aufrufen werden von EJEC-TALL alle GerĂ€te ermittelt, die an den verfĂŒgbaren SCSI-Bussen angeschlossen sind. FĂŒr jedes dieser GerĂ€te wird mit Open() ein Kommunikationskanal geöffnet, ĂŒber den anschließend mit Out() das EJECT-Kommando abgesetzt wird. Eine DatenĂŒbertragung per DMA findet in diesem Fall nicht statt. Um unnötige Wartezeiten zu vermeiden, wird im Kommandoblock von EJECT das Immediate-Bit gesetzt. Dadurch wird erreicht, dass ein GerĂ€t nach Erhalt des EJECT-Kommandos schnellstmöglich den Abschluß der Operation meldet. Abschließend wird das bei Open() erhaltene Handle mit Close() freigegeben, da die Zahl der Handies des SCSIDRV Ă€hnlich wie bei den GEMDOS-Dateioperationen begrenzt ist.

Vor jedem Aufruf des SCSIDRV wird in den Supervisor-Modus gewechselt, der direkt nach dem Aufruf wieder verlassen wird. Zwar wĂ€re es auch möglich, das gesamte Programm im Supervisor-Modus auszufĂŒhren, dies ist jedoch nicht ratsam. In einer Multitasking-Umgebung findet in der Regel kein Taskwechsel statt, falls sich der

Prozessor im Supervisor-Modus befindet. Daher sollte der Supervisor-Modus nur dort genutzt werden, wo unbedingt erforderlich. In den Supervisor-Modus gelangen kann man entweder mit der GEMDOS-Funktion Super() oder dem XBIOS-Aufruf SupexecQ. Der Einfachheit halber wurde in EJECTALL SuperQ verwendet. Im allgemeinen ist es jedoch ratsamer, auf SupexecQ zurĂŒckzugreifen.

Verzicht auf FehlerprĂŒfung

Um EJECTALL möglichst kurz und einfach zu halten, wurde auf einige Dinge verzichtet, die fĂŒr eine ernsthafte Applikation unbedingt erforderlich sind. So werden Fehler bei der AusfĂŒhrung des SCSI-Kommandos nicht weiter berĂŒcksichtigt.

Hier bietet es sich an, das Ergebnis von Out() zu ĂŒberprĂŒfen und eventuell eine Fehleranalyse anhand der Daten von REQUEST SENSE vorzunehmen, wie sie im Fehlerfall nach dem Aufruf von Out() im entsprechenden Puffer abgelegt werden. Dieser Puffer wird bei Bedarf vom SCSIDRV gefĂŒllt, da REQUEST SENSE vom Treiber im Fehlerfall automatisch aufgerufen wird.

Mit Hilfe des SCSI-Kommandos IN-QUIRY ließe sich zunĂ€chst ermitteln, um welchen SCSI-GerĂ€tetyp es sich eigentlich handelt. Man könnte so denn fĂŒr den ATARI gibt es mehrere Möglichkeiten, ein SCSI-GerĂ€t zum Medienauswurf zu bewegen. Wenn es um Wechselplatten geht, kann man sich vorteilhaft eines XHDI-kompatiblen Treibers bedienen, der von Hause aus eine entsprechende Funktion bereitstellt. Bei anderen GerĂ€ten, insbesondere bei Streamern und CD-ROM-Laufwerken, kommt man auf diesem Weg allerdings nicht weiter. Hier bietet sich die Nutzung des SCSIDRV-Interfaces an.

Wie man das SCSI-Kommando EJECT zum Medienauswurf ĂŒber den generischen SCSI-Treiber an alle angeschlossenen SCSI-GerĂ€te schickt, soll Thema dieser Ausgabe sein. Die Grundlagen wurden bereits in [1] gelegt. Dort wurden die wichtigsten Aufrufe des SCSIDRV vorgestellt, wie er in [2] und [3] implementiert ist.

ErlÀuterungen zum Programmlisting

Das Listing zum Programm EJECTALL.TOS ist ausfĂŒhrlich dokumentiert, daher möchte ich hier nur die wesentlichen Operationen ansprechen. Um EJECTALL.C compilieren zu können, sind die Headerfiles zum SCSIDRV erforderlich, wie sie in [2] enthalten sind.

Nun zum Programmablauf:

ZunĂ€chst wird nach dem Cookie "SCSI" gesucht, wie er vom SCSIDRV angelegt wird. Der Parameter zu diesem cookie ist ein Pointer auf eine Liste aller Routinen, die vom SCSIDRV bereitgestellt werden. Zu diesen Routinen zĂ€hlen auch InquireSCSI() und InquireBus(). Mit diesen Aufrufen werden von EJEC-TALL alle GerĂ€te ermittelt, die an den verfĂŒgbaren SCSI-Bussen angeschlossen sind. FĂŒr jedes dieser GerĂ€te wird mit Open() ein Kommunikationskanal geöffnet, ĂŒber den anschließend mit Out() das EJECT-Kommando abgesetzt wird. Eine DatenĂŒbertragung per DMA findet in diesem Fall nicht statt. Um unnötige Wartezeiten zu vermeiden, wird im Kommandoblock von EJECT das Immediate-Bit gesetzt. Dadurch wird erreicht, dass ein GerĂ€t nach Erhalt des EJECT-Kommandos

schnellstmöglich den Abschluß der Operation meldet. Abschließend wird das bei Open() erhaltene Handle mit Close() freigegeben, da die Zahl der Handies des SCSIDRV Ă€hnlich wie bei den GEMDOS-Dateioperationen begrenzt ist.

Vor jedem Aufruf des SCSIDRV wird in den Supervisor-Modus gewechselt, der direkt nach dem Aufruf wieder verlassen wird. Zwar wÀre es auch möglich, das gesamte

Uwe Seimet