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