Home | History | Annotate | Line # | Download | only in scsipi
scsi_base.c revision 1.30
      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 (at) 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