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