Inhalt

10. Beispiel mit Sensepuffer

Wir führen ein TEST UNIT READY Kommando durch, um zu überprüfen, ob ein Medium im Gerät geladen ist. Die Kopf-Deklarationen und die Funktion handle_SCSI_cmd aus dem Inquiry-Bespiel werden hier auch benötigt.

                        Tabelle 73: TEST UNIT READY Command
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Byte |        |        |        |        |        |        |        |        |
|=====+=======================================================================|
| 0   |                           Operation Code (00h)                        |
|-----+-----------------------------------------------------------------------|
| 1   | Logical Unit Number      |                  Reserved                  |
|-----+-----------------------------------------------------------------------|
| 2   |                           Reserved                                    |
|-----+-----------------------------------------------------------------------|
| 3   |                           Reserved                                    |
|-----+-----------------------------------------------------------------------|
| 4   |                           Reserved                                    |
|-----+-----------------------------------------------------------------------|
| 5   |                           Control                                     |
+=============================================================================+

Mit dieser Funktion implementieren wir die Abfrage.

#define TESTUNITREADY_CMD 0
#define TESTUNITREADY_CMDLEN 6

#define ADD_SENSECODE 12
#define ADD_SC_QUALIFIER 13
#define NO_MEDIA_SC 0x3a
#define NO_MEDIA_SCQ 0x00

int TestForMedium ( void )
{
  /* request READY status */
  static unsigned char cmdblk [TESTUNITREADY_CMDLEN] = {
      TESTUNITREADY_CMD, /* command */
                      0, /* lun/reserved */
                      0, /* reserved */
                      0, /* reserved */
                      0, /* reserved */
                      0};/* control */

  memcpy( cmd + SCSI_OFF, cmdblk, sizeof(cmdblk) );

  /*
   * +------------------+
   * | struct sg_header | <- cmd
   * +------------------+
   * | copy of cmdblk   | <- cmd + SCSI_OFF
   * +------------------+
   */

  if (handle_SCSI_cmd(sizeof(cmdblk), 0, cmd, 
                            0, NULL)) {
      fprintf (stderr, "Test unit ready scheiterte\n");
      exit(2);
  }

  return
   *(((struct sg_header*)cmd)->sense_buffer +ADD_SENSECODE) != 
                                                        NO_MEDIA_SC ||
   *(((struct sg_header*)cmd)->sense_buffer +ADD_SC_QUALIFIER) != 
                                                        NO_MEDIA_SCQ;
}

Mit einer neuen main Funktion können wir die Abfrage laufen lassen.

int main( void )
{
  fd = open(DEVICE, O_RDWR);
  if (fd < 0) {
    fprintf( stderr, "Lese-Schreiberlaubnis erforderlich für "DEVICE".\n" 
);
    exit(1);
  }

  /* Abfrage, ob sich ein Medium im Gerät befindet */

  if (!TestForMedium()) {
    printf("Gerät enthält kein Medium\n");
  } else {
    printf("Gerät enthält ein Medium\n");
  }
  return 0;
}

Die Datei generic_demo.c im Anhang enthält beide Beispiele.


Inhalt