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