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