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