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