scsi_base.c revision 1.28 1 /* $NetBSD: scsi_base.c,v 1.28 1995/01/26 12:05:51 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 1994, 1995 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 /*
309 * This routine is called by the scsi interrupt when the transfer is complete.
310 */
311 void
312 scsi_done(xs)
313 struct scsi_xfer *xs;
314 {
315 struct scsi_link *sc_link = xs->sc_link;
316 int error;
317
318 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n"));
319 #ifdef SCSIDEBUG
320 if ((sc_link->flags & SDEV_DB1) != 0)
321 show_scsi_cmd(xs);
322 #endif /* SCSIDEBUG */
323
324 /*
325 * If it's a user level request, bypass all usual completion processing,
326 * let the user work it out.. We take reponsibility for freeing the
327 * xs when the user returns. (and restarting the device's queue).
328 */
329 if ((xs->flags & SCSI_USER) != 0) {
330 SC_DEBUG(sc_link, SDEV_DB3, ("calling user done()\n"));
331 scsi_user_done(xs); /* to take a copy of the sense etc. */
332 SC_DEBUG(sc_link, SDEV_DB3, ("returned from user done()\n "));
333
334 scsi_free_xs(xs, SCSI_NOSLEEP); /* restarts queue too */
335 SC_DEBUG(sc_link, SDEV_DB3, ("returning to adapter\n"));
336 return;
337 }
338
339 /*
340 * If the device has it's own done routine, call it first.
341 * If it returns a legit error value, return that, otherwise
342 * it wants us to continue with normal processing.
343 */
344 if (sc_link->device->done) {
345 SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
346 error = (*sc_link->device->done) (xs);
347 if (error == EJUSTRETURN)
348 goto done;
349 SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
350 }
351 if (xs->bp == NULL) {
352 /*
353 * if it's a normal upper level request, then ask
354 * the upper level code to handle error checking
355 * rather than doing it here at interrupt time
356 */
357 wakeup(xs);
358 return;
359 }
360 /*
361 * Go and handle errors now.
362 * If it returns ERESTART then we should RETRY
363 */
364 retry:
365 if (sc_err1(xs, 1) == ERESTART) {
366 switch ((*(sc_link->adapter->scsi_cmd)) (xs)) {
367 case SUCCESSFULLY_QUEUED:
368 return;
369
370 case TRY_AGAIN_LATER:
371 xs->error = XS_BUSY;
372 case COMPLETE:
373 goto retry;
374 }
375 }
376 done:
377 scsi_free_xs(xs, SCSI_NOSLEEP);
378 }
379
380 int
381 scsi_execute_xs(xs)
382 struct scsi_xfer *xs;
383 {
384 int error;
385 int s;
386
387 xs->flags &= ~ITSDONE;
388 xs->error = XS_NOERROR;
389 xs->resid = xs->datalen;
390
391 retry:
392 /*
393 * Do the transfer. If we are polling we will return:
394 * COMPLETE, Was poll, and scsi_done has been called
395 * TRY_AGAIN_LATER, Adapter short resources, try again
396 *
397 * if under full steam (interrupts) it will return:
398 * SUCCESSFULLY_QUEUED, will do a wakeup when complete
399 * TRY_AGAIN_LATER, (as for polling)
400 * After the wakeup, we must still check if it succeeded
401 *
402 * If we have a bp however, all the error proccessing
403 * and the buffer code both expect us to return straight
404 * to them, so as soon as the command is queued, return
405 */
406 switch ((*(xs->sc_link->adapter->scsi_cmd)) (xs)) {
407 case SUCCESSFULLY_QUEUED:
408 if (xs->bp)
409 return EJUSTRETURN;
410 s = splbio();
411 while ((xs->flags & ITSDONE) == 0)
412 tsleep(xs, PRIBIO + 1, "scsi_scsi_cmd", 0);
413 splx(s);
414 case COMPLETE: /* Polling command completed ok */
415 if (xs->bp)
416 return EJUSTRETURN;
417 doit:
418 SC_DEBUG(xs->sc_link, SDEV_DB3, ("back in cmd()\n"));
419 if ((error = sc_err1(xs, 0)) != ERESTART)
420 return error;
421 goto retry;
422
423 case TRY_AGAIN_LATER: /* adapter resource shortage */
424 xs->error = XS_BUSY;
425 goto doit;
426
427 default:
428 panic("scsi_execute_xs: invalid return code");
429 }
430
431 #ifdef DIAGNOSTIC
432 panic("scsi_execute_xs: impossible");
433 #endif
434 }
435
436 /*
437 * ask the scsi driver to perform a command for us.
438 * tell it where to read/write the data, and how
439 * long the data is supposed to be. If we have a buf
440 * to associate with the transfer, we need that too.
441 */
442 int
443 scsi_scsi_cmd(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
444 retries, timeout, bp, flags)
445 struct scsi_link *sc_link;
446 struct scsi_generic *scsi_cmd;
447 int cmdlen;
448 u_char *data_addr;
449 int datalen;
450 int retries;
451 int timeout;
452 struct buf *bp;
453 int flags;
454 {
455 struct scsi_xfer *xs;
456 int error;
457
458 SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n"));
459
460 #ifdef DIAGNOSTIC
461 if (bp != 0 && (flags & SCSI_NOSLEEP) == 0)
462 panic("scsi_scsi_cmd: buffer without nosleep");
463 #endif
464
465 if ((xs = scsi_make_xs(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
466 retries, timeout, bp, flags)) == NULL)
467 return ENOMEM;
468
469 if ((error = scsi_execute_xs(xs)) == EJUSTRETURN)
470 return 0;
471
472 /*
473 * we have finished with the xfer stuct, free it and
474 * check if anyone else needs to be started up.
475 */
476 scsi_free_xs(xs, flags);
477 return error;
478 }
479
480 int
481 sc_err1(xs, async)
482 struct scsi_xfer *xs;
483 int async;
484 {
485 int error;
486
487 SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%x \n", xs->error));
488
489 /*
490 * If it has a buf, we might be working with
491 * a request from the buffer cache or some other
492 * piece of code that requires us to process
493 * errors at inetrrupt time. We have probably
494 * been called by scsi_done()
495 */
496 switch (xs->error) {
497 case XS_NOERROR: /* nearly always hit this one */
498 error = 0;
499 break;
500
501 case XS_SENSE:
502 if ((error = scsi_interpret_sense(xs)) == ERESTART)
503 goto retry;
504 SC_DEBUG(xs->sc_link, SDEV_DB3,
505 ("scsi_interpret_sense returned %d\n", error));
506 break;
507
508 case XS_BUSY:
509 if (xs->retries) {
510 if ((xs->flags & SCSI_POLL) != 0)
511 delay(1000000);
512 else if ((xs->flags & SCSI_NOSLEEP) == 0)
513 tsleep(&lbolt, PRIBIO, "scbusy", 0);
514 else
515 #if 0
516 timeout(scsi_requeue, xs, hz);
517 #else
518 goto lose;
519 #endif
520 }
521 case XS_TIMEOUT:
522 retry:
523 if (xs->retries--) {
524 xs->error = XS_NOERROR;
525 xs->flags &= ~ITSDONE;
526 return ERESTART;
527 }
528 case XS_DRIVER_STUFFUP:
529 lose:
530 error = EIO;
531 break;
532
533 case XS_SELTIMEOUT:
534 /* XXX Disable device? */
535 error = EIO;
536 break;
537
538 default:
539 sc_print_addr(xs->sc_link);
540 printf("unknown error category from scsi driver\n");
541 error = EIO;
542 break;
543 }
544
545 scsi_error(xs, error);
546 return error;
547 }
548
549 void
550 scsi_error(xs, error)
551 struct scsi_xfer *xs;
552 int error;
553 {
554 struct buf *bp = xs->bp;
555
556 if (bp) {
557 if (error) {
558 bp->b_error = error;
559 bp->b_flags |= B_ERROR;
560 bp->b_resid = bp->b_bcount;
561 } else {
562 bp->b_error = 0;
563 bp->b_resid = xs->resid;
564 }
565 biodone(bp);
566 }
567 }
568
569 /*
570 * Look at the returned sense and act on the error, determining
571 * the unix error number to pass back. (0 = report no error)
572 *
573 * THIS IS THE DEFAULT ERROR HANDLER
574 */
575 int
576 scsi_interpret_sense(xs)
577 struct scsi_xfer *xs;
578 {
579 struct scsi_sense_data *sense;
580 struct scsi_link *sc_link = xs->sc_link;
581 u_int8_t key;
582 u_int32_t info;
583 int error;
584
585 static char *error_mes[] = {
586 "soft error (corrected)",
587 "not ready", "medium error",
588 "non-media hardware failure", "illegal request",
589 "unit attention", "readonly device",
590 "no data found", "vendor unique",
591 "copy aborted", "command aborted",
592 "search returned equal", "volume overflow",
593 "verify miscompare", "unknown error key"
594 };
595
596 sense = &xs->sense;
597 #ifdef SCSIDEBUG
598 if ((sc_link->flags & SDEV_DB1) != 0) {
599 int count;
600 printf("code%x valid%x ",
601 sense->error_code & SSD_ERRCODE,
602 sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
603 printf("seg%x key%x ili%x eom%x fmark%x\n",
604 sense->extended_segment,
605 sense->extended_flags & SSD_KEY,
606 sense->extended_flags & SSD_ILI ? 1 : 0,
607 sense->extended_flags & SSD_EOM ? 1 : 0,
608 sense->extended_flags & SSD_FILEMARK ? 1 : 0);
609 printf("info: %x %x %x %x followed by %d extra bytes\n",
610 sense->extended_info[0],
611 sense->extended_info[1],
612 sense->extended_info[2],
613 sense->extended_info[3],
614 sense->extended_extra_len);
615 printf("extra: ");
616 for (count = 0; count < sense->extended_extra_len; count++)
617 printf("%x ", sense->extended_extra_bytes[count]);
618 printf("\n");
619 }
620 #endif /*SCSIDEBUG */
621 /*
622 * If the device has it's own error handler, call it first.
623 * If it returns a legit error value, return that, otherwise
624 * it wants us to continue with normal error processing.
625 */
626 if (sc_link->device->err_handler) {
627 SC_DEBUG(sc_link, SDEV_DB2, ("calling private err_handler()\n"));
628 error = (*sc_link->device->err_handler) (xs);
629 if (error != -1)
630 return error; /* error >= 0 better ? */
631 }
632 /* otherwise use the default */
633 switch (sense->error_code & SSD_ERRCODE) {
634 /*
635 * If it's code 70, use the extended stuff and interpret the key
636 */
637 case 0x71: /* delayed error */
638 sc_print_addr(sc_link);
639 key = sense->extended_flags & SSD_KEY;
640 printf(" DELAYED ERROR, key = 0x%x\n", key);
641 case 0x70:
642 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
643 bcopy(sense->extended_info, &info, sizeof info);
644 info = ntohl(info);
645 } else
646 info = 0;
647 key = sense->extended_flags & SSD_KEY;
648
649 switch (key) {
650 case 0x0: /* NO SENSE */
651 case 0x1: /* RECOVERED ERROR */
652 if (xs->resid == xs->datalen)
653 xs->resid = 0; /* not short read */
654 case 0xc: /* EQUAL */
655 error = 0;
656 break;
657 case 0x2: /* NOT READY */
658 if ((sc_link->flags & SDEV_REMOVABLE) != 0)
659 sc_link->flags &= ~SDEV_MEDIA_LOADED;
660 if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
661 return 0;
662 if ((xs->flags & SCSI_SILENT) != 0)
663 return EIO;
664 error = EIO;
665 break;
666 case 0x5: /* ILLEGAL REQUEST */
667 if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
668 return 0;
669 error = EINVAL;
670 break;
671 case 0x6: /* UNIT ATTENTION */
672 if ((sc_link->flags & SDEV_REMOVABLE) != 0)
673 sc_link->flags &= ~SDEV_MEDIA_LOADED;
674 if ((xs->flags & SCSI_IGNORE_MEDIA_CHANGE) != 0 ||
675 /* XXX Should reupload any transient state. */
676 (sc_link->flags & SDEV_REMOVABLE) == 0)
677 return ERESTART;
678 if ((xs->flags & SCSI_SILENT) != 0)
679 return EIO;
680 error = EIO;
681 break;
682 case 0x7: /* DATA PROTECT */
683 error = EACCES;
684 break;
685 case 0x8: /* BLANK CHECK */
686 error = 0;
687 break;
688 case 0xd: /* VOLUME OVERFLOW */
689 error = ENOSPC;
690 break;
691 default:
692 error = EIO;
693 break;
694 }
695
696 if (key) {
697 sc_print_addr(sc_link);
698 printf("%s", error_mes[key - 1]);
699 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
700 switch (key) {
701 case 0x2: /* NOT READY */
702 case 0x5: /* ILLEGAL REQUEST */
703 case 0x6: /* UNIT ATTENTION */
704 case 0x7: /* DATA PROTECT */
705 break;
706 case 0x8: /* BLANK CHECK */
707 printf(", requested size: %d (decimal)",
708 info);
709 break;
710 default:
711 printf(", info = %d (decimal)", info);
712 }
713 }
714 if (sense->extended_extra_len != 0) {
715 int n;
716 printf(", data =");
717 for (n = 0; n < sense->extended_extra_len; n++)
718 printf(" %02x", sense->extended_extra_bytes[n]);
719 }
720 printf("\n");
721 }
722 return error;
723
724 /*
725 * Not code 70, just report it
726 */
727 default:
728 sc_print_addr(sc_link);
729 printf("error code %d",
730 sense->error_code & SSD_ERRCODE);
731 if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
732 printf(" at block no. %d (decimal)",
733 (sense->XXX_unextended_blockhi << 16) +
734 (sense->XXX_unextended_blockmed << 8) +
735 (sense->XXX_unextended_blocklow));
736 }
737 printf("\n");
738 return EIO;
739 }
740 }
741
742 /*
743 * Utility routines often used in SCSI stuff
744 */
745
746 /*
747 * convert a physical address to 3 bytes,
748 * MSB at the lowest address,
749 * LSB at the highest.
750 */
751 void
752 lto3b(val, bytes)
753 u_int32_t val;
754 u_int8_t *bytes;
755 {
756
757 *bytes++ = (val & 0xff0000) >> 16;
758 *bytes++ = (val & 0xff00) >> 8;
759 *bytes = val & 0xff;
760 }
761
762 /*
763 * The reverse of lto3b
764 */
765 u_int32_t
766 _3btol(bytes)
767 u_int8_t *bytes;
768 {
769 u_int32_t rc;
770
771 rc = (*bytes++ << 16);
772 rc += (*bytes++ << 8);
773 rc += *bytes;
774 return (rc);
775 }
776
777 /*
778 * Print out the scsi_link structure's address info.
779 */
780 void
781 sc_print_addr(sc_link)
782 struct scsi_link *sc_link;
783 {
784
785 printf("%s(%s:%d:%d): ",
786 sc_link->device_softc ?
787 ((struct device *)sc_link->device_softc)->dv_xname : "probe",
788 ((struct device *)sc_link->adapter_softc)->dv_xname,
789 sc_link->target, sc_link->lun);
790 }
791
792 #ifdef SCSIDEBUG
793 /*
794 * Given a scsi_xfer, dump the request, in all it's glory
795 */
796 void
797 show_scsi_xs(xs)
798 struct scsi_xfer *xs;
799 {
800 printf("xs(0x%x): ", xs);
801 printf("flg(0x%x)", xs->flags);
802 printf("sc_link(0x%x)", xs->sc_link);
803 printf("retr(0x%x)", xs->retries);
804 printf("timo(0x%x)", xs->timeout);
805 printf("cmd(0x%x)", xs->cmd);
806 printf("len(0x%x)", xs->cmdlen);
807 printf("data(0x%x)", xs->data);
808 printf("len(0x%x)", xs->datalen);
809 printf("res(0x%x)", xs->resid);
810 printf("err(0x%x)", xs->error);
811 printf("bp(0x%x)", xs->bp);
812 show_scsi_cmd(xs);
813 }
814
815 void
816 show_scsi_cmd(xs)
817 struct scsi_xfer *xs;
818 {
819 u_char *b = (u_char *) xs->cmd;
820 int i = 0;
821
822 sc_print_addr(xs->sc_link);
823 printf("command: ");
824
825 if ((xs->flags & SCSI_RESET) == 0) {
826 while (i < xs->cmdlen) {
827 if (i)
828 printf(",");
829 printf("%x", b[i++]);
830 }
831 printf("-[%d bytes]\n", xs->datalen);
832 if (xs->datalen)
833 show_mem(xs->data, min(64, xs->datalen));
834 } else
835 printf("-RESET-\n");
836 }
837
838 void
839 show_mem(address, num)
840 u_char *address;
841 int num;
842 {
843 int x;
844
845 printf("------------------------------");
846 for (x = 0; x < num; x++) {
847 if ((x % 16) == 0)
848 printf("\n%03d: ", x);
849 printf("%02x ", *address++);
850 }
851 printf("\n------------------------------\n");
852 }
853 #endif /*SCSIDEBUG */
854