Home | History | Annotate | Line # | Download | only in scsipi
scsi_base.c revision 1.21
      1 /*	$NetBSD: scsi_base.c,v 1.21 1994/12/01 13:07:28 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 	SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n"));
    357 
    358 	xs = get_xs(sc_link, flags);	/* should wait unless booting */
    359 	if (!xs)
    360 		return ENOMEM;
    361 	/*
    362 	 * Fill out the scsi_xfer structure.  We don't know whose context
    363 	 * the cmd is in, so copy it.
    364 	 */
    365 	bcopy(scsi_cmd, &xs->cmdstore, cmdlen);
    366 	xs->flags = INUSE | flags;
    367 	xs->sc_link = sc_link;
    368 	xs->retries = retries;
    369 	xs->timeout = timeout;
    370 	xs->cmd = &xs->cmdstore;
    371 	xs->cmdlen = cmdlen;
    372 	xs->data = data_addr;
    373 	xs->datalen = datalen;
    374 	xs->resid = datalen;
    375 	xs->bp = bp;
    376 	if ((flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) &&
    377 	    ((caddr_t) data_addr < (caddr_t) KERNBASE)) {
    378 		if (bp) {
    379 			printf("Data buffered space not in kernel context\n");
    380 #ifdef	SCSIDEBUG
    381 			show_scsi_cmd(xs);
    382 #endif	/* SCSIDEBUG */
    383 			error = EFAULT;
    384 			goto bad;
    385 		}
    386 		xs->data = malloc(datalen, M_TEMP, M_WAITOK);
    387 		/* I think waiting is ok *//*XXX */
    388 		if (flags & SCSI_DATA_OUT)
    389 			bcopy(data_addr, xs->data, datalen);
    390 		else
    391 			bzero(xs->data, datalen);
    392 	}
    393 retry:
    394 	xs->error = XS_NOERROR;
    395 #ifdef	SCSIDEBUG
    396 	if (sc_link->flags & SDEV_DB3)
    397 		show_scsi_xs(xs);
    398 #endif /* SCSIDEBUG */
    399 	/*
    400 	 * Do the transfer. If we are polling we will return:
    401 	 * COMPLETE,  Was poll, and scsi_done has been called
    402 	 * TRY_AGAIN_LATER, Adapter short resources, try again
    403 	 *
    404 	 * if under full steam (interrupts) it will return:
    405 	 * SUCCESSFULLY_QUEUED, will do a wakeup when complete
    406 	 * TRY_AGAIN_LATER, (as for polling)
    407 	 * After the wakeup, we must still check if it succeeded
    408 	 *
    409 	 * If we have a bp however, all the error proccessing
    410 	 * and the buffer code both expect us to return straight
    411 	 * to them, so as soon as the command is queued, return
    412 	 */
    413 	error = (*(sc_link->adapter->scsi_cmd)) (xs);
    414 
    415 	switch (error) {
    416 	case SUCCESSFULLY_QUEUED:
    417 		if (bp)
    418 			return error;	/* will sleep (or not) elsewhere */
    419 		s = splbio();
    420 		while (!(xs->flags & ITSDONE))
    421 			tsleep(xs, PRIBIO + 1, "scsi_scsi_cmd", 0);
    422 		splx(s);
    423 		/* fall through to check success of completed command */
    424 	case COMPLETE:		/* Polling command completed ok */
    425 /*XXX*/	case HAD_ERROR:		/* Polling command completed with error */
    426 		SC_DEBUG(sc_link, SDEV_DB3, ("back in cmd()\n"));
    427 		if ((error = sc_err1(xs)) == -1)
    428 			goto retry;
    429 		break;
    430 
    431 	case TRY_AGAIN_LATER:	/* adapter resource shortage */
    432 		SC_DEBUG(sc_link, SDEV_DB3, ("will try again \n"));
    433 		if (xs->retries--) {
    434 			xs->flags &= ~ITSDONE;
    435 			tsleep((caddr_t)&lbolt, PRIBIO, "scretry", 0);
    436 			goto retry;
    437 		}
    438 	default:
    439 		error = EIO;
    440 	}
    441 	/*
    442 	 * If we had to copy the data out of the user's context,
    443 	 * then do the other half (copy it back or whatever)
    444 	 * and free the memory buffer
    445 	 */
    446 	if ((flags & SCSI_DATA_IN) && (xs->data != data_addr)) {
    447 		bcopy(xs->data, data_addr, datalen);
    448 		free(xs->data, M_TEMP);
    449 	}
    450 	/*
    451 	 * we have finished with the xfer stuct, free it and
    452 	 * check if anyone else needs to be started up.
    453 	 */
    454 bad:
    455 	free_xs(xs, sc_link, flags);	/* includes the 'start' op */
    456 	if (bp && error) {
    457 		bp->b_error = error;
    458 		bp->b_flags |= B_ERROR;
    459 		biodone(bp);
    460 	}
    461 	return error;
    462 }
    463 
    464 int
    465 sc_err1(xs)
    466 	struct scsi_xfer *xs;
    467 {
    468 	struct buf *bp = xs->bp;
    469 	int error;
    470 
    471 	SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%x \n", xs->error));
    472 	/*
    473 	 * If it has a buf, we might be working with
    474 	 * a request from the buffer cache or some other
    475 	 * piece of code that requires us to process
    476 	 * errors at inetrrupt time. We have probably
    477 	 * been called by scsi_done()
    478 	 */
    479 	switch (xs->error) {
    480 	case XS_NOERROR:	/* nearly always hit this one */
    481 		error = 0;
    482 		break;
    483 
    484 	case XS_SENSE:
    485 		error = scsi_interpret_sense(xs);
    486 		SC_DEBUG(xs->sc_link, SDEV_DB3,
    487 		    ("scsi_interpret_sense returned %d\n", error));
    488 		if (error == -2)
    489 			goto doretry;
    490 		break;
    491 
    492 	case XS_BUSY:
    493 		/* should somehow arange for a 1 sec delay here (how?) */
    494 	case XS_TIMEOUT:
    495 	doretry:
    496 		/*
    497 		 * If we can, resubmit it to the adapter.
    498 		 */
    499 		if (xs->retries--) {
    500 			xs->error = XS_NOERROR;
    501 			xs->flags &= ~ITSDONE;
    502 			goto retry;
    503 		}
    504 		/* fall through */
    505 	case XS_DRIVER_STUFFUP:
    506 		error = EIO;
    507 		break;
    508 
    509 	default:
    510 		sc_print_addr(xs->sc_link);
    511 		printf("unknown error category from scsi driver\n");
    512 		error = EIO;
    513 		break;
    514 	}
    515 
    516 	if (bp) {
    517 		if (error) {
    518 			bp->b_flags |= B_ERROR;
    519 			bp->b_error = error;
    520 			bp->b_resid = bp->b_bcount;
    521 		} else {
    522 			bp->b_error = 0;
    523 			bp->b_resid = 0;
    524 		}
    525 	}
    526 	return error;
    527 
    528 retry:
    529 	return -1;
    530 }
    531 
    532 /*
    533  * Look at the returned sense and act on the error, determining
    534  * the unix error number to pass back.  (0 = report no error)
    535  *
    536  * THIS IS THE DEFAULT ERROR HANDLER
    537  */
    538 int
    539 scsi_interpret_sense(xs)
    540 	struct scsi_xfer *xs;
    541 {
    542 	struct scsi_sense_data *sense;
    543 	struct scsi_link *sc_link = xs->sc_link;
    544 	u_int32 key;
    545 	u_int32 silent;
    546 	u_int32 info;
    547 	int error;
    548 
    549 	static char *error_mes[] =
    550 	{"soft error (corrected)",
    551 	    "not ready", "medium error",
    552 	    "non-media hardware failure", "illegal request",
    553 	    "unit attention", "readonly device",
    554 	    "no data found", "vendor unique",
    555 	    "copy aborted", "command aborted",
    556 	    "search returned equal", "volume overflow",
    557 	    "verify miscompare", "unknown error key"
    558 	};
    559 
    560 	/*
    561 	 * If the flags say errs are ok, then always return ok.
    562 	 */
    563 	if (xs->flags & SCSI_ERR_OK)
    564 		return 0;
    565 
    566 	sense = &xs->sense;
    567 #ifdef	SCSIDEBUG
    568 	if (sc_link->flags & SDEV_DB1) {
    569 		u_int32 count = 0;
    570 		printf("code%x valid%x ",
    571 		    sense->error_code & SSD_ERRCODE,
    572 		    sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
    573 		printf("seg%x key%x ili%x eom%x fmark%x\n",
    574 		    sense->extended_segment,
    575 		    sense->extended_flags & SSD_KEY,
    576 		    sense->extended_flags & SSD_ILI ? 1 : 0,
    577 		    sense->extended_flags & SSD_EOM ? 1 : 0,
    578 		    sense->extended_flags & SSD_FILEMARK ? 1 : 0);
    579 		printf("info: %x %x %x %x followed by %d extra bytes\n",
    580 		    sense->extended_info[0],
    581 		    sense->extended_info[1],
    582 		    sense->extended_info[2],
    583 		    sense->extended_info[3],
    584 		    sense->extended_extra_len);
    585 		printf("extra: ");
    586 		while (count < sense->extended_extra_len)
    587 			printf("%x ", sense->extended_extra_bytes[count++]);
    588 		printf("\n");
    589 	}
    590 #endif	/*SCSIDEBUG */
    591 	/*
    592 	 * If the device has it's own error handler, call it first.
    593 	 * If it returns a legit error value, return that, otherwise
    594 	 * it wants us to continue with normal error processing.
    595 	 */
    596 	if (sc_link->device->err_handler) {
    597 		SC_DEBUG(sc_link, SDEV_DB2, ("calling private err_handler()\n"));
    598 		error = (*sc_link->device->err_handler) (xs);
    599 		if (error != -1)
    600 			return error;		/* error >= 0  better ? */
    601 	}
    602 	/* otherwise use the default */
    603 	silent = (xs->flags & SCSI_SILENT);
    604 	switch (sense->error_code & SSD_ERRCODE) {
    605 		/*
    606 		 * If it's code 70, use the extended stuff and interpret the key
    607 		 */
    608 	case 0x71:		/* delayed error */
    609 		sc_print_addr(sc_link);
    610 		key = sense->extended_flags & SSD_KEY;
    611 		printf(" DELAYED ERROR, key = 0x%x\n", key);
    612 	case 0x70:
    613 		if (sense->error_code & SSD_ERRCODE_VALID) {
    614 			bcopy(sense->extended_info, &info, sizeof info);
    615 			info = ntohl(info);
    616 		} else
    617 			info = 0;
    618 		key = sense->extended_flags & SSD_KEY;
    619 
    620 		if (key && !silent) {
    621 			sc_print_addr(sc_link);
    622 			printf("%s", error_mes[key - 1]);
    623 			if (sense->error_code & SSD_ERRCODE_VALID) {
    624 				switch (key) {
    625 				case 0x2:	/* NOT READY */
    626 				case 0x5:	/* ILLEGAL REQUEST */
    627 				case 0x6:	/* UNIT ATTENTION */
    628 				case 0x7:	/* DATA PROTECT */
    629 					break;
    630 				case 0x8:	/* BLANK CHECK */
    631 					printf(", requested size: %d (decimal)",
    632 					    info);
    633 					break;
    634 				default:
    635 					printf(", info = %d (decimal)", info);
    636 				}
    637 			}
    638 			printf("\n");
    639 		}
    640 		switch (key) {
    641 		case 0x0:	/* NO SENSE */
    642 		case 0x1:	/* RECOVERED ERROR */
    643 			if (xs->resid == xs->datalen)
    644 				xs->resid = 0;	/* not short read */
    645 		case 0xc:	/* EQUAL */
    646 			return 0;
    647 		case 0x2:	/* NOT READY */
    648 			sc_link->flags &= ~SDEV_MEDIA_LOADED;
    649 			return EBUSY;
    650 		case 0x5:	/* ILLEGAL REQUEST */
    651 			return EINVAL;
    652 		case 0x6:	/* UNIT ATTENTION */
    653 			sc_link->flags &= ~SDEV_MEDIA_LOADED;
    654 			if (sc_link->flags & SDEV_OPEN)
    655 				return EIO;
    656 			else
    657 				return 0;
    658 		case 0x7:	/* DATA PROTECT */
    659 			return EACCES;
    660 		case 0xd:	/* VOLUME OVERFLOW */
    661 			return ENOSPC;
    662 		case 0x8:	/* BLANK CHECK */
    663 			return 0;
    664 		default:
    665 			return EIO;
    666 		}
    667 	/*
    668 	 * Not code 70, just report it
    669 	 */
    670 	default:
    671 		if (!silent) {
    672 			sc_print_addr(sc_link);
    673 			printf("error code %d",
    674 			    sense->error_code & SSD_ERRCODE);
    675 			if (sense->error_code & SSD_ERRCODE_VALID) {
    676 				printf(" at block no. %d (decimal)",
    677 				    (sense->XXX_unextended_blockhi << 16) +
    678 				    (sense->XXX_unextended_blockmed << 8) +
    679 				    (sense->XXX_unextended_blocklow));
    680 			}
    681 			printf("\n");
    682 		}
    683 		return EIO;
    684 	}
    685 }
    686 
    687 /*
    688  * Utility routines often used in SCSI stuff
    689  */
    690 
    691 /*
    692  * convert a physical address to 3 bytes,
    693  * MSB at the lowest address,
    694  * LSB at the highest.
    695  */
    696 void
    697 lto3b(val, bytes)
    698 	int	val;
    699 	u_char	*bytes;
    700 {
    701 	*bytes++ = (val & 0xff0000) >> 16;
    702 	*bytes++ = (val & 0xff00) >> 8;
    703 	*bytes = val & 0xff;
    704 }
    705 
    706 /*
    707  * The reverse of lto3b
    708  */
    709 int
    710 _3btol(bytes)
    711 	u_char *bytes;
    712 {
    713 	u_int32 rc;
    714 	rc = (*bytes++ << 16);
    715 	rc += (*bytes++ << 8);
    716 	rc += *bytes;
    717 	return ((int) rc);
    718 }
    719 
    720 /*
    721  * Print out the scsi_link structure's address info.
    722  */
    723 void
    724 sc_print_addr(sc_link)
    725 	struct	scsi_link *sc_link;
    726 {
    727 
    728 	printf("%s(%s:%d:%d): ",
    729 		((struct device *)sc_link->device_softc)->dv_xname,
    730 		((struct device *)sc_link->adapter_softc)->dv_xname,
    731 		sc_link->target, sc_link->lun);
    732 }
    733 
    734 #ifdef	SCSIDEBUG
    735 /*
    736  * Given a scsi_xfer, dump the request, in all it's glory
    737  */
    738 void
    739 show_scsi_xs(xs)
    740 	struct scsi_xfer *xs;
    741 {
    742 	printf("xs(0x%x): ", xs);
    743 	printf("flg(0x%x)", xs->flags);
    744 	printf("sc_link(0x%x)", xs->sc_link);
    745 	printf("retr(0x%x)", xs->retries);
    746 	printf("timo(0x%x)", xs->timeout);
    747 	printf("cmd(0x%x)", xs->cmd);
    748 	printf("len(0x%x)", xs->cmdlen);
    749 	printf("data(0x%x)", xs->data);
    750 	printf("len(0x%x)", xs->datalen);
    751 	printf("res(0x%x)", xs->resid);
    752 	printf("err(0x%x)", xs->error);
    753 	printf("bp(0x%x)", xs->bp);
    754 	show_scsi_cmd(xs);
    755 }
    756 
    757 void
    758 show_scsi_cmd(xs)
    759 	struct scsi_xfer *xs;
    760 {
    761 	u_char *b = (u_char *) xs->cmd;
    762 	int     i = 0;
    763 
    764 	sc_print_addr(xs->sc_link);
    765 	printf("command: ");
    766 
    767 	if (!(xs->flags & SCSI_RESET)) {
    768 		while (i < xs->cmdlen) {
    769 			if (i)
    770 				printf(",");
    771 			printf("%x", b[i++]);
    772 		}
    773 		printf("-[%d bytes]\n", xs->datalen);
    774 		if (xs->datalen)
    775 			show_mem(xs->data, min(64, xs->datalen));
    776 	} else
    777 		printf("-RESET-\n");
    778 }
    779 
    780 void
    781 show_mem(address, num)
    782 	unsigned char *address;
    783 	u_int32 num;
    784 {
    785 	u_int32 x, y;
    786 	printf("------------------------------");
    787 	for (y = 0; y < num; y += 1) {
    788 		if (!(y % 16))
    789 			printf("\n%03d: ", y);
    790 		printf("%02x ", *address++);
    791 	}
    792 	printf("\n------------------------------\n");
    793 }
    794 #endif /*SCSIDEBUG */
    795