[BACK]Return to st.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / scsipi

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/dev/scsipi/st.c between version 1.114 and 1.114.2.7

version 1.114, 1999/09/30 22:57:55 version 1.114.2.7, 2001/02/11 19:16:19
Line 72 
Line 72 
 #include <sys/mtio.h>  #include <sys/mtio.h>
 #include <sys/device.h>  #include <sys/device.h>
 #include <sys/conf.h>  #include <sys/conf.h>
   #include <sys/kernel.h>
 #if NRND > 0  #if NRND > 0
 #include <sys/rnd.h>  #include <sys/rnd.h>
 #endif  #endif
Line 101 
Line 102 
 #define ST_CTL_TIME     (30 * 1000)             /* 30 seconds */  #define ST_CTL_TIME     (30 * 1000)             /* 30 seconds */
 #define ST_SPC_TIME     (4 * 60 * 60 * 1000)    /* 4 hours */  #define ST_SPC_TIME     (4 * 60 * 60 * 1000)    /* 4 hours */
   
   #ifndef         ST_MOUNT_DELAY
   #define         ST_MOUNT_DELAY          0
   #endif
   
 /*  /*
  * Define various devices that we know mis-behave in some way,   * Define various devices that we know mis-behave in some way,
  * and note how they are bad, so we can correct for them   * and note how they are bad, so we can correct for them
Line 118  struct quirkdata {
Line 123  struct quirkdata {
 #define ST_Q_IGNORE_LOADS       0x0004  #define ST_Q_IGNORE_LOADS       0x0004
 #define ST_Q_BLKSIZE            0x0008  /* variable-block media_blksize > 0 */  #define ST_Q_BLKSIZE            0x0008  /* variable-block media_blksize > 0 */
 #define ST_Q_UNIMODAL           0x0010  /* unimode drive rejects mode select */  #define ST_Q_UNIMODAL           0x0010  /* unimode drive rejects mode select */
   #define ST_Q_NOPREVENT          0x0020  /* does not support PREVENT */
   #define ST_Q_ERASE_NOIMM        0x0040  /* drive rejects ERASE/w Immed bit */
         u_int page_0_size;          u_int page_0_size;
 #define MAX_PAGE_0_SIZE 64  #define MAX_PAGE_0_SIZE 64
         struct modes modes[4];          struct modes modes[4];
