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