Home | History | Annotate | Line # | Download | only in scsipi
st.c revision 1.8
      1 /*
      2  * Written by Julian Elischer (julian (at) tfs.com)
      3  * for TRW Financial Systems for use under the MACH(2.5) operating system.
      4  * Hacked by Theo de Raadt <deraadt (at) fsa.ca>
      5  *
      6  * TRW Financial Systems, in accordance with their agreement with Carnegie
      7  * Mellon University, makes this software available to CMU to distribute
      8  * or use in any manner that they see fit as long as this message is kept with
      9  * the software. For this reason TFS also grants any other persons or
     10  * organisations permission to use or modify this software.
     11  *
     12  * TFS supplies this software to be publicly redistributed
     13  * on the understanding that TFS is not responsible for the correct
     14  * functioning of this software in any circumstances.
     15  *
     16  *	$Id: st.c,v 1.8 1993/05/20 03:46:50 cgd Exp $
     17  */
     18 
     19 /*
     20  * To do:
     21  * work out some better way of guessing what a good timeout is going
     22  * to be depending on whether we expect to retension or not.
     23  *
     24  */
     25 
     26 #include "st.h"
     27 
     28 #include "sys/types.h"
     29 #include "sys/param.h"
     30 #include "sys/systm.h"
     31 #include "sys/errno.h"
     32 #include "sys/malloc.h"
     33 #include "sys/ioctl.h"
     34 #include "sys/buf.h"
     35 #include "sys/proc.h"
     36 #include "sys/user.h"
     37 #include "sys/mtio.h"
     38 #include "sys/dkbad.h"
     39 #include "sys/disklabel.h"
     40 #include "scsi/scsi_all.h"
     41 #include "scsi/scsi_tape.h"
     42 #include "scsi/scsiconf.h"
     43 #include "scsi/stdefs.h"
     44 
     45 long int ststrats, stqueues;
     46 
     47 #define	ST_RETRIES	4
     48 
     49 #define MODE(z)		((minor(z) & 0x03))
     50 #define DSTY(z)		(((minor(z) >> 2) & 0x03))
     51 #define UNIT(z)		((minor(z) >> 4))
     52 
     53 #define DSTY_QIC120  3
     54 #define DSTY_QIC150  2
     55 #define DSTY_QIC525  1
     56 
     57 #define QIC120     0x0f
     58 #define QIC150     0x10
     59 #define QIC525     0x11
     60 
     61 #define ESUCCESS 0
     62 
     63 int st_debug = 0;
     64 
     65 struct st_data *st_data[NST];
     66 static int next_st_unit = 0;
     67 
     68 /*
     69  * The routine called by the low level scsi routine when it discovers
     70  * A device suitable for this driver
     71  */
     72 int
     73 stattach(int masunit, struct scsi_switch *sw, int physid, int *unit)
     74 {
     75 	struct st_data *st;
     76 	unsigned char *tbl;
     77 	int targ, lun, i;
     78 
     79 	targ = physid >> 3;
     80 	lun = physid & 7;
     81 
     82 	/*printf("stattach: st%d at %s%d target %d lun %d\n",
     83 		*unit, sw->name, masunit, targ, lun);*/
     84 
     85 	if(*unit==-1) {
     86 		for(i=0; i<NST && *unit==-1; i++)
     87 			if(st_data[*unit]==NULL)
     88 				*unit = i;
     89 	}
     90 	if(*unit >= NST || *unit==-1)
     91 		return 0;
     92 	if(st_data[*unit])
     93 		return 0;
     94 
     95 	st = st_data[*unit] = (struct st_data *)malloc(sizeof *st,
     96 		M_TEMP, M_NOWAIT);
     97 	bzero(st, sizeof *st);
     98 
     99 	st->sc_sw = sw;
    100 	st->ctlr = masunit;
    101 	st->targ = targ;
    102 	st->lu = lun;
    103 
    104 	/*
    105 	 * Use the subdriver to request information regarding
    106 	 * the drive. We cannot use interrupts yet, so the
    107 	 * request must specify this.
    108 	 */
    109 	if( st_mode_sense(*unit, SCSI_NOSLEEP |  SCSI_NOMASK | SCSI_SILENT))
    110 		printf("st%d at %s%d targ %d lun %d: %d blocks of %d bytes\n",
    111 			*unit, sw->name, masunit, targ, lun,
    112 			st->numblks, st->blksiz);
    113 	else
    114 		printf("st%d at %s%d targ %d lun %d: offline\n",
    115 			*unit, sw->name, masunit, targ, lun);
    116 
    117 	/*
    118 	 * Set up the bufs for this device
    119 	 */
    120 	st->buf_queue.b_active = 0;
    121 	st->buf_queue.b_actf = 0;
    122 	st->buf_queue.b_actl = 0;
    123 	st->initialized = 1;
    124 	return 1;
    125 }
    126 
    127 /*
    128  *	open the device.
    129 */
    130 int
    131 stopen(dev_t dev)
    132 {
    133 	int errcode = 0;
    134 	int unit, mode, dsty;
    135 	int dsty_code;
    136 	struct st_data *st;
    137 	unit = UNIT(dev);
    138 	mode = MODE(dev);
    139 	dsty = DSTY(dev);
    140 	st = st_data[unit];
    141 
    142 	/*
    143 	 * Check the unit is legal
    144 	 */
    145 	if( unit >= NST )
    146 		return ENXIO;
    147 	if(!st)
    148 		return ENXIO;
    149 
    150 	/*
    151 	 * Only allow one at a time
    152 	 */
    153 	if(st->flags & ST_OPEN) {
    154 		errcode = EBUSY;
    155 		goto bad;
    156 	}
    157 	/*
    158 	 * Set up the mode flags according to the minor number
    159 	 * ensure all open flags are in a known state
    160 	 */
    161 	st->flags &= ~ST_PER_OPEN;
    162 	switch(mode) {
    163 	case 2:
    164 	case 0:
    165 		st->flags &= ~ST_NOREWIND;
    166 		break;
    167 	case 3:
    168 	case 1:
    169 		st->flags |= ST_NOREWIND;
    170 		break;
    171 	default:
    172 		printf("st%d: bad mode (minor number) %d\n", unit, mode);
    173 		return EINVAL;
    174 	}
    175 	/*
    176 	* Check density code: 0 is drive default
    177 	*/
    178 	switch(dsty) {
    179 	case 0:
    180 		dsty_code = 0;
    181 		break;
    182 	case DSTY_QIC120:
    183 		dsty_code = QIC120;
    184 		break;
    185 	case DSTY_QIC150:
    186 		dsty_code = QIC150;
    187 		break;
    188 	case DSTY_QIC525:
    189 		dsty_code = QIC525;
    190 		break;
    191 	default:
    192 		printf("st%d: bad density (minor number) %d\n", unit, dsty);
    193 		return EINVAL;
    194 	}
    195 
    196 	if(scsi_debug & (PRINTROUTINES | TRACEOPENS))
    197 		printf("st%d: open dev=0x%x (unit %d (of %d))\n", unit, dev, NST);
    198 
    199 	/*
    200 	 * Make sure the device has been initialised
    201 	 */
    202 	if (!st->initialized) {
    203 		/*printf("st%d: uninitialized\n", unit);*/
    204 		return ENXIO;
    205 	}
    206 
    207 	/*
    208 	 * Check that it is still responding and ok.
    209 	 */
    210 	if (!(st_req_sense(unit, 0))) {
    211 		errcode = EIO;
    212 		if(scsi_debug & TRACEOPENS)
    213 			printf("st%d: not responding\n", unit);
    214 		goto bad;
    215 	}
    216 	if(scsi_debug & TRACEOPENS)
    217 		printf("st%d: is responding\n", unit);
    218 
    219 	if(!(st_test_ready(unit, 0))) {
    220 		printf("st%d: not ready\n", unit);
    221 		return EIO;
    222 	}
    223 
    224 	if(!st->info_valid)		/* is media new? */
    225 		if(!st_load(unit, LD_LOAD, 0))
    226 			return EIO;
    227 
    228 	if(!st_rd_blk_lim(unit, 0))
    229 		return EIO;
    230 
    231 	if(!st_mode_sense(unit, 0))
    232 		return EIO;
    233 
    234 	if(!st_mode_select(unit, 0, dsty_code))
    235 		return EIO;
    236 
    237 	st->info_valid = TRUE;
    238 
    239 	st_prevent(unit, PR_PREVENT, 0); /* who cares if it fails? */
    240 
    241 	/*
    242 	 * Load the physical device parameters
    243 	 */
    244 	if(scsi_debug & TRACEOPENS)
    245 		printf("st%d: params ", unit);
    246 	st->flags |= ST_OPEN;
    247 
    248 bad:
    249 	return errcode;
    250 }
    251 
    252 /*
    253  * close the device.. only called if we are the LAST
    254  * occurence of an open device
    255 */
    256 int
    257 stclose(dev_t dev)
    258 {
    259 	unsigned char unit, mode;
    260 	struct st_data *st;
    261 
    262 	unit = UNIT(dev);
    263 	mode = MODE(dev);
    264 	st = st_data[unit];
    265 
    266 	if(scsi_debug & TRACEOPENS)
    267 		printf("st%d: close\n", unit);
    268 	if(st->flags & ST_WRITTEN)
    269 		st_write_filemarks(unit, 1, 0);
    270 
    271 	st->flags &= ~ST_WRITTEN;
    272 	switch(mode) {
    273 	case 0:
    274 		st_rewind(unit, FALSE, SCSI_SILENT);
    275 		st_prevent(unit, PR_ALLOW, SCSI_SILENT);
    276 		break;
    277 	case 1:
    278 		st_prevent(unit, PR_ALLOW, SCSI_SILENT);
    279 		break;
    280 	case 2:
    281 		st_rewind(unit, FALSE, SCSI_SILENT);
    282 		st_prevent(unit, PR_ALLOW, SCSI_SILENT);
    283 		st_load(unit, LD_UNLOAD, SCSI_SILENT);
    284 		break;
    285 	case 3:
    286 		st_prevent(unit, PR_ALLOW, SCSI_SILENT);
    287 		st_load(unit, LD_UNLOAD, SCSI_SILENT);
    288 		break;
    289 	default:
    290 		printf("st%d: bad mode (minor number) %d (how's it open?)\n",
    291 				unit, mode);
    292 		return EINVAL;
    293 	}
    294 	st->flags &= ~ST_PER_OPEN;
    295 	return 0;
    296 }
    297 
    298 /*
    299  * trim the size of the transfer if needed,
    300  * called by physio
    301  * basically the smaller of our min and the scsi driver's*
    302  * minphys
    303  */
    304 void
    305 stminphys(struct buf *bp)
    306 {
    307 	(*(st_data[UNIT(bp->b_dev)]->sc_sw->scsi_minphys))(bp);
    308 }
    309 
    310 /*
    311  * Actually translate the requested transfer into
    312  * one the physical driver can understand
    313  * The transfer is described by a buf and will include
    314  * only one physical transfer.
    315  */
    316 int
    317 ststrategy(struct buf *bp)
    318 {
    319 	struct st_data *st;
    320 	struct buf	 *dp;
    321 	unsigned char unit;
    322 	unsigned int opri;
    323 
    324 	if (bp->b_bcount == 0)
    325 		goto done;
    326 
    327 	ststrats++;
    328 	unit = UNIT((bp->b_dev));
    329 	st = st_data[unit];
    330 	if(scsi_debug & PRINTROUTINES)
    331 		printf("\nststrategy ");
    332 	if(scsi_debug & SHOWREQUESTS)
    333 		printf("st%d: %d bytes @ blk%d\n", unit, bp->b_bcount, bp->b_blkno);
    334 
    335 	/*
    336 	 * Odd sized request on fixed drives are verboten
    337 	 */
    338 	if((st->flags & ST_FIXEDBLOCKS) && bp->b_bcount % st->blkmin) {
    339 		printf("st%d: bad request, must be multiple of %d\n",
    340 			unit, st->blkmin);
    341 		bp->b_error = EIO;
    342 		goto bad;
    343 	}
    344 
    345 	stminphys(bp);
    346 	opri = splbio();
    347 	dp = &st->buf_queue;
    348 
    349 	/*
    350 	 * Place it in the queue of disk activities for this tape*
    351 	 * at the end
    352 	 */
    353 	while ( dp->b_actf)
    354 		dp = dp->b_actf;
    355 	dp->b_actf = bp;
    356 	bp->b_actf = NULL;
    357 
    358 	/*
    359 	 * Tell the device to get going on the transfer if it's
    360 	 * not doing anything, otherwise just wait for completion*
    361 	 */
    362 	ststart(unit);
    363 
    364 	splx(opri);
    365 	return;
    366 bad:
    367 	bp->b_flags |= B_ERROR;
    368 done:
    369 	/*
    370 	 * Correctly set the buf to indicate a completed xfer
    371 	 */
    372 	iodone(bp);
    373 	return;
    374 }
    375 
    376 
    377 /*
    378  * ststart looks to see if there is a buf waiting for the device
    379  * and that the device is not already busy. If both are true,
    380  * It deques the buf and creates a scsi command to perform the
    381  * transfer in the buf. The transfer request will call st_done
    382  * on completion, which will in turn call this routine again
    383  * so that the next queued transfer is performed.
    384  * The bufs are queued by the strategy routine (ststrategy)
    385  *
    386  * This routine is also called after other non-queued requests
    387  * have been made of the scsi driver, to ensure that the queue
    388  * continues to be drained.
    389 */
    390 /* ststart() is called at splbio */
    391 int
    392 ststart(int unit)
    393 {
    394 	struct st_data *st = st_data[unit];
    395 	register struct buf *bp = 0, *dp;
    396 	struct scsi_rw_tape cmd;
    397 	struct scsi_xfer *xs;
    398 	int drivecount, blkno, nblk;
    399 
    400 	if(scsi_debug & PRINTROUTINES)
    401 		printf("st%d: start\n", unit);
    402 
    403 	/*
    404 	 * See if there is a buf to do and we are not already
    405 	 * doing one
    406 	 */
    407 	xs = &st->scsi_xfer;
    408 	if(xs->flags & INUSE)
    409 		return;    /* unit already underway */
    410 
    411 trynext:
    412 	if(st->blockwait) {
    413 		wakeup(&st->blockwait);
    414 		return;
    415 	}
    416 
    417 	dp = &st->buf_queue;
    418 	if ((bp = dp->b_actf) != NULL)
    419 		dp->b_actf = bp->b_actf;
    420 	else
    421 		return;
    422 	xs->flags = INUSE;    /* Now ours */
    423 
    424 	/*
    425 	 * We have a buf, now we should move the data into
    426 	 * a scsi_xfer definition and try start it
    427 	 */
    428 
    429 	/*
    430 	 *  If we are at a filemark but have not reported it yet
    431 	 * then we should report it now
    432 	 */
    433 	if(st->flags & ST_AT_FILEMARK) {
    434 		bp->b_error = 0;
    435 		bp->b_flags |= B_ERROR;	/* EOF*/
    436 		st->flags &= ~ST_AT_FILEMARK;
    437 		biodone(bp);
    438 		xs->flags = 0; /* won't need it now */
    439 		goto trynext;
    440 	}
    441 
    442 	/*
    443 	 *  If we are at EOM but have not reported it yet
    444 	 * then we should report it now
    445 	 */
    446 	if(st->flags & ST_AT_EOM) {
    447 		bp->b_error = EIO;
    448 		bp->b_flags |= B_ERROR;
    449 		st->flags &= ~ST_AT_EOM;
    450 		biodone(bp);
    451 		xs->flags = 0; /* won't need it now */
    452 		goto trynext;
    453 	}
    454 
    455 	/*
    456 	 *  Fill out the scsi command
    457 	 */
    458 	bzero(&cmd, sizeof(cmd));
    459 	if((bp->b_flags & B_READ) == B_WRITE) {
    460 		st->flags |= ST_WRITTEN;
    461 		xs->flags |= SCSI_DATA_OUT;
    462 	}
    463 	else
    464 		xs->flags |= SCSI_DATA_IN;
    465 	cmd.op_code = (bp->b_flags & B_READ) ? READ_COMMAND_TAPE : WRITE_COMMAND_TAPE;
    466 
    467 	/*
    468 	 * Handle "fixed-block-mode" tape drives by using the    *
    469 	 * block count instead of the length.
    470 	 */
    471 	if(st->flags & ST_FIXEDBLOCKS) {
    472 		cmd.fixed = 1;
    473 		lto3b(bp->b_bcount/st->blkmin, cmd.len);
    474 	}
    475 	else
    476 		lto3b(bp->b_bcount, cmd.len);
    477 
    478 	/*
    479 	 * Fill out the scsi_xfer structure
    480 	 *	Note: we cannot sleep as we may be an interrupt
    481 	 */
    482 	xs->flags |= SCSI_NOSLEEP;
    483 	xs->adapter = st->ctlr;
    484 	xs->targ = st->targ;
    485 	xs->lu = st->lu;
    486 	xs->retries = 1;	/* can't retry on tape*/
    487 	xs->timeout = 100000; /* allow 100 secs for retension */
    488 	xs->cmd = (struct scsi_generic *)&cmd;
    489 	xs->cmdlen = sizeof(cmd);
    490 	xs->data = (u_char *)bp->b_un.b_addr;
    491 	xs->datalen = bp->b_bcount;
    492 	xs->resid = bp->b_bcount;
    493 	xs->when_done = st_done;
    494 	xs->done_arg = unit;
    495 	xs->done_arg2 = (int)xs;
    496 	xs->error = XS_NOERROR;
    497 	xs->bp = bp;
    498 
    499 #if defined(OSF) || defined(FIX_ME)
    500 	if (bp->b_flags & B_PHYS) {
    501 	 	xs->data = (u_char*)map_pva_kva(bp->b_proc, bp->b_un.b_addr,
    502 			bp->b_bcount, st_window[unit],
    503 			(bp->b_flags&B_READ)?B_WRITE:B_READ);
    504 	} else
    505 		xs->data = (u_char*)bp->b_un.b_addr;
    506 #endif /* defined(OSF) */
    507 
    508 	if ( (*(st->sc_sw->scsi_cmd))(xs) != SUCCESSFULLY_QUEUED) {
    509 		printf("st%d: oops not queued", unit);
    510 		xs->error = XS_DRIVER_STUFFUP;
    511 		st_done(unit, xs);
    512 	}
    513 	stqueues++;
    514 }
    515 
    516 /*
    517  * This routine is called by the scsi interrupt when
    518  * the transfer is complete.
    519 */
    520 int
    521 st_done(int unit, struct scsi_xfer *xs)
    522 {
    523 	struct st_data *st = st_data[unit];
    524 	struct buf *bp;
    525 	int retval;
    526 
    527 	if(scsi_debug & PRINTROUTINES)
    528 		printf("st%d: done\n", unit);
    529 	if (! (xs->flags & INUSE))
    530 		panic("scsi_xfer not in use!");
    531 
    532 	if(bp = xs->bp) {
    533 		switch(xs->error) {
    534 		case XS_NOERROR:
    535 			bp->b_flags &= ~B_ERROR;
    536 			bp->b_error = 0;
    537 			bp->b_resid = 0;
    538 			break;
    539 		case XS_SENSE:
    540 			retval = st_interpret_sense(unit, xs);
    541 			if(retval) {
    542 				/*
    543 				 * We have a real error, the bit should
    544 				 * be set to indicate this. The return
    545 				 * value will contain the unix error code*
    546 				 * that the error interpretation routine
    547 				 * thought was suitable, so pass this
    548 				 * value back in the buf structure.
    549 				 * Furthermore we return information
    550 				 * saying that no data was transferred
    551 				 */
    552 				bp->b_flags |= B_ERROR;
    553 				bp->b_error = retval;
    554 				bp->b_resid =  bp->b_bcount;
    555 				st->flags &= ~(ST_AT_FILEMARK|ST_AT_EOM);
    556 			} else if(xs->resid && ( xs->resid != xs->datalen )) {
    557 				/*
    558 				 * Here we have the tricky part..
    559 				 * We successfully read less data than
    560 				 * we requested. (but not 0)
    561 				 *------for variable blocksize tapes:----*
    562 				 * UNDER 386BSD:
    563 				 * We should legitimatly have the error
    564 				 * bit set, with the error value set to
    565 				 * zero.. This is to indicate to the
    566 				 * physio code that while we didn't get
    567 				 * as much information as was requested,
    568 				 * we did reach the end of the record
    569 				 * and so physio should not call us
    570 				 * again for more data... we have it all
    571 				 * SO SET THE ERROR BIT!
    572 				 *
    573 				 * UNDER MACH:(CMU)
    574 				 * To indicate the same as above, we
    575 				 * need only have a non 0 resid that is
    576 				 * less than the b_bcount, but the
    577 				 * ERROR BIT MUST BE CLEAR! (sigh)
    578 				 *
    579 				 * UNDER OSF1:
    580 				 * To indicate the same as above, we
    581 				 * need to have a non 0 resid that is
    582 				 * less than the b_bcount, but the
    583 				 * ERROR BIT MUST BE SET! (gasp)(sigh)
    584 				 *
    585 				 *-------for fixed blocksize device------*
    586 				 * We could have read some successful
    587 				 * records before hitting
    588 				 * the EOF or EOT. These must be passed
    589 				 * to the user, before we report the
    590 				 * EOx. Only if there is no data for the
    591 				 * user do we report it now. (via an EIO
    592 				 * for EOM and resid == count for EOF).
    593 				 * We will report the EOx NEXT time..
    594 				 */
    595 				bp->b_flags |= B_ERROR;
    596 				bp->b_error = 0;
    597 				bp->b_resid = xs->resid;
    598 				if((st->flags & ST_FIXEDBLOCKS)) {
    599 					bp->b_resid *= st->blkmin;
    600 					if(  (st->flags & ST_AT_EOM)
    601 				 	  && (bp->b_resid == bp->b_bcount)) {
    602 						bp->b_error = EIO;
    603 						st->flags &= ~ST_AT_EOM;
    604 					}
    605 				}
    606 				xs->error = XS_NOERROR;
    607 				break;
    608 			} else {
    609 				/*
    610 				 * We have come out of the error handler
    611 				 * with no error code.. we have also
    612 				 * not had an ili (would have gone to
    613 				 * the previous clause). Now we need to
    614 				 * distiguish between succesful read of
    615 				 * no data (EOF or EOM) and successfull
    616 				 * read of all requested data.
    617 				 * At least all o/s agree that:
    618 				 * 0 bytes read with no error is EOF
    619 				 * 0 bytes read with an EIO is EOM
    620 				 */
    621 				bp->b_resid = bp->b_bcount;
    622 				if(st->flags & ST_AT_FILEMARK) {
    623 					st->flags &= ~ST_AT_FILEMARK;
    624 					bp->b_flags &= ~B_ERROR;
    625 					bp->b_error = 0;
    626 					break;
    627 				}
    628 				if(st->flags & ST_AT_EOM) {
    629 					bp->b_flags |= B_ERROR;
    630 					bp->b_error = EIO;
    631 					st->flags &= ~ST_AT_EOM;
    632 					break;
    633 				}
    634 				printf("st%d: error ignored\n", unit);
    635 			}
    636 			break;
    637 		case    XS_TIMEOUT:
    638 			printf("st%d: timeout\n", unit);
    639 			break;
    640 		case    XS_BUSY:	/* should retry -- how? */
    641 			/*
    642 			 * SHOULD put buf back at head of queue
    643 			 * and decrement retry count in (*xs)
    644 			 * HOWEVER, this should work as a kludge
    645 			 */
    646 			if(xs->retries--) {
    647 				xs->flags &= ~ITSDONE;
    648 				xs->error = XS_NOERROR;
    649 				if ( (*(st->sc_sw->scsi_cmd))(xs)
    650 				   == SUCCESSFULLY_QUEUED) {
    651 					/* don't wake the job, ok? */
    652 					return;
    653 				}
    654 				printf("st%d: device busy\n");
    655 				xs->flags |= ITSDONE;
    656 			}
    657 		case XS_DRIVER_STUFFUP:
    658 			bp->b_flags |= B_ERROR;
    659 			bp->b_error = EIO;
    660 			break;
    661 		default:
    662 			printf("st%d: unknown error category %d from scsi driver\n",
    663 				unit, xs->error);
    664 		}
    665 		biodone(bp);
    666 		xs->flags = 0;	/* no longer in use */
    667 		ststart(unit);		/* If there's another waiting.. do it */
    668 	} else
    669 		wakeup(xs);
    670 }
    671 
    672 /*
    673  * Perform special action on behalf of the user
    674  * Knows about the internals of this device
    675 */
    676 int
    677 stioctl(dev_t dev, int cmd, caddr_t arg, int mode)
    678 {
    679 	struct st_data *st;
    680 	struct mtop *mt;
    681 	struct mtget *g;
    682 	unsigned int opri;
    683 	unsigned char unit;
    684 	register i, j;
    685 	int errcode=0, number, flags, ret;
    686 
    687 	/*
    688 	 * Find the device that the user is talking about
    689 	 */
    690 	flags = 0;	/* give error messages, act on errors etc. */
    691 	unit = UNIT(dev);
    692 	st = st_data[unit];
    693 
    694 	if(unit >= NST)
    695 		return ENXIO;
    696 	if(!st)
    697 		return ENXIO;
    698 
    699 	switch(cmd) {
    700 	case MTIOCGET:
    701 		g = (struct mtget *)arg;
    702 		bzero(g, sizeof *g);
    703 		g->mt_type = 0x7;	/* Ultrix compat */
    704 		ret=TRUE;
    705 		break;
    706 	case MTIOCTOP:
    707 		mt = (struct mtop *)arg;
    708 
    709 		if (st_debug)
    710 			printf("[sctape_sstatus: %x %x]\n", mt->mt_op, mt->mt_count);
    711 
    712 		/* compat: in U*x it is a short */
    713 		number = mt->mt_count;
    714 		switch ((short)(mt->mt_op)) {
    715 		case MTWEOF:	/* write an end-of-file record */
    716 			ret = st_write_filemarks(unit, number, flags);
    717 			st->flags &= ~ST_WRITTEN;
    718 			break;
    719 		case MTFSF:	/* forward space file */
    720 			ret = st_space(unit, number, SP_FILEMARKS, flags);
    721 			break;
    722 		case MTBSF:	/* backward space file */
    723 			ret = st_space(unit, -number, SP_FILEMARKS, flags);
    724 			break;
    725 		case MTFSR:	/* forward space record */
    726 			ret = st_space(unit, number, SP_BLKS, flags);
    727 			break;
    728 		case MTBSR:	/* backward space record */
    729 			ret = st_space(unit, -number, SP_BLKS, flags);
    730 			break;
    731 		case MTREW:	/* rewind */
    732 			ret = st_rewind(unit, FALSE, flags);
    733 			break;
    734 		case MTOFFL:	/* rewind and put the drive offline */
    735 			if((ret = st_rewind(unit, FALSE, flags))) {
    736 				st_prevent(unit, PR_ALLOW, 0);
    737 				ret = st_load(unit, LD_UNLOAD, flags);
    738 			} else
    739 				printf("st%d: rewind failed; unit still loaded\n");
    740 			break;
    741 		case MTNOP:	/* no operation, sets status only */
    742 		case MTCACHE:	/* enable controller cache */
    743 		case MTNOCACHE:	/* disable controller cache */
    744 			ret = TRUE;
    745 			break;
    746 		default:
    747 			return EINVAL;
    748 		}
    749 		break;
    750 	case MTIOCIEOT:
    751 	case MTIOCEEOT:
    752 		ret=TRUE;
    753 		break;
    754 	}
    755 	return ret ? ESUCCESS : EIO;
    756 }
    757 
    758 
    759 /*
    760  * Check with the device that it is ok, (via scsi driver)*
    761 */
    762 int
    763 st_req_sense(int unit, int flags)
    764 {
    765 	struct scsi_sense_data sense;
    766 	struct scsi_sense	scsi_cmd;
    767 
    768 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    769 	scsi_cmd.op_code = REQUEST_SENSE;
    770 	scsi_cmd.length = sizeof(sense);
    771 
    772 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    773 	    sizeof(scsi_cmd), (u_char *)&sense, sizeof(sense),
    774 	    100000, flags | SCSI_DATA_IN) != 0)
    775 		return FALSE;
    776 	else
    777 		return TRUE;
    778 }
    779 
    780 /*
    781  * Get scsi driver to send a "are you ready" command
    782 */
    783 int
    784 st_test_ready(int unit, int flags)
    785 {
    786 	struct scsi_test_unit_ready scsi_cmd;
    787 
    788 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    789 	scsi_cmd.op_code = TEST_UNIT_READY;
    790 
    791 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    792 	    sizeof(scsi_cmd), (u_char *)0, 0, 100000, flags) != 0)
    793 		return FALSE;
    794 	else
    795 		return TRUE;
    796 }
    797 
    798 
    799 #ifdef	__STDC__
    800 #define b2tol(a)	(((unsigned)(a##_1) << 8) + (unsigned)a##_0 )
    801 #else
    802 #define b2tol(a)	(((unsigned)(a/**/_1) << 8) + (unsigned)a/**/_0 )
    803 #endif
    804 
    805 /*
    806  * Ask the drive what it's min and max blk sizes are.
    807 */
    808 int
    809 st_rd_blk_lim(int unit, int flags)
    810 {
    811 	struct st_data *st = st_data[unit];
    812 	struct scsi_blk_limits scsi_cmd;
    813 	struct scsi_blk_limits_data scsi_blkl;
    814 
    815 	st = st_data[unit];
    816 
    817 	/*
    818 	 * First check if we have it all loaded
    819 	 */
    820 	if (st->info_valid)
    821 		goto done;
    822 
    823 	/*
    824 	 * do a 'Read Block Limits'
    825 	 */
    826 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    827 	scsi_cmd.op_code = READ_BLK_LIMITS;
    828 
    829 	/*
    830 	 * do the command,	update the global values
    831 	 */
    832 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    833 	    sizeof(scsi_cmd), (u_char *)&scsi_blkl, sizeof(scsi_blkl),
    834 	    5000, flags | SCSI_DATA_IN) != 0) {
    835 		if(!(flags & SCSI_SILENT))
    836 			printf("st%d: read block limits failed\n", unit);
    837 		st->info_valid = FALSE;
    838 		return FALSE;
    839 	}
    840 	if (st_debug)
    841 		printf("st%d: block size min %d max %d\n", unit,
    842 			b2tol(scsi_blkl.min_length),
    843 			_3btol(&scsi_blkl.max_length_2));
    844 
    845 	st->blkmin = b2tol(scsi_blkl.min_length);
    846 	st->blkmax = _3btol(&scsi_blkl.max_length_2);
    847 
    848 done:
    849 	if(st->blkmin && (st->blkmin == st->blkmax))
    850 		st->flags |= ST_FIXEDBLOCKS;
    851 	return TRUE;
    852 }
    853 
    854 /*
    855  * Get the scsi driver to send a full inquiry to the
    856  * device and use the results to fill out the global
    857  * parameter structure.
    858 */
    859 int
    860 st_mode_sense(int unit, int flags)
    861 {
    862 	struct st_data *st = st_data[unit];
    863 	struct scsi_mode_sense scsi_cmd;
    864 	struct {
    865 		struct scsi_mode_header_tape header;
    866 		struct blk_desc	blk_desc;
    867 	} scsi_s;
    868 
    869 	/*
    870 	 * First check if we have it all loaded
    871 	 */
    872 	if(st->info_valid)
    873 		return TRUE;
    874 	/*
    875 	 * First do a mode sense
    876 	 */
    877 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    878 	scsi_cmd.op_code = MODE_SENSE;
    879 	scsi_cmd.length = sizeof(scsi_s);
    880 
    881 	/*
    882 	 * do the command, but we don't need the results
    883 	 * just print them for our interest's sake
    884 	 */
    885 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    886 	    sizeof(scsi_cmd), (u_char *)&scsi_s, sizeof(scsi_s),
    887 	    5000, flags | SCSI_DATA_IN) != 0) {
    888 		if(!(flags & SCSI_SILENT))
    889 			printf("st%d: mode sense failed\n", unit);
    890 		st->info_valid = FALSE;
    891 		return FALSE;
    892 	}
    893 	if (st_debug)
    894 		printf("st%d: %d blocks of %d bytes, write %s, %sbuffered\n",
    895 			unit,
    896 			_3btol((u_char *)&scsi_s.blk_desc.nblocks),
    897 			_3btol((u_char *)&scsi_s.blk_desc.blklen),
    898 			scsi_s.header.write_protected ? "protected" : "enabled",
    899 			scsi_s.header.buf_mode ? "" : "un");
    900 
    901 	st->numblks = _3btol((u_char *)&scsi_s.blk_desc.nblocks);
    902 	st->blksiz = _3btol((u_char *)&scsi_s.blk_desc.blklen);
    903 	return TRUE;
    904 }
    905 
    906 /*
    907  * Get the scsi driver to send a full inquiry to the
    908  * device and use the results to fill out the global
    909  * parameter structure.
    910 */
    911 int
    912 st_mode_select(int unit, int flags, int dsty_code)
    913 {
    914 	struct st_data *st = st_data[unit];
    915 	struct scsi_mode_select scsi_cmd;
    916 	struct {
    917 		struct scsi_mode_header_tape header;
    918 		struct blk_desc	blk_desc;
    919 	} dat;
    920 
    921 	/*
    922 	 * Set up for a mode select
    923 	 */
    924 	bzero(&dat, sizeof(dat));
    925 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    926 	scsi_cmd.op_code = MODE_SELECT;
    927 	scsi_cmd.length = sizeof(dat);
    928 	dat.header.blk_desc_len = sizeof(struct  blk_desc);
    929 	dat.header.buf_mode = 1;
    930 	dat.blk_desc.density = dsty_code;
    931 	if(st->flags & ST_FIXEDBLOCKS)
    932 		lto3b(st->blkmin, dat.blk_desc.blklen);
    933 
    934 /*	lto3b( st->numblks, dat.blk_desc.nblocks); use defaults!!!!
    935 	lto3b( st->blksiz, dat.blk_desc.blklen);
    936  */
    937 	/*
    938 	 * do the command
    939 	 */
    940 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    941 	    sizeof(scsi_cmd), (u_char *)&dat, sizeof(dat),
    942 	    5000, flags | SCSI_DATA_OUT) != 0) {
    943 		if(!(flags & SCSI_SILENT))
    944 			printf("st%d: mode select failed\n", unit);
    945 #if 0
    946 		st->info_valid = FALSE;
    947 		return FALSE;
    948 #endif
    949 	}
    950 	return TRUE;
    951 }
    952 
    953 /*
    954  * skip N blocks/filemarks/seq filemarks/eom
    955 */
    956 int
    957 st_space(int unit, int number, int what, int flags)
    958 {
    959 	struct st_data *st = st_data[unit];
    960 	struct scsi_space scsi_cmd;
    961 
    962 	/* if we are at a filemark now, we soon won't be*/
    963 	st->flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
    964 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    965 	scsi_cmd.op_code = SPACE;
    966 	scsi_cmd.code = what;
    967 	lto3b(number, scsi_cmd.number);
    968 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    969 	    sizeof(scsi_cmd), (u_char *)0, 0, 600000, flags) != 0) {
    970 		if(!(flags & SCSI_SILENT))
    971 			printf("st%d: %s space failed\n", unit,
    972 				(number > 0) ? "forward" : "backward");
    973 		st->info_valid = FALSE;
    974 		return FALSE;
    975 	}
    976 	return TRUE;
    977 }
    978 
    979 /*
    980  * write N filemarks
    981 */
    982 int
    983 st_write_filemarks(int unit, int number, int flags)
    984 {
    985 	struct st_data *st = st_data[unit];
    986 	struct scsi_write_filemarks scsi_cmd;
    987 
    988 	st->flags &= ~(ST_AT_FILEMARK);
    989 	bzero(&scsi_cmd, sizeof(scsi_cmd));
    990 	scsi_cmd.op_code = WRITE_FILEMARKS;
    991 	lto3b(number, scsi_cmd.number);
    992 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
    993 	    sizeof(scsi_cmd), (u_char *)0, 0, 100000, flags) != 0) {
    994 		if(!(flags & SCSI_SILENT))
    995 			printf("st%d: write file marks failed\n", unit);
    996 		st->info_valid = FALSE;
    997 		return FALSE;
    998 	}
    999 	return TRUE;
   1000 }
   1001 
   1002 /*
   1003  * load /unload (with retension if true)
   1004 */
   1005 int
   1006 st_load(int unit, int type, int flags)
   1007 {
   1008 	struct st_data *st = st_data[unit];
   1009 	struct  scsi_load  scsi_cmd;
   1010 
   1011 	st->flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
   1012 	bzero(&scsi_cmd, sizeof(scsi_cmd));
   1013 	scsi_cmd.op_code = LOAD_UNLOAD;
   1014 	scsi_cmd.load=type;
   1015 	if (type == LD_LOAD)
   1016 	{
   1017 		/*scsi_cmd.reten=TRUE;*/
   1018 		scsi_cmd.reten=FALSE;
   1019 	}
   1020 	else
   1021 	{
   1022 		scsi_cmd.reten=FALSE;
   1023 	}
   1024 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
   1025 	    sizeof(scsi_cmd), (u_char *)0, 0, 30000, flags) != 0) {
   1026 		if(!(flags & SCSI_SILENT))
   1027 			printf("st%d: %s failed\n", unit,
   1028 				type == LD_LOAD ? "load" : "unload");
   1029 		st->info_valid = FALSE;
   1030 		return FALSE;
   1031 	}
   1032 	return TRUE;
   1033 }
   1034 
   1035 /*
   1036  * Prevent or allow the user to remove the tape
   1037 */
   1038 int
   1039 st_prevent(int unit, int type, int flags)
   1040 {
   1041 	struct st_data *st = st_data[unit];
   1042 	struct scsi_prevent	scsi_cmd;
   1043 
   1044 	bzero(&scsi_cmd, sizeof(scsi_cmd));
   1045 	scsi_cmd.op_code = PREVENT_ALLOW;
   1046 	scsi_cmd.prevent=type;
   1047 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
   1048 	    sizeof(scsi_cmd), (u_char *)0, 0, 5000, flags) != 0) {
   1049 		if(!(flags & SCSI_SILENT))
   1050 			printf("st%d: %s failed\n", unit,
   1051 				type == PR_PREVENT ? "prevent" : "allow");
   1052 		st->info_valid = FALSE;
   1053 		return FALSE;
   1054 	}
   1055 	return TRUE;
   1056 }
   1057 
   1058 /*
   1059  *  Rewind the device
   1060 */
   1061 int
   1062 st_rewind(int unit, int immed, int flags)
   1063 {
   1064 	struct st_data *st = st_data[unit];
   1065 	struct scsi_rewind	scsi_cmd;
   1066 
   1067 	st->flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
   1068 	bzero(&scsi_cmd, sizeof(scsi_cmd));
   1069 	scsi_cmd.op_code = REWIND;
   1070 	scsi_cmd.immed=immed;
   1071 	if (st_scsi_cmd(unit, (struct scsi_generic *)&scsi_cmd,
   1072 	    sizeof(scsi_cmd), (u_char *)0, 0, immed?5000:300000, flags) != 0) {
   1073 		if(!(flags & SCSI_SILENT))
   1074 			printf("st%d: rewind failed\n", unit);
   1075 		st->info_valid = FALSE;
   1076 		return FALSE;
   1077 	}
   1078 	return TRUE;
   1079 }
   1080 
   1081 /*
   1082  * ask the scsi driver to perform a command for us.
   1083  * Call it through the switch table, and tell it which
   1084  * sub-unit we want, and what target and lu we wish to
   1085  * talk to. Also tell it where to find the command
   1086  * how long int is.
   1087  * Also tell it where to read/write the data, and how
   1088  * long the data is supposed to be
   1089 */
   1090 int
   1091 st_scsi_cmd(int unit, struct scsi_generic *scsi_cmd, int cmdlen,
   1092 	u_char *data_addr, int datalen, int timeout, int flags)
   1093 {
   1094 	struct st_data *st = st_data[unit];
   1095 	struct scsi_xfer *xs;
   1096 	int retval, s;
   1097 
   1098 	if(scsi_debug & PRINTROUTINES)
   1099 		printf("\nst_scsi_cmd%d ", unit);
   1100 	if(!st->sc_sw) {
   1101 		printf("st%d: not set up\n", unit);
   1102 		return EINVAL;
   1103 	}
   1104 
   1105 	xs = &st->scsi_xfer;
   1106 	if(!(flags & SCSI_NOMASK))
   1107 		s = splbio();
   1108 	st->blockwait++;	/* there is someone waiting */
   1109 	while (xs->flags & INUSE)
   1110 		sleep(&st->blockwait, PRIBIO+1);
   1111 	st->blockwait--;
   1112 	xs->flags = INUSE;
   1113 	if(!(flags & SCSI_NOMASK))
   1114 		splx(s);
   1115 
   1116 	/*
   1117 	 * Fill out the scsi_xfer structure
   1118 	 */
   1119 	xs->flags	|= flags;
   1120 	xs->adapter = st->ctlr;
   1121 	xs->targ = st->targ;
   1122 	xs->lu = st->lu;
   1123 	xs->retries = ST_RETRIES;
   1124 	xs->timeout = timeout;
   1125 	xs->cmd = scsi_cmd;
   1126 	xs->cmdlen = cmdlen;
   1127 	xs->data = data_addr;
   1128 	xs->datalen = datalen;
   1129 	xs->resid = datalen;
   1130 	xs->when_done = (flags & SCSI_NOMASK) ? (int (*)())0 : st_done;
   1131 	xs->done_arg = unit;
   1132 	xs->done_arg2 = (int)xs;
   1133 retry:
   1134 	xs->error = XS_NOERROR;
   1135 	xs->bp = 0;
   1136 	retval = (*(st->sc_sw->scsi_cmd))(xs);
   1137 	switch(retval) {
   1138 	case SUCCESSFULLY_QUEUED:
   1139 		s = splbio();
   1140 		while(!(xs->flags & ITSDONE))
   1141 			sleep(xs,PRIBIO+1);
   1142 		splx(s);
   1143 	case HAD_ERROR:
   1144 	case COMPLETE:
   1145 		switch(xs->error) {
   1146 		case XS_NOERROR:
   1147 			retval = ESUCCESS;
   1148 			break;
   1149 		case XS_SENSE:
   1150 			retval = st_interpret_sense(unit, xs);
   1151 			/* only useful for reads */
   1152 			if (retval)
   1153 				st->flags &= ~(ST_AT_FILEMARK | ST_AT_EOM);
   1154 			else {
   1155 				xs->error = XS_NOERROR;
   1156 				retval = ESUCCESS;
   1157 			}
   1158 			break;
   1159 		case XS_DRIVER_STUFFUP:
   1160 			retval = EIO;
   1161 			break;
   1162 		case    XS_TIMEOUT:
   1163 		case    XS_BUSY:
   1164 			if(xs->retries-- ) {
   1165 				xs->flags &= ~ITSDONE;
   1166 				goto retry;
   1167 			}
   1168 			retval = EIO;
   1169 			break;
   1170 		default:
   1171 			retval = EIO;
   1172 			printf("st%d: unknown error category %d from scsi driver\n",
   1173 				unit, xs->error);
   1174 			break;
   1175 		}
   1176 		break;
   1177 	case 	TRY_AGAIN_LATER:
   1178 		if(xs->retries--) {
   1179 			xs->flags &= ~ITSDONE;
   1180 			goto retry;
   1181 		}
   1182 		retval = EIO;
   1183 		break;
   1184 	default:
   1185 		retval = EIO;
   1186 	}
   1187 	xs->flags = 0;	/* it's free! */
   1188 	ststart(unit);
   1189 
   1190 	return retval;
   1191 }
   1192 
   1193 /*
   1194  * Look at the returned sense and act on the error and detirmine
   1195  * The unix error number to pass back... (0 = report no error)
   1196 */
   1197 
   1198 int
   1199 st_interpret_sense(int unit, struct scsi_xfer *xs)
   1200 {
   1201 	struct st_data *st = st_data[unit];
   1202 	struct scsi_sense_data *sense;
   1203 	int silent = xs->flags & SCSI_SILENT, key;
   1204 
   1205 	/*
   1206 	 * If errors are ok, report a success
   1207 	 */
   1208 	if(xs->flags & SCSI_ERR_OK)
   1209 		return ESUCCESS;
   1210 
   1211 	/*
   1212 	 * Get the sense fields and work out what CLASS
   1213 	 */
   1214 	sense = &(xs->sense);
   1215 	if(st_debug) {
   1216 		int count = 0;
   1217 		printf("code%x class%x valid%x\n", sense->error_code,
   1218 			sense->error_class, sense->valid);
   1219 		printf("seg%x key%x ili%x eom%x fmark%x\n",
   1220 			sense->ext.extended.segment, sense->ext.extended.sense_key,
   1221 			sense->ext.extended.ili, sense->ext.extended.eom,
   1222 			sense->ext.extended.filemark);
   1223 		printf("info: %x %x %x %x followed by %d extra bytes\n",
   1224 			sense->ext.extended.info[0], sense->ext.extended.info[1],
   1225 			sense->ext.extended.info[2], sense->ext.extended.info[3],
   1226 			sense->ext.extended.extra_len);
   1227 		printf("extra: ");
   1228 		while(count < sense->ext.extended.extra_len)
   1229 			printf("%x ", sense->ext.extended.extra_bytes[count++]);
   1230 		printf("\n");
   1231 	}
   1232 
   1233 	switch(sense->error_class) {
   1234 	case 0:
   1235 	case 1:
   1236 	case 2:
   1237 	case 3:
   1238 	case 4:
   1239 	case 5:
   1240 	case 6:
   1241 		if(!silent) {
   1242 			printf("st%d: error class %d code %d\n", unit,
   1243 				sense->error_class, sense->error_code);
   1244 			if(sense->valid)
   1245 				printf("block no. %d (decimal)\n",
   1246 					(sense->ext.unextended.blockhi <<16),
   1247 					+ (sense->ext.unextended.blockmed <<8),
   1248 					+ (sense->ext.unextended.blocklow ));
   1249 		}
   1250 		return EIO;
   1251 	case 7:
   1252 		/*
   1253 		 * If it's class 7, use the extended stuff and interpret
   1254 		 * the key
   1255 		 */
   1256 		if(sense->ext.extended.eom)
   1257 			st->flags |= ST_AT_EOM;
   1258 		if(sense->ext.extended.filemark)
   1259 			st->flags |= ST_AT_FILEMARK;
   1260 
   1261 		if(sense->ext.extended.ili) {
   1262 			if(sense->valid) {
   1263 				/*
   1264 				 * In all ili cases, note that
   1265 				 * the resid is non-0 AND not
   1266 				 * unchanged.
   1267 				 */
   1268 				xs->resid = ntohl(*((long *)sense->ext.extended.info));
   1269 				if(xs->bp) {
   1270 					if(xs->resid < 0) {
   1271 						/* never on block devices */
   1272 						/*
   1273 						 * it's only really bad
   1274 						 * if we have lost data
   1275 						 * (the record was
   1276 						 * bigger than the read)
   1277 						 */
   1278 						return EIO;
   1279 					}
   1280 				}
   1281 			} else
   1282 				printf("st%d: bad length error?", unit);
   1283 		}
   1284 
   1285 		key = sense->ext.extended.sense_key;
   1286 		switch(key) {
   1287 		case 0x0:
   1288 			return ESUCCESS;
   1289 		case 0x1:
   1290 			if(!silent) {
   1291 				printf("st%d: soft error (corrected)", unit);
   1292 				if(sense->valid) {
   1293 			   		printf(" block %d\n",
   1294 			  		(sense->ext.extended.info[0] <<24)|
   1295 			  		(sense->ext.extended.info[1] <<16)|
   1296 			  		(sense->ext.extended.info[2] <<8)|
   1297 			  		(sense->ext.extended.info[3] ));
   1298 				} else
   1299 			 		printf("\n");
   1300 			}
   1301 			return ESUCCESS;
   1302 		case 0x2:
   1303 			if(!silent)
   1304 				printf("st%d: not ready\n", unit);
   1305 			return ENODEV;
   1306 		case 0x3:
   1307 			if(!silent) {
   1308 				printf("st%d: medium error", unit);
   1309 				if(sense->valid) {
   1310 			   		printf(" block %d\n",
   1311 			  		(sense->ext.extended.info[0] <<24)|
   1312 			  		(sense->ext.extended.info[1] <<16)|
   1313 			  		(sense->ext.extended.info[2] <<8)|
   1314 			  		(sense->ext.extended.info[3] ));
   1315 				} else
   1316 			 		printf("\n");
   1317 			}
   1318 			return EIO;
   1319 		case 0x4:
   1320 			if(!silent)
   1321 				printf("st%d: component failure\n",
   1322 					unit);
   1323 			return EIO;
   1324 		case 0x5:
   1325 			if(!silent)
   1326 				printf("st%d: illegal request\n", unit);
   1327 			return EINVAL;
   1328 		case 0x6:
   1329 			if(!silent)
   1330 				printf("st%d: media change\n", unit);
   1331 			st->flags &= ~(ST_AT_FILEMARK|ST_AT_EOM);
   1332 			st->info_valid = FALSE;
   1333 			if (st->flags & ST_OPEN) /* TEMP!!!! */
   1334 				return EIO;
   1335 			return ESUCCESS;
   1336 		case 0x7:
   1337 			if(!silent) {
   1338 				printf("st%d: attempted protection violation",
   1339 					unit);
   1340 				if(sense->valid) {
   1341 			   		printf(" block %d\n",
   1342 			  		(sense->ext.extended.info[0] <<24)|
   1343 			  		(sense->ext.extended.info[1] <<16)|
   1344 			  		(sense->ext.extended.info[2] <<8)|
   1345 			  		(sense->ext.extended.info[3] ));
   1346 				} else
   1347 			 		printf("\n");
   1348 			}
   1349 			return EACCES;
   1350 		case 0x8:
   1351 			if(!silent) {
   1352 				printf("st%d: block wrong state (worm)", unit);
   1353 				if(sense->valid) {
   1354 			   		printf(" block %d\n",
   1355 			  		(sense->ext.extended.info[0] <<24)|
   1356 			  		(sense->ext.extended.info[1] <<16)|
   1357 			  		(sense->ext.extended.info[2] <<8)|
   1358 			  		(sense->ext.extended.info[3] ));
   1359 				} else
   1360 			 		printf("\n");
   1361 			}
   1362 			return EIO;
   1363 		case 0x9:
   1364 			if(!silent)
   1365 				printf("st%d: vendor unique\n", unit);
   1366 			return EIO;
   1367 		case 0xa:
   1368 			if(!silent)
   1369 				printf("st%d: copy aborted\n", unit);
   1370 			return EIO;
   1371 		case 0xb:
   1372 			if(!silent)
   1373 				printf("st%d: command aborted\n", unit);
   1374 			return EIO;
   1375 		case 0xc:
   1376 			if(!silent) {
   1377 				printf("st%d: search returned", unit);
   1378 				if(sense->valid) {
   1379 			   		printf(" block %d\n",
   1380 			  		(sense->ext.extended.info[0] <<24)|
   1381 			  		(sense->ext.extended.info[1] <<16)|
   1382 			  		(sense->ext.extended.info[2] <<8)|
   1383 			  		(sense->ext.extended.info[3] ));
   1384 				} else
   1385 			 		printf("\n");
   1386 			}
   1387 			return ESUCCESS;
   1388 		case 0xd:
   1389 			if(!silent)
   1390 				printf("st%d: volume overflow\n", unit);
   1391 			return ENOSPC;
   1392 		case 0xe:
   1393 			if(!silent) {
   1394 			 	printf("st%d: verify miscompare\n", unit);
   1395 				if(sense->valid) {
   1396 			   		printf("block no. %d (decimal)\n",
   1397 			  		(sense->ext.extended.info[0] <<24)|
   1398 			  		(sense->ext.extended.info[1] <<16)|
   1399 			  		(sense->ext.extended.info[2] <<8)|
   1400 			  		(sense->ext.extended.info[3] ));
   1401 				} else
   1402 			 		printf("\n");
   1403 			}
   1404 			return EIO;
   1405 		case 0xf:
   1406 			if(!silent)
   1407 				printf("st%d: unknown error key\n", unit);
   1408 			return EIO;
   1409 		}
   1410 		break;
   1411 	}
   1412 	return 0;
   1413 }
   1414