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