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