SCSI(2)                                                   SCSI(2)

     NAME
          openscsi, closescsi, scsiready, scsi, scsicmd, scsierror -
          SCSI device operations

     SYNOPSIS
          #include <u.h>
          #include <libc.h>
          #include <disk.h>

          typedef struct Scsi {
               char  *inquire;
               int   rawfd;
               int   nchange;
               ulong changetime;
          };

          Scsi* openscsi(char *devdir)

          void  closescsi(Scsi *s)

          int   scsiready(Scsi *s)

          int   scsi(Scsi *s, uchar *cmd, int ncmd,
                              void *data, int ndata, int dir)

          int   scsicmd(Scsi *s, uchar *cmd, int ncmd,
                              void *data, int ndata, int dir)

          char* scsierror(int asc, int ascq)

          int   scsiverbose;

     DESCRIPTION
          These routines provide an interface to a SCSI or ATAPI
          device via sd(3).

          Openscsi attempts to open the file devdir/raw and use it to
          send raw SCSI commands.  On success, it reads the device's
          inquiry string and stores it in inquire in the returned Scsi
          structure.  Closescsi closes the connection and frees the
          Scsi structure.

          Scsiready sends the ``unit ready'' command up to three
          times, returning zero if the unit responds that it is ready,
          or -1 on error.

          Scsierror returns a textual description of the SCSI status
          denoted by the ASC and ASCQ sense codes.  The description is
          found by consulting /sys/lib/scsicodes.  The returned string
          will be overwritten by the next call to scsierror.

     SCSI(2)                                                   SCSI(2)

          Scsi and scsicmd execute a single SCSI command on the named
          device.  There should be ncmd bytes of command data in cmd;
          if dir is Sread, a successful operation will store up to
          ndata bytes into data, returning the number of bytes stored.
          If dir is Swrite, the ndata bytes beginning at data are
          transmitted as the data argument to the command, and the
          number of bytes written is returned.  If dir is Snone, data
          and ndata are ignored.  On error, scsi and scsicmd return
          -1.  Scsicmd simply issues the command and returns the
          result; scsi works a bit harder and is the more commonly
          used routine.  Scsi attempts to send the command; if it is
          successful, scsi returns what scsicmd returned.  Otherwise,
          scsi sends a request sense command to obtain the reason for
          the failure, sends a unit ready command in an attempt to
          bring the unit out of any inconsistent states, and tries
          again.  If the second try fails, scsi sends the request
          sense and unit ready commands again and then uses scsierror
          to set errstr with a reason for failure.

          The nchange and changetime fields in the Scsi structure
          record the number of times a media change has been detected,
          and the time when the current media was inserted into the
          drive (really the first time a SCSI command was issued after
          it was inserted).  They are maintained by scsi.

          If scsiverbose is set, these commands will produce a fair
          amount of debugging output on file descriptor 2 when SCSI
          commands fail.

     FILES
          /sys/lib/scsicodes
               List of textual messages corresponding to SCSI error
               codes; consulted by scsierror.

     SOURCE
          /sys/src/libdisk/scsi.c

     SEE ALSO
          sd(3), scuzz(8)