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