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