Home | History | Annotate | Line # | Download | only in scsipi
scsi_base.c revision 1.61
      1 /*	$NetBSD: scsi_base.c,v 1.61 1998/07/01 17:16:46 mjacob Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1994, 1995, 1997 Charles M. 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 M. 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 "opt_scsiverbose.h"
     37 
     38 #include <sys/types.h>
     39 #include <sys/param.h>
     40 #include <sys/systm.h>
     41 #include <sys/kernel.h>
     42 #include <sys/buf.h>
     43 #include <sys/uio.h>
     44 #include <sys/malloc.h>
     45 #include <sys/errno.h>
     46 #include <sys/device.h>
     47 #include <sys/proc.h>
     48 
     49 #include <dev/scsipi/scsipi_all.h>
     50 #include <dev/scsipi/scsi_all.h>
     51 #include <dev/scsipi/scsi_disk.h>
     52 #include <dev/scsipi/scsiconf.h>
     53 #include <dev/scsipi/scsipi_base.h>
     54 
     55 /*
     56  * Do a scsi operation, asking a device to run as SCSI-II if it can.
     57  */
     58 int
     59 scsi_change_def(sc_link, flags)
     60 	struct scsipi_link *sc_link;
     61 	int flags;
     62 {
     63 	struct scsi_changedef scsipi_cmd;
     64 
     65 	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
     66 	scsipi_cmd.opcode = SCSI_CHANGE_DEFINITION;
     67 	scsipi_cmd.how = SC_SCSI_2;
     68 
     69 	return (scsipi_command(sc_link,
     70 	    (struct scsipi_generic *) &scsipi_cmd, sizeof(scsipi_cmd),
     71 	    0, 0, 2, 100000, NULL, flags));
     72 }
     73 
     74 /*
     75  * ask the scsi driver to perform a command for us.
     76  * tell it where to read/write the data, and how
     77  * long the data is supposed to be. If we have  a buf
     78  * to associate with the transfer, we need that too.
     79  */
     80 int
     81 scsi_scsipi_cmd(sc_link, scsipi_cmd, cmdlen, data_addr, datalen,
     82 	retries, timeout, bp, flags)
     83 	struct scsipi_link *sc_link;
     84 	struct scsipi_generic *scsipi_cmd;
     85 	int cmdlen;
     86 	u_char *data_addr;
     87 	int datalen;
     88 	int retries;
     89 	int timeout;
     90 	struct buf *bp;
     91 	int flags;
     92 {
     93 	struct scsipi_xfer *xs;
     94 	int error;
     95 
     96 	SC_DEBUG(sc_link, SDEV_DB2, ("scsi_scsipi_cmd\n"));
     97 
     98 #ifdef DIAGNOSTIC
     99 	if (bp != 0 && (flags & SCSI_NOSLEEP) == 0)
    100 		panic("scsi_scsipi_cmd: buffer without nosleep");
    101 #endif
    102 
    103 	if ((xs = scsipi_make_xs(sc_link, scsipi_cmd, cmdlen, data_addr,
    104 	    datalen, retries, timeout, bp, flags)) == NULL)
    105 		return (ENOMEM);
    106 
    107 	/*
    108 	 * Set the LUN in the CDB if we have an older device.  We also
    109 	 * set it for more modern SCSI-II devices "just in case".
    110 	 */
    111 	if ((sc_link->scsipi_scsi.scsi_version & SID_ANSII) <= 2)
    112 		xs->cmd->bytes[0] |=
    113 		    ((sc_link->scsipi_scsi.lun << SCSI_CMD_LUN_SHIFT) &
    114 			SCSI_CMD_LUN_MASK);
    115 
    116 	if ((error = scsipi_execute_xs(xs)) == EJUSTRETURN)
    117 		return (0);
    118 
    119 	/*
    120 	 * we have finished with the xfer stuct, free it and
    121 	 * check if anyone else needs to be started up.
    122 	 */
    123 	scsipi_free_xs(xs, flags);
    124 	return (error);
    125 }
    126 
    127 /*
    128  * Look at the returned sense and act on the error, determining
    129  * the unix error number to pass back.  (0 = report no error)
    130  *
    131  * THIS IS THE DEFAULT ERROR HANDLER FOR SCSI DEVICES
    132  */
    133 int
    134 scsi_interpret_sense(xs)
    135 	struct scsipi_xfer *xs;
    136 {
    137 	struct scsipi_sense_data *sense;
    138 	struct scsipi_link *sc_link = xs->sc_link;
    139 	u_int8_t key;
    140 	u_int32_t info;
    141 	int error;
    142 #ifndef	SCSIVERBOSE
    143 	static char *error_mes[] = {
    144 		"soft error (corrected)",
    145 		"not ready", "medium error",
    146 		"non-media hardware failure", "illegal request",
    147 		"unit attention", "readonly device",
    148 		"no data found", "vendor unique",
    149 		"copy aborted", "command aborted",
    150 		"search returned equal", "volume overflow",
    151 		"verify miscompare", "unknown error key"
    152 	};
    153 #endif
    154 
    155 	sense = &xs->sense.scsi_sense;
    156 #ifdef	SCSIDEBUG
    157 	if ((sc_link->flags & SDEV_DB1) != 0) {
    158 		int count;
    159 		printf("code 0x%x valid 0x%x ",
    160 			sense->error_code & SSD_ERRCODE,
    161 			sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
    162 		printf("seg 0x%x key 0x%x ili 0x%x eom 0x%x fmark 0x%x\n",
    163 			sense->segment,
    164 			sense->flags & SSD_KEY,
    165 			sense->flags & SSD_ILI ? 1 : 0,
    166 			sense->flags & SSD_EOM ? 1 : 0,
    167 			sense->flags & SSD_FILEMARK ? 1 : 0);
    168 		printf("info: 0x%x 0x%x 0x%x 0x%x followed by %d extra bytes\n",
    169 			sense->info[0],
    170 			sense->info[1],
    171 			sense->info[2],
    172 			sense->info[3],
    173 			sense->extra_len);
    174 		printf("extra: ");
    175 		for (count = 0; count < ADD_BYTES_LIM(sense); count++)
    176 			printf("0x%x ", sense->cmd_spec_info[count]);
    177 		printf("\n");
    178 	}
    179 #endif	/* SCSIDEBUG */
    180 	/*
    181 	 * If the device has it's own error handler, call it first.
    182 	 * If it returns a legit error value, return that, otherwise
    183 	 * it wants us to continue with normal error processing.
    184 	 */
    185 	if (sc_link->device->err_handler) {
    186 		SC_DEBUG(sc_link, SDEV_DB2,
    187 		    ("calling private err_handler()\n"));
    188 		error = (*sc_link->device->err_handler)(xs);
    189 		if (error != -1)
    190 			return (error);		/* error >= 0  better ? */
    191 	}
    192 	/* otherwise use the default */
    193 	switch (sense->error_code & SSD_ERRCODE) {
    194 		/*
    195 		 * If it's code 70, use the extended stuff and
    196 		 * interpret the key
    197 		 */
    198 	case 0x71:		/* delayed error */
    199 		sc_link->sc_print_addr(sc_link);
    200 		key = sense->flags & SSD_KEY;
    201 		printf(" DEFERRED ERROR, key = 0x%x\n", key);
    202 		/* FALLTHROUGH */
    203 	case 0x70:
    204 		if ((sense->error_code & SSD_ERRCODE_VALID) != 0)
    205 			info = _4btol(sense->info);
    206 		else
    207 			info = 0;
    208 		key = sense->flags & SSD_KEY;
    209 
    210 		switch (key) {
    211 		case SKEY_NO_SENSE:
    212 		case SKEY_RECOVERABLE_ERROR:
    213 			if (xs->resid == xs->datalen)
    214 				xs->resid = 0;	/* not short read */
    215 		case SKEY_EQUAL:
    216 			error = 0;
    217 			break;
    218 		case SKEY_NOT_READY:
    219 			if ((sc_link->flags & SDEV_REMOVABLE) != 0)
    220 				sc_link->flags &= ~SDEV_MEDIA_LOADED;
    221 			if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
    222 				return (0);
    223 			if ((xs->flags & SCSI_SILENT) != 0)
    224 				return (EIO);
    225 			error = EIO;
    226 			break;
    227 		case SKEY_ILLEGAL_REQUEST:
    228 			if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
    229 				return (0);
    230 			if ((xs->flags & SCSI_SILENT) != 0)
    231 				return (EIO);
    232 			error = EINVAL;
    233 			break;
    234 		case SKEY_UNIT_ATTENTION:
    235 			if ((sc_link->flags & SDEV_REMOVABLE) != 0)
    236 				sc_link->flags &= ~SDEV_MEDIA_LOADED;
    237 			if ((xs->flags & SCSI_IGNORE_MEDIA_CHANGE) != 0 ||
    238 				/* XXX Should reupload any transient state. */
    239 				(sc_link->flags & SDEV_REMOVABLE) == 0)
    240 				return (ERESTART);
    241 			if ((xs->flags & SCSI_SILENT) != 0)
    242 				return (EIO);
    243 			error = EIO;
    244 			break;
    245 		case SKEY_WRITE_PROTECT:
    246 			error = EROFS;
    247 			break;
    248 		case SKEY_BLANK_CHECK:
    249 			error = 0;
    250 			break;
    251 		case SKEY_ABORTED_COMMAND:
    252 			error = ERESTART;
    253 			break;
    254 		case SKEY_VOLUME_OVERFLOW:
    255 			error = ENOSPC;
    256 			break;
    257 		default:
    258 			error = EIO;
    259 			break;
    260 		}
    261 
    262 #ifdef SCSIVERBOSE
    263 		if ((xs->flags & SCSI_SILENT) == 0)
    264 			scsi_print_sense(xs, 0);
    265 #else
    266 		if (key) {
    267 			sc_link->sc_print_addr(sc_link);
    268 			printf("%s", error_mes[key - 1]);
    269 			if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
    270 				switch (key) {
    271 				case SKEY_NOT_READY:
    272 				case SKEY_ILLEGAL_REQUEST:
    273 				case SKEY_UNIT_ATTENTION:
    274 				case SKEY_WRITE_PROTECT:
    275 					break;
    276 				case SKEY_BLANK_CHECK:
    277 					printf(", requested size: %d (decimal)",
    278 					    info);
    279 					break;
    280 				case SKEY_ABORTED_COMMAND:
    281 					if (xs->retries)
    282 						printf(", retrying");
    283 					printf(", cmd 0x%x, info 0x%x",
    284 					    xs->cmd->opcode, info);
    285 					break;
    286 				default:
    287 					printf(", info = %d (decimal)", info);
    288 				}
    289 			}
    290 			if (sense->extra_len != 0) {
    291 				int n;
    292 				printf(", data =");
    293 				for (n = 0; n < sense->extra_len; n++)
    294 					printf(" %02x",
    295 					    sense->cmd_spec_info[n]);
    296 			}
    297 			printf("\n");
    298 		}
    299 #endif
    300 		return (error);
    301 
    302 	/*
    303 	 * Not code 70, just report it
    304 	 */
    305 	default:
    306 		sc_link->sc_print_addr(sc_link);
    307 		printf("error code %d", sense->error_code & SSD_ERRCODE);
    308 		if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
    309 			struct scsipi_sense_data_unextended *usense =
    310 			    (struct scsipi_sense_data_unextended *)sense;
    311 			printf(" at block no. %d (decimal)",
    312 			    _3btol(usense->block));
    313 		}
    314 		printf("\n");
    315 		return (EIO);
    316 	}
    317 }
    318 
    319 /*
    320  * Utility routines often used in SCSI stuff
    321  */
    322 
    323 
    324 /*
    325  * Print out the scsi_link structure's address info.
    326  */
    327 void
    328 scsi_print_addr(sc_link)
    329 	struct scsipi_link *sc_link;
    330 {
    331 
    332 	printf("%s(%s:%d:%d): ",
    333 	    sc_link->device_softc ?
    334 	    ((struct device *)sc_link->device_softc)->dv_xname : "probe",
    335 	    ((struct device *)sc_link->adapter_softc)->dv_xname,
    336 	    sc_link->scsipi_scsi.target, sc_link->scsipi_scsi.lun);
    337 }
    338