Line 128  struct st_quirk_inquiry_pattern {
Line 135  struct st_quirk_inquiry_pattern {
         struct quirkdata quirkdata;          struct quirkdata quirkdata;
 };  };
   
 struct st_quirk_inquiry_pattern st_quirk_patterns[] = {  const struct st_quirk_inquiry_pattern st_quirk_patterns[] = {
         {{T_SEQUENTIAL, T_REMOV,          {{T_SEQUENTIAL, T_REMOV,
          "        ", "                ", "    "}, {0, 0, {           "        ", "                ", "    "}, {0, 0, {
                 {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 0-3 */                  {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 0-3 */
Line 193  struct st_quirk_inquiry_pattern st_quirk
Line 200  struct st_quirk_inquiry_pattern st_quirk
                 {0, 0, QIC_120}                         /* minor 12-15 */                  {0, 0, QIC_120}                         /* minor 12-15 */
         }}},          }}},
         {{T_SEQUENTIAL, T_REMOV,          {{T_SEQUENTIAL, T_REMOV,
          "ARCHIVE ", "VIPER 150  21247", ""},     {0, 12, {           "ARCHIVE ", "VIPER 150  21247", ""},     {ST_Q_ERASE_NOIMM, 12, {
                 {ST_Q_SENSE_HELP, 0, 0},                /* minor 0-3 */                  {ST_Q_SENSE_HELP, 0, 0},                /* minor 0-3 */
                 {0, 0, QIC_150},                        /* minor 4-7 */                  {0, 0, QIC_150},                        /* minor 4-7 */
                 {0, 0, QIC_120},                        /* minor 8-11 */                  {0, 0, QIC_120},                        /* minor 8-11 */
                 {0, 0, QIC_24}                          /* minor 12-15 */                  {0, 0, QIC_24}                          /* minor 12-15 */
         }}},          }}},
         {{T_SEQUENTIAL, T_REMOV,          {{T_SEQUENTIAL, T_REMOV,
          "ARCHIVE ", "VIPER 150  21531", ""},     {0, 12, {           "ARCHIVE ", "VIPER 150  21531", ""},     {ST_Q_ERASE_NOIMM, 12, {
                 {ST_Q_SENSE_HELP, 0, 0},                /* minor 0-3 */                  {ST_Q_SENSE_HELP, 0, 0},                /* minor 0-3 */
                 {0, 0, QIC_150},                        /* minor 4-7 */                  {0, 0, QIC_150},                        /* minor 4-7 */
                 {0, 0, QIC_120},                        /* minor 8-11 */                  {0, 0, QIC_120},                        /* minor 8-11 */
Line 242  struct st_quirk_inquiry_pattern st_quirk
Line 249  struct st_quirk_inquiry_pattern st_quirk
                 {0, 0, 0}                               /* minor 12-15 */                  {0, 0, 0}                               /* minor 12-15 */
         }}},          }}},
         {{T_SEQUENTIAL, T_REMOV,          {{T_SEQUENTIAL, T_REMOV,
          "STK",      "9490",             ""},           "STK",      "9490",             ""},
                                 {ST_Q_FORCE_BLKSIZE, 0, {                                  {ST_Q_FORCE_BLKSIZE, 0, {
                 {0, 0, 0},                              /* minor 0-3 */                  {0, 0, 0},                              /* minor 0-3 */
                 {0, 0, 0},                              /* minor 4-7 */                  {0, 0, 0},                              /* minor 4-7 */
Line 280  struct st_quirk_inquiry_pattern st_quirk
Line 287  struct st_quirk_inquiry_pattern st_quirk
                 {0, 0, 0}                               /* minor 12-15 */                  {0, 0, 0}                               /* minor 12-15 */
         }}},          }}},
 #endif  #endif
           {{T_SEQUENTIAL, T_REMOV,
            "TEAC    ", "MT-2ST/N50      ", ""},     {ST_Q_IGNORE_LOADS, 0, {
                   {0, 0, 0},                              /* minor 0-3 */
                   {0, 0, 0},                              /* minor 4-7 */
                   {0, 0, 0},                              /* minor 8-11 */
                   {0, 0, 0}                               /* minor 12-15 */
           }}},
           {{T_SEQUENTIAL, T_REMOV,
            "OnStream", "ADR50 Drive", ""},          {ST_Q_UNIMODAL, 0, {
                   {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 0-3 */
                   {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 4-7 */
                   {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 8-11 */
                   {ST_Q_FORCE_BLKSIZE, 512, 0},           /* minor 12-15 */
           }}},
           {{T_SEQUENTIAL, T_REMOV,
            "NCR H621", "0-STD-03-46F880 ", ""},     {ST_Q_NOPREVENT, 0, {
                   {0, 0, 0},                             /* minor 0-3 */
                   {0, 0, 0},                             /* minor 4-7 */
                   {0, 0, 0},                             /* minor 8-11 */
                   {0, 0, 0}                              /* minor 12-15 */
           }}},
 };  };
   
 #define NOEJECT 0  #define NOEJECT 0
Line 296  struct st_softc {
Line 324  struct st_softc {
         u_int last_dsty;        /* last density opened               */          u_int last_dsty;        /* last density opened               */
         short mt_resid;         /* last (short) resid                */          short mt_resid;         /* last (short) resid                */
         short mt_erreg;         /* last error (sense key) seen       */          short mt_erreg;         /* last error (sense key) seen       */
   #define mt_key  mt_erreg
           u_int8_t asc;           /* last asc code seen                */
           u_int8_t ascq;          /* last asc code seen                */
 /*--------------------device/scsi parameters---------------------------------*/  /*--------------------device/scsi parameters---------------------------------*/
         struct scsipi_link *sc_link;    /* our link to the adpter etc.       */          struct scsipi_periph *sc_periph;/* our link to the adpter etc.       */
 /*--------------------parameters reported by the device ---------------------*/  /*--------------------parameters reported by the device ---------------------*/
         int blkmin;             /* min blk size                       */          int blkmin;             /* min blk size                       */
         int blkmax;             /* max blk size                       */          int blkmax;             /* max blk size                       */
Line 320  struct st_softc {
Line 351  struct st_softc {
                                                  * additional sense data needed                                                   * additional sense data needed
                                                  * for mode sense/select.                                                   * for mode sense/select.
                                                  */                                                   */
         struct buf buf_queue;           /* the queue of pending IO */          struct buf_queue buf_queue;     /* the queue of pending IO */
                                         /* operations */                                          /* operations */
 #if NRND > 0  #if NRND > 0
         rndsource_element_t     rnd_source;          rndsource_element_t     rnd_source;
Line 336  void st_loadquirks __P((struct st_softc 
Line 367  void st_loadquirks __P((struct st_softc 
 int     st_mount_tape __P((dev_t, int));  int     st_mount_tape __P((dev_t, int));
 void    st_unmount __P((struct st_softc *, boolean));  void    st_unmount __P((struct st_softc *, boolean));
 int     st_decide_mode __P((struct st_softc *, boolean));  int     st_decide_mode __P((struct st_softc *, boolean));
 void    ststart __P((void *));  void    ststart __P((struct scsipi_periph *));
 void    stdone __P((struct scsipi_xfer *));  void    stdone __P((struct scsipi_xfer *));
 int     st_read __P((struct st_softc *, char *, int, int));  int     st_read __P((struct st_softc *, char *, int, int));
 int     st_read_block_limits __P((struct st_softc *, int));  int     st_read_block_limits __P((struct st_softc *, int));
Line 360  struct cfattach st_ca = {
Line 391  struct cfattach st_ca = {
   
 extern struct cfdriver st_cd;  extern struct cfdriver st_cd;
   
 struct scsipi_device st_switch = {  const struct scsipi_periphsw st_switch = {
         st_interpret_sense,          st_interpret_sense,
         ststart,          ststart,
         NULL,          NULL,
Line 430  stattach(parent, self, aux)
Line 461  stattach(parent, self, aux)
 {  {
         struct st_softc *st = (void *)self;          struct st_softc *st = (void *)self;
         struct scsipibus_attach_args *sa = aux;          struct scsipibus_attach_args *sa = aux;
         struct scsipi_link *sc_link = sa->sa_sc_link;          struct scsipi_periph *periph = sa->sa_periph;
   
         SC_DEBUG(sc_link, SDEV_DB2, ("stattach: "));          SC_DEBUG(periph, SCSIPI_DB2, ("stattach: "));
   
         /*          /*
          * Store information needed to contact our base driver           * Store information needed to contact our base driver
          */           */
         st->sc_link = sc_link;          st->sc_periph = periph;
         sc_link->device = &st_switch;          periph->periph_dev = &st->sc_dev;
         sc_link->device_softc = st;          periph->periph_switch = &st_switch;
         sc_link->openings = 1;  
   
         /*          /*
          * Set initial flags           * Set initial flags
Line 454  stattach(parent, self, aux)
Line 484  stattach(parent, self, aux)
          */           */
         st_identify_drive(st, &sa->sa_inqbuf);          st_identify_drive(st, &sa->sa_inqbuf);
         /*          /*
          * Use the subdriver to request information regarding           * Use the subdriver to request information regarding the drive.
          * the drive. We cannot use interrupts yet, so the  
          * request must specify this.  
          */           */
         printf("\n");          printf("\n");
         printf("%s: %s", st->sc_dev.dv_xname, st->quirkdata ? "rogue, " : "");          printf("%s: %s", st->sc_dev.dv_xname, st->quirkdata ? "rogue, " : "");
         if (scsipi_test_unit_ready(sc_link,          if (scsipi_test_unit_ready(periph,
             XS_CTL_DISCOVERY | XS_CTL_SILENT | XS_CTL_IGNORE_MEDIA_CHANGE) ||              XS_CTL_DISCOVERY | XS_CTL_SILENT | XS_CTL_IGNORE_MEDIA_CHANGE) ||
             st_mode_sense(st,              st_mode_sense(st,
             XS_CTL_DISCOVERY | XS_CTL_SILENT | XS_CTL_IGNORE_MEDIA_CHANGE))              XS_CTL_DISCOVERY | XS_CTL_SILENT | XS_CTL_IGNORE_MEDIA_CHANGE))
                 printf("drive empty\n");                  printf("drive empty\n");
         else {          else {
                 printf("density code 0x%x, ", st->media_density);                  printf("density code %d, ", st->media_density);
                 if (st->media_blksize > 0)                  if (st->media_blksize > 0)
                         printf("%d-byte", st->media_blksize);                          printf("%d-byte", st->media_blksize);
                 else                  else
Line 478  stattach(parent, self, aux)
Line 506  stattach(parent, self, aux)
         /*          /*
          * Set up the buf queue for this device           * Set up the buf queue for this device
          */           */
         st->buf_queue.b_active = 0;          BUFQ_INIT(&st->buf_queue);
         st->buf_queue.b_actf = 0;  
         st->buf_queue.b_actb = &st->buf_queue.b_actf;  
   
 #if NRND > 0  #if NRND > 0
         rnd_attach_source(&st->rnd_source, st->sc_dev.dv_xname,          rnd_attach_source(&st->rnd_source, st->sc_dev.dv_xname,
Line 541  st_loadquirks(st)
Line 567  st_loadquirks(st)
                         mode2->density = mode->density;                          mode2->density = mode->density;
                         st->modeflags[i] |= DENSITY_SET_BY_QUIRK;                          st->modeflags[i] |= DENSITY_SET_BY_QUIRK;
                 }                  }
                   mode2->quirks |= mode->quirks;
                 mode++;                  mode++;
                 mode2++;                  mode2++;
         }          }
Line 556  stopen(dev, flags, mode, p)
Line 583  stopen(dev, flags, mode, p)
         int mode;          int mode;
         struct proc *p;          struct proc *p;
 {  {
         int unit;  
         u_int stmode, dsty;          u_int stmode, dsty;
         int error;          int error, sflags, unit, tries, ntries;
         struct st_softc *st;          struct st_softc *st;
         struct scsipi_link *sc_link;          struct scsipi_periph *periph;
           struct scsipi_adapter *adapt;
   
         unit = STUNIT(dev);          unit = STUNIT(dev);
         if (unit >= st_cd.cd_ndevs)          if (unit >= st_cd.cd_ndevs)
Line 571  stopen(dev, flags, mode, p)
Line 598  stopen(dev, flags, mode, p)
   
         stmode = STMODE(dev);          stmode = STMODE(dev);
         dsty = STDSTY(dev);          dsty = STDSTY(dev);
         sc_link = st->sc_link;  
   
         SC_DEBUG(sc_link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,          periph = st->sc_periph;
           adapt = periph->periph_channel->chan_adapter;
   
           SC_DEBUG(periph, SCSIPI_DB1, ("open: dev=0x%x (unit %d (of %d))\n", dev,
             unit, st_cd.cd_ndevs));              unit, st_cd.cd_ndevs));
   
   
         /*          /*
          * Only allow one at a time           * Only allow one at a time
          */           */
         if (sc_link->flags & SDEV_OPEN) {          if (periph->periph_flags & PERIPH_OPEN) {
                 printf("%s: already open\n", st->sc_dev.dv_xname);                  printf("%s: already open\n", st->sc_dev.dv_xname);
                 return (EBUSY);                  return (EBUSY);
         }          }
   
         if ((error = scsipi_adapter_addref(sc_link)) != 0)          if ((error = scsipi_adapter_addref(adapt)) != 0)
                 return (error);                  return (error);
   
         /*          /*
Line 593  stopen(dev, flags, mode, p)
Line 622  stopen(dev, flags, mode, p)
          */           */
         st->mt_resid = 0;          st->mt_resid = 0;
         st->mt_erreg = 0;          st->mt_erreg = 0;
           st->asc = 0;
           st->ascq = 0;
   
         /*          /*
          * Catch any unit attention errors.           * Catch any unit attention errors. Be silent about this
            * unless we're already mounted. We ignore media change
            * if we're in control mode or not mounted yet.
          */           */
         error = scsipi_test_unit_ready(sc_link, XS_CTL_IGNORE_MEDIA_CHANGE |          if ((st->flags & ST_MOUNTED) == 0 || stmode == CTRL_MODE) {
             (stmode == CTRL_MODE ? XS_CTL_SILENT : 0));  #ifdef SCSIDEBUG
         if (error && stmode != CTRL_MODE) {                  sflags = XS_CTL_IGNORE_MEDIA_CHANGE;
                 goto bad;  #else
                   sflags = XS_CTL_SILENT|XS_CTL_IGNORE_MEDIA_CHANGE;
   #endif
           } else
                   sflags = 0;
   
           /*
            * If we're already mounted or we aren't configured for
            * a mount delay, only try a test unit ready once. Otherwise,
            * try up to ST_MOUNT_DELAY times with a rest interval of
            * one second between each try.
            */
   
           if ((st->flags & ST_MOUNTED) || ST_MOUNT_DELAY == 0) {
                   ntries = 1;
           } else {
                   ntries = ST_MOUNT_DELAY;
         }          }
         sc_link->flags |= SDEV_OPEN;    /* unit attn are now errors */  
           for (error = tries = 0; tries < ntries; tries++) {
                   int slpintr, oflags;
   
                   /*
                    * If we had no error, or we're opening the control mode
                    * device, we jump out right away.
                    */
   
                   error = scsipi_test_unit_ready(periph, sflags);
                   if (error == 0 || stmode == CTRL_MODE) {
                           break;
                   }
   
                   /*
                    * We had an error.
                    *
                    * If we're already mounted or we aren't configured for
                    * a mount delay, or the error isn't a NOT READY error,
                    * skip to the error exit now.
                    */
                   if ((st->flags & ST_MOUNTED) || ST_MOUNT_DELAY == 0 ||
                       (st->mt_key != SKEY_NOT_READY)) {
                           goto bad;
                   }
   
                   /*
                    * clear any latched errors.
                    */
                   st->mt_resid = 0;
                   st->mt_erreg = 0;
                   st->asc = 0;
                   st->ascq = 0;
   
                   /*
                    * Fake that we have the device open so
                    * we block other apps from getting in.
                    */
   
                   oflags = periph->periph_flags;
                   periph->periph_flags |= PERIPH_OPEN;
   
                   slpintr = tsleep(&lbolt, PUSER|PCATCH, "stload", 0);
   
                   periph->periph_flags = oflags;  /* restore flags */
                   if (slpintr) {
                           goto bad;
                   }
           }
   
   
         /*          /*
          * If the mode is 3 (e.g. minor = 3,7,11,15) then the device has           * If the mode is 3 (e.g. minor = 3,7,11,15) then the device has
Line 612  stopen(dev, flags, mode, p)
Line 710  stopen(dev, flags, mode, p)
          * as to whether or not we got a NOT READY for the above           * as to whether or not we got a NOT READY for the above
          * unit attention). If a tape is there, go do a mount sequence.           * unit attention). If a tape is there, go do a mount sequence.
          */           */
         if (stmode == CTRL_MODE && st->mt_erreg == SKEY_NOT_READY) {          if (stmode == CTRL_MODE && st->mt_key == SKEY_NOT_READY) {
                   periph->periph_flags |= PERIPH_OPEN;
                 return (0);                  return (0);
         }          }
   
         /*          /*
            * If we get this far and had an error set, that means we failed
            * to pass the 'test unit ready' test for the non-controlmode device,
            * so we bounce the open.
            */
   
           if (error)
                   return (error);
   
           /*
            * Else, we're now committed to saying we're open.
            */
   
           periph->periph_flags |= PERIPH_OPEN; /* unit attn are now errors */
   
           /*
          * If it's a different mode, or if the media has been           * If it's a different mode, or if the media has been
          * invalidated, unmount the tape from the previous           * invalidated, unmount the tape from the previous
          * session but continue with open processing           * session but continue with open processing
          */           */
         if (st->last_dsty != dsty || !(sc_link->flags & SDEV_MEDIA_LOADED))          if (st->last_dsty != dsty ||
               (periph->periph_flags & PERIPH_MEDIA_LOADED) == 0)
                 st_unmount(st, NOEJECT);                  st_unmount(st, NOEJECT);
   
         /*          /*
Line 629  stopen(dev, flags, mode, p)
Line 744  stopen(dev, flags, mode, p)
          * mount session.           * mount session.
          */           */
         if (!(st->flags & ST_MOUNTED)) {          if (!(st->flags & ST_MOUNTED)) {
                 st_mount_tape(dev, flags);                  if ((error = st_mount_tape(dev, flags)) != 0)
                           goto bad;
                 st->last_dsty = dsty;                  st->last_dsty = dsty;
         }          }
   
         SC_DEBUG(sc_link, SDEV_DB2, ("open complete\n"));          SC_DEBUG(periph, SCSIPI_DB2, ("open complete\n"));
         return (0);          return (0);
   
 bad:  bad:
         st_unmount(st, NOEJECT);          st_unmount(st, NOEJECT);
         scsipi_adapter_delref(sc_link);          scsipi_adapter_delref(adapt);
         sc_link->flags &= ~SDEV_OPEN;          periph->periph_flags &= ~PERIPH_OPEN;
         return (error);          return (error);
 }  }
   
Line 656  stclose(dev, flags, mode, p)
Line 772  stclose(dev, flags, mode, p)
 {  {
         int stxx, error = 0;          int stxx, error = 0;
         struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];          struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];
           struct scsipi_periph *periph = st->sc_periph;
           struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
   
         SC_DEBUG(st->sc_link, SDEV_DB1, ("closing\n"));          SC_DEBUG(st->sc_periph, SCSIPI_DB1, ("closing\n"));
   
         /*          /*
          * Make sure that a tape opened in write-only mode will have           * Make sure that a tape opened in write-only mode will have
Line 697  stclose(dev, flags, mode, p)
Line 815  stclose(dev, flags, mode, p)
                  *                   *
                  *      file - FMK - file - FMK ... file - FMK FMK (EOM)                   *      file - FMK - file - FMK ... file - FMK FMK (EOM)
                  */                   */
                 if (!(st->sc_link->flags & SDEV_MEDIA_LOADED)) {                  if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
                         st_unmount(st, NOEJECT);                          st_unmount(st, NOEJECT);
                 } else if (error == 0) {                  } else if (error == 0) {
                         /*                          /*
Line 709  stclose(dev, flags, mode, p)
Line 827  stclose(dev, flags, mode, p)
                          *      operation a write?                           *      operation a write?
                          *                           *
                          *      Are there supposed to be 2FM at EOD?                           *      Are there supposed to be 2FM at EOD?
                          *                           *
                          * If both statements are true, then we backspace                           * If both statements are true, then we backspace
                          * one filemark.                           * one filemark.
                          */                           */
Line 725  stclose(dev, flags, mode, p)
Line 843  stclose(dev, flags, mode, p)
                 break;                  break;
         }          }
   
         scsipi_wait_drain(st->sc_link);          scsipi_wait_drain(periph);
   
         scsipi_adapter_delref(st->sc_link);          scsipi_adapter_delref(adapt);
         st->sc_link->flags &= ~SDEV_OPEN;          periph->periph_flags &= ~PERIPH_OPEN;
   
         return (error);          return (error);
 }  }
Line 746  st_mount_tape(dev, flags)
Line 864  st_mount_tape(dev, flags)
         int unit;          int unit;
         u_int dsty;          u_int dsty;
         struct st_softc *st;          struct st_softc *st;
         struct scsipi_link *sc_link;          struct scsipi_periph *periph;
         int error = 0;          int error = 0;
   
         unit = STUNIT(dev);          unit = STUNIT(dev);
         dsty = STDSTY(dev);          dsty = STDSTY(dev);
         st = st_cd.cd_devs[unit];          st = st_cd.cd_devs[unit];
         sc_link = st->sc_link;          periph = st->sc_periph;
   
         if (st->flags & ST_MOUNTED)          if (st->flags & ST_MOUNTED)
                 return (0);                  return (0);
   
         SC_DEBUG(sc_link, SDEV_DB1, ("mounting\n "));          SC_DEBUG(periph, SCSIPI_DB1, ("mounting\n "));
         st->flags |= ST_NEW_MOUNT;          st->flags |= ST_NEW_MOUNT;
         st->quirks = st->drive_quirks | st->modes[dsty].quirks;          st->quirks = st->drive_quirks | st->modes[dsty].quirks;
         /*          /*
          * If the media is new, then make sure we give it a chance to           * If the media is new, then make sure we give it a chance to
          * to do a 'load' instruction.  (We assume it is new.)           * to do a 'load' instruction.  (We assume it is new.)
          */           */
         if ((error = st_load(st, LD_LOAD, 0)) != 0)          if ((error = st_load(st, LD_LOAD, XS_CTL_SILENT)) != 0)
                 return (error);                  return (error);
         /*          /*
          * Throw another dummy instruction to catch           * Throw another dummy instruction to catch
Line 772  st_mount_tape(dev, flags)
Line 890  st_mount_tape(dev, flags)
          * these after doing a Load instruction (with           * these after doing a Load instruction (with
          * the MEDIUM MAY HAVE CHANGED asc/ascq).           * the MEDIUM MAY HAVE CHANGED asc/ascq).
          */           */
         scsipi_test_unit_ready(sc_link, XS_CTL_SILENT); /* XXX */          scsipi_test_unit_ready(periph, XS_CTL_SILENT);  /* XXX */
   
         /*          /*
          * Some devices can't tell you much until they have been           * Some devices can't tell you much until they have been
Line 823  st_mount_tape(dev, flags)
Line 941  st_mount_tape(dev, flags)
                 printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);                  printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
                 return (error);                  return (error);
         }          }
         scsipi_prevent(sc_link, PR_PREVENT,          if (!(st->quirks & ST_Q_NOPREVENT)) {
             XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY);                  scsipi_prevent(periph, PR_PREVENT,
                       XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY);
           }
         st->flags &= ~ST_NEW_MOUNT;          st->flags &= ~ST_NEW_MOUNT;
         st->flags |= ST_MOUNTED;          st->flags |= ST_MOUNTED;
         sc_link->flags |= SDEV_MEDIA_LOADED;    /* move earlier? */          periph->periph_flags |= PERIPH_MEDIA_LOADED;    /* move earlier? */
   
         return (0);          return (0);
 }  }
Line 843  st_unmount(st, eject)
Line 963  st_unmount(st, eject)
         struct st_softc *st;          struct st_softc *st;
         boolean eject;          boolean eject;
 {  {
         struct scsipi_link *sc_link = st->sc_link;          struct scsipi_periph *periph = st->sc_periph;
         int nmarks;          int nmarks;
   
         if (!(st->flags & ST_MOUNTED))          if ((st->flags & ST_MOUNTED) == 0)
                 return;                  return;
         SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n"));          SC_DEBUG(periph, SCSIPI_DB1, ("unmounting\n"));
         st_check_eod(st, FALSE, &nmarks, XS_CTL_IGNORE_NOT_READY);          st_check_eod(st, FALSE, &nmarks, XS_CTL_IGNORE_NOT_READY);
         st_rewind(st, 0, XS_CTL_IGNORE_NOT_READY);          st_rewind(st, 0, XS_CTL_IGNORE_NOT_READY);
         scsipi_prevent(sc_link, PR_ALLOW,  
           /*
            * Section 9.3.3 of the SCSI specs states that a device shall return
            * the density value specified in the last succesfull MODE SELECT
            * after an unload operation, in case it is not able to
            * automatically determine the density of the new medium.
            *
            * So we instruct the device to use the default density, which will
            * prevent the use of stale density values (in particular,
            * in st_touch_tape().
            */
           st->density = 0;
           if (st_mode_select(st, 0) != 0) {
                   printf("%s: WARNING: cannot revert to default density\n",
                           st->sc_dev.dv_xname);
           }
   
           scsipi_prevent(periph, PR_ALLOW,
             XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY);              XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_NOT_READY);
         if (eject)          if (eject)
                 st_load(st, LD_UNLOAD, XS_CTL_IGNORE_NOT_READY);                  st_load(st, LD_UNLOAD, XS_CTL_IGNORE_NOT_READY);
         st->flags &= ~(ST_MOUNTED | ST_NEW_MOUNT);          st->flags &= ~(ST_MOUNTED | ST_NEW_MOUNT);
         sc_link->flags &= ~SDEV_MEDIA_LOADED;          periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
 }  }
   
 /*  /*
Line 869  st_decide_mode(st, first_read)
Line 1006  st_decide_mode(st, first_read)
         struct st_softc *st;          struct st_softc *st;
         boolean first_read;          boolean first_read;
 {  {
 #ifdef SCSIDEBUG  
         struct scsipi_link *sc_link = st->sc_link;  
 #endif  
   
         SC_DEBUG(sc_link, SDEV_DB2, ("starting block mode decision\n"));          SC_DEBUG(st->sc_periph, SCSIPI_DB2, ("starting block mode decision\n"));
   
         /*          /*
          * If the drive can only handle fixed-length blocks and only at           * If the drive can only handle fixed-length blocks and only at
Line 882  st_decide_mode(st, first_read)
Line 1016  st_decide_mode(st, first_read)
         if (st->blkmin && (st->blkmin == st->blkmax)) {          if (st->blkmin && (st->blkmin == st->blkmax)) {
                 st->flags |= ST_FIXEDBLOCKS;                  st->flags |= ST_FIXEDBLOCKS;
                 st->blksize = st->blkmin;                  st->blksize = st->blkmin;
                 SC_DEBUG(sc_link, SDEV_DB3,                  SC_DEBUG(st->sc_periph, SCSIPI_DB3,
                     ("blkmin == blkmax of %d\n", st->blkmin));                      ("blkmin == blkmax of %d\n", st->blkmin));
                 goto done;                  goto done;
         }          }
Line 897  st_decide_mode(st, first_read)
Line 1031  st_decide_mode(st, first_read)
         case DDS:          case DDS:
                 st->flags &= ~ST_FIXEDBLOCKS;                  st->flags &= ~ST_FIXEDBLOCKS;
                 st->blksize = 0;                  st->blksize = 0;
                 SC_DEBUG(sc_link, SDEV_DB3, ("density specified variable\n"));                  SC_DEBUG(st->sc_periph, SCSIPI_DB3,
                       ("density specified variable\n"));
                 goto done;                  goto done;
         case QIC_11:          case QIC_11:
         case QIC_24:          case QIC_24:
Line 905  st_decide_mode(st, first_read)
Line 1040  st_decide_mode(st, first_read)
         case QIC_150:          case QIC_150:
         case QIC_525:          case QIC_525:
         case QIC_1320:          case QIC_1320:
           case QIC_3095:
           case QIC_3220:
                 st->flags |= ST_FIXEDBLOCKS;                  st->flags |= ST_FIXEDBLOCKS;
                 if (st->media_blksize > 0)                  if (st->media_blksize > 0)
                         st->blksize = st->media_blksize;                          st->blksize = st->media_blksize;
                 else                  else
                         st->blksize = DEF_FIXED_BSIZE;                          st->blksize = DEF_FIXED_BSIZE;
                 SC_DEBUG(sc_link, SDEV_DB3, ("density specified fixed\n"));                  SC_DEBUG(st->sc_periph, SCSIPI_DB3,
                       ("density specified fixed\n"));
                 goto done;                  goto done;
         }          }
         /*          /*
Line 927  st_decide_mode(st, first_read)
Line 1065  st_decide_mode(st, first_read)
                 else                  else
                         st->flags &= ~ST_FIXEDBLOCKS;                          st->flags &= ~ST_FIXEDBLOCKS;
                 st->blksize = st->media_blksize;                  st->blksize = st->media_blksize;
                 SC_DEBUG(sc_link, SDEV_DB3,                  SC_DEBUG(st->sc_periph, SCSIPI_DB3,
                     ("Used media_blksize of %d\n", st->media_blksize));                      ("Used media_blksize of %d\n", st->media_blksize));
                 goto done;                  goto done;
         }          }
Line 937  st_decide_mode(st, first_read)
Line 1075  st_decide_mode(st, first_read)
          */           */
         st->flags &= ~ST_FIXEDBLOCKS;          st->flags &= ~ST_FIXEDBLOCKS;
         st->blksize = 0;          st->blksize = 0;
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(st->sc_periph, SCSIPI_DB3,
             ("Give up and default to variable mode\n"));              ("Give up and default to variable mode\n"));
   
 done:  done:
Line 957  done:
Line 1095  done:
         case QIC_150:          case QIC_150:
         case QIC_525:          case QIC_525:
         case QIC_1320:          case QIC_1320:
           case QIC_3095:
           case QIC_3220:
                 st->flags &= ~ST_2FM_AT_EOD;                  st->flags &= ~ST_2FM_AT_EOD;
                 break;                  break;
         default:          default:
Line 976  ststrategy(bp)
Line 1116  ststrategy(bp)
         struct buf *bp;          struct buf *bp;
 {  {
         struct st_softc *st = st_cd.cd_devs[STUNIT(bp->b_dev)];          struct st_softc *st = st_cd.cd_devs[STUNIT(bp->b_dev)];
         struct buf *dp;  
         int s;          int s;
   
         SC_DEBUG(st->sc_link, SDEV_DB1,          SC_DEBUG(st->sc_periph, SCSIPI_DB1,
             ("ststrategy %ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));              ("ststrategy %ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
         /*          /*
          * If it's a null transfer, return immediatly           * If it's a null transfer, return immediatly
Line 1021  ststrategy(bp)
Line 1160  ststrategy(bp)
          * at the end (a bit silly because we only have on user..           * at the end (a bit silly because we only have on user..
          * (but it could fork()))           * (but it could fork()))
          */           */
         dp = &st->buf_queue;          BUFQ_INSERT_TAIL(&st->buf_queue, bp);
         bp->b_actf = NULL;  
         bp->b_actb = dp->b_actb;  
         *dp->b_actb = bp;  
         dp->b_actb = &bp->b_actf;  
   
         /*          /*
          * Tell the device to get going on the transfer if it's           * Tell the device to get going on the transfer if it's
          * not doing anything, otherwise just wait for completion           * not doing anything, otherwise just wait for completion
          * (All a bit silly if we're only allowing 1 open but..)           * (All a bit silly if we're only allowing 1 open but..)
          */           */
         ststart(st);          ststart(st->sc_periph);
   
         splx(s);          splx(s);
         return;          return;
Line 1062  done:
Line 1197  done:
  * ststart() is called at splbio   * ststart() is called at splbio
  */   */
 void  void
 ststart(v)  ststart(periph)
         void *v;          struct scsipi_periph *periph;
 {  {
         struct st_softc *st = v;          struct st_softc *st = (void *)periph->periph_dev;
         struct scsipi_link *sc_link = st->sc_link;          struct buf *bp;
         register struct buf *bp, *dp;  
         struct scsi_rw_tape cmd;          struct scsi_rw_tape cmd;
         int flags, error;          int flags, error;
   
         SC_DEBUG(sc_link, SDEV_DB2, ("ststart "));          SC_DEBUG(periph, SCSIPI_DB2, ("ststart "));
         /*          /*
          * See if there is a buf to do and we are not already           * See if there is a buf to do and we are not already
          * doing one           * doing one
          */           */
         while (sc_link->active < sc_link->openings) {          while (periph->periph_active < periph->periph_openings) {
                 /* if a special awaits, let it proceed first */                  /* if a special awaits, let it proceed first */
                 if (sc_link->flags & SDEV_WAITING) {                  if (periph->periph_flags & PERIPH_WAITING) {
                         sc_link->flags &= ~SDEV_WAITING;                          periph->periph_flags &= ~PERIPH_WAITING;
                         wakeup((caddr_t)sc_link);                          wakeup((caddr_t)periph);
                         return;                          return;
                 }                  }
   
                 dp = &st->buf_queue;                  if ((bp = BUFQ_FIRST(&st->buf_queue)) == NULL)
                 if ((bp = dp->b_actf) == NULL)  
                         return;                          return;
                 if ((dp = bp->b_actf) != NULL)                  BUFQ_REMOVE(&st->buf_queue, bp);
                         dp->b_actb = bp->b_actb;  
                 else  
                         st->buf_queue.b_actb = bp->b_actb;  
                 *bp->b_actb = dp;  
   
                 /*                  /*
                  * if the device has been unmounted bye the user                   * If the device has been unmounted by the user
                  * then throw away all requests until done                   * then throw away all requests until done.
                  */                   */
                 if (!(st->flags & ST_MOUNTED) ||                  if ((st->flags & ST_MOUNTED) == 0 ||
                     !(sc_link->flags & SDEV_MEDIA_LOADED)) {                      (periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
                         /* make sure that one implies the other.. */                          /* make sure that one implies the other.. */
                         sc_link->flags &= ~SDEV_MEDIA_LOADED;                          periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
                         bp->b_flags |= B_ERROR;                          bp->b_flags |= B_ERROR;
                         bp->b_error = EIO;                          bp->b_error = EIO;
                         bp->b_resid = bp->b_bcount;                          bp->b_resid = bp->b_bcount;
Line 1141  ststart(v)
Line 1270  ststart(v)
                 }                  }
                 /*                  /*
                  * If we are at EOM but have not reported it                   * If we are at EOM but have not reported it
                  * yet then we should report it now.                   * yet then we should report it now.
                  */                   */
                 if (st->flags & (ST_EOM_PENDING|ST_EIO_PENDING)) {                  if (st->flags & (ST_EOM_PENDING|ST_EIO_PENDING)) {
                         bp->b_resid = bp->b_bcount;                          bp->b_resid = bp->b_bcount;
Line 1155  ststart(v)
Line 1284  ststart(v)
                 }                  }
   
                 /*                  /*
                  *  Fill out the scsi command                   * Fill out the scsi command
                  */                   */
                 bzero(&cmd, sizeof(cmd));                  bzero(&cmd, sizeof(cmd));
                   flags = XS_CTL_NOSLEEP | XS_CTL_ASYNC;
                 if ((bp->b_flags & B_READ) == B_WRITE) {                  if ((bp->b_flags & B_READ) == B_WRITE) {
                         cmd.opcode = WRITE;                          cmd.opcode = WRITE;
                         st->flags &= ~ST_FM_WRITTEN;                          st->flags &= ~ST_FM_WRITTEN;
                         flags = XS_CTL_DATA_OUT;                          flags |= XS_CTL_DATA_OUT;
                 } else {                  } else {
                         cmd.opcode = READ;                          cmd.opcode = READ;
                         flags = XS_CTL_DATA_IN;                          flags |= XS_CTL_DATA_IN;
                 }                  }
   
                 /*                  /*
Line 1179  ststart(v)
Line 1309  ststart(v)
   
                 /*                  /*
                  * go ask the adapter to do all this for us                   * go ask the adapter to do all this for us
                  * XXX Really need NOSLEEP?  
                  */                   */
                 error = scsipi_command(sc_link,                  error = scsipi_command(periph,
                     (struct scsipi_generic *)&cmd, sizeof(cmd),                      (struct scsipi_generic *)&cmd, sizeof(cmd),
                     (u_char *)bp->b_data, bp->b_bcount,                      (u_char *)bp->b_data, bp->b_bcount,
                     0, ST_IO_TIME, bp, flags | XS_CTL_NOSLEEP | XS_CTL_ASYNC);                      0, ST_IO_TIME, bp, flags);
                 if (error) {                  if (error) {
                         printf("%s: not queued, error %d\n",                          printf("%s: not queued, error %d\n",
                             st->sc_dev.dv_xname, error);                              st->sc_dev.dv_xname, error);
Line 1196  void
Line 1325  void
 stdone(xs)  stdone(xs)
         struct scsipi_xfer *xs;          struct scsipi_xfer *xs;
 {  {
           struct st_softc *st = (void *)xs->xs_periph->periph_dev;
   
         if (xs->bp != NULL) {          if (xs->bp != NULL) {
                 struct st_softc *st = xs->sc_link->device_softc;  
                 if ((xs->bp->b_flags & B_READ) == B_WRITE) {                  if ((xs->bp->b_flags & B_READ) == B_WRITE) {
                         st->flags |= ST_WRITTEN;                          st->flags |= ST_WRITTEN;
                 } else {                  } else {
Line 1219  stread(dev, uio, iomode)
Line 1348  stread(dev, uio, iomode)
         struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];          struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];
   
         return (physio(ststrategy, NULL, dev, B_READ,          return (physio(ststrategy, NULL, dev, B_READ,
             st->sc_link->adapter->scsipi_minphys, uio));              st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio));
 }  }
   
 int  int
Line 1231  stwrite(dev, uio, iomode)
Line 1360  stwrite(dev, uio, iomode)
         struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];          struct st_softc *st = st_cd.cd_devs[STUNIT(dev)];
   
         return (physio(ststrategy, NULL, dev, B_WRITE,          return (physio(ststrategy, NULL, dev, B_WRITE,
             st->sc_link->adapter->scsipi_minphys, uio));              st->sc_periph->periph_channel->chan_adapter->adapt_minphys, uio));
 }  }
   
 /*  /*
Line 1273  stioctl(dev, cmd, arg, flag, p)
Line 1402  stioctl(dev, cmd, arg, flag, p)
                  * (to get the current state of READONLY)                   * (to get the current state of READONLY)
                  */                   */
                 error = st_mode_sense(st, XS_CTL_SILENT);                  error = st_mode_sense(st, XS_CTL_SILENT);
                 if (error)                  if (error) {
                         break;                          /*
                 SC_DEBUG(st->sc_link, SDEV_DB1, ("[ioctl: get status]\n"));                           * Ignore the error if in control mode;
                            * this is mandated by st(4).
                            */
                           if (STMODE(dev) != CTRL_MODE)
                                   break;
                           error = 0;
                   }
                   SC_DEBUG(st->sc_periph, SCSIPI_DB1, ("[ioctl: get status]\n"));
                 bzero(g, sizeof(struct mtget));                  bzero(g, sizeof(struct mtget));
                 g->mt_type = 0x7;       /* Ultrix compat *//*? */                  g->mt_type = 0x7;       /* Ultrix compat *//*? */
                 g->mt_blksiz = st->blksize;                  g->mt_blksiz = st->blksize;
Line 1299  stioctl(dev, cmd, arg, flag, p)
Line 1435  stioctl(dev, cmd, arg, flag, p)
                  */                   */
                 st->mt_resid = 0;                  st->mt_resid = 0;
                 st->mt_erreg = 0;                  st->mt_erreg = 0;
                   st->asc = 0;
                   st->ascq = 0;
                 break;                  break;
         }          }
         case MTIOCTOP: {          case MTIOCTOP: {
   
                 SC_DEBUG(st->sc_link, SDEV_DB1,                  SC_DEBUG(st->sc_periph, SCSIPI_DB1,
                     ("[ioctl: op=0x%x count=0x%x]\n", mt->mt_op,                      ("[ioctl: op=0x%x count=0x%x]\n", mt->mt_op,
                         mt->mt_count));                          mt->mt_count));
   
Line 1428  stioctl(dev, cmd, arg, flag, p)
Line 1566  stioctl(dev, cmd, arg, flag, p)
   
   
         default:          default:
                 error = scsipi_do_ioctl(st->sc_link, dev, cmd, arg,                  error = scsipi_do_ioctl(st->sc_periph, dev, cmd, arg,
                                         flag, p);                                          flag, p);
                 break;                  break;
         }          }
Line 1438  try_new_value:
Line 1576  try_new_value:
         /*          /*
          * Check that the mode being asked for is aggreeable to the           * Check that the mode being asked for is aggreeable to the
          * drive. If not, put it back the way it was.           * drive. If not, put it back the way it was.
            *
            * If in control mode, we can make (persistent) mode changes
            * even if no medium is loaded (see st(4)).
          */           */
         if ((error = st_mode_select(st, 0)) != 0) {/* put it back as it was */          if ((STMODE(dev) != CTRL_MODE || (st->flags & ST_MOUNTED) != 0) &&
               (error = st_mode_select(st, 0)) != 0) {
                   /* put it back as it was */
                 printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);                  printf("%s: cannot set selected mode\n", st->sc_dev.dv_xname);
                 st->density = hold_density;                  st->density = hold_density;
                 st->blksize = hold_blksize;                  st->blksize = hold_blksize;
Line 1497  st_read(st, buf, size, flags)
Line 1640  st_read(st, buf, size, flags)
                     cmd.len);                      cmd.len);
         } else          } else
                 _lto3b(size, cmd.len);                  _lto3b(size, cmd.len);
         return (scsipi_command(st->sc_link,          return (scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd),              (struct scsipi_generic *)&cmd, sizeof(cmd),
             (u_char *)buf, size, 0, ST_IO_TIME, NULL, flags | XS_CTL_DATA_IN));              (u_char *)buf, size, 0, ST_IO_TIME, NULL, flags | XS_CTL_DATA_IN));
 }  }
Line 1512  st_read_block_limits(st, flags)
Line 1655  st_read_block_limits(st, flags)
 {  {
         struct scsi_block_limits cmd;          struct scsi_block_limits cmd;
         struct scsi_block_limits_data block_limits;          struct scsi_block_limits_data block_limits;
         struct scsipi_link *sc_link = st->sc_link;          struct scsipi_periph *periph = st->sc_periph;
         int error;          int error;
   
         /*          /*
          * First check if we have it all loaded  
          */  
         if ((sc_link->flags & SDEV_MEDIA_LOADED))  
                 return (0);  
   
         /*  
          * do a 'Read Block Limits'           * do a 'Read Block Limits'
          */           */
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
Line 1530  st_read_block_limits(st, flags)
Line 1667  st_read_block_limits(st, flags)
         /*          /*
          * do the command, update the global values           * do the command, update the global values
          */           */
         error = scsipi_command(sc_link, (struct scsipi_generic *)&cmd,          error = scsipi_command(periph, (struct scsipi_generic *)&cmd,
             sizeof(cmd), (u_char *)&block_limits, sizeof(block_limits),              sizeof(cmd), (u_char *)&block_limits, sizeof(block_limits),
             ST_RETRIES, ST_CTL_TIME, NULL, flags | XS_CTL_DATA_IN);              ST_RETRIES, ST_CTL_TIME, NULL,
               flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK);
         if (error)          if (error)
                 return (error);                  return (error);
   
         st->blkmin = _2btol(block_limits.min_length);          st->blkmin = _2btol(block_limits.min_length);
         st->blkmax = _3btol(block_limits.max_length);          st->blkmax = _3btol(block_limits.max_length);
   
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(periph, SCSIPI_DB3,
             ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax));              ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax));
         return (0);          return (0);
 }  }
Line 1567  st_mode_sense(st, flags)
Line 1705  st_mode_sense(st, flags)
                 struct scsi_blk_desc blk_desc;                  struct scsi_blk_desc blk_desc;
                 u_char sense_data[MAX_PAGE_0_SIZE];                  u_char sense_data[MAX_PAGE_0_SIZE];
         } scsipi_sense;          } scsipi_sense;
         struct scsipi_link *sc_link = st->sc_link;          struct scsipi_periph *periph = st->sc_periph;
   
         scsipi_sense_len = 12 + st->page_0_size;          scsipi_sense_len = 12 + st->page_0_size;
   
Line 1584  st_mode_sense(st, flags)
Line 1722  st_mode_sense(st, flags)
          * or if we need it as a template for the mode select           * or if we need it as a template for the mode select
          * store it away.           * store it away.
          */           */
         error = scsipi_command(sc_link, (struct scsipi_generic *)&cmd,          error = scsipi_command(periph, (struct scsipi_generic *)&cmd,
             sizeof(cmd), (u_char *)&scsipi_sense, scsipi_sense_len,              sizeof(cmd), (u_char *)&scsipi_sense, scsipi_sense_len,
             ST_RETRIES, ST_CTL_TIME, NULL, flags | XS_CTL_DATA_IN);              ST_RETRIES, ST_CTL_TIME, NULL,
               flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK);
         if (error)          if (error)
                 return (error);                  return (error);
   
Line 1597  st_mode_sense(st, flags)
Line 1736  st_mode_sense(st, flags)
                 st->flags |= ST_READONLY;                  st->flags |= ST_READONLY;
         else          else
                 st->flags &= ~ST_READONLY;                  st->flags &= ~ST_READONLY;
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(periph, SCSIPI_DB3,
             ("density code 0x%x, %d-byte blocks, write-%s, ",              ("density code %d, %d-byte blocks, write-%s, ",
             st->media_density, st->media_blksize,              st->media_density, st->media_blksize,
             st->flags & ST_READONLY ? "protected" : "enabled"));              st->flags & ST_READONLY ? "protected" : "enabled"));
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(periph, SCSIPI_DB3,
             ("%sbuffered\n",              ("%sbuffered\n",
             scsipi_sense.header.dev_spec & SMH_DSP_BUFF_MODE ? "" : "un"));              scsipi_sense.header.dev_spec & SMH_DSP_BUFF_MODE ? "" : "un"));
         if (st->page_0_size)          if (st->page_0_size)
                 bcopy(scsipi_sense.sense_data, st->sense_data,                  bcopy(scsipi_sense.sense_data, st->sense_data,
                     st->page_0_size);                      st->page_0_size);
         sc_link->flags |= SDEV_MEDIA_LOADED;          periph->periph_flags |= PERIPH_MEDIA_LOADED;
         return (0);          return (0);
 }  }
   
Line 1627  st_mode_select(st, flags)
Line 1766  st_mode_select(st, flags)
                 struct scsi_blk_desc blk_desc;                  struct scsi_blk_desc blk_desc;
                 u_char sense_data[MAX_PAGE_0_SIZE];                  u_char sense_data[MAX_PAGE_0_SIZE];
         } scsi_select;          } scsi_select;
         struct scsipi_link *sc_link = st->sc_link;          struct scsipi_periph *periph = st->sc_periph;
   
         scsi_select_len = 12 + st->page_0_size;          scsi_select_len = 12 + st->page_0_size;
   
Line 1637  st_mode_select(st, flags)
Line 1776  st_mode_select(st, flags)
          * even if the selected mode is the one that is supported.           * even if the selected mode is the one that is supported.
          */           */
         if (st->quirks & ST_Q_UNIMODAL) {          if (st->quirks & ST_Q_UNIMODAL) {
                 SC_DEBUG(sc_link, SDEV_DB3,                  SC_DEBUG(periph, SCSIPI_DB3,
                     ("not setting density 0x%x blksize 0x%x\n",                      ("not setting density 0x%x blksize 0x%x\n",
                     st->density, st->blksize));                      st->density, st->blksize));
                 return (0);                  return (0);
Line 1666  st_mode_select(st, flags)
Line 1805  st_mode_select(st, flags)
         /*          /*
          * do the command           * do the command
          */           */
         return (scsipi_command(sc_link, (struct scsipi_generic *)&cmd,          return (scsipi_command(periph, (struct scsipi_generic *)&cmd,
             sizeof(cmd), (u_char *)&scsi_select, scsi_select_len,              sizeof(cmd), (u_char *)&scsi_select, scsi_select_len,
             ST_RETRIES, ST_CTL_TIME, NULL, flags | XS_CTL_DATA_OUT));              ST_RETRIES, ST_CTL_TIME, NULL,
               flags | XS_CTL_DATA_OUT | XS_CTL_DATA_ONSTACK));
 }  }
   
 int  int
Line 1687  st_cmprss(st, onoff)
Line 1827  st_cmprss(st, onoff)
         } scsi_pdata;          } scsi_pdata;
         struct scsi_tape_dev_conf_page *ptr;          struct scsi_tape_dev_conf_page *ptr;
         struct scsi_tape_dev_compression_page *cptr;          struct scsi_tape_dev_compression_page *cptr;
         struct scsipi_link *sc_link = st->sc_link;          struct scsipi_periph *periph = st->sc_periph;
         int error, ison, flags;          int error, ison, flags;
   
         scsi_dlen = sizeof(scsi_pdata);          scsi_dlen = sizeof(scsi_pdata);
Line 1709  st_cmprss(st, onoff)
Line 1849  st_cmprss(st, onoff)
          */           */
 again:  again:
         bzero(&scsi_pdata, scsi_dlen);          bzero(&scsi_pdata, scsi_dlen);
         error = scsipi_command(sc_link,          error = scsipi_command(periph,
             (struct scsipi_generic *)&scmd, sizeof(scmd),              (struct scsipi_generic *)&scmd, sizeof(scmd),
             (u_char *)&scsi_pdata, scsi_dlen,              (u_char *)&scsi_pdata, scsi_dlen,
             ST_RETRIES, ST_CTL_TIME, NULL, flags | XS_CTL_DATA_IN);              ST_RETRIES, ST_CTL_TIME, NULL,
               flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK);
   
         if (error) {          if (error) {
                 if (scmd.byte2 != SMS_DBD) {                  if (scmd.byte2 != SMS_DBD) {
Line 1795  again:
Line 1936  again:
         /*          /*
          * Do the command           * Do the command
          */           */
         error = scsipi_command(sc_link,          error = scsipi_command(periph,
             (struct scsipi_generic *)&mcmd, sizeof(mcmd),              (struct scsipi_generic *)&mcmd, sizeof(mcmd),
             (u_char *)&scsi_pdata, scsi_dlen,              (u_char *)&scsi_pdata, scsi_dlen,
             ST_RETRIES, ST_CTL_TIME, NULL, flags | XS_CTL_DATA_OUT);              ST_RETRIES, ST_CTL_TIME, NULL,
               flags | XS_CTL_DATA_OUT | XS_CTL_DATA_ONSTACK);
   
         if (error && (scmd.page & SMS_PAGE_CODE) == 0xf) {          if (error && (scmd.page & SMS_PAGE_CODE) == 0xf) {
                 /*                  /*
Line 1828  st_erase(st, full, flags)
Line 1970  st_erase(st, full, flags)
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.opcode = ERASE;          cmd.opcode = ERASE;
         if (full) {          if (full) {
                 cmd.byte2 = SE_IMMED|SE_LONG;                  cmd.byte2 = SE_LONG;
                 tmo = ST_SPC_TIME;                  tmo = ST_SPC_TIME;
         } else {          } else {
                 tmo = ST_IO_TIME;                  tmo = ST_IO_TIME;
                 cmd.byte2 = SE_IMMED;  
         }          }
   
         /*          /*
          * XXX We always do this asynchronously, for now.  How long should           * XXX We always do this asynchronously, for now, unless the device
          * we wait if we want to (eventually) to it synchronously?           * has the ST_Q_ERASE_NOIMM quirk.  How long should we wait if we
            * want to (eventually) to it synchronously?
          */           */
         return (scsipi_command(st->sc_link,          if ((st->quirks & ST_Q_ERASE_NOIMM) == 0)
                   cmd.byte2 |= SE_IMMED;
   
           return (scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd),              (struct scsipi_generic *)&cmd, sizeof(cmd),
             0, 0, ST_RETRIES, tmo, NULL, flags));              0, 0, ST_RETRIES, tmo, NULL, flags));
 }  }
Line 1927  st_space(st, number, what, flags)
Line 2072  st_space(st, number, what, flags)
         cmd.byte2 = what;          cmd.byte2 = what;
         _lto3b(number, cmd.number);          _lto3b(number, cmd.number);
   
         return (scsipi_command(st->sc_link,          return (scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd),              (struct scsipi_generic *)&cmd, sizeof(cmd),
             0, 0, 0, ST_SPC_TIME, NULL, flags));              0, 0, 0, ST_SPC_TIME, NULL, flags));
 }  }
