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