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