Line 1967  st_write_filemarks(st, number, flags)
Line 2112  st_write_filemarks(st, number, flags)
         cmd.opcode = WRITE_FILEMARKS;          cmd.opcode = WRITE_FILEMARKS;
         _lto3b(number, cmd.number);          _lto3b(number, cmd.number);
   
         return (scsipi_command(st->sc_link,          return (scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd),              (struct scsipi_generic *)&cmd, sizeof(cmd),
             0, 0, 0, ST_IO_TIME * 4, NULL, flags));              0, 0, 0, ST_IO_TIME * 4, NULL, flags));
 }  }
Line 2042  st_load(st, type, flags)
Line 2187  st_load(st, type, flags)
         cmd.opcode = LOAD;          cmd.opcode = LOAD;
         cmd.how = type;          cmd.how = type;
   
         error = scsipi_command(st->sc_link,          error = scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd),              (struct scsipi_generic *)&cmd, sizeof(cmd),
             0, 0, ST_RETRIES, ST_SPC_TIME, NULL, flags);              0, 0, ST_RETRIES, ST_SPC_TIME, NULL, flags);
         if (error) {          if (error) {
Line 2077  st_rewind(st, immediate, flags)
Line 2222  st_rewind(st, immediate, flags)
         cmd.opcode = REWIND;          cmd.opcode = REWIND;
         cmd.byte2 = immediate;          cmd.byte2 = immediate;
   
         error = scsipi_command(st->sc_link,          error = scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd), 0, 0, ST_RETRIES,              (struct scsipi_generic *)&cmd, sizeof(cmd), 0, 0, ST_RETRIES,
             immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags);              immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags);
         if (error) {          if (error) {
Line 2116  st_rdpos(st, hard, blkptr)
Line 2261  st_rdpos(st, hard, blkptr)
         if (hard)          if (hard)
                 cmd.byte1 = 1;                  cmd.byte1 = 1;
   
         error = scsipi_command(st->sc_link,          error = scsipi_command(st->sc_periph,
             (struct scsipi_generic *)&cmd, sizeof(cmd), (u_char *)&posdata,              (struct scsipi_generic *)&cmd, sizeof(cmd), (u_char *)&posdata,
             sizeof(posdata), ST_RETRIES, ST_CTL_TIME, NULL,              sizeof(posdata), ST_RETRIES, ST_CTL_TIME, NULL,
             XS_CTL_SILENT | XS_CTL_DATA_IN);              XS_CTL_SILENT | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK);
   
         if (error == 0) {          if (error == 0) {
 #if     0  #if     0
Line 2165  st_setpos(st, hard, blkptr)
Line 2310  st_setpos(st, hard, blkptr)
         if (hard)          if (hard)
                 cmd.byte2 = 1 << 2;                  cmd.byte2 = 1 << 2;
         _lto4b(*blkptr, cmd.blkaddr);          _lto4b(*blkptr, cmd.blkaddr);
         error = scsipi_command(st->sc_link,          error = scsipi_command(st->sc_periph,
                 (struct scsipi_generic *)&cmd, sizeof(cmd),                  (struct scsipi_generic *)&cmd, sizeof(cmd),
                 NULL, 0, ST_RETRIES, ST_SPC_TIME, NULL, 0);                  NULL, 0, ST_RETRIES, ST_SPC_TIME, NULL, 0);
         /*          /*
Line 2185  int
Line 2330  int
 st_interpret_sense(xs)  st_interpret_sense(xs)
         struct scsipi_xfer *xs;          struct scsipi_xfer *xs;
 {  {
         struct scsipi_link *sc_link = xs->sc_link;          struct scsipi_periph *periph = xs->xs_periph;
         struct scsipi_sense_data *sense = &xs->sense.scsi_sense;          struct scsipi_sense_data *sense = &xs->sense.scsi_sense;
         struct buf *bp = xs->bp;          struct buf *bp = xs->bp;
         struct st_softc *st = sc_link->device_softc;          struct st_softc *st = (void *)periph->periph_dev;
         int retval = SCSIRET_CONTINUE;          int retval = EJUSTRETURN;
         int doprint = ((xs->xs_control & XS_CTL_SILENT) == 0);          int doprint = ((xs->xs_control & XS_CTL_SILENT) == 0);
         u_int8_t key;          u_int8_t key;
         int32_t info;          int32_t info;
Line 2209  st_interpret_sense(xs)
Line 2354  st_interpret_sense(xs)
                 info = xs->datalen;     /* bad choice if fixed blocks */                  info = xs->datalen;     /* bad choice if fixed blocks */
         key = sense->flags & SSD_KEY;          key = sense->flags & SSD_KEY;
         st->mt_erreg = key;          st->mt_erreg = key;
           st->asc = sense->add_sense_code;
           st->ascq = sense->add_sense_code_qual;
         st->mt_resid = (short) info;          st->mt_resid = (short) info;
   
         /*          /*
          * If the device is not open yet, let generic handle           * If the device is not open yet, let generic handle
          */           */
         if ((sc_link->flags & SDEV_OPEN) == 0) {          if ((periph->periph_flags & PERIPH_OPEN) == 0) {
                 return (retval);                  return (retval);
         }          }
   
Line 2250  st_interpret_sense(xs)
Line 2397  st_interpret_sense(xs)
                          * information.                           * information.
                          */                           */
                         if ((st->quirks & ST_Q_SENSE_HELP) &&                          if ((st->quirks & ST_Q_SENSE_HELP) &&
                             !(sc_link->flags & SDEV_MEDIA_LOADED))                              (periph->periph_flags & PERIPH_MEDIA_LOADED) == 0)
                                 st->blksize -= 512;                                  st->blksize -= 512;
                 }                  }
                 /*                  /*
Line 2262  st_interpret_sense(xs)
Line 2409  st_interpret_sense(xs)
                         if (st->flags & ST_AT_FILEMARK) {                          if (st->flags & ST_AT_FILEMARK) {
                                 if (bp)                                  if (bp)
                                         bp->b_resid = xs->resid;                                          bp->b_resid = xs->resid;
                                 return (SCSIRET_NOERROR);                                  return (0);
                         }                          }
                 }                  }
         } else {                /* must be variable mode */          } else {                /* must be variable mode */
Line 2277  st_interpret_sense(xs)
Line 2424  st_interpret_sense(xs)
                          */                           */
                         if (st->flags & ST_EARLYWARN) {                          if (st->flags & ST_EARLYWARN) {
                                 st->flags |= ST_EOM_PENDING;                                  st->flags |= ST_EOM_PENDING;
                                 retval = SCSIRET_NOERROR;                                  retval = 0;
                         } else {                          } else {
                                 retval = EIO;                                  retval = EIO;
                         }                          }
Line 2290  st_interpret_sense(xs)
Line 2437  st_interpret_sense(xs)
                                 doprint = 0;                                  doprint = 0;
                         }                          }
                 } else if (sense->flags & SSD_FILEMARK) {                  } else if (sense->flags & SSD_FILEMARK) {
                         retval = SCSIRET_NOERROR;                          retval = 0;
                 } else if (sense->flags & SSD_ILI) {                  } else if (sense->flags & SSD_ILI) {
                         if (info < 0) {                          if (info < 0) {
                                 /*                                  /*
Line 2305  st_interpret_sense(xs)
Line 2452  st_interpret_sense(xs)
                                 }                                  }
                                 retval = EIO;                                  retval = EIO;
                         } else {                          } else {
                                 retval = SCSIRET_NOERROR;                                  retval = 0;
                         }                          }
                 }                  }
                 xs->resid = info;                  xs->resid = info;
Line 2313  st_interpret_sense(xs)
Line 2460  st_interpret_sense(xs)
                         bp->b_resid = info;                          bp->b_resid = info;
         }          }
   
 #ifndef SCSIDEBUG  #ifdef SCSIPI_DEBUG
         if (retval == SCSIRET_NOERROR && key == SKEY_NO_SENSE) {          if (retval == 0 && key == SKEY_NO_SENSE)
                 doprint = 0;                  doprint = 0;
         }  
 #endif  #endif
         if (key == SKEY_BLANK_CHECK) {          if (key == SKEY_BLANK_CHECK) {
                 /*                  /*
Line 2326  st_interpret_sense(xs)
Line 2472  st_interpret_sense(xs)
                  * MODE SENSE information.                   * MODE SENSE information.
                  */                   */
                 if ((st->quirks & ST_Q_SENSE_HELP) &&                  if ((st->quirks & ST_Q_SENSE_HELP) &&
                     !(sc_link->flags & SDEV_MEDIA_LOADED)) {                      (periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
                         /* still starting */                          /* still starting */
                         st->blksize -= 512;                          st->blksize -= 512;
                 } else if (!(st->flags & (ST_2FM_AT_EOD | ST_BLANK_READ))) {                  } else if (!(st->flags & (ST_2FM_AT_EOD | ST_BLANK_READ))) {
Line 2336  st_interpret_sense(xs)
Line 2482  st_interpret_sense(xs)
                                 bp->b_resid = xs->resid;                                  bp->b_resid = xs->resid;
                                 /* return an EOF */                                  /* return an EOF */
                         }                          }
                         retval = SCSIRET_NOERROR;                          retval = 0;
                 }                  }
         }          }
 #ifdef  SCSIVERBOSE  
           /*
            * If generic sense processing will continue, we should not
            * print sense info here.
            */
           if (retval == EJUSTRETURN)
                   doprint = 0;
   
         if (doprint) {          if (doprint) {
   #ifdef  SCSIVERBOSE
                 scsipi_print_sense(xs, 0);                  scsipi_print_sense(xs, 0);
         }  
 #else  #else
         if (doprint) {                  scsipi_printaddr(periph);
                 xs->sc_link->sc_print_addr(xs->sc_link);  
                 printf("Sense Key 0x%02x", key);                  printf("Sense Key 0x%02x", key);
                 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {                  if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
                         switch (key) {                          switch (key) {
                         case SKEY_NOT_READY:                          case SKEY_NOT_READY:
                         case SKEY_ILLEGAL_REQUEST:                          case SKEY_ILLEGAL_REQUEST:
                         case SKEY_UNIT_ATTENTION:                          case SKEY_UNIT_ATTENTION:
Line 2356  st_interpret_sense(xs)
Line 2508  st_interpret_sense(xs)
                                 break;                                  break;
                         case SKEY_BLANK_CHECK:                          case SKEY_BLANK_CHECK:
                                 printf(", requested size: %d (decimal)", info);                                  printf(", requested size: %d (decimal)", info);
                                 break;                                  break;
                         case SKEY_ABORTED_COMMAND:                          case SKEY_ABORTED_COMMAND:
                                 if (xs->retries)                                  if (xs->retries)
                                         printf(", retrying");                                          printf(", retrying");
Line 2366  st_interpret_sense(xs)
Line 2518  st_interpret_sense(xs)
                         default:                          default:
                                 printf(", info = %d (decimal)", info);                                  printf(", info = %d (decimal)", info);
                         }                          }
                 }                  }
                 if (sense->extra_len != 0) {                  if (sense->extra_len != 0) {
                         int n;                          int n;
                         printf(", data =");                          printf(", data =");
                         for (n = 0; n < sense->extra_len; n++)                          for (n = 0; n < sense->extra_len; n++)
                                 printf(" %02x", sense->cmd_spec_info[n]);                                  printf(" %02x", sense->cmd_spec_info[n]);
                 }                  }
                 printf("\n");                  printf("\n");
         }  
 #endif  #endif
           }
         return (retval);          return (retval);
 }  }
   
