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