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