Line 2409  st_touch_tape(st)
Line 2561  st_touch_tape(st)
   
         if ((error = st_mode_sense(st, 0)) != 0)          if ((error = st_mode_sense(st, 0)) != 0)
                 goto bad;                  goto bad;
         st->blksize = 1024;  
           /*
            * If the block size is already known from the
            * sense data, use it. Else start probing at 1024.
            */
           if (st->media_blksize > 0)
                   st->blksize = st->media_blksize;
           else
                   st->blksize = 1024;
   
         do {          do {
                 switch (st->blksize) {                  switch (st->blksize) {
                 case 512:                  case 512:
Line 2421  st_touch_tape(st)
Line 2582  st_touch_tape(st)
                         readsize = 1;                          readsize = 1;
                         st->flags &= ~ST_FIXEDBLOCKS;                          st->flags &= ~ST_FIXEDBLOCKS;
                 }                  }
                 if ((error = st_mode_select(st, 0)) != 0)                  if ((error = st_mode_select(st, XS_CTL_SILENT)) != 0) {
                         goto bad;                          /*
                            * The device did not agree with the proposed
                            * block size. If we exhausted our options,
                            * return failure, else try another.
                            */
                           if (readsize == 1)
                                   goto bad;
                           st->blksize -= 512;
                           continue;
                   }
                 st_read(st, buf, readsize, XS_CTL_SILENT);      /* XXX */                  st_read(st, buf, readsize, XS_CTL_SILENT);      /* XXX */
                 if ((error = st_rewind(st, 0, 0)) != 0) {                  if ((error = st_rewind(st, 0, 0)) != 0) {
 bad:                    free(buf, M_TEMP);  bad:                    free(buf, M_TEMP);

Legend:
Removed from v.1.114  
changed lines
  Added in v.1.114.2.7

CVSweb <webmaster@jp.NetBSD.org>