Fixed broken pte bit definitions. I fixed this long ago in pte.h, but
[unix-history] / sys / scsi / scsi_base.c
CommitLineData
519fb2b7
RG
1/*
2 * Written By Julian ELischer
3 * Copyright julian Elischer 1993.
4 * Permission is granted to use or redistribute this file in any way as long
5 * as this notice remains. Julian Elischer does not guarantee that this file
6 * is totally correct for any given task and users of this file must
7 * accept responsibility for any damage that occurs from the application of this
8 * file.
9 *
10 * Written by Julian Elischer (julian@dialix.oz.au)
3e9e774f 11 * $Id: scsi_base.c,v 1.7 1994/04/20 07:06:54 davidg Exp $
519fb2b7
RG
12 */
13
14#define SPLSD splbio
15#define ESUCCESS 0
1d7f5b47 16#include <sys/types.h>
519fb2b7 17#include <sys/param.h>
1d7f5b47
DG
18#include <machine/param.h>
19#include <vm/vm_statistics.h>
20#include <vm/vm_param.h>
21#include <vm/lock.h>
22#include <machine/pmap.h>
23#include <machine/vmparam.h>
fde1aeb2 24#include "systm.h"
519fb2b7
RG
25#include <sys/buf.h>
26#include <sys/uio.h>
27#include <sys/malloc.h>
28#include <sys/errno.h>
29#include <scsi/scsi_all.h>
30#include <scsi/scsi_disk.h>
31#include <scsi/scsiconf.h>
32
fde1aeb2
GW
33static errval sc_err1(struct scsi_xfer *);
34static errval scsi_interpret_sense(struct scsi_xfer *);
35
519fb2b7
RG
36#ifdef NetBSD
37#ifdef DDB
38int Debugger();
39#else /* DDB */
40#define Debugger()
41#endif /* DDB */
42#else /* NetBSD */
fde1aeb2 43#include "ddb.h"
519fb2b7 44#if NDDB > 0
519fb2b7
RG
45#else /* NDDB > 0 */
46#define Debugger()
47#endif /* NDDB > 0 */
48#endif
49
50void sc_print_addr __P((struct scsi_link *sc_link));
51
52struct scsi_xfer *next_free_xs;
53
54/*
55 * Get a scsi transfer structure for the caller. Charge the structure
56 * to the device that is referenced by the sc_link structure. If the
57 * sc_link structure has no 'credits' then the device already has the
58 * maximum number or outstanding operations under way. In this stage,
59 * wait on the structure so that when one is freed, we are awoken again
60 * If the SCSI_NOSLEEP flag is set, then do not wait, but rather, return
61 * a NULL pointer, signifying that no slots were available
62 * Note in the link structure, that we are waiting on it.
63 */
64
65struct scsi_xfer *
66get_xs(sc_link, flags)
67 struct scsi_link *sc_link; /* who to charge the xs to */
68 u_int32 flags; /* if this call can sleep */
69{
70 struct scsi_xfer *xs;
71 u_int32 s;
72
73 SC_DEBUG(sc_link, SDEV_DB3, ("get_xs\n"));
74 s = splbio();
75 while (!sc_link->opennings) {
76 SC_DEBUG(sc_link, SDEV_DB3, ("sleeping\n"));
77 if (flags & SCSI_NOSLEEP) {
78 splx(s);
79 return 0;
80 }
81 sc_link->flags |= SDEV_WAITING;
fde1aeb2 82 tsleep((caddr_t)sc_link, PRIBIO, "scsiget", 0);
519fb2b7
RG
83 }
84 sc_link->opennings--;
85 if (xs = next_free_xs) {
86 next_free_xs = xs->next;
87 splx(s);
88 } else {
89 splx(s);
90 SC_DEBUG(sc_link, SDEV_DB3, ("making\n"));
91 xs = malloc(sizeof(*xs), M_TEMP,
92 ((flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK));
93 if (xs == NULL) {
94 sc_print_addr(sc_link);
95 printf("cannot allocate scsi xs\n");
96 return (NULL);
97 }
98 }
99 SC_DEBUG(sc_link, SDEV_DB3, ("returning\n"));
100 xs->sc_link = sc_link;
101 return (xs);
102}
103
104/*
105 * Given a scsi_xfer struct, and a device (referenced through sc_link)
106 * return the struct to the free pool and credit the device with it
107 * If another process is waiting for an xs, do a wakeup, let it proceed
108 */
109void
110free_xs(xs, sc_link, flags)
111 struct scsi_xfer *xs;
112 struct scsi_link *sc_link; /* who to credit for returning it */
113 u_int32 flags;
114{
115 xs->next = next_free_xs;
116 next_free_xs = xs;
117
118 SC_DEBUG(sc_link, SDEV_DB3, ("free_xs\n"));
119 /* if was 0 and someone waits, wake them up */
120 if ((!sc_link->opennings++) && (sc_link->flags & SDEV_WAITING)) {
e59513a1 121 sc_link->flags &= ~SDEV_WAITING;
fde1aeb2 122 wakeup((caddr_t)sc_link); /* remember, it wakes them ALL up */
519fb2b7
RG
123 } else {
124 if (sc_link->device->start) {
125 SC_DEBUG(sc_link, SDEV_DB2, ("calling private start()\n"));
126 (*(sc_link->device->start)) (sc_link->dev_unit);
127 }
128 }
129}
130
131/*
132 * Find out from the device what its capacity is.
133 */
134u_int32
135scsi_size(sc_link, flags)
136 struct scsi_link *sc_link;
137 u_int32 flags;
138{
139 struct scsi_read_cap_data rdcap;
140 struct scsi_read_capacity scsi_cmd;
141 u_int32 size;
142
143 /*
144 * make up a scsi command and ask the scsi driver to do
145 * it for you.
146 */
147 bzero(&scsi_cmd, sizeof(scsi_cmd));
148 scsi_cmd.op_code = READ_CAPACITY;
149
150 /*
151 * If the command works, interpret the result as a 4 byte
152 * number of blocks
153 */
154 if (scsi_scsi_cmd(sc_link,
155 (struct scsi_generic *) &scsi_cmd,
156 sizeof(scsi_cmd),
157 (u_char *) & rdcap,
158 sizeof(rdcap),
159 2,
160 20000,
161 NULL,
162 flags | SCSI_DATA_IN) != 0) {
163
164 sc_print_addr(sc_link);
165 printf("could not get size\n");
166 return (0);
167 } else {
168 size = rdcap.addr_0 + 1;
169 size += rdcap.addr_1 << 8;
170 size += rdcap.addr_2 << 16;
171 size += rdcap.addr_3 << 24;
172 }
173 return (size);
174}
175
176/*
177 * Get scsi driver to send a "are you ready?" command
178 */
179errval
180scsi_test_unit_ready(sc_link, flags)
181 struct scsi_link *sc_link;
182 u_int32 flags;
183{
184 struct scsi_test_unit_ready scsi_cmd;
185
186 bzero(&scsi_cmd, sizeof(scsi_cmd));
187 scsi_cmd.op_code = TEST_UNIT_READY;
188
189 return (scsi_scsi_cmd(sc_link,
190 (struct scsi_generic *) &scsi_cmd,
191 sizeof(scsi_cmd),
192 0,
193 0,
194 2,
195 100000,
196 NULL,
197 flags));
198}
199
200/*
201 * Do a scsi operation, asking a device to run as SCSI-II if it can.
202 */
203errval
204scsi_change_def(sc_link, flags)
205 struct scsi_link *sc_link;
206 u_int32 flags;
207{
208 struct scsi_changedef scsi_cmd;
209
210 bzero(&scsi_cmd, sizeof(scsi_cmd));
211 scsi_cmd.op_code = CHANGE_DEFINITION;
212 scsi_cmd.how = SC_SCSI_2;
213
214 return (scsi_scsi_cmd(sc_link,
215 (struct scsi_generic *) &scsi_cmd,
216 sizeof(scsi_cmd),
217 0,
218 0,
219 2,
220 100000,
221 NULL,
222 flags));
223}
224
225/*
226 * Do a scsi operation asking a device what it is
227 * Use the scsi_cmd routine in the switch table.
228 */
229errval
230scsi_inquire(sc_link, inqbuf, flags)
231 struct scsi_link *sc_link;
232 struct scsi_inquiry_data *inqbuf;
233 u_int32 flags;
234{
235 struct scsi_inquiry scsi_cmd;
236
237 bzero(&scsi_cmd, sizeof(scsi_cmd));
238 scsi_cmd.op_code = INQUIRY;
239 scsi_cmd.length = sizeof(struct scsi_inquiry_data);
240
241 return (scsi_scsi_cmd(sc_link,
242 (struct scsi_generic *) &scsi_cmd,
243 sizeof(scsi_cmd),
244 (u_char *) inqbuf,
245 sizeof(struct scsi_inquiry_data),
246 2,
247 100000,
248 NULL,
249 SCSI_DATA_IN | flags));
250}
251
252/*
253 * Prevent or allow the user to remove the media
254 */
255errval
256scsi_prevent(sc_link, type, flags)
257 struct scsi_link *sc_link;
258 u_int32 type, flags;
259{
260 struct scsi_prevent scsi_cmd;
261
262 bzero(&scsi_cmd, sizeof(scsi_cmd));
263 scsi_cmd.op_code = PREVENT_ALLOW;
264 scsi_cmd.how = type;
265 return (scsi_scsi_cmd(sc_link,
266 (struct scsi_generic *) &scsi_cmd,
267 sizeof(scsi_cmd),
268 0,
269 0,
270 2,
271 5000,
272 NULL,
273 flags));
274}
275
276/*
277 * Get scsi driver to send a "start up" command
278 */
279errval
280scsi_start_unit(sc_link, flags)
281 struct scsi_link *sc_link;
282 u_int32 flags;
283{
284 struct scsi_start_stop scsi_cmd;
285
286 bzero(&scsi_cmd, sizeof(scsi_cmd));
287 scsi_cmd.op_code = START_STOP;
288 scsi_cmd.how = SSS_START;
289
290 return (scsi_scsi_cmd(sc_link,
291 (struct scsi_generic *) &scsi_cmd,
46d39670
RG
292 sizeof(scsi_cmd),
293 0,
294 0,
295 2,
3e9e774f 296 10000,
46d39670
RG
297 NULL,
298 flags));
299}
300
301/*
302 * Get scsi driver to send a "stop" command
303 */
304errval
305scsi_stop_unit(sc_link, eject, flags)
306 struct scsi_link *sc_link;
307 u_int32 eject;
308 u_int32 flags;
309{
310 struct scsi_start_stop scsi_cmd;
311
312 bzero(&scsi_cmd, sizeof(scsi_cmd));
313 scsi_cmd.op_code = START_STOP;
314 if (eject) {
315 scsi_cmd.how = SSS_LOEJ;
316 }
317
318 return (scsi_scsi_cmd(sc_link,
319 (struct scsi_generic *) &scsi_cmd,
519fb2b7
RG
320 sizeof(scsi_cmd),
321 0,
322 0,
323 2,
3e9e774f 324 10000,
519fb2b7
RG
325 NULL,
326 flags));
327}
328
329/*
330 * This routine is called by the scsi interrupt when the transfer is complete.
331 */
332void
333scsi_done(xs)
334 struct scsi_xfer *xs;
335{
336 struct scsi_link *sc_link = xs->sc_link;
337 struct buf *bp = xs->bp;
338 errval retval;
339
340 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n"));
341#ifdef SCSIDEBUG
342 if (sc_link->flags & SDEV_DB1)
343 {
344 show_scsi_cmd(xs);
345 }
346#endif /*SCSIDEBUG */
347 /*
348 * If it's a user level request, bypass all usual completion processing,
349 * let the user work it out.. We take reponsibility for freeing the
350 * xs when the user returns. (and restarting the device's queue).
351 */
352 if (xs->flags & SCSI_USER) {
353 biodone(xs->bp);
354#ifdef NOTNOW
355 SC_DEBUG(sc_link, SDEV_DB3, ("calling user done()\n"));
356 scsi_user_done(xs); /* to take a copy of the sense etc. */
357 SC_DEBUG(sc_link, SDEV_DB3, ("returned from user done()\n "));
358#endif
359 free_xs(xs, sc_link, SCSI_NOSLEEP); /* restarts queue too */
360 SC_DEBUG(sc_link, SDEV_DB3, ("returning to adapter\n"));
361 return;
362 }
363 /*
364 * If the device has it's own done routine, call it first.
365 * If it returns a legit error value, return that, otherwise
366 * it wants us to continue with normal processing.
367 */
368
369 if (sc_link->device->done) {
370 SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
371 retval = (*sc_link->device->done) (xs);
372 if (retval == -1) {
373 free_xs(xs, sc_link, SCSI_NOSLEEP); /*XXX */
374 return; /* it did it all, finish up */
375 }
376 if (retval == -2) {
377 return; /* it did it all, finish up */
378 }
379 SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
380 }
381 if ((bp = xs->bp) == NULL) {
382 /*
383 * if it's a normal upper level request, then ask
384 * the upper level code to handle error checking
385 * rather than doing it here at interrupt time
386 */
fde1aeb2 387 wakeup((caddr_t)xs);
519fb2b7
RG
388 return;
389 }
390 /*
391 * Go and handle errors now.
392 * If it returns -1 then we should RETRY
393 */
394 if ((retval = sc_err1(xs)) == -1) {
395 if ((*(sc_link->adapter->scsi_cmd)) (xs)
396 == SUCCESSFULLY_QUEUED) { /* don't wake the job, ok? */
397 return;
398 }
399 xs->flags |= ITSDONE;
400 }
401 free_xs(xs, sc_link, SCSI_NOSLEEP); /* does a start if needed */
402 biodone(bp);
403}
404
405/*
406 * ask the scsi driver to perform a command for us.
407 * tell it where to read/write the data, and how
408 * long the data is supposed to be. If we have a buf
409 * to associate with the transfer, we need that too.
410 */
411errval
412scsi_scsi_cmd(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
413 retries, timeout, bp, flags)
414 struct scsi_link *sc_link;
415 struct scsi_generic *scsi_cmd;
416 u_int32 cmdlen;
417 u_char *data_addr;
418 u_int32 datalen;
419 u_int32 retries;
420 u_int32 timeout;
421 struct buf *bp;
422 u_int32 flags;
423{
424 struct scsi_xfer *xs;
425 errval retval;
426 u_int32 s;
427
428 if (bp) flags |= SCSI_NOSLEEP;
429 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n"));
430
431 xs = get_xs(sc_link, flags); /* should wait unless booting */
432 if (!xs) return (ENOMEM);
433 /*
434 * Fill out the scsi_xfer structure. We don't know whose context
435 * the cmd is in, so copy it.
436 */
437 bcopy(scsi_cmd, &(xs->cmdstore), cmdlen);
438 xs->flags = INUSE | flags;
439 xs->sc_link = sc_link;
440 xs->retries = retries;
441 xs->timeout = timeout;
442 xs->cmd = &xs->cmdstore;
443 xs->cmdlen = cmdlen;
444 xs->data = data_addr;
445 xs->datalen = datalen;
446 xs->resid = datalen;
447 xs->bp = bp;
448/*XXX*/ /*use constant not magic number */
1d7f5b47 449 if (datalen && ((caddr_t) data_addr < (caddr_t) KERNBASE)) {
519fb2b7
RG
450 if (bp) {
451 printf("Data buffered space not in kernel context\n");
452#ifdef SCSIDEBUG
453 show_scsi_cmd(xs);
454#endif /* SCSIDEBUG */
455 retval = EFAULT;
456 goto bad;
457 }
aa27e2cd
DG
458#ifdef NOBOUNCE
459 xs->data = malloc(datalen, M_TEMP, M_WAITOK);
460#else
461 xs->data = (caddr_t) vm_bounce_kva_alloc( (datalen + PAGE_SIZE - 1)/PAGE_SIZE);
462#endif
519fb2b7 463 /* I think waiting is ok *//*XXX */
fde1aeb2 464 switch ((int)(flags & (SCSI_DATA_IN | SCSI_DATA_OUT))) {
519fb2b7
RG
465 case 0:
466 printf("No direction flags, assuming both\n");
467#ifdef SCSIDEBUG
468 show_scsi_cmd(xs);
469#endif /* SCSIDEBUG */
470 case SCSI_DATA_IN | SCSI_DATA_OUT: /* weird */
471 case SCSI_DATA_OUT:
472 bcopy(data_addr, xs->data, datalen);
473 break;
474 case SCSI_DATA_IN:
475 bzero(xs->data, datalen);
476 }
477 }
478retry:
479 xs->error = XS_NOERROR;
480#ifdef PARANOID
1d7f5b47 481 if (datalen && ((caddr_t) xs->data < (caddr_t) KERNBASE)) {
519fb2b7
RG
482 printf("It's still wrong!\n");
483 }
484#endif /*PARANOID*/
485#ifdef SCSIDEBUG
486 if (sc_link->flags & SDEV_DB3) show_scsi_xs(xs);
487#endif /* SCSIDEBUG */
488 /*
489 * Do the transfer. If we are polling we will return:
490 * COMPLETE, Was poll, and scsi_done has been called
491 * TRY_AGAIN_LATER, Adapter short resources, try again
492 *
493 * if under full steam (interrupts) it will return:
494 * SUCCESSFULLY_QUEUED, will do a wakeup when complete
495 * TRY_AGAIN_LATER, (as for polling)
496 * After the wakeup, we must still check if it succeeded
497 *
498 * If we have a bp however, all the error proccessing
499 * and the buffer code both expect us to return straight
500 * to them, so as soon as the command is queued, return
501 */
502
503 retval = (*(sc_link->adapter->scsi_cmd)) (xs);
504
505 switch (retval) {
506 case SUCCESSFULLY_QUEUED:
507 if (bp)
508 return retval; /* will sleep (or not) elsewhere */
509 s = splbio();
fde1aeb2
GW
510 while (!(xs->flags & ITSDONE)) {
511 tsleep((caddr_t)xs, PRIBIO + 1, "scsicmd", 0);
512 }
519fb2b7
RG
513 splx(s);
514 /* fall through to check success of completed command */
515 case COMPLETE: /* Polling command completed ok */
516/*XXX*/ case HAD_ERROR: /* Polling command completed with error */
517 SC_DEBUG(sc_link, SDEV_DB3, ("back in cmd()\n"));
518 if ((retval = sc_err1(xs)) == -1)
519 goto retry;
520 break;
521
522 case TRY_AGAIN_LATER: /* adapter resource shortage */
523 SC_DEBUG(sc_link, SDEV_DB3, ("will try again \n"));
524 /* should sleep 1 sec here */
525 if (xs->retries--) {
526 xs->flags &= ~ITSDONE;
527 goto retry;
528 }
529 default:
530 retval = EIO;
531 }
532 /*
533 * If we had to copy the data out of the user's context,
534 * then do the other half (copy it back or whatever)
535 * and free the memory buffer
536 */
537 if (datalen && (xs->data != data_addr)) {
fde1aeb2 538 switch ((int)(flags & (SCSI_DATA_IN | SCSI_DATA_OUT))) {
519fb2b7
RG
539 case 0:
540 case SCSI_DATA_IN | SCSI_DATA_OUT: /* weird */
541 case SCSI_DATA_IN:
542 bcopy(xs->data, data_addr, datalen);
543 break;
544 }
aa27e2cd 545#ifdef NOBOUNCE
519fb2b7 546 free(xs->data, M_TEMP);
aa27e2cd
DG
547#else
548 vm_bounce_kva_alloc_free(xs->data, (datalen + PAGE_SIZE - 1)/PAGE_SIZE, 0);
549#endif
519fb2b7
RG
550 }
551 /*
552 * we have finished with the xfer stuct, free it and
553 * check if anyone else needs to be started up.
554 */
555bad:
556 free_xs(xs, sc_link, flags); /* includes the 'start' op */
557 if (bp && retval) {
558 bp->b_error = retval;
559 bp->b_flags |= B_ERROR;
560 biodone(bp);
561 }
562 return (retval);
563}
564
fde1aeb2 565static errval
519fb2b7
RG
566sc_err1(xs)
567 struct scsi_xfer *xs;
568{
569 struct buf *bp = xs->bp;
570 errval retval;
571
572 SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%x \n", xs->error));
573 /*
574 * If it has a buf, we might be working with
575 * a request from the buffer cache or some other
576 * piece of code that requires us to process
577 * errors at inetrrupt time. We have probably
578 * been called by scsi_done()
579 */
fde1aeb2 580 switch ((int)xs->error) {
519fb2b7
RG
581 case XS_NOERROR: /* nearly always hit this one */
582 retval = ESUCCESS;
583 if (bp) {
584 bp->b_error = 0;
585 bp->b_resid = 0;
586 }
587 break;
588
589 case XS_SENSE:
590 if (bp) {
591 bp->b_error = 0;
592 bp->b_resid = 0;
593 if (retval = (scsi_interpret_sense(xs))) {
594 bp->b_flags |= B_ERROR;
595 bp->b_error = retval;
596 bp->b_resid = bp->b_bcount;
597 }
598 SC_DEBUG(xs->sc_link, SDEV_DB3,
599 ("scsi_interpret_sense (bp) returned %d\n", retval));
600 } else {
601 retval = (scsi_interpret_sense(xs));
602 SC_DEBUG(xs->sc_link, SDEV_DB3,
603 ("scsi_interpret_sense (no bp) returned %d\n", retval));
604 }
605 break;
606
607 case XS_BUSY:
608 /*should somehow arange for a 1 sec delay here (how?) */
fde1aeb2
GW
609 /* XXX tsleep(&localvar, priority, "foo", hz);
610 that's how! */
519fb2b7
RG
611 case XS_TIMEOUT:
612 /*
613 * If we can, resubmit it to the adapter.
614 */
615 if (xs->retries--) {
616 xs->error = XS_NOERROR;
617 xs->flags &= ~ITSDONE;
618 goto retry;
619 }
620 /* fall through */
621 case XS_DRIVER_STUFFUP:
622 if (bp) {
623 bp->b_flags |= B_ERROR;
624 bp->b_error = EIO;
625 }
626 retval = EIO;
627 break;
628 default:
629 retval = EIO;
630 sc_print_addr(xs->sc_link);
631 printf("unknown error category from scsi driver\n");
632 }
633 return retval;
634retry:
635 return (-1);
636}
637
638/*
639 * Look at the returned sense and act on the error, determining
640 * the unix error number to pass back. (0 = report no error)
641 *
642 * THIS IS THE DEFAULT ERROR HANDLER
643 */
fde1aeb2 644static errval
519fb2b7
RG
645scsi_interpret_sense(xs)
646 struct scsi_xfer *xs;
647{
648 struct scsi_sense_data *sense;
649 struct scsi_link *sc_link = xs->sc_link;
650 u_int32 key;
651 u_int32 silent;
652 u_int32 info;
653 errval errcode;
654
655 static char *error_mes[] =
656 {"soft error (corrected)",
657 "not ready", "medium error",
658 "non-media hardware failure", "illegal request",
659 "unit attention", "readonly device",
660 "no data found", "vendor unique",
661 "copy aborted", "command aborted",
662 "search returned equal", "volume overflow",
663 "verify miscompare", "unknown error key"
664 };
665
666 /*
667 * If the flags say errs are ok, then always return ok.
668 */
669 if (xs->flags & SCSI_ERR_OK)
670 return (ESUCCESS);
671
672 sense = &(xs->sense);
673#ifdef SCSIDEBUG
674 if (sc_link->flags & SDEV_DB1) {
675 u_int32 count = 0;
676 printf("code%x valid%x ",
677 sense->error_code & SSD_ERRCODE,
678 sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
679 printf("seg%x key%x ili%x eom%x fmark%x\n",
680 sense->ext.extended.segment,
681 sense->ext.extended.flags & SSD_KEY,
682 sense->ext.extended.flags & SSD_ILI ? 1 : 0,
683 sense->ext.extended.flags & SSD_EOM ? 1 : 0,
684 sense->ext.extended.flags & SSD_FILEMARK ? 1 : 0);
685 printf("info: %x %x %x %x followed by %d extra bytes\n",
686 sense->ext.extended.info[0],
687 sense->ext.extended.info[1],
688 sense->ext.extended.info[2],
689 sense->ext.extended.info[3],
690 sense->ext.extended.extra_len);
691 printf("extra: ");
692 while (count < sense->ext.extended.extra_len) {
693 printf("%x ", sense->ext.extended.extra_bytes[count++]);
694 }
695 printf("\n");
696 }
697#endif /*SCSIDEBUG */
698 /*
699 * If the device has it's own error handler, call it first.
700 * If it returns a legit error value, return that, otherwise
701 * it wants us to continue with normal error processing.
702 */
703 if (sc_link->device->err_handler) {
704 SC_DEBUG(sc_link, SDEV_DB2, ("calling private err_handler()\n"));
705 errcode = (*sc_link->device->err_handler) (xs);
706 if (errcode != -1)
707 return errcode; /* errcode >= 0 better ? */
708 }
709 /* otherwise use the default */
710 silent = (xs->flags & SCSI_SILENT);
711 switch (sense->error_code & SSD_ERRCODE) {
712 /*
713 * If it's code 70, use the extended stuff and interpret the key
714 */
715 case 0x71: /* delayed error */
716 sc_print_addr(sc_link);
717 key = sense->ext.extended.flags & SSD_KEY;
718 printf(" DELAYED ERROR, key = 0x%x\n", key);
719 case 0x70:
720 if (sense->error_code & SSD_ERRCODE_VALID) {
721 info = ntohl(*((long *) sense->ext.extended.info));
722 } else {
723 info = 0;
724 }
725 key = sense->ext.extended.flags & SSD_KEY;
726
727 if (key && !silent) {
728 sc_print_addr(sc_link);
729 printf("%s", error_mes[key - 1]);
730 if (sense->error_code & SSD_ERRCODE_VALID) {
fde1aeb2 731 switch ((int)key) {
519fb2b7
RG
732 case 0x2: /* NOT READY */
733 case 0x5: /* ILLEGAL REQUEST */
734 case 0x6: /* UNIT ATTENTION */
735 case 0x7: /* DATA PROTECT */
736 break;
737 case 0x8: /* BLANK CHECK */
738 printf(", requested size: %d (decimal)",
739 info);
740 break;
741 default:
742 printf(", info = %d (decimal)", info);
743 }
744 }
745 printf("\n");
746 }
fde1aeb2 747 switch ((int)key) {
519fb2b7
RG
748 case 0x0: /* NO SENSE */
749 case 0x1: /* RECOVERED ERROR */
750 if (xs->resid == xs->datalen)
751 xs->resid = 0; /* not short read */
752 case 0xc: /* EQUAL */
753 return (ESUCCESS);
754 case 0x2: /* NOT READY */
755 sc_link->flags &= ~SDEV_MEDIA_LOADED;
756 return (EBUSY);
757 case 0x5: /* ILLEGAL REQUEST */
758 return (EINVAL);
759 case 0x6: /* UNIT ATTENTION */
760 sc_link->flags &= ~SDEV_MEDIA_LOADED;
761 if (sc_link->flags & SDEV_OPEN) {
762 return (EIO);
763 } else {
764 return 0;
765 }
766 case 0x7: /* DATA PROTECT */
767 return (EACCES);
768 case 0xd: /* VOLUME OVERFLOW */
769 return (ENOSPC);
770 case 0x8: /* BLANK CHECK */
771 return (ESUCCESS);
772 default:
773 return (EIO);
774 }
775 /*
776 * Not code 70, just report it
777 */
778 default:
779 if (!silent) {
780 sc_print_addr(sc_link);
781 printf("error code %d",
782 sense->error_code & SSD_ERRCODE);
783 if (sense->error_code & SSD_ERRCODE_VALID) {
784 printf(" at block no. %d (decimal)",
785 (sense->ext.unextended.blockhi << 16) +
786 (sense->ext.unextended.blockmed << 8) +
787 (sense->ext.unextended.blocklow));
788 }
789 printf("\n");
790 }
791 return (EIO);
792 }
793}
794
795/*
796 * Utility routines often used in SCSI stuff
797 */
798
799/*
800 * convert a physical address to 3 bytes,
801 * MSB at the lowest address,
802 * LSB at the highest.
803 */
804void
805lto3b(val, bytes)
806 int val;
807 u_char *bytes;
808{
809 *bytes++ = (val & 0xff0000) >> 16;
810 *bytes++ = (val & 0xff00) >> 8;
811 *bytes = val & 0xff;
812}
813
814/*
815 * The reverse of lto3b
816 */
817int
818_3btol(bytes)
819 u_char *bytes;
820{
821 u_int32 rc;
822 rc = (*bytes++ << 16);
823 rc += (*bytes++ << 8);
824 rc += *bytes;
825 return ((int) rc);
826}
827
828/*
829 * Print out the scsi_link structure's address info.
830 */
831
832void
833sc_print_addr(sc_link)
834 struct scsi_link *sc_link;
835{
836
837 printf("%s%d(%s%d:%d:%d): ", sc_link->device->name, sc_link->dev_unit,
838 sc_link->adapter->name, sc_link->adapter_unit,
839 sc_link->target, sc_link->lun);
840}
841#ifdef SCSIDEBUG
842/*
843 * Given a scsi_xfer, dump the request, in all it's glory
844 */
845void
846show_scsi_xs(xs)
847 struct scsi_xfer *xs;
848{
849 printf("xs(0x%x): ", xs);
850 printf("flg(0x%x)", xs->flags);
851 printf("sc_link(0x%x)", xs->sc_link);
852 printf("retr(0x%x)", xs->retries);
853 printf("timo(0x%x)", xs->timeout);
854 printf("cmd(0x%x)", xs->cmd);
855 printf("len(0x%x)", xs->cmdlen);
856 printf("data(0x%x)", xs->data);
857 printf("len(0x%x)", xs->datalen);
858 printf("res(0x%x)", xs->resid);
859 printf("err(0x%x)", xs->error);
860 printf("bp(0x%x)", xs->bp);
861 show_scsi_cmd(xs);
862}
863
864void
865show_scsi_cmd(struct scsi_xfer *xs)
866{
867 u_char *b = (u_char *) xs->cmd;
868 int i = 0;
869
870 sc_print_addr(xs->sc_link);
871 printf("command: ");
872
873 if (!(xs->flags & SCSI_RESET)) {
874 while (i < xs->cmdlen) {
875 if (i)
876 printf(",");
877 printf("%x", b[i++]);
878 }
879 printf("-[%d bytes]\n", xs->datalen);
880 if (xs->datalen)
881 show_mem(xs->data, min(64, xs->datalen));
882 } else {
883 printf("-RESET-\n");
884 }
885}
886
887void
888show_mem(address, num)
889 unsigned char *address;
890 u_int32 num;
891{
892 u_int32 x, y;
893 printf("------------------------------");
894 for (y = 0; y < num; y += 1) {
895 if (!(y % 16))
896 printf("\n%03d: ", y);
897 printf("%02x ", *address++);
898 }
899 printf("\n------------------------------\n");
900}
901#endif /*SCSIDEBUG */