home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / st.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  36.8 KB  |  1,416 lines

  1. /*
  2.  * Copyright (c) 1990 University of Utah.
  3.  * Copyright (c) 1990 The Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * This code is derived from software contributed to Berkeley by
  7.  * the Systems Programming Group of the University of Utah Computer
  8.  * Science Department.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  *
  38.  * from: Utah $Hdr: st.c 1.8 90/10/14$
  39.  *
  40.  *      @(#)st.c    7.3 (Berkeley) 5/4/91
  41.  */
  42.  
  43. /*
  44.  * SCSI CCS (Command Command Set) tape driver.
  45.  *
  46.  * Specific to Exabyte:
  47.  * mt status: residual="Mbytes to LEOM"
  48.  * minor bit 4 [b1bbbb] (aka /dev/rst16) selects short filemarks
  49.  * minor bit 5 [1bbbbb] (aka /dev/rst32) selects fix block mode, 1k blocks.
  50.  *
  51.  * Archive drive:
  52.  * can read both QIC-24 and QIC-II. But only writes
  53.  * QIC-24.
  54.  * 
  55.  * Supports Archive Viper QIC-150 tape drive, but scsi.c reports selection
  56.  * errors.
  57.  *
  58.  * Supports Archive Python DAT drive, but will sometimes hang machine.
  59.  *
  60.  * Supports HP 35450A DAT drive, but will sometimes hang machine.
  61.  * Partitioning of tape not supported.
  62.  * Vendor unique support has not been added.
  63.  *
  64.  *
  65.  * Supports Archive VIPER (QIC-150).
  66.  * Mostly Supports Archive PYTHON (DAT). 
  67.  *     Hangs if write after spin down. 
  68.  *     Need scsi.c that does connect/disconnect.
  69.  */
  70.  
  71. /*
  72.  * support for the block device not implemented 
  73.  */
  74.  
  75. #include "st.h"
  76. #if NST > 0
  77.  
  78. #include "param.h"
  79. #include "systm.h"
  80. #include "buf.h"
  81. #include "scsireg.h"
  82. #include "file.h"
  83. #include "tty.h"
  84. #include "proc.h"
  85. #include "mtio.h"
  86. #include "ioctl.h"
  87. #include "kernel.h"
  88. #include "tprintf.h"
  89.  
  90. #include "device.h"
  91. #include "stvar.h"
  92.  
  93. #define ADD_DELAY
  94.  
  95. extern int scsi_test_unit_rdy();
  96. extern int scsi_request_sense();
  97. extern int scsiustart();
  98. extern int scsigo();
  99. extern void scsifree();
  100. extern void scsireset();
  101. extern void scsi_delay();
  102. extern int scsi_tt_oddio();
  103.  
  104. extern int scsi_immed_command();
  105.  
  106. int    stinit(), ststart(), stgo(), stintr();
  107. struct    driver stdriver = {
  108.     stinit, "st", ststart, stgo, stintr,
  109. };
  110.  
  111. struct    st_softc {
  112.     struct    hp_device *sc_hd;
  113.     struct    devqueue sc_dq;
  114.     long    sc_blkno;       /* (possible block device support?) */
  115.     long    sc_resid;    /* (possible block device support?) */
  116.     int    sc_flags;
  117.     int    sc_blklen;    /* 0 = variable len records */
  118.     int    sc_filepos;    /* file position on tape */
  119.     long    sc_numblks;    /* number of blocks on tape */
  120.     short    sc_type;    /* ansi scsi type */
  121.     short    sc_punit;    /* physical unit (scsi lun) */
  122.     short    sc_tapeid;    /* tape drive id */
  123.     char    sc_datalen[32];    /* additional data length on some commands */
  124.     short    sc_tticntdwn;    /* interrupts between TTi display updates */
  125.     tpr_t    sc_ctty;
  126.     struct    buf *sc_bp;
  127.     u_char    sc_cmd;
  128. } st_softc[NST];
  129.  
  130. /* softc flags */
  131. #define STF_ALIVE    0x0001
  132. #define STF_OPEN    0x0002
  133. #define STF_WMODE    0x0004
  134. #define STF_WRTTN    0x0008
  135. #define STF_CMD        0x0010
  136. #define STF_LEOT    0x0020
  137. #define STF_MOVED    0x0040
  138.  
  139. struct    st_mode st_mode[NST];
  140.  
  141. /*
  142.  * Maybe this should not be global, but gives chance to get
  143.  * tape remaining, Rewrites/ECC, etc outside the driver 
  144.  */
  145. static struct st_xsense {
  146.     struct    scsi_xsense sc_xsense;    /* data from sense */
  147.     struct    exb_xsense exb_xsense;    /* additional info from exabyte */
  148. } st_xsense[NST];
  149.  
  150. static struct scsi_fmt_cdb stcmd[NST];
  151.  
  152. static struct scsi_fmt_cdb st_read_cmd = { 6, CMD_READ };
  153. static struct scsi_fmt_cdb st_write_cmd = { 6, CMD_WRITE };
  154.  
  155. struct buf sttab[NST];
  156. struct buf stbuf[NST];
  157.  
  158. #define UNIT(x)        (minor(x) & 3)
  159. #define stpunit(x)    ((x) & 7)
  160.  
  161. #define STDEV_NOREWIND    0x04
  162. #define STDEV_HIDENSITY    0x08
  163. #define STDEV_EXSFMK    0x10
  164. #define STDEV_FIXEDBLK    0x20
  165.  
  166. #ifdef DEBUG
  167. int st_debug = 0x0000;
  168. #define ST_OPEN        0x0001
  169. #define ST_GO        0x0002
  170. #define ST_FMKS        0x0004
  171. #define ST_OPENSTAT    0x0008
  172. #define ST_BRESID    0x0010
  173. #define ST_ODDIO    0x0020
  174. #endif
  175.  
  176. /*
  177.  * Patchable variable.  If an even length read is requested a dma transfer is
  178.  * used.  Only after the read will we find out if the read had an odd number
  179.  * of bytes.  The HP98658 hardware cannot do odd length transfers, the last
  180.  * byte of the data will always be 0x00.  Normally, the driver will complain
  181.  * about such transfers and return EIO.  However, if st_dmaoddretry is non-
  182.  * zero, the driver will try and issue a BSR and then re-read the data using
  183.  * 'programmed transfer mode'.  In most cases this works, however for unknown
  184.  * reasons it will hang the machine in certain cases.
  185.  *
  186.  * Note:
  187.  * Odd length read requests are always done using programmed transfer mode.
  188.  */
  189. int st_dmaoddretry = 0;
  190.  
  191. /*
  192.  * Exabyte only:
  193.  * From adb can have access to fixed vs. variable length modes.
  194.  * Use 0x400 for 1k (best capacity) fixed length records.
  195.  * In st_open, if minor bit 4 set then 1k records are used.
  196.  * If st_exblken is set to anything other then 0 we are in fixed length mode.
  197.  * Minor bit 4 overrides any setting of st_exblklen.
  198.  * 
  199.  */
  200. int st_exblklen = 0;
  201.  
  202. /* exabyte here for adb access, set at open time */
  203. #define EX_CT     0x80        /* international cart - more space W/P6  */
  204. #define EX_ND    0x20        /* no disconnect  */
  205. #define EX_NBE    0x08        /* no busy enable  */
  206. #define EX_EBD    0x04        /* even byte disconnect  */
  207. #define EX_PE    0x02        /* parity enable  */
  208. #define EX_NAL    0x01        /* no auto load  */
  209. int st_exvup = (EX_CT|EX_ND|EX_NBE); /* vendor unique parameters */
  210.  
  211. /*
  212.  * motion and reconnect thresholds guidelines:
  213.  * write operation; lower motion threshold for faster transfer
  214.  *                  raise reconnect threshold for slower transfer
  215.  * read operation; lower motion threshold for slower transfer
  216.  *                 raise reconnect threshold for faster transfer
  217.  */
  218. int st_exmotthr = 0x80;        /* motion threshold, 0x80 default */
  219. int st_exreconthr = 0xa0;    /* reconnect threshold, 0xa0 default */
  220. int st_exgapthr = 7;        /* gap threshold, 7 default */
  221. #ifdef TTI
  222. int st_extti = 0x01;        /* bitmask of unit numbers, do extra */
  223.                 /* sensing so TTi display gets updated */
  224. #endif
  225.  
  226. stinit(hd)
  227.     register struct hp_device *hd;
  228. {
  229.     register struct st_softc *sc = &st_softc[hd->hp_unit];
  230.  
  231.     sc->sc_hd = hd;
  232.     sc->sc_punit = stpunit(hd->hp_flags);
  233.     sc->sc_type = stident(sc, hd);
  234.     if (sc->sc_type < 0)
  235.         return(0);
  236.     sc->sc_dq.dq_ctlr = hd->hp_ctlr;
  237.     sc->sc_dq.dq_unit = hd->hp_unit;
  238.     sc->sc_dq.dq_slave = hd->hp_slave;
  239.     sc->sc_dq.dq_driver = &stdriver;
  240.     sc->sc_blkno = 0;
  241.     sc->sc_flags = STF_ALIVE;
  242.     return(1);
  243. }
  244.  
  245. stident(sc, hd)
  246.     register struct st_softc *sc;
  247.     register struct hp_device *hd;
  248. {
  249.     int unit;
  250.     int ctlr, slave;
  251.     int i, stat, inqlen;
  252.     char idstr[32];
  253. #ifdef ADD_DELAY
  254.     static int havest = 0;
  255. #endif
  256.     struct st_inquiry {
  257.         struct    scsi_inquiry inqbuf;
  258.         struct  exb_inquiry exb_inquiry;
  259.     } st_inqbuf;
  260.     static struct scsi_fmt_cdb st_inq = {
  261.         6,
  262.         CMD_INQUIRY, 0, 0, 0, sizeof(st_inqbuf), 0
  263.     };
  264.  
  265.     ctlr = hd->hp_ctlr;
  266.     slave = hd->hp_slave;
  267.     unit = sc->sc_punit;
  268.     scsi_delay(-1);
  269.  
  270.     inqlen = 0x05; /* min */
  271.     st_inq.cdb[4] = 0x05;
  272.     stat = scsi_immed_command(ctlr, slave, unit, &st_inq, 
  273.                   (u_char *)&st_inqbuf, inqlen, B_READ);
  274.     /* do twice as first command on some scsi tapes always fails */
  275.     stat = scsi_immed_command(ctlr, slave, unit, &st_inq, 
  276.                   (u_char *)&st_inqbuf, inqlen, B_READ);
  277.     if (stat == -1)
  278.         goto failed;
  279.  
  280.     if (st_inqbuf.inqbuf.type != 0x01 ||  /* sequential access device */
  281.         st_inqbuf.inqbuf.qual != 0x80 ||  /* removable media */
  282.         (st_inqbuf.inqbuf.version != 0x01 && /* current ANSI SCSI spec */
  283.          st_inqbuf.inqbuf.version != 0x02))  /* 0x02 is for HP DAT */
  284.         goto failed;
  285.  
  286.     /* now get additonal info */
  287.     inqlen = 0x05 + st_inqbuf.inqbuf.len;
  288.     st_inq.cdb[4] = inqlen;
  289.     bzero(&st_inqbuf, sizeof(st_inqbuf));
  290.     stat = scsi_immed_command(ctlr, slave, unit, &st_inq, 
  291.                   (u_char *)&st_inqbuf, inqlen, B_READ);
  292.  
  293.     if (st_inqbuf.inqbuf.len >= 28) {
  294.         bcopy((caddr_t)&st_inqbuf.inqbuf.vendor_id, (caddr_t)idstr, 28);
  295.         for (i = 27; i > 23; --i)
  296.             if (idstr[i] != ' ')
  297.                 break;
  298.         idstr[i+1] = 0;
  299.         for (i = 23; i > 7; --i)
  300.             if (idstr[i] != ' ')
  301.                 break;
  302.         idstr[i+1] = 0;
  303.         for (i = 7; i >= 0; --i)
  304.             if (idstr[i] != ' ')
  305.                 break;
  306.         idstr[i+1] = 0;
  307.         printf("st%d: %s %s rev %s\n", hd->hp_unit, idstr, &idstr[8],
  308.                &idstr[24]);
  309.     } else if (inqlen == 5)
  310.         /* great it's a stupid device, doesn't know it's know name */
  311.         idstr[0] = idstr[8] = '\0';
  312.     else
  313.         idstr[8] = '\0';
  314.  
  315.     if (stat == 0xff) { 
  316.         printf("st%d: Cant handle this tape drive\n", hd->hp_unit);
  317.         goto failed;
  318.     }
  319.  
  320.     if (bcmp("EXB-8200", &idstr[8], 8) == 0) {
  321.         sc->sc_tapeid = MT_ISEXABYTE;
  322.         sc->sc_datalen[CMD_REQUEST_SENSE] = 26;
  323.         sc->sc_datalen[CMD_INQUIRY] = 52;
  324.         sc->sc_datalen[CMD_MODE_SELECT] = 17;
  325.         sc->sc_datalen[CMD_MODE_SENSE] = 17;
  326.     } else if (bcmp("VIPER 150", &idstr[8], 9) == 0) {
  327.         sc->sc_tapeid = MT_ISVIPER1;
  328.         sc->sc_datalen[CMD_REQUEST_SENSE] = 14;
  329.         sc->sc_datalen[CMD_INQUIRY] = 36;
  330.         sc->sc_datalen[CMD_MODE_SELECT] = 12;
  331.         sc->sc_datalen[CMD_MODE_SENSE] = 12;
  332.     } else if (bcmp("Python 25501", &idstr[8], 12) == 0) {
  333.         sc->sc_tapeid = MT_ISPYTHON;
  334.         sc->sc_datalen[CMD_REQUEST_SENSE] = 14;
  335.         sc->sc_datalen[CMD_INQUIRY] = 36;
  336.         sc->sc_datalen[CMD_MODE_SELECT] = 12;
  337.         sc->sc_datalen[CMD_MODE_SENSE] = 12;
  338.     } else if (bcmp("HP35450A", &idstr[8], 8) == 0) {
  339.         /* XXX "extra" stat makes the HP drive happy at boot time */
  340.         stat = scsi_test_unit_rdy(ctlr, slave, unit);
  341.         sc->sc_tapeid = MT_ISHPDAT;
  342.         sc->sc_datalen[CMD_REQUEST_SENSE] = 14;
  343.         sc->sc_datalen[CMD_INQUIRY] = 36;
  344.         sc->sc_datalen[CMD_MODE_SELECT] = 12;
  345.         sc->sc_datalen[CMD_MODE_SENSE] = 12;
  346.     } else {
  347.         if (idstr[8] == '\0')
  348.             printf("st%d: No ID, assuming Archive\n", hd->hp_unit);
  349.         else
  350.             printf("st%d: Unsupported tape device\n", hd->hp_unit);
  351.         sc->sc_tapeid = MT_ISAR;
  352.         sc->sc_datalen[CMD_REQUEST_SENSE] = 8;
  353.         sc->sc_datalen[CMD_INQUIRY] = 5;
  354.         sc->sc_datalen[CMD_MODE_SELECT] = 12;
  355.         sc->sc_datalen[CMD_MODE_SENSE] = 12;
  356.     }
  357.  
  358.     sc->sc_filepos = 0;
  359.     
  360.     /* load xsense */
  361.     stxsense(ctlr, slave, unit, sc);
  362.  
  363.     scsi_delay(0);
  364. #ifdef ADD_DELAY
  365.     /* XXX if we have a tape, we must up the delays in the HA driver */
  366.     if (!havest) {
  367.         havest = 1;
  368.         scsi_delay(20000);
  369.     }
  370. #endif
  371.     return(st_inqbuf.inqbuf.type);
  372. failed:
  373.     scsi_delay(0);
  374.     return(-1);
  375. }
  376.  
  377. stopen(dev, flag, type, p)
  378.     dev_t dev;
  379.     int flag, type;
  380.     struct proc *p;
  381. {
  382.     register struct st_softc *sc = &st_softc[UNIT(dev)];
  383.     register struct st_xsense *xsense;
  384.     register int count;
  385.     register int stat;
  386.     int ctlr, slave, unit;
  387.     struct mode_select_data msd;
  388.     struct mode_sense mode;
  389.     int modlen;
  390.     static struct scsi_fmt_cdb modsel = {
  391.         6,
  392.         CMD_MODE_SELECT, 0, 0, 0, sizeof(msd), 0
  393.     };
  394.     static struct scsi_fmt_cdb unitready = {
  395.         6,
  396.         CMD_TEST_UNIT_READY, 0, 0, 0, 0, 0
  397.     };
  398.     static struct scsi_fmt_cdb modsense = {
  399.         6,
  400.         CMD_MODE_SENSE, 0, 0, 0, sizeof(mode), 0
  401.     };
  402.  
  403.     ctlr = sc->sc_dq.dq_ctlr;
  404.     slave = sc->sc_dq.dq_slave;
  405.     unit = sc->sc_punit;
  406.     xsense = &st_xsense[UNIT(dev)];
  407.  
  408.     if (UNIT(dev) > NST || (sc->sc_flags & STF_ALIVE) == 0)
  409.         return(ENXIO);
  410.     if (sc->sc_flags & STF_OPEN)
  411.         return(EBUSY);
  412.  
  413.     /* do a mode sense to get current */
  414.     modlen = sc->sc_datalen[CMD_MODE_SENSE];
  415.     modsense.cdb[4] = modlen;
  416.     stat = scsi_immed_command(ctlr, slave, unit, &modsense,
  417.                   (u_char *)&mode, modlen, B_READ);
  418.  
  419.     /* do a mode sense to get current */
  420.     modlen = sc->sc_datalen[CMD_MODE_SENSE];
  421.     modsense.cdb[4] = modlen;
  422.     stat = scsi_immed_command(ctlr, slave, unit, &modsense,
  423.                   (u_char *)&mode, modlen, B_READ);
  424.  
  425.     /* set record length */
  426.     switch (sc->sc_tapeid) {
  427.     case MT_ISAR:
  428.         sc->sc_blklen = 512;
  429.         break;
  430.     case MT_ISEXABYTE:
  431.         if (minor(dev) & STDEV_FIXEDBLK)
  432.             sc->sc_blklen = 0x400;
  433.         else
  434.             sc->sc_blklen = st_exblklen;
  435.         break;
  436.     case MT_ISHPDAT:
  437.         sc->sc_blklen = 512;
  438.         break;
  439.     case MT_ISVIPER1:
  440.         sc->sc_blklen = 512;
  441.         break;
  442.     case MT_ISPYTHON:
  443.         sc->sc_blklen = 512;
  444.         break;
  445.     default:
  446.         if ((mode.md.blklen2 << 16 |
  447.              mode.md.blklen1 << 8 |
  448.              mode.md.blklen0) != 0)
  449.             sc->sc_blklen = mode.md.blklen2 << 16 |
  450.                     mode.md.blklen1 << 8 |
  451.                     mode.md.blklen0;
  452.         else
  453.             sc->sc_blklen = 512;
  454.     }
  455.  
  456.     /* setup for mode select */
  457.     msd.rsvd1 = 0;
  458.     msd.rsvd2 = 0;
  459.     msd.rsvd3 = 0;
  460.     msd.buff = 1;
  461.     msd.speed = 0;
  462.     msd.blkdeslen = 0x08;
  463.     msd.density = 0;
  464.     msd.blks2 = 0;
  465.     msd.blks1 = 0;
  466.     msd.blks0 = 0;
  467.     msd.rsvd4 = 0;
  468.     msd.blklen2 = (sc->sc_blklen >> 16) & 0xff;
  469.     msd.blklen1 = (sc->sc_blklen >> 8) & 0xff;
  470.     msd.blklen0 = sc->sc_blklen & 0xff;
  471.  
  472.     switch (sc->sc_tapeid) {
  473.     case MT_ISAR:
  474.         if (minor(dev) & STDEV_HIDENSITY)
  475.             msd.density = 0x5;
  476.         else {
  477.             if (flag & FWRITE) {
  478.                 uprintf("Can only write QIC-24\n");
  479.                 return(EIO);
  480.             }
  481.             msd.density = 0x4;
  482.         }
  483.         break;
  484.     case MT_ISEXABYTE:
  485.         if (minor(dev) & STDEV_HIDENSITY)
  486.             uprintf("EXB-8200 density support only\n");
  487.         msd.vupb = (u_char)st_exvup;
  488.         msd.rsvd5 = 0;
  489.         msd.p5 = 0;
  490.         msd.motionthres = (u_char)st_exmotthr;
  491.         msd.reconthres = (u_char)st_exreconthr;
  492.         msd.gapthres = (u_char)st_exgapthr;
  493.         break;
  494.     case MT_ISHPDAT:
  495.     case MT_ISVIPER1:
  496.     case MT_ISPYTHON:
  497.         if (minor(dev) & STDEV_HIDENSITY)
  498.             uprintf("Only one density supported\n");
  499.         break;
  500.     default:
  501.         uprintf("Unsupported drive\n");
  502.         return(EIO);
  503.     }
  504.  
  505.     modlen = sc->sc_datalen[CMD_MODE_SELECT];
  506.     modsel.cdb[4] = modlen;
  507.  
  508.     /* mode select */
  509.     count = 0;
  510. retryselect:
  511.     stat = scsi_immed_command(ctlr, slave, unit, &modsel,
  512.                   (u_char *)&msd, modlen, B_WRITE);
  513.     /*
  514.      * First command after power cycle, bus reset or tape change 
  515.      * will error. Try command again
  516.      */
  517.     if (stat == STS_CHECKCOND) {
  518.         sc->sc_filepos = 0;
  519.         stxsense(ctlr, slave, unit, sc);
  520.         stat = scsi_immed_command(ctlr, slave, unit, &modsel,
  521.                       (u_char *)&msd, modlen, B_WRITE);
  522. #ifdef DEBUG
  523.         if (stat && (st_debug & ST_OPEN))
  524.             printf("stopen: stat on mode select 0x%x second try\n", stat);
  525. #endif
  526.         if (stat == STS_CHECKCOND) {
  527.             stxsense(ctlr, slave, unit, sc);
  528.             prtkey(UNIT(dev), sc);
  529.         }
  530.         if (stat)
  531.             return(EIO);
  532.     }
  533.     if (stat == -1 || stat == STS_BUSY) {
  534.         /*
  535.          * XXX it might just be that the bus is busy because
  536.          * another tape is doing a command. This would change
  537.          * with connect/disconnect, ie. the other drive would
  538.          * not hold onto the bus.
  539.          *
  540.          * Sleep on lbolt for up to 20 minutes (max time to FSF
  541.          * an exabyte to EOT: 16:xx minutes)
  542.          */
  543.         if (++count > 60*20) {
  544.             uprintf("SCSI bus timeout\n");
  545.             return(EBUSY);
  546.         }
  547.         sleep((caddr_t)&lbolt, PZERO+1);
  548.         goto retryselect;
  549.     }
  550.  
  551.     /* drive ready ? */
  552.     stat = scsi_test_unit_rdy(ctlr, slave, unit);
  553.  
  554.     if (stat == STS_CHECKCOND) {
  555.         stxsense(ctlr, slave, unit, sc);
  556.         switch (sc->sc_tapeid) {
  557.         case MT_ISEXABYTE:
  558.             if ((xsense->sc_xsense.key & XSK_NOTRDY) &&
  559.                 xsense->exb_xsense.tnp)
  560.                 uprintf("no cartridge\n");
  561.             else if (xsense->sc_xsense.key & XSK_NOTRDY)
  562.                 uprintf("cartridge not loaded\n");
  563.             else if (xsense->sc_xsense.key & XSK_UNTATTEN) {
  564.                 uprintf("new cart/power interrupt\n");
  565.                 stat = 0;
  566.             } else if ((xsense->sc_xsense.key & XSK_UNTATTEN) &&
  567.                    xsense->exb_xsense.tnp)
  568.                 uprintf("cartridge unloading\n");
  569.             else 
  570.                 prtkey(UNIT(dev), sc);
  571.             break;
  572.         case MT_ISAR:
  573.             if (xsense->sc_xsense.key & XSK_UNTATTEN)
  574.                 stat = scsi_test_unit_rdy(ctlr, slave, unit);
  575.             if (stat == STS_CHECKCOND) {
  576.                 stxsense(ctlr, slave, unit, sc);
  577.                 if (xsense->sc_xsense.key)
  578.                     prtkey(UNIT(dev), sc);
  579.             } else { 
  580.                 sc->sc_filepos = 0; /* new tape */
  581.                 stat = 0;
  582.             }
  583.             break;
  584.         case MT_ISHPDAT:
  585.         case MT_ISVIPER1:
  586.         case MT_ISPYTHON:
  587.             if (xsense->sc_xsense.key & XSK_UNTATTEN)
  588.                 stat = scsi_test_unit_rdy(ctlr, slave, unit);
  589.             if (stat == STS_CHECKCOND) {
  590.                 stxsense(ctlr, slave, unit, sc);
  591.                 if (xsense->sc_xsense.key)
  592.                     prtkey(UNIT(dev), sc);
  593.             }
  594.             break;
  595.         default:
  596.             uprintf("st%d: not ready\n", UNIT(dev));
  597.             prtkey(UNIT(dev), sc);
  598.             break;
  599.         }
  600.     }
  601.     if (stat)
  602.         return(EIO);
  603.  
  604.     /* mode sense */
  605.     modlen = sc->sc_datalen[CMD_MODE_SENSE];
  606.     modsense.cdb[4] = modlen;
  607.     stat = scsi_immed_command(ctlr, slave, unit, &modsense,
  608.                   (u_char *)&mode, modlen, B_READ);
  609. #ifdef DEBUG
  610.     if (st_debug & ST_OPENSTAT)
  611.         prtmodstat(&mode);
  612. #endif
  613.  
  614.     if (stat == STS_CHECKCOND) {
  615.         stxsense(ctlr, slave, unit, sc);
  616. #ifdef DEBUG
  617.         if (st_debug & ST_OPEN)
  618.             dumpxsense(xsense);
  619. #endif
  620.     }
  621.     if (stat)
  622.         return(EIO);
  623.  
  624.     if ((flag & FWRITE) && mode.md.wp) {
  625.         uprintf("st:%d write protected\n", UNIT(dev));
  626.         return(EACCES);
  627.     }
  628.  
  629.     sc->sc_ctty = tprintf_open(p);
  630.     /* save total number of blocks on tape */
  631.     sc->sc_numblks = mode.md.numblk2 << 16 |
  632.              mode.md.numblk1 << 8 |
  633.              mode.md.numblk0;
  634.  
  635.     if (xsense->sc_xsense.eom && !(sc->sc_flags & STF_LEOT))
  636.         sc->sc_filepos = 0;
  637. #ifdef DEBUG
  638.     if (st_debug & ST_FMKS)
  639.         printf("st%d: open filepos = %d\n", UNIT(dev), sc->sc_filepos);
  640. #endif
  641.  
  642.     sc->sc_flags |= (STF_OPEN);
  643.     if (flag & FWRITE)
  644.         sc->sc_flags |= STF_WMODE;
  645.     sc->sc_flags &= ~STF_MOVED;
  646.  
  647. #ifdef TTI
  648.     /* make stats available, also lit up TTi display */
  649.     sc->sc_tticntdwn = 100;
  650. #endif
  651.     stxsense(ctlr, slave, unit, sc);
  652.  
  653.     return(0);
  654. }
  655.  
  656. /*ARGSUSED*/
  657. stclose(dev, flag)
  658.     dev_t dev;
  659.     int flag;
  660. {
  661.     register struct st_softc *sc = &st_softc[UNIT(dev)];
  662.     register int hit = 0;
  663.  
  664.     if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) {
  665.         /*
  666.          * XXX driver only supports cartridge tapes.
  667.          * Cartridge tapes don't do double EOFs on EOT.
  668.          */
  669.         stcommand(dev, MTWEOF, 1); 
  670.         hit++;
  671.     }
  672.     if ((minor(dev) & STDEV_NOREWIND) == 0) {
  673.         stcommand(dev, MTREW, 1);
  674.         hit++;
  675.     }
  676. #ifdef NOTDEF
  677.     /* wait until more stable before trying [XXX Needed ?] */
  678.     if (!hit && (sc->sc_flags & SFT_WMODE))
  679.         /* force out any any bufferd write data */
  680.         stcommand(dev, MTFSR, 0); 
  681. #endif
  682.     /* make stats available */
  683.     stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, sc->sc_punit, sc);
  684.  
  685.     sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN);
  686.     tprintf_close(sc->sc_ctty);
  687.     return(0);    /* XXX */
  688. }
  689.  
  690. ststrategy(bp)
  691.     register struct buf *bp;
  692. {
  693.     struct buf *dp;
  694.     int unit, s;
  695.  
  696.     unit = UNIT(bp->b_dev);
  697.     dp = &sttab[unit];
  698.     bp->av_forw = NULL;
  699.     s = splbio();
  700.     if (dp->b_actf == NULL)
  701.         dp->b_actf = bp;
  702.     else
  703.         dp->b_actl->av_forw = bp;
  704.     dp->b_actl = bp;
  705.     if (dp->b_active == 0) {
  706.         dp->b_active = 1;
  707.         stustart(unit);
  708.     }
  709.     splx(s);
  710. }
  711.  
  712. stustart(unit)
  713.     int unit;
  714. {
  715.     if (scsireq(&st_softc[unit].sc_dq))
  716.         ststart(unit);
  717. }
  718.  
  719. ststart(unit)
  720.     int unit;
  721. {
  722.     struct hp_device *hp = st_softc[unit].sc_hd;
  723.  
  724.     if (scsiustart(hp->hp_ctlr))
  725.         stgo(unit);
  726. }
  727.  
  728. stgo(unit)
  729.     int unit;
  730. {
  731.     register struct st_softc *sc = &st_softc[unit];
  732.     register struct scsi_fmt_cdb *cmd;
  733.     register struct buf *bp = sttab[unit].b_actf;
  734.     struct hp_device *hp = sc->sc_hd;
  735.     int pad, stat;
  736.     long nblks;
  737.  
  738.     if (sc->sc_flags & STF_CMD) {
  739.         cmd = &stcmd[unit];
  740.         pad = 0;
  741.     } else {
  742.         cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd;
  743.         if (sc->sc_blklen)
  744.             cmd->cdb[1] |= 0x01; /* fixed mode */
  745.         else
  746.             cmd->cdb[1] &= 0xfe;
  747.         if (bp->b_flags & B_READ)
  748.             sc->sc_flags &= ~STF_WRTTN;
  749.         else
  750.             sc->sc_flags |= STF_WRTTN;
  751.  
  752.         if (sc->sc_blklen) { /* fixed mode */
  753.             nblks = bp->b_bcount / sc->sc_blklen;
  754.             if (bp->b_bcount % sc->sc_blklen) {
  755.                 tprintf(sc->sc_ctty,
  756.                     "st%d: I/O not block aligned %d/%ld\n",
  757.                     unit, sc->sc_blklen, bp->b_bcount);
  758.                 cmd->cdb[1] &= 0xfe; /* force error */
  759.             }
  760.         } else    /* variable len */
  761.             nblks = bp->b_bcount;
  762.  
  763.         *(u_char *)(&cmd->cdb[2]) = (u_char) (nblks >> 16);
  764.         *(u_char *)(&cmd->cdb[3]) = (u_char) (nblks >> 8);
  765.         *(u_char *)(&cmd->cdb[4]) = (u_char) nblks;
  766.         /*
  767.          * Always Zero. We are either writing in variable
  768.          * length mode we are writing in fixed block mode,
  769.          * or we are going to do odd length IO and are not
  770.          * going to use DMA.
  771.          */
  772.         pad = 0; 
  773.     }
  774.  
  775. #ifdef DEBUG
  776.     if (st_debug & ST_GO)
  777.         printf("stgo: cmd len %d [0]0x%x [1]0x%x [2]0x%x [3]0x%x [4]0x%x [5]0x%x\n",
  778.                cmd->len, cmd->cdb[0], cmd->cdb[1], cmd->cdb[2],
  779.                cmd->cdb[3], cmd->cdb[4], cmd->cdb[5]);
  780. #endif
  781.  
  782.     sc->sc_flags |= STF_MOVED;
  783.     if (bp->b_bcount & 1) {
  784. #ifdef DEBUG
  785.         if (st_debug & ST_ODDIO)
  786.             printf("stgo%d: odd count %d using manual transfer\n",
  787.                    unit, bp->b_bcount);
  788. #endif
  789.         stat = scsi_tt_oddio(hp->hp_ctlr, hp->hp_slave, sc->sc_punit,
  790.                      bp->b_un.b_addr, bp->b_bcount,
  791.                      bp->b_flags, 1);
  792.         if (stat == 0) {
  793.             bp->b_resid = 0;
  794.             stfinish(unit, sc, bp);
  795.         }
  796.     } else
  797.         stat = scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit,
  798.                   bp, cmd, pad);
  799.     if (stat) {
  800.         bp->b_error = EIO;
  801.         bp->b_flags |= B_ERROR;
  802.         stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, 
  803.              sc->sc_punit, sc);
  804.         sterror(unit, sc, stat);
  805.         stfinish(unit, sc, bp);
  806.     }
  807. }
  808.  
  809. stfinish(unit, sc, bp)
  810.     int unit;
  811.     struct st_softc *sc;
  812.     struct buf *bp;
  813. {
  814.     sttab[unit].b_errcnt = 0;
  815.     sttab[unit].b_actf = bp->b_actf;
  816.     iodone(bp);
  817.     scsifree(&sc->sc_dq);
  818.     if (sttab[unit].b_actf)
  819.         stustart(unit);
  820.     else
  821.         sttab[unit].b_active = 0;
  822. }
  823.  
  824. stread(dev, uio)
  825.     dev_t dev;
  826.     struct uio *uio;
  827. {
  828.     int unit = UNIT(dev);
  829.  
  830.     return(physio(ststrategy, &stbuf[unit], dev, B_READ, minphys, uio));
  831. }
  832.  
  833. stwrite(dev, uio)
  834.     dev_t dev;
  835.     struct uio *uio;
  836. {
  837.     int unit = UNIT(dev);
  838.  
  839.     return(physio(ststrategy, &stbuf[unit], dev, B_WRITE, minphys, uio));
  840. }
  841.  
  842. /*ARGSUSED*/
  843. stdump(dev)
  844.     dev_t dev;
  845. {
  846.     return(ENXIO);
  847. }
  848.  
  849. /*ARGSUSED*/
  850. stioctl(dev, cmd, data, flag)
  851.     dev_t dev;
  852.     int cmd;
  853.     caddr_t data; 
  854.     int flag;
  855. {
  856.     register struct st_softc *sc = &st_softc[UNIT(dev)];
  857.     register int cnt;
  858.     register struct mtget *mtget;
  859.     register struct st_xsense *xp = &st_xsense[UNIT(dev)];
  860.     register struct mtop *op;
  861.     long resid;
  862.  
  863.     switch (cmd) {
  864.  
  865.     /* tape operation */
  866.     case MTIOCTOP:
  867.         op = (struct mtop *)data;
  868.         switch (op->mt_op) {
  869.  
  870.         case MTBSR:
  871.         case MTFSR:
  872.             if (sc->sc_tapeid == MT_ISAR)
  873.                 return(ENXIO);
  874.         case MTWEOF:
  875.         case MTFSF:
  876.         case MTBSF:
  877.             cnt = (int)op->mt_count;
  878.             break;
  879.  
  880.         case MTREW:
  881.         case MTOFFL:
  882.             cnt = 1;
  883.             break;
  884.  
  885.         case MTNOP:
  886.             return(0);
  887.         default:
  888.             return(EINVAL);
  889.         }
  890.         if (cnt <= 0)
  891.             return(EINVAL);
  892.         stcommand(dev, (u_int)op->mt_op, cnt);
  893.         break;
  894.  
  895.     /* drive status */
  896.     case MTIOCGET:
  897.         mtget = (struct mtget *)data;
  898.         stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, 
  899.              sc->sc_punit, sc);
  900.         mtget->mt_type = sc->sc_tapeid;
  901.         mtget->mt_dsreg = 0;
  902.         mtget->mt_erreg = ((xp->sc_xsense.valid << 15) |
  903.                    (xp->sc_xsense.filemark << 14) |
  904.                    (xp->sc_xsense.eom << 13) |
  905.                    (xp->sc_xsense.ili << 12) |
  906.                    (xp->sc_xsense.key << 8));
  907.         
  908.         if (sc->sc_tapeid == MT_ISEXABYTE) {
  909.             mtget->mt_dsreg = sc->sc_flags;
  910.             resid = (xp->exb_xsense.tplft2 << 16 |
  911.                  xp->exb_xsense.tplft1 << 8 |
  912.                  xp->exb_xsense.tplft0);
  913.             mtget->mt_resid = resid / 1000;
  914.             mtget->mt_erreg |= (((xp->exb_xsense.rwerrcnt2 << 16 |
  915.                           xp->exb_xsense.rwerrcnt1 << 8 |
  916.                           xp->exb_xsense.rwerrcnt0) * 100) / 
  917.                         (sc->sc_numblks - resid)) & 0xff;
  918.         } else if (xp->sc_xsense.valid) {
  919.             resid = ((xp->sc_xsense.info1 << 24) |
  920.                  (xp->sc_xsense.info2 << 16) |
  921.                  (xp->sc_xsense.info3 << 8) |
  922.                  (xp->sc_xsense.info4));
  923.             if (sc->sc_blklen) /* if fixed mode */
  924.                 resid *= sc->sc_blklen;
  925.             mtget->mt_resid = resid;
  926.         } else
  927.             mtget->mt_resid = 0;
  928.         break;
  929.  
  930.     default:
  931.         return(ENXIO);
  932.     }
  933.     return(0);
  934. }
  935.  
  936. stintr(unit, stat)
  937.     int unit, stat;
  938. {
  939.     register struct st_softc *sc = &st_softc[unit];
  940.     register struct st_xsense *xp = &st_xsense[unit];
  941.     register struct buf *bp = sttab[unit].b_actf;
  942.     struct hp_device *hp = sc->sc_hd;
  943.  
  944. #ifdef DEBUG
  945.     if (bp == NULL) {
  946.         printf("st%d: bp == NULL\n", unit);
  947.         return;
  948.     }
  949. #endif
  950.     switch (stat) {
  951.     /* scsi command completed ok */
  952.     case 0:
  953.         bp->b_resid = 0;
  954.         break;
  955.  
  956.     /* more status */
  957.     case STS_CHECKCOND:
  958.         stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, 
  959.              sc->sc_punit, sc);
  960.         if (xp->sc_xsense.valid) {
  961.             bp->b_resid = (u_long)((xp->sc_xsense.info1 << 24) |
  962.                           (xp->sc_xsense.info2 << 16) |
  963.                           (xp->sc_xsense.info3 << 8) |
  964.                           (xp->sc_xsense.info4));
  965.             if (sc->sc_blklen) /* fixed mode */
  966.                 bp->b_resid *= sc->sc_blklen;
  967.         }
  968.         if (xp->sc_xsense.filemark) {
  969.             sc->sc_filepos++;
  970.             break;
  971.         }
  972.         if (xp->sc_xsense.key) {
  973.             sterror(unit, sc, stat);
  974.             bp->b_flags |= B_ERROR;
  975.             bp->b_error = EIO;
  976.             break;
  977.         }
  978.         if (xp->sc_xsense.ili) {
  979.             /*
  980.              * Fixed length blocks, an error.
  981.              */
  982.             if (sc->sc_blklen) {
  983.                 tprintf(sc->sc_ctty,
  984.                     "st%d: Incorrect Length Indicator, blkcnt diff %d\n",
  985.                     unit, sc->sc_blklen - bp->b_resid);
  986.                 bp->b_flags |= B_ERROR;
  987.                 bp->b_error = EIO;
  988.                 break;
  989.             }
  990.             /*
  991.              * Variable length but read more than requested,
  992.              * an error.
  993.              */
  994.             if (bp->b_resid < 0) {
  995.                 bp->b_resid = 0;
  996.                 bp->b_flags |= B_ERROR;
  997.                 bp->b_error = ENOMEM;
  998.                 break;
  999.             }
  1000.             /*
  1001.              * Variable length and odd, may require special
  1002.              * handling.
  1003.              */
  1004.             if (bp->b_resid & 1 && sc->sc_tapeid != MT_ISAR) {
  1005.                 /*
  1006.                  * Normal behavior, treat as an error.
  1007.                  */
  1008.                 if (!st_dmaoddretry) {
  1009.                     tprintf(sc->sc_ctty,
  1010.                         "st%d: Odd length read %d\n", 
  1011.                         UNIT(bp->b_dev),
  1012.                         bp->b_bcount - bp->b_resid);
  1013.                     bp->b_error = EIO;
  1014.                     bp->b_flags |= B_ERROR;
  1015.                     break;
  1016.                 }
  1017.                 /*
  1018.                  * Attempt to back up and re-read using oddio.
  1019.                  */
  1020. #ifdef DEBUG
  1021.                 if (st_debug & ST_ODDIO)
  1022.                     printf("st%d: stintr odd count %d, do BSR then oddio\n",
  1023.                            UNIT(bp->b_dev),
  1024.                            bp->b_bcount - bp->b_resid);
  1025. #endif
  1026.                 stat = scsi_tt_oddio(hp->hp_ctlr, hp->hp_slave,
  1027.                              sc->sc_punit, 0, -1, 0, 0);
  1028.                 if (stat == 0)
  1029.                     stat = scsi_tt_oddio(hp->hp_ctlr,
  1030.                                  hp->hp_slave,
  1031.                                  sc->sc_punit,
  1032.                                  bp->b_un.b_addr,
  1033.                                  bp->b_bcount - bp->b_resid,
  1034.                                  bp->b_flags, 0);
  1035.                 if (stat) {
  1036.                     bp->b_error = EIO;
  1037.                     bp->b_flags |= B_ERROR;
  1038.                     stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave,
  1039.                          sc->sc_punit, sc);
  1040.                     sterror(unit, sc, stat);
  1041.                 }
  1042.             }
  1043.             break;
  1044.         }
  1045.         if (xp->sc_xsense.eom) {
  1046.             bp->b_flags |= B_ERROR;
  1047.             bp->b_error = ENOSPC;
  1048.             break;
  1049.         }
  1050.         tprintf(sc->sc_ctty, "st%d: unknown scsi error\n", unit);
  1051.         bp->b_flags |= B_ERROR;
  1052.         bp->b_error = EIO;
  1053.         break;
  1054.  
  1055.     default:
  1056.         printf("st%d: stintr unknown stat 0x%x\n", unit, stat);
  1057.         break;
  1058.     }
  1059. #ifdef DEBUG
  1060.     if ((st_debug & ST_BRESID) && bp->b_resid != 0)
  1061.         printf("b_resid %d b_flags 0x%x b_error 0x%x\n", 
  1062.                bp->b_resid, bp->b_flags, bp->b_error);
  1063. #endif
  1064.     /* asked for more filemarks then on tape */
  1065.     if (bp->b_resid != 0 &&
  1066.         (sc->sc_flags & STF_CMD) && sc->sc_cmd == CMD_SPACE) {
  1067.         sc->sc_filepos -= bp->b_resid;
  1068.         if (sc->sc_filepos < 0)
  1069.             sc->sc_filepos = 0;
  1070.     }
  1071.  
  1072. #ifdef TTI
  1073.     if (st_extti & (1<<unit) &&
  1074.         sc->sc_type == MT_ISEXABYTE) /* to make display lit up */
  1075.         /*
  1076.          * XXX severe performance penality for this.
  1077.          * Try and throttle by not calling stxsense on every intr.
  1078.          * Mostly for TTi we, get a stxsense call in open and close.
  1079.          */
  1080.         if (sc->sc_tticntdwn-- == 0) {
  1081.             stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave,
  1082.                  sc->sc_punit, sc);
  1083.             sc->sc_tticntdwn = 100;
  1084.         }
  1085. #endif
  1086.  
  1087.     stfinish(unit, sc, bp);
  1088. }
  1089.  
  1090. stcommand(dev, command, cnt)
  1091.     dev_t dev;
  1092.     u_int command;
  1093.     int cnt;
  1094. {
  1095.     register struct st_softc *sc = &st_softc[UNIT(dev)];
  1096.     register struct buf *bp = &stbuf[UNIT(dev)];
  1097.     register struct scsi_fmt_cdb *cmd = &stcmd[UNIT(dev)];
  1098.     register cmdcnt;
  1099.     int s;
  1100.  
  1101.     cmd->len = 6; /* all tape commands are cdb6 */
  1102.     cmd->cdb[1] = sc->sc_punit;
  1103.     cmd->cdb[2] = cmd->cdb[3] = cmd->cdb[4] = cmd->cdb[5] = 0;
  1104.     cmdcnt = 0;
  1105.  
  1106.     /*
  1107.      * XXX Assumption is that everything except Archive can take
  1108.      * repeat count in cdb block.
  1109.      */
  1110.     switch (command) {
  1111.     case MTWEOF:
  1112.         cmd->cdb[0] = CMD_WRITE_FILEMARK;
  1113.         if (sc->sc_tapeid != MT_ISAR) {
  1114.             cmdcnt = cnt;
  1115.             cnt = 1;
  1116.         } else
  1117.             cmdcnt = 1;
  1118.         *(u_char *)(&cmd->cdb[2]) = (u_char) (cmdcnt >> 16);
  1119.         *(u_char *)(&cmd->cdb[3]) = (u_char) (cmdcnt >> 8);
  1120.         *(u_char *)(&cmd->cdb[4]) = (u_char) cmdcnt;
  1121.  
  1122.         if (sc->sc_tapeid == MT_ISEXABYTE &&
  1123.             (minor(dev) & STDEV_EXSFMK)) /* short filemarks */
  1124.             cmd->cdb[5] |= 0x80;
  1125.         else
  1126.             cmd->cdb[5] &= 0x7f;
  1127.         break;
  1128.     case MTBSF:
  1129.         /* Archive can't back up, will not get to BSR case */
  1130.         if (sc->sc_tapeid == MT_ISAR) {
  1131.             if ((sc->sc_filepos - cnt) < 0) {
  1132.                 stcommand(dev, MTREW, 1);
  1133.                 return;
  1134.             }
  1135.             cmdcnt = sc->sc_filepos - cnt + 1;
  1136.             stcommand(dev, MTREW, 1);
  1137.             stcommand(dev, MTFSF, cmdcnt);
  1138.             return;
  1139.         }
  1140.     case MTBSR:
  1141.     case MTFSR:
  1142.     case MTFSF:
  1143.         if (command == MTBSF || command == MTBSR)
  1144.             cnt = cnt * (-1); /* backward move */
  1145.         if (command == MTFSF || command == MTBSF)
  1146.             cmd->cdb[1] |= 0x01; /* filemarks */
  1147.         else
  1148.             cmd->cdb[1] |= 0x00; /* logical blocks */
  1149.         if (sc->sc_tapeid != MT_ISAR) {
  1150.             cmdcnt = cnt;
  1151.             cnt = 1;
  1152.         } else
  1153.             cmdcnt = 1;
  1154.         *(u_char *)(&cmd->cdb[2]) = (u_char) (cmdcnt >> 16);
  1155.         *(u_char *)(&cmd->cdb[3]) = (u_char) (cmdcnt >> 8);
  1156.         *(u_char *)(&cmd->cdb[4]) = (u_char) cmdcnt;
  1157.         cmd->cdb[0] = CMD_SPACE;
  1158.         break;
  1159.     case MTREW:
  1160.         cmd->cdb[0] = CMD_REWIND;
  1161.         sc->sc_filepos = 0;
  1162.         break;
  1163.     case MTOFFL:
  1164.         cmd->cdb[0] = CMD_LOADUNLOAD;
  1165.         sc->sc_filepos = 0;
  1166.         break;
  1167.     default:
  1168.         printf("st%d: stcommand bad command 0x%x\n", 
  1169.                UNIT(dev), command);
  1170.     }
  1171.  
  1172.     sc->sc_flags |= STF_CMD;
  1173.     sc->sc_cmd = cmd->cdb[0];
  1174.  
  1175.     sc->sc_bp = bp;
  1176. again:
  1177. #ifdef DEBUG
  1178.     if (st_debug & ST_FMKS)
  1179.         printf("st%d: stcommand filepos %d cmdcnt %d cnt %d\n", 
  1180.                UNIT(dev), sc->sc_filepos, cmdcnt, cnt);
  1181. #endif
  1182.     s = splbio();
  1183.     while (bp->b_flags & B_BUSY) {
  1184.         if (bp->b_flags & B_DONE)
  1185.             break;
  1186.         bp->b_flags |= B_WANTED;
  1187.         sleep((caddr_t)bp, PRIBIO);
  1188.     }
  1189.     bp->b_flags = B_BUSY|B_READ;
  1190.     splx(s);
  1191.     bp->b_dev = dev;
  1192.     bp->b_bcount = 0;
  1193.     bp->b_resid = 0;
  1194.     bp->b_blkno = 0;
  1195.     bp->b_error = 0;
  1196.     ststrategy(bp);
  1197.     iowait(bp);
  1198.     if (bp->b_flags & B_WANTED)
  1199.         wakeup((caddr_t)bp);
  1200.     bp->b_flags &= B_ERROR;
  1201.  
  1202.     if (command == MTWEOF || command == MTFSF || command == MTBSF)
  1203.         sc->sc_filepos += cmdcnt;
  1204.  
  1205.     if (--cnt > 0)
  1206.         goto again;
  1207.  
  1208.     sc->sc_flags |= STF_MOVED;
  1209.     sc->sc_flags &= ~(STF_CMD|STF_WRTTN);
  1210. }
  1211.  
  1212. sterror(unit, sc, stat)
  1213.     int unit, stat;
  1214.     struct st_softc *sc;
  1215. {
  1216.     /* stxsense must have been called before sterror() */
  1217.     if (stat & STS_CHECKCOND)
  1218.         prtkey(unit, sc);
  1219.     else if (stat)
  1220.         tprintf(sc->sc_ctty,
  1221.             "st%d: bad scsi status 0x%x\n", unit, stat);
  1222.  
  1223.     if ((sc->sc_flags & STF_CMD) && sc->sc_cmd == CMD_SPACE) /* fsf */
  1224.         sc->sc_filepos--;
  1225. }
  1226.  
  1227. stxsense(ctlr, slave, unit, sc)
  1228.     int ctlr, slave, unit;
  1229.     struct st_softc *sc;
  1230. {
  1231.     u_char *sensebuf;
  1232.     unsigned len;
  1233.  
  1234.     sensebuf = (u_char *)&st_xsense[sc->sc_dq.dq_unit];
  1235.     len = sc->sc_datalen[CMD_REQUEST_SENSE];
  1236.     scsi_request_sense(ctlr, slave, unit, sensebuf, len);
  1237. }
  1238.  
  1239. prtkey(unit, sc)
  1240.     int unit;
  1241.     struct st_softc *sc;
  1242. {
  1243.     register struct st_xsense *xp = &st_xsense[unit];
  1244.  
  1245.     switch (xp->sc_xsense.key) {
  1246.     case XSK_NOSENCE:
  1247.         break;
  1248.     case XSK_NOTUSED1:
  1249.     case XSK_NOTUSEDC:
  1250.     case XSK_NOTUSEDE:
  1251.         break;
  1252.     case XSK_REVERVED:
  1253.         tprintf(sc->sc_ctty, "st%d: Reserved sense key 0x%x\n",
  1254.             unit, xp->sc_xsense.key);
  1255.         break;
  1256.     case XSK_NOTRDY:
  1257.         tprintf(sc->sc_ctty, "st%d: NOT READY\n", unit);
  1258.         break;
  1259.     case XSK_MEDERR:
  1260.         tprintf(sc->sc_ctty, "st%d: MEDIUM ERROR\n", unit);
  1261.         break;
  1262.     case XSK_HRDWERR:
  1263.         tprintf(sc->sc_ctty, "st%d: HARDWARE ERROR\n", unit);
  1264.         break;
  1265.     case XSK_ILLREQ:
  1266.         tprintf(sc->sc_ctty, "st%d: ILLEGAL REQUEST\n", unit);
  1267.         break;
  1268.     case XSK_UNTATTEN:
  1269.         tprintf(sc->sc_ctty, "st%d: UNIT ATTENTION\n", unit);
  1270.         break;
  1271.     case XSK_DATAPROT:
  1272.         tprintf(sc->sc_ctty, "st%d: DATA PROTECT\n", unit);
  1273.         break;
  1274.     case XSK_BLNKCHK:
  1275.         tprintf(sc->sc_ctty, "st%d: BLANK CHECK\n", unit);
  1276.         break;
  1277.     case XSK_VENDOR:
  1278.         tprintf(sc->sc_ctty, "st%d: VENDER UNIQUE SENSE KEY ", unit);
  1279.         switch (sc->sc_tapeid) {
  1280.         case MT_ISEXABYTE:
  1281.             tprintf(sc->sc_ctty, "Exabyte: ");
  1282.             if (xp->exb_xsense.xfr)
  1283.                 tprintf(sc->sc_ctty,
  1284.                     "Transfer Abort Error\n");
  1285.             if (xp->exb_xsense.tmd)
  1286.                 tprintf(sc->sc_ctty,
  1287.                     "Tape Mark Detect Error\n");
  1288.             break;
  1289.         default:
  1290.             tprintf(sc->sc_ctty, "\n");
  1291.         }
  1292.         break;
  1293.     case XSK_CPYABORT:
  1294.         tprintf(sc->sc_ctty, "st%d: COPY ABORTED\n", unit);
  1295.         break;
  1296.     case XSK_ABORTCMD:
  1297.         tprintf(sc->sc_ctty, "st%d: ABORTED COMMAND\n", unit);
  1298.         break;
  1299.     case XSK_VOLOVER:
  1300.         tprintf(sc->sc_ctty, "st%d: VOLUME OVERFLOW\n", unit);
  1301.         break;
  1302.     default:
  1303.         tprintf(sc->sc_ctty, "st%d: unknown sense key 0x%x\n",
  1304.             unit, xp->sc_xsense.key);
  1305.     }
  1306.     if (sc->sc_tapeid == MT_ISEXABYTE) {
  1307.         if (xp->exb_xsense.bpe)
  1308.             tprintf(sc->sc_ctty, "st%d: Bus Parity Errorn", unit);
  1309.         if (xp->exb_xsense.fpe)
  1310.             tprintf(sc->sc_ctty,
  1311.                 "st%d: Formatted Buffer Parity Errorn", unit);
  1312.         if (xp->exb_xsense.eco)
  1313.             tprintf(sc->sc_ctty, "st%d: Error Counter Overflown",
  1314.                 unit);
  1315.         if (xp->exb_xsense.tme)
  1316.             tprintf(sc->sc_ctty, "st%d: Tape Motion Errorn", unit);
  1317.         if (xp->exb_xsense.xfr)
  1318.             tprintf(sc->sc_ctty, "st%d: Transfer About Errorn",
  1319.                 unit);
  1320.         if (xp->exb_xsense.tmd)
  1321.             tprintf(sc->sc_ctty, "st%d: Tape Mark Detect Errorn",
  1322.                 unit);
  1323.         if (xp->exb_xsense.fmke)
  1324.             tprintf(sc->sc_ctty, "st%d: Filemark Errorn", unit);
  1325.         if (xp->exb_xsense.ure)
  1326.             tprintf(sc->sc_ctty, "st%d: Under Run Errorn", unit);
  1327.         if (xp->exb_xsense.sse)
  1328.             tprintf(sc->sc_ctty, "st%d: Servo System Errorn",
  1329.                 unit);
  1330.         if (xp->exb_xsense.fe)
  1331.             tprintf(sc->sc_ctty, "st%d: Formatter Errorn", unit);
  1332.         if (xp->exb_xsense.wseb)
  1333.             tprintf(sc->sc_ctty, "st%d: WSEB Errorn", unit);
  1334.         if (xp->exb_xsense.wseo)
  1335.             tprintf(sc->sc_ctty, "st%d: WSEO Errorn", unit);
  1336.     }
  1337. }
  1338.  
  1339. #ifdef DEBUG
  1340.  
  1341. dumpxsense(sensebuf)
  1342.     struct st_xsense *sensebuf;
  1343. {
  1344.         struct st_xsense *xp = sensebuf;
  1345.  
  1346.     printf("valid 0x%x errorclass 0x%x errorcode 0x%x\n", 
  1347.            xp->sc_xsense.valid, 
  1348.            xp->sc_xsense.class, xp->sc_xsense.code);
  1349.     printf("seg number 0x%x\n", xp->sc_xsense.segment);
  1350.     printf("FMK 0x%x EOM 0x%x ILI 0x%x RSVD 0x%x sensekey 0x%x\n", 
  1351.            xp->sc_xsense.filemark, xp->sc_xsense.eom, xp->sc_xsense.ili, 
  1352.            xp->sc_xsense.rsvd, xp->sc_xsense.key);
  1353.     printf("info 0x%lx\n", 
  1354.            (u_long)((xp->sc_xsense.info1<<24)|(xp->sc_xsense.info2<<16)|
  1355.             (xp->sc_xsense.info3<<8)|(xp->sc_xsense.info4)) );
  1356.     printf("ASenseL 0x%x\n", xp->sc_xsense.len);
  1357.  
  1358.     if (xp->sc_xsense.len != 0x12) /* MT_ISEXB Exabyte only ?? */
  1359.         return;            /* What about others */
  1360.  
  1361.     printf("ASenseC 0x%x\n", xp->exb_xsense.addsens);
  1362.     printf("AsenseQ 0x%x\n", xp->exb_xsense.addsensq);
  1363.     printf("R/W Errors 0x%lx\n", 
  1364.            (u_long)((xp->exb_xsense.rwerrcnt2<<16)|
  1365.             (xp->exb_xsense.rwerrcnt1<<8)|
  1366.             (xp->exb_xsense.rwerrcnt1)) );
  1367.     printf("PF   0x%x BPE  0x%x FPE 0x%x ME   0x%x ECO 0x%x TME 0x%x TNP 0x%x BOT 0x%x\n",
  1368.            xp->exb_xsense.pf, xp->exb_xsense.bpe, xp->exb_xsense.fpe, 
  1369.            xp->exb_xsense.me, xp->exb_xsense.eco, xp->exb_xsense.tme, 
  1370.            xp->exb_xsense.tnp, xp->exb_xsense.bot);
  1371.     printf("XFR  0x%x TMD  0x%x WP  0x%x FMKE 0x%x URE 0x%x WE1 0x%x SSE 0x%x FE  0x%x\n",
  1372.            xp->exb_xsense.xfr, xp->exb_xsense.tmd, xp->exb_xsense.wp, 
  1373.            xp->exb_xsense.fmke, xp->exb_xsense.ure, xp->exb_xsense.we1, 
  1374.            xp->exb_xsense.sse, xp->exb_xsense.fe);
  1375.     printf("WSEB 0x%x WSEO 0x%x\n",
  1376.            xp->exb_xsense.wseb, xp->exb_xsense.wseo);
  1377.     printf("Remaining Tape 0x%lx\n", 
  1378.            (u_long)((xp->exb_xsense.tplft2<<16)|
  1379.             (xp->exb_xsense.tplft1<<8)|
  1380.             (xp->exb_xsense.tplft0)) );
  1381. }
  1382.  
  1383. prtmodsel(msd, modlen)
  1384.     struct mode_select_data *msd;
  1385.     int modlen;
  1386. {
  1387.     printf("Modsel command. len is 0x%x.\n", modlen);
  1388.     printf("rsvd1 0x%x rsvd2 0x%x rsvd3 0x%x bufferd 0x%x speed 0x%x bckdeslen 0x%x\n",
  1389.            msd->rsvd1,msd->rsvd2,msd->rsvd3,msd->buff,msd->speed,msd->blkdeslen);
  1390.     printf("density 0x%x blks2 0x%x blks1 0x%x blks0 0x%x rsvd 0x%x blklen2 0x%x blklen1 0x%x blklen0 0x%x\n",
  1391.            msd->density,msd->blks2,msd->blks1,msd->blks0,msd->rsvd4,msd->blklen2,msd->blklen1,msd->blklen0);
  1392.     printf("vupb 0x%x rsvd 0x%x p5 0x%x motionthres 0x%x reconthres 0x%x gapthres 0x%x \n",
  1393.            msd->vupb,msd->rsvd5,msd->p5,msd->motionthres,msd->reconthres,msd->gapthres);
  1394. }
  1395.  
  1396. prtmodstat(mode)
  1397.     struct mode_sense *mode;
  1398. {
  1399.     printf("Mode Status\n");
  1400.     printf("sdl 0x%x medtype 0x%x wp 0x%x bfmd 0x%x speed 0x%x bdl 0x%x\n",
  1401.            mode->md.sdl, mode->md.medtype, mode->md.wp, mode->md.bfmd, 
  1402.            mode->md.speed, mode->md.bdl);
  1403.     printf("dencod 0x%x numblk 0x%x blklen 0x%x\n",
  1404.            mode->md.dencod, 
  1405.            (mode->md.numblk2<<16)|(mode->md.numblk1<<8)|(mode->md.numblk0),
  1406.            (mode->md.blklen2<<16)|(mode->md.blklen1<<8)|(mode->md.blklen0) );
  1407.     printf("ct 0x%x nd 0x%x nbe 0x%x edb 0x%x pe 0x%x nal 0x%x p5 0x%x\n",
  1408.            mode->ex.ct, mode->ex.nd, mode->ex.nbe, 
  1409.            mode->ex.ebd, mode->ex.pe, mode->ex.nal, mode->ex.p5);
  1410.     printf("motionthres 0x%x reconthres 0x%x gapthres 0x%x\n",
  1411.            mode->ex.motionthres, mode->ex.reconthres,  mode->ex.gapthres);
  1412. }
  1413. #endif /* DEBUG */
  1414.  
  1415. #endif
  1416.