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