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