dslib:  dsopen,  dsclose  -  communicate with SCSI devices
       accessed using the linux-xscsi subsystem.


SYNOPSIS

       #include <dslib.h>

       struct dsreq *dsopen(opath, oflags)

       dsclose(dsp)

       ds_showcmd(dsp)

       testunitready00(dsp)
       requestsense03(dsp, data, datalen, vu)
       read08(dsp, data, datalen, lba, vu)
       write0a(dsp, data, datalen, lba, vu)
       inquiry12(dsp, data, datalen, vu)
       modeselect15(dsp, data, datalen, save, vu)
       modeselect55(dsp, data, datalen, save, vu)
       reserveunit16(dsp, data, datalen, tpr, tpdid, extent, resid, vu)
       releaseunit17(dsp, tpr, tpdid, extent, resid, vu)
       modesense1a(dsp, data, datalen, pagectrl, pagecode, vu)
       modesense5a(dsp, data, datalen, pagectrl, pagecode, vu)
       modesenseNB_5a(dsp, data, datalen, pagectrl, pagecode, vu)
       senddiagnostic1d(dsp, data, datalen, self, dofl, uofl, vu)

       readcapacity25(dsp, data, datalen, lba, pmi, vu)
       readextended28(dsp, data, datalen, lba, vu)
       writeextended2a(dsp, data, datalen, lba, vu)

       getfd(dsp)
       doscsireq(fd, dsp)
       void fillg0cmd(dsp, cmdbuf, b0, ..., b5)
       void fillg1cmd(dsp, cmdbuf, b0, ..., b9)
       void fillg2cmd(dsp, cmdbuf, b0, ..., b9)
       void fillg5cmd(dsp, cmdbuf, b0, ..., b11)
       void filldsreq(dsp, data, datalen, flags)
       void vtostr(value, table)

       extern int dsdebug;
       extern int ds_default_timeout;
       extern long dsreqflags;
       DSDBG(statement; ...)

       struct dsreq *dsp;
       struct vtab *table;
       char *opath, *cmdbuf, *data;
       char b0, ..., b9, dofl, extent, pagecode, pagectrl, pmi, resid,
            save, self, tpdid, tpr, uofl, vu;
       int fd, oflags;
       long datalen, lba, value;

       These routines form the basis for a  simplified  interface
       to  ds(8) devices.  They are included in a program by com­
       piling with the -lds option.  An application  would  typi­
       cally  use  dsopen, dsclose, and a set of command-specific
       routines such as  testunitready00.   The  source  to  this
       library   can   be   obtained  by  installing  the  xscsi­
       tools-*.src.rpm with the source code for  the  library  in
       the  files dstab.c and dslib.c There are also several sam­
       ple programs using the dslib library provided in the  rpm.

       The  number  of  truly general SCSI commands is quite lim­
       ited, so provision is made for supporting  vendor-specific
       commands.   This  is  normally  done  by  using one of the
       existing routines as a template, and creating a  new  rou­
       tine  of  your own.  This might be useful if support for a
       SCSI command group other than Group  0,  1,  2,  or  5  is
       needed.   It is expected that most non-trivial uses of the
       library will involve creating or modifying  existing  rou­
       tines.  Any SCSI command length from 1 to 12 bytes is sup­
       ported by the underlying  kernel  drivers,  providing  the
       ds_cmdlen field is set correctly.

       A set of helper routines (fillg0cmd and so on) are used as
       the basis for creating your  own  routines.   The  utility
       function  ds_showcmd(dsp)  can be used to show information
       about the most recently executed command, in  cases  where
       the  use  of dsdebug is too verbose.  testunitready00, for
       instance, is implemented as:

         testunitready00(dsp)
         struct dsreq *dsp;
         {
           fillg0cmd(dsp, CMDBUF(dsp), G0_TEST, 0, 0, 0, 0, 0);
           filldsreq(dsp, 0, 0, DSRQ_READ|DSRQ_SENSE);
           return(doscsireq(getfd(dsp), dsp));
         }

       Note that many of these routines  depend  upon  the  exact
       setup of the dsreq structure used by dsopen.  It is there­
       fore not recommended that users attempt  to  use  indepen­
       dently derived dsreq structures with them.

       dsopen  passes  opath  and oflags to the open system call.
       If the open succeeds, dsopen allocates and fills  a  dsreq
       structure, along with some associated context information.
       dsclose deallocates the specified  dsreq  structure,  then
       calls close to close the device.

       fillg0cmd, fillg1cmd, fillg2cmd, and fillg5cmd are used to
       fill Group 0, 1, 2, and 5 command  buffers,  respectively.
       filldsreq  fills  a  dsreq  structure with commonly needed
       data.  The value of dsreqflags is ORed into  the  ds_flags

       DSRQ_SENSE) set for some or all commands, as it allows you
       to  avoid duplicating the library routines when you need a
       special flag set.  It also sets the default  timeout  (for
       functions  that  do  not  explicitly  set a timeout).  The
       timeout is set from the global  variable  ds_default_time­
       out,  and  that variable is initialized to 10 seconds.  It
       may be changed for applications that want  longer  default
       timeouts.   Individual  functions  may  still  need to set
       longer (or shorter)  timeouts,  after  calling  filldsreq.
       doscsireq  issues  the  SCSI  ioctl, performs a variety of
       error-handling functions,  and  returns  the  SCSI  status
       byte.   Also  of  interest  on return is the ds_ret field,
       which is 0 on successful returns, and  on  failures  indi­
       cates  what  type  of error occurred (the DSRT_* values in
       <xscsids.h>.

       ds_vtostr Takes a value, and a table to look it up in.  If
       the value is found in the given table, a string describing
       the value is returned, else the empty string.  Five tables
       are provided:

       dsrqnametab    for the DSRQ_* flags
       dsrtnametab    for the DSRT_* flags
       cmdstatustab   for  the SCSI status byte return in ds_sta­
                      tus
       msgnametab     for the SCSI message bytes
       cmdnametab     for the SCSI  commands,  such  as  Testuni­
                      tready  (value is the command byte; G0_TEST
                      in this case)

       The dsdebug variable, and the DSDBG() macro can be used to
       enable debug printfs, and to add your own.  If the dsdebug
       variable is non-zero, debugging information is printed  by
       the  library  routines.   The DSDBG macro is used for this
       purpose.  A more or less arbitrary sequence of  statements
       can be used within the parentheses of the DSDBG macro, but
       some form of print statement is most frequently used.

       Overlay structures define the layouts of the three  (Group
       0,  1,  6)  Common Command Set command buffers.  Bytes are
       named both by position (g0_b0) and by typical function  in
       the command buffer (g1_op_code).

       Mnemonic  names are also defined for all CCS command codes
       (G0_TEST), message bytes  (MSG_ABORT),  and  status  bytes
       (STA_BUSY).   There  are  also a number of macros suitable
       for accessing dsreq structures, SCSI byte and bit  fields,
       etc.

       A  set  of  structures  contains values, name strings, and
       descriptions for commonly  used  codes  and  values.   The
       structures  document  DSRQ_* and DSRT_* codes, CCS command
       codes,  and  CCS  status  and  message  bytes.   They  are



EXAMPLE PROGRAM

       The following code fragment illustrates simple use of  the
       library,  and of some /dev/xscsi/pci*/target*/lun*/ds sup­
       port macros.

         while (--argc > 0) {
           fn = *++argv;
           printf("%-17s  ", fn);
           if ((dsp = dsopen(fn, O_RDONLY)) == NULL) {
             fflush(stdout);
             perror("cannot open");
             continue;
           }

           if(inquiry12(dsp, inqbuf, sizeof inqbuf, 0) != 0)
             printf("%-10s inquiry failure0, "---");
           else {
             pdt = DATABUF(dsp)[0] & 0x7F;
             if (DATASENT(dsp) >= 1)
               printf("%-10s", pdt_types[(pdt<NPDT) ? pdt : NPDT-1]);
             if (DATASENT(dsp) >= 16) printf("  %-12.8s", &DATABUF(dsp)[8]);
             if (DATASENT(dsp) >= 32) printf("  %.16s",   &DATABUF(dsp)[16]);
             if (DATASENT(dsp) >= 36) printf("  %.4s",    &DATABUF(dsp)[32]);
             /*  do test unit ready only if inquiry successful, since many
               devices, such as tapes, return inquiry info, even if
               not ready (i.e., no tape in a tape drive). */
             if(testunitready00(dsp) != 0) {
               printf("  %s0,
                 (RET(dsp)==DSRT_NOSEL) ? "cannot select" : "not ready");
             }
             else
               printf("  ready0);
           }
           dsclose(dsp);
         }

       Each device is opened, and the necessary  data  structures
       created.   An inquiry is done to see if the device exists;
       if so, it's type is printed.  A test unit ready is done to
       see  if  the device is ready for I/O.  Finally, the device
       is closed, releasing the data structures.


DIAGNOSTICS

       dsopen returns  a  NULL  pointer  on  failure.   doscsireq
       returns -1 on absolute failure, and the status byte other­
       wise.  A status byte of 0xff indicates an  invalid  status
       byte  because  the  scsi  command  didn't  complete.   The
       RET(dsp) macro returns a result code, which  can  be  con­
       sulted  for any error or 'unusual' status from the driver;
       a value of 0 indicates a normal return.

       A common failure occurs when the byte count passed to  the
       dslib routines doesn't match the byte count implied by the
       values in  the  SCSI  command  descriptor  (as  filled  by
       fillg0cmd  and  so  on).  This is particularly common with
       read08,write0a,readextended28, and writeextended2a.   This
       is because these commands occur in a number of device spe­
       cific forms.  If you get console error messages similar to
       SCSI  Bus=#  ID=#  LUN=#: Too much data (probable SCSI bus
       cabling problem) then you are probably seeing this kind of
       mismatch.  See the comments in the dslib.c source file for
       more information.

       In the SGI Linux XSCSI infrastructure, devices can be open
       via  both  the ds and other high level drivers at the same
       time, Only one program can have any ds device  open  at  a
       time, however.


FILES

       /dev/xscsi/pci*/target*/lun*/ds


SEE ALSO

       ds(8), xscsicontrol(8), xscsidisktest(8).


Man(1) output converted with man2html