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