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