[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.43 and 1.44

version 1.43, 1994/11/22 00:14:24 version 1.44, 1994/12/28 19:43:17
Line 86 
Line 86 
  * and note how they are bad, so we can correct for them   * and note how they are bad, so we can correct for them
  */   */
 struct modes {  struct modes {
         u_int blksiz;          u_int quirks;                   /* same definitions as in quirkdata */
         u_int quirks;           /* same definitions as in rogues */          int blksize;
         char density;          u_int8_t density;
         char spare[3];  
 };  };
   
 struct rogues {  struct quirkdata {
         char *manu;          u_int quirks;
         char *model;  #define ST_Q_FORCE_BLKSIZE      0x0001
         char *version;  #define ST_Q_SENSE_HELP         0x0002  /* must do READ for good MODE SENSE */
         u_int quirks;           /* valid for all modes */  #define ST_Q_IGNORE_LOADS       0x0004
   #define ST_Q_BLKSIZE            0x0008  /* variable-block media_blksize > 0 */
         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];
 };  };
   
 /* define behaviour codes (quirks) */  struct st_quirk_inquiry_pattern {
 #define ST_Q_FORCE_FIXED_MODE   0x00002          struct scsi_inquiry_pattern pattern;
 #define ST_Q_FORCE_VAR_MODE     0x00004          struct quirkdata quirkdata;
 #define ST_Q_SENSE_HELP         0x00008 /* must do READ for good MODE SENSE */  };
 #define ST_Q_IGNORE_LOADS       0x00010  
 #define ST_Q_BLKSIZ             0x00020 /* variable-block media_blksiz > 0 */  struct st_quirk_inquiry_pattern st_quirk_patterns[] = {
           {T_SEQUENTIAL, T_REMOV,
 static struct rogues gallery[] =        /* ends with an all-null entry */           "unknown ", "unknown         ", "????", 0, 0, {
 {                  ST_Q_FORCE_BLKSIZE, 512, 0,             /* minor 0-3 */
     {"pre-scsi", " unknown model  ", "????",                  ST_Q_FORCE_BLKSIZE, 512, QIC_24,        /* minor 4-7 */
         0, 0,                  ST_Q_FORCE_BLKSIZE, 0, HALFINCH_1600,   /* minor 8-11 */
         {                  ST_Q_FORCE_BLKSIZE, 0, HALFINCH_6250    /* minor 12-15 */
             {512, ST_Q_FORCE_FIXED_MODE, 0},            /* minor 0-3 */          }},
             {512, ST_Q_FORCE_FIXED_MODE, QIC_24},       /* minor 4-7 */          {T_SEQUENTIAL, T_REMOV,
             {0, ST_Q_FORCE_VAR_MODE, HALFINCH_1600},    /* minor 8-11 */           "TANDBERG", " TDC 3600       ", "",     0, 12, {
             {0, ST_Q_FORCE_VAR_MODE, HALFINCH_6250}     /* minor 12-15 */                  0, 0, 0,                                /* minor 0-3 */
         }                  ST_Q_FORCE_BLKSIZE, 0, QIC_525,         /* minor 4-7 */
     },                  0, 0, QIC_150,                          /* minor 8-11 */
     {"TANDBERG", " TDC 3600", "????",                  0, 0, QIC_120                           /* minor 12-15 */
         0, 12,          }},
         {          /*
             {0, 0, 0},                                  /* minor 0-3 */           * At least -005 and -007 need this.  I'll assume they all do unless I
             {0, ST_Q_FORCE_VAR_MODE, QIC_525},          /* minor 4-7 */           * hear otherwise.  - mycroft, 31MAR1994
             {0, 0, QIC_150},                            /* minor 8-11 */           */
             {0, 0, QIC_120}                             /* minor 12-15 */          {T_SEQUENTIAL, T_REMOV,
         }           "ARCHIVE ", "VIPER 2525 25462", "",     0, 0, {
     },                  ST_Q_SENSE_HELP, 0, 0,                  /* minor 0-3 */
     /*                  ST_Q_SENSE_HELP, 0, QIC_525,            /* minor 4-7 */
      * At least -005 and -007 need this.  I'll assume they all do unless I                  0, 0, QIC_150,                          /* minor 8-11 */
      * hear otherwise.  - mycroft, 31MAR1994                  0, 0, QIC_120                           /* minor 12-15 */
      */          }},
     {"ARCHIVE ", "VIPER 2525 25462", "????",          /*
         0, 0,           * One user reports that this works for his tape drive.  It probably
         {           * needs more work.  - mycroft, 09APR1994
             {0, ST_Q_SENSE_HELP, 0},                    /* minor 0-3 */           */
             {0, ST_Q_SENSE_HELP, QIC_525},              /* minor 4-7 */          {T_SEQUENTIAL, T_REMOV,
             {0, 0, QIC_150},                            /* minor 8-11 */           "SANKYO  ", "CP525           ", "",     0, 0, {
             {0, 0, QIC_120}                             /* minor 12-15 */                  ST_Q_FORCE_BLKSIZE, 512, 0,             /* minor 0-3 */
         }                  ST_Q_FORCE_BLKSIZE, 512, QIC_525,       /* minor 4-7 */
     },                  0, 0, QIC_150,                          /* minor 8-11 */
     /*                  0, 0, QIC_120                           /* minor 12-15 */
      * One user reports that this works for his tape drive.  It probably          }},
      * needs more work.  - mycroft, 09APR1994          {T_SEQUENTIAL, T_REMOV,
      */           "ARCHIVE ", "VIPER 150  21247", "",     0, 12, {
     {"SANKYO  ", "CP525", "????",                  0, 0, 0,                                /* minor 0-3 */
         0, 0,                  0, 0, QIC_150,                          /* minor 4-7 */
         {                  0, 0, QIC_120,                          /* minor 8-11 */
             {512, ST_Q_FORCE_FIXED_MODE, 0},            /* minor 0-3 */                  0, 0, QIC_24                            /* minor 12-15 */
             {512, ST_Q_FORCE_FIXED_MODE, QIC_525},      /* minor 4-7 */          }},
             {0, 0, QIC_150},                            /* minor 8-11 */          {T_SEQUENTIAL, T_REMOV,
             {0, 0, QIC_120}                             /* minor 12-15 */           "WANGTEK ", "5525ES SCSI REV7", "",     0, 0, {
         }                  0, 0, 0,                                /* minor 0-3 */
     },                  ST_Q_BLKSIZE, 0, QIC_525,               /* minor 4-7 */
     {"ARCHIVE ", "VIPER 150", "????",                  0, 0, QIC_150,                          /* minor 8-11 */
         0, 12,                  0, 0, QIC_120                           /* minor 12-15 */
         {          }},
             {0, 0, 0},                                  /* minor 0-3 */          {T_SEQUENTIAL, T_REMOV,
             {0, 0, QIC_150},                            /* minor 4-7 */           "WangDAT ", "Model 1300      ", "",     0, 0, {
             {0, 0, QIC_120},                            /* minor 8-11 */                  0, 0, 0,                                /* minor 0-3 */
             {0, 0, QIC_24}                              /* minor 12-15 */                  ST_Q_FORCE_BLKSIZE, 512, DDS,           /* minor 4-7 */
         }                  ST_Q_FORCE_BLKSIZE, 1024, DDS,          /* minor 8-11 */
     },                  ST_Q_FORCE_BLKSIZE, 0, DDS              /* minor 12-15 */
     {"WANGTEK ", "5525ES SCSI REV7", "????",          }},
         0, 0,  
         {  
             {0, 0, 0},                                  /* minor 0-3 */  
             {0, ST_Q_BLKSIZ, QIC_525},                  /* minor 4-7 */  
             {0, 0, QIC_150},                            /* minor 8-11 */  
             {0, 0, QIC_120}                             /* minor 12-15 */  
         }  
     },  
     {"WangDAT ", "Model 1300", "????",  
         0, 0,  
         {  
             {0, 0, 0},                                  /* minor 0-3 */  
             {512, ST_Q_FORCE_FIXED_MODE, DDS},          /* minor 4-7 */  
             {1024, ST_Q_FORCE_FIXED_MODE, DDS},         /* minor 8-11 */  
             {0, ST_Q_FORCE_VAR_MODE, DDS}               /* minor 12-15 */  
         }  
     },  
 #if 0  #if 0
     {"EXABYTE ", "EXB-8200", "????",          {T_SEQUENTIAL, T_REMOV,
         0, 5,           "EXABYTE ", "EXB-8200        ", "",     0, 12, {
         {                  0, 0, 0,                                /* minor 0-3 */
             {0, 0, 0},                                  /* minor 0-3 */                  0, 0, 0,                                /* minor 4-7 */
             {0, 0, 0},                                  /* minor 4-7 */                  0, 0, 0,                                /* minor 8-11 */
             {0, 0, 0},                                  /* minor 8-11 */                  0, 0, 0                                 /* minor 12-15 */
             {0, 0, 0}                                   /* minor 12-15 */          }},
         }  
     },  
 #endif  #endif
     {0}  
 };  };
   
 #define NOEJECT 0  #define NOEJECT 0
 #define EJECT 1  #define EJECT 1
   
 struct st_data {  struct st_softc {
         struct device sc_dev;          struct device sc_dev;
 /*--------------------present operating parameters, flags etc.----------------*/  /*--------------------present operating parameters, flags etc.----------------*/
         int flags;              /* see below                          */          int flags;              /* see below                          */
         u_int blksiz;           /* blksiz we are using                */  
         u_int density;          /* present density                    */  
         u_int quirks;           /* quirks for the open mode           */          u_int quirks;           /* quirks for the open mode           */
           int blksize;            /* blksize we are using                */
           u_int8_t density;       /* present density                    */
         u_int page_0_size;      /* size of page 0 data                */          u_int page_0_size;      /* size of page 0 data                */
         u_int last_dsty;        /* last density openned               */          u_int last_dsty;        /* last density opened               */
 /*--------------------device/scsi parameters----------------------------------*/  /*--------------------device/scsi parameters----------------------------------*/
         struct scsi_link *sc_link;      /* our link to the adpter etc.        */          struct scsi_link *sc_link;      /* our link to the adpter etc.        */
 /*--------------------parameters reported by the device ----------------------*/  /*--------------------parameters reported by the device ----------------------*/
         u_int blkmin;           /* min blk size                       */          int blkmin;             /* min blk size                       */
         u_int blkmax;           /* max blk size                       */          int blkmax;             /* max blk size                       */
         struct rogues *rogues;  /* if we have a rogue entry           */          struct quirkdata *quirkdata;    /* if we have a rogue entry           */
 /*--------------------parameters reported by the device for this media--------*/  /*--------------------parameters reported by the device for this media--------*/
         u_int numblks;          /* nominal blocks capacity            */          u_long numblks;         /* nominal blocks capacity            */
         u_int media_blksiz;     /* 0 if not ST_FIXEDBLOCKS            */          int media_blksize;      /* 0 if not ST_FIXEDBLOCKS            */
         u_int media_density;    /* this is what it said when asked    */          u_int8_t media_density; /* this is what it said when asked    */
 /*--------------------quirks for the whole drive------------------------------*/  /*--------------------quirks for the whole drive------------------------------*/
         u_int drive_quirks;     /* quirks of this drive               */          u_int drive_quirks;     /* quirks of this drive               */
 /*--------------------How we should set up when openning each minor device----*/  /*--------------------How we should set up when opening each minor device----*/
         struct modes modes[4];  /* plus more for each mode            */          struct modes modes[4];  /* plus more for each mode            */
         u_int8  modeflags[4];   /* flags for the modes                */          u_int8_t  modeflags[4]; /* flags for the modes                */
 #define DENSITY_SET_BY_USER     0x01  #define DENSITY_SET_BY_USER     0x01
 #define DENSITY_SET_BY_QUIRK    0x02  #define DENSITY_SET_BY_QUIRK    0x02
 #define BLKSIZE_SET_BY_USER     0x04  #define BLKSIZE_SET_BY_USER     0x04
Line 233  struct st_data {
Line 213  struct st_data {
                                                  * for mode sense/select.                                                   * for mode sense/select.
                                                  */                                                   */
         struct buf buf_queue;           /* the queue of pending IO operations */          struct buf buf_queue;           /* the queue of pending IO operations */
         struct scsi_xfer scsi_xfer;     /* scsi xfer struct for this drive */  
         u_int xfer_block_wait;          /* is a process waiting? */  
 };  };
   
   int stmatch __P((struct device *, void *, void *));
 void stattach __P((struct device *, struct device *, void *));  void stattach __P((struct device *, struct device *, void *));
   
 struct cfdriver stcd = {  struct cfdriver stcd = {
         NULL, "st", scsi_targmatch, stattach, DV_TAPE, sizeof(struct st_data)          NULL, "st", stmatch, stattach, DV_TAPE, sizeof(struct st_softc)
 };  };
   
 int     st_space __P((struct st_data *, int number, u_int what, int flags));  int     st_space __P((struct st_softc *, int number, u_int what, int flags));
 int     st_rewind __P((struct st_data *, u_int immediate, int flags));  int     st_rewind __P((struct st_softc *, u_int immediate, int flags));
 int     st_mode_sense __P((struct st_data *, int flags));  int     st_mode_sense __P((struct st_softc *, int flags));
 int     st_decide_mode __P((struct st_data *, boolean first_read));  int     st_decide_mode __P((struct st_softc *, boolean first_read));
 int     st_read_block_limits __P((struct st_data *, int flags));  int     st_read_block_limits __P((struct st_softc *, int flags));
 int     st_touch_tape __P((struct st_data *));  int     st_touch_tape __P((struct st_softc *));
 int     st_write_filemarks __P((struct st_data *, int number, int flags));  int     st_write_filemarks __P((struct st_softc *, int number, int flags));
 int     st_load __P((struct st_data *, u_int type, int flags));  int     st_load __P((struct st_softc *, u_int type, int flags));
 int     st_mode_select __P((struct st_data *, int flags));  int     st_mode_select __P((struct st_softc *, int flags));
 void    ststrategy();  void    ststrategy();
 void    stminphys();  void    stminphys();
 int     st_check_eod();  int     st_check_eod();
Line 267  struct scsi_device st_switch = {
Line 246  struct scsi_device st_switch = {
         ststart,          ststart,
         NULL,          NULL,
         NULL,          NULL,
         "st",  
         0  
 };  };
   
 #define ST_INFO_VALID   0x0001  #define ST_INFO_VALID   0x0001
Line 290  struct scsi_device st_switch = {
Line 267  struct scsi_device st_switch = {
   
 #define ST_PER_ACTION   (ST_AT_FILEMARK | ST_EIO_PENDING | ST_BLANK_READ)  #define ST_PER_ACTION   (ST_AT_FILEMARK | ST_EIO_PENDING | ST_BLANK_READ)
 #define ST_PER_MOUNT    (ST_INFO_VALID | ST_BLOCK_SET | ST_WRITTEN | \  #define ST_PER_MOUNT    (ST_INFO_VALID | ST_BLOCK_SET | ST_WRITTEN | \
                         ST_FIXEDBLOCKS | ST_READONLY | \                           ST_FIXEDBLOCKS | ST_READONLY | ST_FM_WRITTEN | \
                         ST_FM_WRITTEN | ST_2FM_AT_EOD | ST_PER_ACTION)                           ST_2FM_AT_EOD | ST_PER_ACTION)
   
   struct scsi_inquiry_pattern st_patterns[] = {
           {T_SEQUENTIAL, T_REMOV,
            "",         "",                 ""},
   };
   
   int
   stmatch(parent, match, aux)
           struct device *parent;
           void *match, *aux;
   {
           struct cfdata *cf = match;
           struct scsibus_attach_args *sa = aux;
           int priority;
   
           (void)scsi_inqmatch(sa->sa_inqbuf,
               (caddr_t)st_patterns, sizeof(st_patterns)/sizeof(st_patterns[0]),
               sizeof(st_patterns[0]), &priority);
           return (priority);
   }
   
 /*  /*
  * The routine called by the low level scsi routine when it discovers   * The routine called by the low level scsi routine when it discovers
Line 302  stattach(parent, self, aux)
Line 299  stattach(parent, self, aux)
         struct device *parent, *self;          struct device *parent, *self;
         void *aux;          void *aux;
 {  {
         struct st_data *st = (void *)self;          struct st_softc *st = (void *)self;
         struct scsi_link *sc_link = aux;          struct scsibus_attach_args *sa = aux;
           struct scsi_link *sc_link = sa->sa_sc_link;
   
         SC_DEBUG(sc_link, SDEV_DB2, ("stattach: "));          SC_DEBUG(sc_link, SDEV_DB2, ("stattach: "));
   
         sc_link->device = &st_switch;  
         sc_link->device_softc = st;  
   
         /*          /*
          * Store information needed to contact our base driver           * Store information needed to contact our base driver
          */           */
         st->sc_link = sc_link;          st->sc_link = sc_link;
           sc_link->device = &st_switch;
           sc_link->device_softc = st;
           sc_link->openings = 1;
   
         /*          /*
          * Check if the drive is a known criminal and take           * Check if the drive is a known criminal and take
          * Any steps needed to bring it into line           * Any steps needed to bring it into line
          */           */
         st_identify_drive(st);          st_identify_drive(st, sa->sa_inqbuf);
   
         /*          /*
          * Use the subdriver to request information regarding           * Use the subdriver to request information regarding
          * the drive. We cannot use interrupts yet, so the           * the drive. We cannot use interrupts yet, so the
          * request must specify this.           * request must specify this.
          */           */
         printf(": %s", st->rogues ? "rogue, " : "");          printf(": %s", st->quirkdata ? "rogue, " : "");
         if (st_mode_sense(st, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT))          if (scsi_test_unit_ready(sc_link,
                 printf("drive offline\n");              SCSI_AUTOCONF | SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE) ||
         else if (scsi_test_unit_ready(sc_link,              st_mode_sense(st,
             SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT))              SCSI_AUTOCONF | SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE))
                 printf("drive empty\n");                  printf("drive empty\n");
         else {          else {
                 printf("density code 0x%x, ", st->media_density);                  printf("density code 0x%x, ", st->media_density);
                 if (st->media_blksiz)                  if (st->media_blksize > 0)
                         printf("%d-byte", st->media_blksiz);                          printf("%d-byte", st->media_blksize);
                 else                  else
                         printf("variable");                          printf("variable");
                 printf(" blocks, write-%s\n",                  printf(" blocks, write-%s\n",
Line 355  stattach(parent, self, aux)
Line 353  stattach(parent, self, aux)
  * Further tailor our behaviour.   * Further tailor our behaviour.
  */   */
 void  void
 st_identify_drive(st)  st_identify_drive(st, inqbuf)
         struct st_data *st;          struct st_softc *st;
 {          struct scsi_inquiry_data *inqbuf;
         struct scsi_inquiry_data inqbuf;  {
         struct rogues *finger;          struct st_quirk_inquiry_pattern *finger;
         char manu[32];          int priority;
         char model[32];  
         char model2[32];          finger = (struct st_quirk_inquiry_pattern *)scsi_inqmatch(inqbuf,
         char version[32];              (caddr_t)st_quirk_patterns,
         u_int model_len;              sizeof(st_quirk_patterns)/sizeof(st_quirk_patterns[0]),
               sizeof(st_quirk_patterns[0]), &priority);
         /*          if (priority != 0) {
          * Get the device type information                  st->quirkdata = &finger->quirkdata;
          */                  st->drive_quirks = finger->quirkdata.quirks;
         if (scsi_inquire(st->sc_link, &inqbuf,                  st->quirks = finger->quirkdata.quirks;  /* start value */
             SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT) != 0) {                  st->page_0_size = finger->quirkdata.page_0_size;
                 printf("%s: couldn't get device type, using default\n",                  st_loadquirks(st);
                     st->sc_dev.dv_xname);  
                 return;  
         }  
         if ((inqbuf.version & SID_ANSII) == 0) {  
                 /*  
                  * If not advanced enough, use default values  
                  */  
                 strncpy(manu, "pre-scsi", 8);  
                 manu[8] = 0;  
                 strncpy(model, " unknown model  ", 16);  
                 model[16] = 0;  
                 strncpy(version, "????", 4);  
                 version[4] = 0;  
         } else {  
                 strncpy(manu, inqbuf.vendor, 8);  
                 manu[8] = 0;  
                 strncpy(model, inqbuf.product, 16);  
                 model[16] = 0;  
                 strncpy(version, inqbuf.revision, 4);  
                 version[4] = 0;  
         }  
   
         /*  
          * Load the parameters for this kind of device, so we  
          * treat it as appropriate for each operating mode.  
          * Only check the number of characters in the array's  
          * model entry, not the entire model string returned.  
          */  
         finger = gallery;  
         while (finger->manu) {  
                 model_len = 0;  
                 while (finger->model[model_len] && (model_len < 32)) {  
                         model2[model_len] = model[model_len];  
                         model_len++;  
                 }  
                 model2[model_len] = 0;  
                 if ((strcmp(manu, finger->manu) == 0) &&  
                     (strcmp(model2, finger->model) == 0 ||  
                     strcmp("????????????????", finger->model) == 0) &&  
                     (strcmp(version, finger->version) == 0 ||  
                     strcmp("????", finger->version) == 0)) {  
                         st->rogues = finger;  
                         st->drive_quirks = finger->quirks;  
                         st->quirks = finger->quirks;    /* start value */  
                         st->page_0_size = finger->page_0_size;  
                         st_loadquirks(st);  
                         break;  
                 } else  
                         finger++;       /* go to next suspect */  
         }          }
 }  }
   
Line 431  st_identify_drive(st)
Line 380  st_identify_drive(st)
  */   */
 void  void
 st_loadquirks(st)  st_loadquirks(st)
         struct st_data *st;          struct st_softc *st;
 {  {
         int i;          int i;
         struct  modes *mode;          struct  modes *mode;
         struct  modes *mode2;          struct  modes *mode2;
   
         if (!st->rogues)          mode = st->quirkdata->modes;
                 return;  
         mode = st->rogues->modes;  
         mode2 = st->modes;          mode2 = st->modes;
         for (i = 0; i < 4; i++) {          for (i = 0; i < 4; i++) {
                 bzero(mode2, sizeof(struct modes));                  bzero(mode2, sizeof(struct modes));
                 st->modeflags[i] &= ~(BLKSIZE_SET_BY_QUIRK |                  st->modeflags[i] &= ~(BLKSIZE_SET_BY_QUIRK |
                     DENSITY_SET_BY_QUIRK | BLKSIZE_SET_BY_USER |                      DENSITY_SET_BY_QUIRK | BLKSIZE_SET_BY_USER |
                     DENSITY_SET_BY_USER);                      DENSITY_SET_BY_USER);
                 if (mode->blksiz && ((mode->quirks | st->drive_quirks) &                  if ((mode->quirks | st->drive_quirks) & ST_Q_FORCE_BLKSIZE) {
                     ST_Q_FORCE_FIXED_MODE)) {                          mode2->blksize = mode->blksize;
                         mode2->blksiz = mode->blksiz;  
                         st->modeflags[i] |= BLKSIZE_SET_BY_QUIRK;  
                 } else if ((mode->quirks | st->drive_quirks) &  
                     ST_Q_FORCE_VAR_MODE) {  
                         mode2->blksiz = 0;  
                         st->modeflags[i] |= BLKSIZE_SET_BY_QUIRK;                          st->modeflags[i] |= BLKSIZE_SET_BY_QUIRK;
                 }                  }
                 if (mode->density) {                  if (mode->density) {
Line 475  stopen(dev, flags)
Line 417  stopen(dev, flags)
         int unit;          int unit;
         u_int mode, dsty;          u_int mode, dsty;
         int error = 0;          int error = 0;
         struct st_data *st;          struct st_softc *st;
         struct scsi_link *sc_link;          struct scsi_link *sc_link;
   
         unit = STUNIT(dev);          unit = STUNIT(dev);
Line 503  stopen(dev, flags)
Line 445  stopen(dev, flags)
         /*          /*
          * Catch any unit attention errors.           * Catch any unit attention errors.
          */           */
         scsi_test_unit_ready(sc_link, SCSI_SILENT);          if (error = scsi_test_unit_ready(sc_link,
               SCSI_IGNORE_MEDIA_CHANGE | (mode == CTLMODE ? SCSI_IGNORE_NOT_READY : 0)))
                   goto bad;
   
         sc_link->flags |= SDEV_OPEN;    /* unit attn are now errors */          sc_link->flags |= SDEV_OPEN;    /* unit attn are now errors */
   
         /*          /*
          * If the mode is 3 (e.g. minor = 3,7,11,15)           * If the mode is 3 (e.g. minor = 3,7,11,15)
          * then the device has been openned to set defaults           * then the device has been opened to set defaults
          * This mode does NOT ALLOW I/O, only ioctls           * This mode does NOT ALLOW I/O, only ioctls
          */           */
         if (mode == CTLMODE)          if (mode == CTLMODE)
                 return 0;                  return 0;
   
         /*          /*
          * Check that the device is ready to use (media loaded?)  
          * This time take notice of the return result  
          */  
         if (scsi_test_unit_ready(sc_link, 0)) {  
                 SC_DEBUG(sc_link, SDEV_DB3, ("device not responding\n"));  
                 st_unmount(st, NOEJECT);  
                 error = EIO;  
                 goto bad;  
         }  
   
         /*  
          * 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
Line 555  stopen(dev, flags)
Line 488  stopen(dev, flags)
         return 0;          return 0;
   
 bad:  bad:
           st_unmount(st, NOEJECT);
         sc_link->flags &= ~SDEV_OPEN;          sc_link->flags &= ~SDEV_OPEN;
         return error;          return error;
 }  }
Line 567  int 
Line 501  int 
 stclose(dev)  stclose(dev)
         dev_t dev;          dev_t dev;
 {  {
         struct st_data *st = stcd.cd_devs[STUNIT(dev)];          struct st_softc *st = stcd.cd_devs[STUNIT(dev)];
   
         SC_DEBUG(st->sc_link, SDEV_DB1, ("closing\n"));          SC_DEBUG(st->sc_link, SDEV_DB1, ("closing\n"));
         if ((st->flags & (ST_WRITTEN | ST_FM_WRITTEN)) == ST_WRITTEN)          if ((st->flags & (ST_WRITTEN | ST_FM_WRITTEN)) == ST_WRITTEN)
Line 603  st_mount_tape(dev, flags)
Line 537  st_mount_tape(dev, flags)
 {  {
         int unit;          int unit;
         u_int mode, dsty;          u_int mode, dsty;
         struct st_data *st;          struct st_softc *st;
         struct scsi_link *sc_link;          struct scsi_link *sc_link;
         int error = 0;          int error = 0;
   
Line 631  st_mount_tape(dev, flags)
Line 565  st_mount_tape(dev, flags)
          * these after doing a Load instruction.           * these after doing a Load instruction.
          * (noteably some DAT drives)           * (noteably some DAT drives)
          */           */
         scsi_test_unit_ready(sc_link, SCSI_SILENT);          scsi_test_unit_ready(sc_link, SCSI_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 648  st_mount_tape(dev, flags)
Line 582  st_mount_tape(dev, flags)
                 return error;                  return error;
         /*          /*
          * Load the media dependent parameters           * Load the media dependent parameters
          * includes: media_blksiz,media_density,numblks           * includes: media_blksize,media_density,numblks
          * As we have a tape in, it should be reflected here.           * As we have a tape in, it should be reflected here.
          * If not you may need the "quirk" above.           * If not you may need the "quirk" above.
          */           */
Line 670  st_mount_tape(dev, flags)
Line 604  st_mount_tape(dev, flags)
          */           */
         st->flags &= ~ST_FIXEDBLOCKS;          st->flags &= ~ST_FIXEDBLOCKS;
         if (st->modeflags[dsty] & (BLKSIZE_SET_BY_QUIRK | BLKSIZE_SET_BY_USER)) {          if (st->modeflags[dsty] & (BLKSIZE_SET_BY_QUIRK | BLKSIZE_SET_BY_USER)) {
                 st->blksiz = st->modes[dsty].blksiz;                  st->blksize = st->modes[dsty].blksize;
                 if (st->blksiz)                  if (st->blksize)
                         st->flags |= ST_FIXEDBLOCKS;                          st->flags |= ST_FIXEDBLOCKS;
         } else {          } else {
                 if (error = st_decide_mode(st, FALSE))                  if (error = st_decide_mode(st, FALSE))
Line 681  st_mount_tape(dev, flags)
Line 615  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;
         }          }
         scsi_prevent(sc_link, PR_PREVENT, 0);   /* who cares if it fails? */          scsi_prevent(sc_link, PR_PREVENT,
               SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_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? */          sc_link->flags |= SDEV_MEDIA_LOADED;    /* move earlier? */
Line 697  st_mount_tape(dev, flags)
Line 632  st_mount_tape(dev, flags)
  */   */
 void  void
 st_unmount(st, eject)  st_unmount(st, eject)
         struct st_data *st;          struct st_softc *st;
         boolean eject;          boolean eject;
 {  {
         struct scsi_link *sc_link = st->sc_link;          struct scsi_link *sc_link = st->sc_link;
Line 706  st_unmount(st, eject)
Line 641  st_unmount(st, eject)
         if (!(st->flags & ST_MOUNTED))          if (!(st->flags & ST_MOUNTED))
                 return;                  return;
         SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n"));          SC_DEBUG(sc_link, SDEV_DB1, ("unmounting\n"));
         st_check_eod(st, FALSE, &nmarks, SCSI_SILENT);          st_check_eod(st, FALSE, &nmarks, SCSI_IGNORE_NOT_READY);
         st_rewind(st, 0, SCSI_SILENT);          st_rewind(st, 0, SCSI_IGNORE_NOT_READY);
         scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT);          scsi_prevent(sc_link, PR_ALLOW,
               SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
         if (eject)          if (eject)
                 st_load(st, LD_UNLOAD, SCSI_SILENT);                  st_load(st, LD_UNLOAD, SCSI_IGNORE_NOT_READY);
         st->flags &= ~(ST_MOUNTED | ST_NEW_MOUNT);          st->flags &= ~(ST_MOUNTED | ST_NEW_MOUNT);
         sc_link->flags &= ~SDEV_MEDIA_LOADED;          sc_link->flags &= ~SDEV_MEDIA_LOADED;
 }  }
Line 722  st_unmount(st, eject)
Line 658  st_unmount(st, eject)
  */   */
 int  int
 st_decide_mode(st, first_read)  st_decide_mode(st, first_read)
         struct st_data *st;          struct st_softc *st;
         boolean first_read;          boolean first_read;
 {  {
 #ifdef SCSIDEBUG  #ifdef SCSIDEBUG
Line 732  st_decide_mode(st, first_read)
Line 668  st_decide_mode(st, first_read)
         SC_DEBUG(sc_link, SDEV_DB2, ("starting block mode decision\n"));          SC_DEBUG(sc_link, SDEV_DB2, ("starting block mode decision\n"));
   
         /*          /*
          * If the user hasn't already specified fixed or variable-length  
          * blocks and the block size (zero if variable-length), we'll  
          * have to try to figure them out ourselves.  
          *  
          * Our first shot at a method is, "The quirks made me do it!"  
          */  
         switch (st->quirks & (ST_Q_FORCE_FIXED_MODE | ST_Q_FORCE_VAR_MODE)) {  
         case (ST_Q_FORCE_FIXED_MODE | ST_Q_FORCE_VAR_MODE):  
                 printf("%s: bad quirks\n", st->sc_dev.dv_xname);  
                 return EINVAL;  
         case ST_Q_FORCE_FIXED_MODE:     /*specified fixed, but not what size */  
                 st->flags |= ST_FIXEDBLOCKS;  
                 if (st->blkmin && (st->blkmin == st->blkmax))  
                         st->blksiz = st->blkmin;  
                 else if (st->media_blksiz > 0)  
                         st->blksiz = st->media_blksiz;  
                 else  
                         st->blksiz = DEF_FIXED_BSIZE;  
                 SC_DEBUG(sc_link, SDEV_DB3, ("Quirks force fixed mode(%d)\n",  
                         st->blksiz));  
                 goto done;  
         case ST_Q_FORCE_VAR_MODE:  
                 st->flags &= ~ST_FIXEDBLOCKS;  
                 st->blksiz = 0;  
                 SC_DEBUG(sc_link, SDEV_DB3, ("Quirks force variable mode\n"));  
                 goto done;  
         }  
   
         /*  
          * If the drive can only handle fixed-length blocks and only at           * If the drive can only handle fixed-length blocks and only at
          * one size, perhaps we should just do that.           * one size, perhaps we should just do that.
          */           */
         if (st->blkmin && (st->blkmin == st->blkmax)) {          if (st->blkmin && (st->blkmin == st->blkmax)) {
                 st->flags |= ST_FIXEDBLOCKS;                  st->flags |= ST_FIXEDBLOCKS;
                 st->blksiz = st->blkmin;                  st->blksize = st->blkmin;
                 SC_DEBUG(sc_link, SDEV_DB3,                  SC_DEBUG(sc_link, SDEV_DB3,
                     ("blkmin == blkmax of %d\n", st->blkmin));                      ("blkmin == blkmax of %d\n", st->blkmin));
                 goto done;                  goto done;
Line 781  st_decide_mode(st, first_read)
Line 688  st_decide_mode(st, first_read)
         case HALFINCH_6250:          case HALFINCH_6250:
         case DDS:          case DDS:
                 st->flags &= ~ST_FIXEDBLOCKS;                  st->flags &= ~ST_FIXEDBLOCKS;
                 st->blksiz = 0;                  st->blksize = 0;
                 SC_DEBUG(sc_link, SDEV_DB3, ("density specified variable\n"));                  SC_DEBUG(sc_link, SDEV_DB3, ("density specified variable\n"));
                 goto done;                  goto done;
         case QIC_11:          case QIC_11:
Line 791  st_decide_mode(st, first_read)
Line 698  st_decide_mode(st, first_read)
         case QIC_525:          case QIC_525:
         case QIC_1320:          case QIC_1320:
                 st->flags |= ST_FIXEDBLOCKS;                  st->flags |= ST_FIXEDBLOCKS;
                 if (st->media_blksiz > 0)                  if (st->media_blksize > 0)
                         st->blksiz = st->media_blksiz;                          st->blksize = st->media_blksize;
                 else                  else
                         st->blksiz = DEF_FIXED_BSIZE;                          st->blksize = DEF_FIXED_BSIZE;
                 SC_DEBUG(sc_link, SDEV_DB3, ("density specified fixed\n"));                  SC_DEBUG(sc_link, SDEV_DB3, ("density specified fixed\n"));
                 goto done;                  goto done;
         }          }
Line 804  st_decide_mode(st, first_read)
Line 711  st_decide_mode(st, first_read)
          * what the drive found on the tape.           * what the drive found on the tape.
          */           */
         if (first_read &&          if (first_read &&
             (!(st->quirks & ST_Q_BLKSIZ) || (st->media_blksiz == 0) ||              (!(st->quirks & ST_Q_BLKSIZE) || (st->media_blksize == 0) ||
             (st->media_blksiz == DEF_FIXED_BSIZE) ||              (st->media_blksize == DEF_FIXED_BSIZE) ||
             (st->media_blksiz == 1024))) {              (st->media_blksize == 1024))) {
                 if (st->media_blksiz == 0)                  if (st->media_blksize > 0)
                         st->flags &= ~ST_FIXEDBLOCKS;  
                 else  
                         st->flags |= ST_FIXEDBLOCKS;                          st->flags |= ST_FIXEDBLOCKS;
                 st->blksiz = st->media_blksiz;                  else
                           st->flags &= ~ST_FIXEDBLOCKS;
                   st->blksize = st->media_blksize;
                 SC_DEBUG(sc_link, SDEV_DB3,                  SC_DEBUG(sc_link, SDEV_DB3,
                     ("Used media_blksiz of %d\n", st->media_blksiz));                      ("Used media_blksize of %d\n", st->media_blksize));
                 goto done;                  goto done;
         }          }
         /*          /*
Line 821  st_decide_mode(st, first_read)
Line 728  st_decide_mode(st, first_read)
          * length blocks arbitrarily.           * length blocks arbitrarily.
          */           */
         st->flags &= ~ST_FIXEDBLOCKS;          st->flags &= ~ST_FIXEDBLOCKS;
         st->blksiz = 0;          st->blksize = 0;
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(sc_link, SDEV_DB3,
             ("Give up and default to variable mode\n"));              ("Give up and default to variable mode\n"));
 done:  
   
   done:
         /*          /*
          * Decide whether or not to write two file marks to signify end-           * Decide whether or not to write two file marks to signify end-
          * of-data.  Make the decision as a function of density.  If           * of-data.  Make the decision as a function of density.  If
Line 860  void 
Line 767  void 
 stminphys(bp)  stminphys(bp)
         struct buf *bp;          struct buf *bp;
 {  {
         register struct st_data *st = stcd.cd_devs[STUNIT(bp->b_dev)];          register struct st_softc *st = stcd.cd_devs[STUNIT(bp->b_dev)];
   
         (st->sc_link->adapter->scsi_minphys) (bp);          (st->sc_link->adapter->scsi_minphys) (bp);
 }  }
Line 875  void 
Line 782  void 
 ststrategy(bp)  ststrategy(bp)
         struct buf *bp;          struct buf *bp;
 {  {
         struct st_data *st = stcd.cd_devs[STUNIT(bp->b_dev)];          struct st_softc *st = stcd.cd_devs[STUNIT(bp->b_dev)];
         struct buf *dp;          struct buf *dp;
         int opri;          int opri;
   
Line 890  ststrategy(bp)
Line 797  ststrategy(bp)
          * Odd sized request on fixed drives are verboten           * Odd sized request on fixed drives are verboten
          */           */
         if (st->flags & ST_FIXEDBLOCKS) {          if (st->flags & ST_FIXEDBLOCKS) {
                 if (bp->b_bcount % st->blksiz) {                  if (bp->b_bcount % st->blksize) {
                         printf("%s: bad request, must be multiple of %d\n",                          printf("%s: bad request, must be multiple of %d\n",
                             st->sc_dev.dv_xname, st->blksiz);                              st->sc_dev.dv_xname, st->blksize);
                         bp->b_error = EIO;                          bp->b_error = EIO;
                         goto bad;                          goto bad;
                 }                  }
Line 956  done:
Line 863  done:
  */   */
 void  void
 ststart(st)  ststart(st)
         struct st_data *st;          struct st_softc *st;
 {  {
         struct scsi_link *sc_link = st->sc_link;          struct scsi_link *sc_link = st->sc_link;
         register struct buf *bp, *dp;          register struct buf *bp, *dp;
Line 968  ststart(st)
Line 875  ststart(st)
          * 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->opennings) {          while (sc_link->openings > 0) {
                 /* if a special awaits, let it proceed first */                  /* if a special awaits, let it proceed first */
                 if (sc_link->flags & SDEV_WAITING) {                  if (sc_link->flags & SDEV_WAITING) {
                         sc_link->flags &= ~SDEV_WAITING;                          sc_link->flags &= ~SDEV_WAITING;
Line 1048  ststart(st)
Line 955  ststart(st)
                  */                   */
                 bzero(&cmd, sizeof(cmd));                  bzero(&cmd, sizeof(cmd));
                 if ((bp->b_flags & B_READ) == B_WRITE) {                  if ((bp->b_flags & B_READ) == B_WRITE) {
                         cmd.op_code = WRITE;                          cmd.opcode = WRITE;
                         st->flags &= ~ST_FM_WRITTEN;                          st->flags &= ~ST_FM_WRITTEN;
                         st->flags |= ST_WRITTEN;                          st->flags |= ST_WRITTEN;
                         flags = SCSI_DATA_OUT;                          flags = SCSI_DATA_OUT;
                 } else {                  } else {
                         cmd.op_code = READ;                          cmd.opcode = READ;
                         flags = SCSI_DATA_IN;                          flags = SCSI_DATA_IN;
                 }                  }
   
Line 1063  ststart(st)
Line 970  ststart(st)
                  */                   */
                 if (st->flags & ST_FIXEDBLOCKS) {                  if (st->flags & ST_FIXEDBLOCKS) {
                         cmd.byte2 |= SRW_FIXED;                          cmd.byte2 |= SRW_FIXED;
                         lto3b(bp->b_bcount / st->blksiz, cmd.len);                          lto3b(bp->b_bcount / st->blksize, cmd.len);
                 } else                  } else
                         lto3b(bp->b_bcount, cmd.len);                          lto3b(bp->b_bcount, cmd.len);
   
Line 1072  ststart(st)
Line 979  ststart(st)
                  */                   */
                 if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,                  if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
                     sizeof(cmd), (u_char *) bp->b_data, bp->b_bcount, 0,                      sizeof(cmd), (u_char *) bp->b_data, bp->b_bcount, 0,
                     100000, bp, flags | SCSI_NOSLEEP) != SUCCESSFULLY_QUEUED)                      100000, bp, flags | SCSI_NOSLEEP))
                         printf("%s: not queued\n", st->sc_dev.dv_xname);                          printf("%s: not queued\n", st->sc_dev.dv_xname);
         } /* go back and see if we can cram more work in.. */          } /* go back and see if we can cram more work in.. */
 }  }
Line 1082  ststart(st)
Line 989  ststart(st)
  * knows about the internals of this device   * knows about the internals of this device
  */   */
 int  int
 stioctl(dev, cmd, arg, flag)  stioctl(dev, cmd, arg, flag, p)
         dev_t dev;          dev_t dev;
         u_long cmd;          u_long cmd;
         caddr_t arg;          caddr_t arg;
         int flag;          int flag;
           struct proc *p;
 {  {
         int error = 0;          int error = 0;
         int unit;          int unit;
         int number, nmarks, dsty;          int number, nmarks, dsty;
         int flags;          int flags;
         struct st_data *st;          struct st_softc *st;
         u_int hold_blksiz;          int hold_blksize;
         u_int hold_density;          u_int8_t hold_density;
         struct mtop *mt = (struct mtop *) arg;          struct mtop *mt = (struct mtop *) arg;
   
         /*          /*
Line 1104  stioctl(dev, cmd, arg, flag)
Line 1012  stioctl(dev, cmd, arg, flag)
         unit = STUNIT(dev);          unit = STUNIT(dev);
         dsty = STDSTY(dev);          dsty = STDSTY(dev);
         st = stcd.cd_devs[unit];          st = stcd.cd_devs[unit];
         hold_blksiz = st->blksiz;          hold_blksize = st->blksize;
         hold_density = st->density;          hold_density = st->density;
   
         switch (cmd) {          switch (cmd) {
Line 1115  stioctl(dev, cmd, arg, flag)
Line 1023  stioctl(dev, cmd, arg, flag)
                 SC_DEBUG(st->sc_link, SDEV_DB1, ("[ioctl: get status]\n"));                  SC_DEBUG(st->sc_link, SDEV_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->blksiz;                  g->mt_blksiz = st->blksize;
                 g->mt_density = st->density;                  g->mt_density = st->density;
                 g->mt_mblksiz[0] = st->modes[0].blksiz;                  g->mt_mblksiz[0] = st->modes[0].blksize;
                 g->mt_mblksiz[1] = st->modes[1].blksiz;                  g->mt_mblksiz[1] = st->modes[1].blksize;
                 g->mt_mblksiz[2] = st->modes[2].blksiz;                  g->mt_mblksiz[2] = st->modes[2].blksize;
                 g->mt_mblksiz[3] = st->modes[3].blksiz;                  g->mt_mblksiz[3] = st->modes[3].blksize;
                 g->mt_mdensity[0] = st->modes[0].density;                  g->mt_mdensity[0] = st->modes[0].density;
                 g->mt_mdensity[1] = st->modes[1].density;                  g->mt_mdensity[1] = st->modes[1].density;
                 g->mt_mdensity[2] = st->modes[2].density;                  g->mt_mdensity[2] = st->modes[2].density;
Line 1193  stioctl(dev, cmd, arg, flag)
Line 1101  stioctl(dev, cmd, arg, flag)
                                 }                                  }
                                 st->flags |= ST_FIXEDBLOCKS;                                  st->flags |= ST_FIXEDBLOCKS;
                         }                          }
                         st->blksiz = number;                          st->blksize = number;
                         st->flags |= ST_BLOCK_SET;      /*XXX */                          st->flags |= ST_BLOCK_SET;      /*XXX */
                         goto try_new_value;                          goto try_new_value;
   
Line 1214  stioctl(dev, cmd, arg, flag)
Line 1122  stioctl(dev, cmd, arg, flag)
                 break;                  break;
         default:          default:
                 if (STMODE(dev) == CTLMODE)                  if (STMODE(dev) == CTLMODE)
                         error = scsi_do_ioctl(st->sc_link, dev, cmd, arg, flag);                          error = scsi_do_ioctl(st->sc_link, dev, cmd, arg, flag, p);
                 else                  else
                         error = ENOTTY;                          error = ENOTTY;
                 break;                  break;
Line 1229  try_new_value:
Line 1137  try_new_value:
         if (error = st_mode_select(st, 0)) {    /* put it back as it was */          if (error = st_mode_select(st, 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->blksiz = hold_blksiz;                  st->blksize = hold_blksize;
                 if (st->blksiz)                  if (st->blksize)
                         st->flags |= ST_FIXEDBLOCKS;                          st->flags |= ST_FIXEDBLOCKS;
                 else                  else
                         st->flags &= ~ST_FIXEDBLOCKS;                          st->flags &= ~ST_FIXEDBLOCKS;
Line 1247  try_new_value:
Line 1155  try_new_value:
                 /* XXX */                  /* XXX */
                 switch ((short) (mt->mt_op)) {                  switch ((short) (mt->mt_op)) {
                 case MTSETBSIZ:                  case MTSETBSIZ:
                         st->modes[dsty].blksiz = st->blksiz;                          st->modes[dsty].blksize = st->blksize;
                         st->modeflags[dsty] |= BLKSIZE_SET_BY_USER;                          st->modeflags[dsty] |= BLKSIZE_SET_BY_USER;
                         break;                          break;
                 case MTSETDNSTY:                  case MTSETDNSTY:
Line 1264  try_new_value:
Line 1172  try_new_value:
  */   */
 int  int
 st_read(st, buf, size, flags)  st_read(st, buf, size, flags)
         struct st_data *st;          struct st_softc *st;
         u_int size;          int size;
         int flags;          int flags;
         char *buf;          char *buf;
 {  {
Line 1277  st_read(st, buf, size, flags)
Line 1185  st_read(st, buf, size, flags)
         if (size == 0)          if (size == 0)
                 return 0;                  return 0;
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = READ;          cmd.opcode = READ;
         if (st->flags & ST_FIXEDBLOCKS) {          if (st->flags & ST_FIXEDBLOCKS) {
                 cmd.byte2 |= SRW_FIXED;                  cmd.byte2 |= SRW_FIXED;
                 lto3b(size / (st->blksiz ? st->blksiz : DEF_FIXED_BSIZE),                  lto3b(size / (st->blksize ? st->blksize : DEF_FIXED_BSIZE),
                     cmd.len);                      cmd.len);
         } else          } else
                 lto3b(size, cmd.len);                  lto3b(size, cmd.len);
Line 1300  st_read(st, buf, size, flags)
Line 1208  st_read(st, buf, size, flags)
  */   */
 int  int
 st_read_block_limits(st, flags)  st_read_block_limits(st, flags)
         struct st_data *st;          struct st_softc *st;
         int flags;          int flags;
 {  {
         struct scsi_block_limits cmd;          struct scsi_block_limits cmd;
Line 1318  st_read_block_limits(st, flags)
Line 1226  st_read_block_limits(st, flags)
          * do a 'Read Block Limits'           * do a 'Read Block Limits'
          */           */
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = READ_BLOCK_LIMITS;          cmd.opcode = READ_BLOCK_LIMITS;
   
         /*          /*
          * do the command, update the global values           * do the command, update the global values
Line 1332  st_read_block_limits(st, flags)
Line 1240  st_read_block_limits(st, flags)
         st->blkmax = _3btol(&block_limits.max_length_2);          st->blkmax = _3btol(&block_limits.max_length_2);
   
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(sc_link, SDEV_DB3,
             ("(%d <= blksiz <= %d)\n", st->blkmin, st->blkmax));              ("(%d <= blksize <= %d)\n", st->blkmin, st->blkmax));
         return 0;          return 0;
 }  }
   
Line 1348  st_read_block_limits(st, flags)
Line 1256  st_read_block_limits(st, flags)
  */   */
 int  int
 st_mode_sense(st, flags)  st_mode_sense(st, flags)
         struct st_data *st;          struct st_softc *st;
         int flags;          int flags;
 {  {
         u_int scsi_sense_len;          u_int scsi_sense_len;
Line 1356  st_mode_sense(st, flags)
Line 1264  st_mode_sense(st, flags)
         struct scsi_mode_sense cmd;          struct scsi_mode_sense cmd;
         struct scsi_sense {          struct scsi_sense {
                 struct scsi_mode_header header;                  struct scsi_mode_header header;
                 struct 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_sense;          } scsi_sense;
         struct scsi_link *sc_link = st->sc_link;          struct scsi_link *sc_link = st->sc_link;
Line 1367  st_mode_sense(st, flags)
Line 1275  st_mode_sense(st, flags)
          * Set up a mode sense           * Set up a mode sense
          */           */
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = MODE_SENSE;          cmd.opcode = MODE_SENSE;
         cmd.length = scsi_sense_len;          cmd.length = scsi_sense_len;
   
         /*          /*
Line 1382  st_mode_sense(st, flags)
Line 1290  st_mode_sense(st, flags)
                 return error;                  return error;
   
         st->numblks = _3btol(scsi_sense.blk_desc.nblocks);          st->numblks = _3btol(scsi_sense.blk_desc.nblocks);
         st->media_blksiz = _3btol(scsi_sense.blk_desc.blklen);          st->media_blksize = _3btol(scsi_sense.blk_desc.blklen);
         st->media_density = scsi_sense.blk_desc.density;          st->media_density = scsi_sense.blk_desc.density;
         if (scsi_sense.header.dev_spec & SMH_DSP_WRITE_PROT)          if (scsi_sense.header.dev_spec & SMH_DSP_WRITE_PROT)
                 st->flags |= ST_READONLY;                  st->flags |= ST_READONLY;
         SC_DEBUG(sc_link, SDEV_DB3,          SC_DEBUG(sc_link, SDEV_DB3,
             ("density code 0x%x, %d-byte blocks, write-%s, ",              ("density code 0x%x, %d-byte blocks, write-%s, ",
             st->media_density, st->media_blksiz,              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(sc_link, SDEV_DB3,
             ("%sbuffered\n",              ("%sbuffered\n",
Line 1405  st_mode_sense(st, flags)
Line 1313  st_mode_sense(st, flags)
  */   */
 int  int
 st_mode_select(st, flags)  st_mode_select(st, flags)
         struct st_data *st;          struct st_softc *st;
         int flags;          int flags;
 {  {
         u_int scsi_select_len;          u_int scsi_select_len;
Line 1413  st_mode_select(st, flags)
Line 1321  st_mode_select(st, flags)
         struct scsi_mode_select cmd;          struct scsi_mode_select cmd;
         struct scsi_select {          struct scsi_select {
                 struct scsi_mode_header header;                  struct scsi_mode_header header;
                 struct 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 scsi_link *sc_link = st->sc_link;          struct scsi_link *sc_link = st->sc_link;
Line 1424  st_mode_select(st, flags)
Line 1332  st_mode_select(st, flags)
          * Set up for a mode select           * Set up for a mode select
          */           */
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = MODE_SELECT;          cmd.opcode = MODE_SELECT;
         cmd.length = scsi_select_len;          cmd.length = scsi_select_len;
   
         bzero(&scsi_select, scsi_select_len);          bzero(&scsi_select, scsi_select_len);
         scsi_select.header.blk_desc_len = sizeof(struct blk_desc);          scsi_select.header.blk_desc_len = sizeof(struct scsi_blk_desc);
         scsi_select.header.dev_spec |= SMH_DSP_BUFF_MODE_ON;          scsi_select.header.dev_spec |= SMH_DSP_BUFF_MODE_ON;
         scsi_select.blk_desc.density = st->density;          scsi_select.blk_desc.density = st->density;
         if (st->flags & ST_FIXEDBLOCKS)          if (st->flags & ST_FIXEDBLOCKS)
                 lto3b(st->blksiz, scsi_select.blk_desc.blklen);                  lto3b(st->blksize, scsi_select.blk_desc.blklen);
         if (st->page_0_size)          if (st->page_0_size)
                 bcopy(st->sense_data, scsi_select.sense_data, st->page_0_size);                  bcopy(st->sense_data, scsi_select.sense_data, st->page_0_size);
   
Line 1449  st_mode_select(st, flags)
Line 1357  st_mode_select(st, flags)
  */   */
 int  int
 st_space(st, number, what, flags)  st_space(st, number, what, flags)
         struct st_data *st;          struct st_softc *st;
         u_int what;          u_int what;
         int flags;          int flags;
         int number;          int number;
Line 1518  st_space(st, number, what, flags)
Line 1426  st_space(st, number, what, flags)
                 return 0;                  return 0;
   
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = SPACE;          cmd.opcode = SPACE;
         cmd.byte2 = what;          cmd.byte2 = what;
         lto3b(number, cmd.number);          lto3b(number, cmd.number);
   
Line 1531  st_space(st, number, what, flags)
Line 1439  st_space(st, number, what, flags)
  */   */
 int  int
 st_write_filemarks(st, number, flags)  st_write_filemarks(st, number, flags)
         struct st_data *st;          struct st_softc *st;
         int flags;          int flags;
         int number;          int number;
 {  {
Line 1558  st_write_filemarks(st, number, flags)
Line 1466  st_write_filemarks(st, number, flags)
         }          }
   
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = WRITE_FILEMARKS;          cmd.opcode = WRITE_FILEMARKS;
         lto3b(number, cmd.number);          lto3b(number, cmd.number);
   
         return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,          return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
Line 1575  st_write_filemarks(st, number, flags)
Line 1483  st_write_filemarks(st, number, flags)
  */   */
 int  int
 st_check_eod(st, position, nmarks, flags)  st_check_eod(st, position, nmarks, flags)
         struct st_data *st;          struct st_softc *st;
         boolean position;          boolean position;
         int *nmarks;          int *nmarks;
         int flags;          int flags;
Line 1604  st_check_eod(st, position, nmarks, flags
Line 1512  st_check_eod(st, position, nmarks, flags
  */   */
 int  int
 st_load(st, type, flags)  st_load(st, type, flags)
         struct st_data *st;          struct st_softc *st;
         u_int type;          u_int type;
         int flags;          int flags;
 {  {
Line 1622  st_load(st, type, flags)
Line 1530  st_load(st, type, flags)
                 return 0;                  return 0;
   
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = LOAD;          cmd.opcode = LOAD;
         cmd.how = type;          cmd.how = type;
   
         return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,          return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
Line 1634  st_load(st, type, flags)
Line 1542  st_load(st, type, flags)
  */   */
 int  int
 st_rewind(st, immediate, flags)  st_rewind(st, immediate, flags)
         struct st_data *st;          struct st_softc *st;
         u_int immediate;          u_int immediate;
         int flags;          int flags;
 {  {
Line 1648  st_rewind(st, immediate, flags)
Line 1556  st_rewind(st, immediate, flags)
         st->flags &= ~ST_PER_ACTION;          st->flags &= ~ST_PER_ACTION;
   
         bzero(&cmd, sizeof(cmd));          bzero(&cmd, sizeof(cmd));
         cmd.op_code = REWIND;          cmd.opcode = REWIND;
         cmd.byte2 = immediate;          cmd.byte2 = immediate;
   
         return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,          return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
Line 1667  st_interpret_sense(xs)
Line 1575  st_interpret_sense(xs)
 {  {
         struct scsi_link *sc_link = xs->sc_link;          struct scsi_link *sc_link = xs->sc_link;
         struct scsi_sense_data *sense = &xs->sense;          struct scsi_sense_data *sense = &xs->sense;
         boolean silent = xs->flags & SCSI_SILENT;  
         struct buf *bp = xs->bp;          struct buf *bp = xs->bp;
         struct st_data *st = sc_link->device_softc;          struct st_softc *st = sc_link->device_softc;
         u_int key;          u_int8_t key;
         int info;          u_int32_t info;
   
         /*          /*
          * Get the sense fields and work out what code           * Get the sense fields and work out what code
Line 1684  st_interpret_sense(xs)
Line 1591  st_interpret_sense(xs)
         if ((sense->error_code & SSD_ERRCODE) != 0x70)          if ((sense->error_code & SSD_ERRCODE) != 0x70)
                 return -1;      /* let the generic code handle it */                  return -1;      /* let the generic code handle it */
         if (st->flags & ST_FIXEDBLOCKS) {          if (st->flags & ST_FIXEDBLOCKS) {
                 xs->resid = info * st->blksiz;                  xs->resid = info * st->blksize;
                 if (sense->extended_flags & SSD_EOM) {                  if (sense->extended_flags & SSD_EOM) {
                         st->flags |= ST_EIO_PENDING;                          st->flags |= ST_EIO_PENDING;
                         if (bp)                          if (bp)
Line 1699  st_interpret_sense(xs)
Line 1606  st_interpret_sense(xs)
                         st->flags |= ST_EIO_PENDING;                          st->flags |= ST_EIO_PENDING;
                         if (bp)                          if (bp)
                                 bp->b_resid = xs->resid;                                  bp->b_resid = xs->resid;
                         if (sense->error_code & SSD_ERRCODE_VALID && !silent)                          if (sense->error_code & SSD_ERRCODE_VALID &&
                               (xs->flags & SCSI_SILENT) == 0)
                                 printf("%s: block wrong size, %d blocks residual\n",                                  printf("%s: block wrong size, %d blocks residual\n",
                                     st->sc_dev.dv_xname, info);                                      st->sc_dev.dv_xname, info);
   
Line 1712  st_interpret_sense(xs)
Line 1620  st_interpret_sense(xs)
                          */                           */
                         if ((st->quirks & ST_Q_SENSE_HELP) &&                          if ((st->quirks & ST_Q_SENSE_HELP) &&
                             !(sc_link->flags & SDEV_MEDIA_LOADED))                              !(sc_link->flags & SDEV_MEDIA_LOADED))
                                 st->blksiz -= 512;                                  st->blksize -= 512;
                 }                  }
                 /*                  /*
                  * If no data was tranfered, do it immediatly                   * If no data was tranfered, do it immediatly
Line 1740  st_interpret_sense(xs)
Line 1648  st_interpret_sense(xs)
                                 /*                                  /*
                                  * the record was bigger than the read                                   * the record was bigger than the read
                                  */                                   */
                                 if (!silent)                                  if ((xs->flags & SCSI_SILENT) == 0)
                                         printf("%s: %d-byte record too big\n",                                          printf("%s: %d-byte record too big\n",
                                             st->sc_dev.dv_xname,                                              st->sc_dev.dv_xname,
                                             xs->datalen - info);                                              xs->datalen - info);
Line 1763  st_interpret_sense(xs)
Line 1671  st_interpret_sense(xs)
                 if ((st->quirks & ST_Q_SENSE_HELP) &&                  if ((st->quirks & ST_Q_SENSE_HELP) &&
                     !(sc_link->flags & SDEV_MEDIA_LOADED)) {                      !(sc_link->flags & SDEV_MEDIA_LOADED)) {
                         /* still starting */                          /* still starting */
                         st->blksiz -= 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))) {
                         st->flags |= ST_BLANK_READ;                          st->flags |= ST_BLANK_READ;
                         xs->resid = xs->datalen;                          xs->resid = xs->datalen;
Line 1795  st_interpret_sense(xs)
Line 1703  st_interpret_sense(xs)
  */   */
 int  int
 st_touch_tape(st)  st_touch_tape(st)
         struct st_data *st;          struct st_softc *st;
 {  {
         char   *buf;          char *buf;
         u_int readsiz;          int readsize;
         int error;          int error;
   
         buf = malloc(1024, M_TEMP, M_NOWAIT);          buf = malloc(1024, M_TEMP, M_NOWAIT);
Line 1807  st_touch_tape(st)
Line 1715  st_touch_tape(st)
   
         if (error = st_mode_sense(st, 0))          if (error = st_mode_sense(st, 0))
                 goto bad;                  goto bad;
         st->blksiz = 1024;          st->blksize = 1024;
         do {          do {
                 switch (st->blksiz) {                  switch (st->blksize) {
                 case 512:                  case 512:
                 case 1024:                  case 1024:
                         readsiz = st->blksiz;                          readsize = st->blksize;
                         st->flags |= ST_FIXEDBLOCKS;                          st->flags |= ST_FIXEDBLOCKS;
                         break;                          break;
                 default:                  default:
                         readsiz = 1;                          readsize = 1;
                         st->flags &= ~ST_FIXEDBLOCKS;                          st->flags &= ~ST_FIXEDBLOCKS;
                 }                  }
                 if (error = st_mode_select(st, 0))                  if (error = st_mode_select(st, 0))
                         goto bad;                          goto bad;
                 st_read(st, buf, readsiz, SCSI_SILENT);                  st_read(st, buf, readsize, SCSI_SILENT);        /* XXX */
                 if (error = st_rewind(st, 0, 0)) {                  if (error = st_rewind(st, 0, 0)) {
 bad:                    free(buf, M_TEMP);  bad:                    free(buf, M_TEMP);
                         return error;                          return error;
                 }                  }
         } while (readsiz != 1 && readsiz > st->blksiz);          } while (readsize != 1 && readsize > st->blksize);
   
         free(buf, M_TEMP);          free(buf, M_TEMP);
         return 0;          return 0;
 }  }

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.44

CVSweb <webmaster@jp.NetBSD.org>