Home | History | Annotate | Line # | Download | only in scsipi
scsi_base.c revision 1.65
      1  1.65   mycroft /*	$NetBSD: scsi_base.c,v 1.65 1998/08/15 10:10:56 mycroft Exp $	*/
      2  1.14       cgd 
      3  1.65   mycroft /*-
      4  1.65   mycroft  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  1.65   mycroft  * All rights reserved.
      6  1.65   mycroft  *
      7  1.65   mycroft  * This code is derived from software contributed to The NetBSD Foundation
      8  1.65   mycroft  * by Charles M. Hannum.
      9   1.9   mycroft  *
     10   1.9   mycroft  * Redistribution and use in source and binary forms, with or without
     11   1.9   mycroft  * modification, are permitted provided that the following conditions
     12   1.9   mycroft  * are met:
     13   1.9   mycroft  * 1. Redistributions of source code must retain the above copyright
     14   1.9   mycroft  *    notice, this list of conditions and the following disclaimer.
     15   1.9   mycroft  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.9   mycroft  *    notice, this list of conditions and the following disclaimer in the
     17   1.9   mycroft  *    documentation and/or other materials provided with the distribution.
     18   1.9   mycroft  * 3. All advertising materials mentioning features or use of this software
     19   1.9   mycroft  *    must display the following acknowledgement:
     20  1.65   mycroft  *        This product includes software developed by the NetBSD
     21  1.65   mycroft  *        Foundation, Inc. and its contributors.
     22  1.65   mycroft  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.65   mycroft  *    contributors may be used to endorse or promote products derived
     24  1.65   mycroft  *    from this software without specific prior written permission.
     25   1.9   mycroft  *
     26  1.65   mycroft  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.65   mycroft  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.65   mycroft  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.65   mycroft  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.65   mycroft  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.65   mycroft  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.65   mycroft  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.65   mycroft  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.65   mycroft  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.65   mycroft  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.65   mycroft  * POSSIBILITY OF SUCH DAMAGE.
     37   1.1   mycroft  */
     38  1.49     enami 
     39  1.64    mjacob #include "opt_scsi.h"
     40   1.1   mycroft 
     41   1.1   mycroft #include <sys/types.h>
     42   1.1   mycroft #include <sys/param.h>
     43  1.30   thorpej #include <sys/systm.h>
     44  1.11   mycroft #include <sys/kernel.h>
     45   1.1   mycroft #include <sys/buf.h>
     46   1.1   mycroft #include <sys/uio.h>
     47   1.1   mycroft #include <sys/malloc.h>
     48   1.1   mycroft #include <sys/errno.h>
     49   1.1   mycroft #include <sys/device.h>
     50  1.33  christos #include <sys/proc.h>
     51   1.2   mycroft 
     52  1.47    bouyer #include <dev/scsipi/scsipi_all.h>
     53  1.47    bouyer #include <dev/scsipi/scsi_all.h>
     54  1.47    bouyer #include <dev/scsipi/scsi_disk.h>
     55  1.47    bouyer #include <dev/scsipi/scsiconf.h>
     56  1.47    bouyer #include <dev/scsipi/scsipi_base.h>
     57  1.47    bouyer 
     58   1.1   mycroft /*
     59   1.1   mycroft  * Do a scsi operation, asking a device to run as SCSI-II if it can.
     60   1.1   mycroft  */
     61  1.50     enami int
     62   1.1   mycroft scsi_change_def(sc_link, flags)
     63  1.47    bouyer 	struct scsipi_link *sc_link;
     64  1.11   mycroft 	int flags;
     65   1.1   mycroft {
     66  1.47    bouyer 	struct scsi_changedef scsipi_cmd;
     67   1.1   mycroft 
     68  1.47    bouyer 	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
     69  1.47    bouyer 	scsipi_cmd.opcode = SCSI_CHANGE_DEFINITION;
     70  1.47    bouyer 	scsipi_cmd.how = SC_SCSI_2;
     71   1.1   mycroft 
     72  1.55   thorpej 	return (scsipi_command(sc_link,
     73  1.50     enami 	    (struct scsipi_generic *) &scsipi_cmd, sizeof(scsipi_cmd),
     74  1.50     enami 	    0, 0, 2, 100000, NULL, flags));
     75  1.22   mycroft }
     76  1.22   mycroft 
     77  1.22   mycroft /*
     78  1.22   mycroft  * ask the scsi driver to perform a command for us.
     79  1.22   mycroft  * tell it where to read/write the data, and how
     80  1.22   mycroft  * long the data is supposed to be. If we have  a buf
     81  1.22   mycroft  * to associate with the transfer, we need that too.
     82  1.22   mycroft  */
     83  1.50     enami int
     84  1.47    bouyer scsi_scsipi_cmd(sc_link, scsipi_cmd, cmdlen, data_addr, datalen,
     85  1.47    bouyer 	retries, timeout, bp, flags)
     86  1.47    bouyer 	struct scsipi_link *sc_link;
     87  1.47    bouyer 	struct scsipi_generic *scsipi_cmd;
     88  1.22   mycroft 	int cmdlen;
     89  1.22   mycroft 	u_char *data_addr;
     90  1.22   mycroft 	int datalen;
     91  1.22   mycroft 	int retries;
     92  1.22   mycroft 	int timeout;
     93  1.22   mycroft 	struct buf *bp;
     94  1.22   mycroft 	int flags;
     95  1.22   mycroft {
     96  1.47    bouyer 	struct scsipi_xfer *xs;
     97  1.22   mycroft 	int error;
     98  1.22   mycroft 
     99  1.47    bouyer 	SC_DEBUG(sc_link, SDEV_DB2, ("scsi_scsipi_cmd\n"));
    100  1.22   mycroft 
    101  1.25   mycroft #ifdef DIAGNOSTIC
    102  1.25   mycroft 	if (bp != 0 && (flags & SCSI_NOSLEEP) == 0)
    103  1.47    bouyer 		panic("scsi_scsipi_cmd: buffer without nosleep");
    104  1.25   mycroft #endif
    105  1.25   mycroft 
    106  1.50     enami 	if ((xs = scsipi_make_xs(sc_link, scsipi_cmd, cmdlen, data_addr,
    107  1.50     enami 	    datalen, retries, timeout, bp, flags)) == NULL)
    108  1.50     enami 		return (ENOMEM);
    109  1.58       cgd 
    110  1.58       cgd 	/*
    111  1.58       cgd 	 * Set the LUN in the CDB if we have an older device.  We also
    112  1.58       cgd 	 * set it for more modern SCSI-II devices "just in case".
    113  1.58       cgd 	 */
    114  1.58       cgd 	if ((sc_link->scsipi_scsi.scsi_version & SID_ANSII) <= 2)
    115  1.58       cgd 		xs->cmd->bytes[0] |=
    116  1.58       cgd 		    ((sc_link->scsipi_scsi.lun << SCSI_CMD_LUN_SHIFT) &
    117  1.58       cgd 			SCSI_CMD_LUN_MASK);
    118  1.22   mycroft 
    119  1.47    bouyer 	if ((error = scsipi_execute_xs(xs)) == EJUSTRETURN)
    120  1.50     enami 		return (0);
    121  1.22   mycroft 
    122   1.1   mycroft 	/*
    123   1.1   mycroft 	 * we have finished with the xfer stuct, free it and
    124   1.1   mycroft 	 * check if anyone else needs to be started up.
    125   1.1   mycroft 	 */
    126  1.47    bouyer 	scsipi_free_xs(xs, flags);
    127  1.50     enami 	return (error);
    128   1.1   mycroft }
    129   1.1   mycroft 
    130   1.1   mycroft /*
    131   1.1   mycroft  * Look at the returned sense and act on the error, determining
    132   1.1   mycroft  * the unix error number to pass back.  (0 = report no error)
    133   1.1   mycroft  *
    134  1.47    bouyer  * THIS IS THE DEFAULT ERROR HANDLER FOR SCSI DEVICES
    135   1.1   mycroft  */
    136  1.50     enami int
    137   1.1   mycroft scsi_interpret_sense(xs)
    138  1.47    bouyer 	struct scsipi_xfer *xs;
    139   1.1   mycroft {
    140  1.47    bouyer 	struct scsipi_sense_data *sense;
    141  1.47    bouyer 	struct scsipi_link *sc_link = xs->sc_link;
    142  1.22   mycroft 	u_int8_t key;
    143  1.22   mycroft 	u_int32_t info;
    144   1.2   mycroft 	int error;
    145  1.46    mjacob #ifndef	SCSIVERBOSE
    146  1.22   mycroft 	static char *error_mes[] = {
    147  1.22   mycroft 		"soft error (corrected)",
    148  1.22   mycroft 		"not ready", "medium error",
    149  1.22   mycroft 		"non-media hardware failure", "illegal request",
    150  1.22   mycroft 		"unit attention", "readonly device",
    151  1.22   mycroft 		"no data found", "vendor unique",
    152  1.22   mycroft 		"copy aborted", "command aborted",
    153  1.22   mycroft 		"search returned equal", "volume overflow",
    154  1.22   mycroft 		"verify miscompare", "unknown error key"
    155   1.1   mycroft 	};
    156  1.46    mjacob #endif
    157   1.1   mycroft 
    158  1.47    bouyer 	sense = &xs->sense.scsi_sense;
    159   1.1   mycroft #ifdef	SCSIDEBUG
    160  1.22   mycroft 	if ((sc_link->flags & SDEV_DB1) != 0) {
    161  1.22   mycroft 		int count;
    162  1.45      fair 		printf("code 0x%x valid 0x%x ",
    163  1.47    bouyer 			sense->error_code & SSD_ERRCODE,
    164  1.47    bouyer 			sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
    165  1.45      fair 		printf("seg 0x%x key 0x%x ili 0x%x eom 0x%x fmark 0x%x\n",
    166  1.47    bouyer 			sense->segment,
    167  1.47    bouyer 			sense->flags & SSD_KEY,
    168  1.47    bouyer 			sense->flags & SSD_ILI ? 1 : 0,
    169  1.47    bouyer 			sense->flags & SSD_EOM ? 1 : 0,
    170  1.47    bouyer 			sense->flags & SSD_FILEMARK ? 1 : 0);
    171  1.45      fair 		printf("info: 0x%x 0x%x 0x%x 0x%x followed by %d extra bytes\n",
    172  1.47    bouyer 			sense->info[0],
    173  1.47    bouyer 			sense->info[1],
    174  1.47    bouyer 			sense->info[2],
    175  1.47    bouyer 			sense->info[3],
    176  1.47    bouyer 			sense->extra_len);
    177  1.40  christos 		printf("extra: ");
    178  1.52    mjacob 		for (count = 0; count < ADD_BYTES_LIM(sense); count++)
    179  1.52    mjacob 			printf("0x%x ", sense->cmd_spec_info[count]);
    180  1.40  christos 		printf("\n");
    181   1.1   mycroft 	}
    182  1.46    mjacob #endif	/* SCSIDEBUG */
    183   1.1   mycroft 	/*
    184   1.1   mycroft 	 * If the device has it's own error handler, call it first.
    185   1.1   mycroft 	 * If it returns a legit error value, return that, otherwise
    186   1.1   mycroft 	 * it wants us to continue with normal error processing.
    187   1.1   mycroft 	 */
    188   1.1   mycroft 	if (sc_link->device->err_handler) {
    189  1.50     enami 		SC_DEBUG(sc_link, SDEV_DB2,
    190  1.50     enami 		    ("calling private err_handler()\n"));
    191  1.50     enami 		error = (*sc_link->device->err_handler)(xs);
    192  1.63    mjacob 		if (error != SCSIRET_CONTINUE)
    193  1.50     enami 			return (error);		/* error >= 0  better ? */
    194   1.1   mycroft 	}
    195   1.1   mycroft 	/* otherwise use the default */
    196   1.1   mycroft 	switch (sense->error_code & SSD_ERRCODE) {
    197   1.1   mycroft 		/*
    198  1.50     enami 		 * If it's code 70, use the extended stuff and
    199  1.50     enami 		 * interpret the key
    200   1.1   mycroft 		 */
    201   1.1   mycroft 	case 0x71:		/* delayed error */
    202  1.47    bouyer 		sc_link->sc_print_addr(sc_link);
    203  1.34   mycroft 		key = sense->flags & SSD_KEY;
    204  1.46    mjacob 		printf(" DEFERRED ERROR, key = 0x%x\n", key);
    205  1.46    mjacob 		/* FALLTHROUGH */
    206   1.1   mycroft 	case 0x70:
    207  1.34   mycroft 		if ((sense->error_code & SSD_ERRCODE_VALID) != 0)
    208  1.34   mycroft 			info = _4btol(sense->info);
    209  1.34   mycroft 		else
    210   1.1   mycroft 			info = 0;
    211  1.34   mycroft 		key = sense->flags & SSD_KEY;
    212   1.1   mycroft 
    213  1.22   mycroft 		switch (key) {
    214  1.61    mjacob 		case SKEY_NO_SENSE:
    215  1.62    mjacob 		case SKEY_RECOVERED_ERROR:
    216  1.62    mjacob 			if (xs->resid == xs->datalen && xs->datalen) {
    217  1.62    mjacob 				/*
    218  1.62    mjacob 				 * Why is this here?
    219  1.62    mjacob 				 */
    220  1.22   mycroft 				xs->resid = 0;	/* not short read */
    221  1.62    mjacob 			}
    222  1.61    mjacob 		case SKEY_EQUAL:
    223  1.22   mycroft 			error = 0;
    224  1.22   mycroft 			break;
    225  1.61    mjacob 		case SKEY_NOT_READY:
    226  1.22   mycroft 			if ((sc_link->flags & SDEV_REMOVABLE) != 0)
    227  1.22   mycroft 				sc_link->flags &= ~SDEV_MEDIA_LOADED;
    228  1.22   mycroft 			if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
    229  1.50     enami 				return (0);
    230  1.22   mycroft 			if ((xs->flags & SCSI_SILENT) != 0)
    231  1.50     enami 				return (EIO);
    232  1.22   mycroft 			error = EIO;
    233  1.22   mycroft 			break;
    234  1.61    mjacob 		case SKEY_ILLEGAL_REQUEST:
    235  1.22   mycroft 			if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
    236  1.50     enami 				return (0);
    237  1.37  christos 			if ((xs->flags & SCSI_SILENT) != 0)
    238  1.50     enami 				return (EIO);
    239  1.22   mycroft 			error = EINVAL;
    240  1.22   mycroft 			break;
    241  1.61    mjacob 		case SKEY_UNIT_ATTENTION:
    242  1.22   mycroft 			if ((sc_link->flags & SDEV_REMOVABLE) != 0)
    243  1.22   mycroft 				sc_link->flags &= ~SDEV_MEDIA_LOADED;
    244  1.22   mycroft 			if ((xs->flags & SCSI_IGNORE_MEDIA_CHANGE) != 0 ||
    245  1.47    bouyer 				/* XXX Should reupload any transient state. */
    246  1.47    bouyer 				(sc_link->flags & SDEV_REMOVABLE) == 0)
    247  1.50     enami 				return (ERESTART);
    248  1.22   mycroft 			if ((xs->flags & SCSI_SILENT) != 0)
    249  1.50     enami 				return (EIO);
    250  1.22   mycroft 			error = EIO;
    251  1.22   mycroft 			break;
    252  1.61    mjacob 		case SKEY_WRITE_PROTECT:
    253  1.57        is 			error = EROFS;
    254  1.22   mycroft 			break;
    255  1.61    mjacob 		case SKEY_BLANK_CHECK:
    256  1.22   mycroft 			error = 0;
    257  1.22   mycroft 			break;
    258  1.61    mjacob 		case SKEY_ABORTED_COMMAND:
    259  1.32    briggs 			error = ERESTART;
    260  1.32    briggs 			break;
    261  1.61    mjacob 		case SKEY_VOLUME_OVERFLOW:
    262  1.22   mycroft 			error = ENOSPC;
    263  1.22   mycroft 			break;
    264  1.22   mycroft 		default:
    265  1.22   mycroft 			error = EIO;
    266  1.22   mycroft 			break;
    267  1.22   mycroft 		}
    268  1.22   mycroft 
    269  1.47    bouyer #ifdef SCSIVERBOSE
    270  1.51    mjacob 		if ((xs->flags & SCSI_SILENT) == 0)
    271  1.51    mjacob 			scsi_print_sense(xs, 0);
    272  1.46    mjacob #else
    273  1.22   mycroft 		if (key) {
    274  1.47    bouyer 			sc_link->sc_print_addr(sc_link);
    275  1.40  christos 			printf("%s", error_mes[key - 1]);
    276  1.22   mycroft 			if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
    277   1.1   mycroft 				switch (key) {
    278  1.61    mjacob 				case SKEY_NOT_READY:
    279  1.61    mjacob 				case SKEY_ILLEGAL_REQUEST:
    280  1.61    mjacob 				case SKEY_UNIT_ATTENTION:
    281  1.61    mjacob 				case SKEY_WRITE_PROTECT:
    282   1.1   mycroft 					break;
    283  1.61    mjacob 				case SKEY_BLANK_CHECK:
    284  1.40  christos 					printf(", requested size: %d (decimal)",
    285  1.50     enami 					    info);
    286  1.32    briggs 					break;
    287  1.61    mjacob 				case SKEY_ABORTED_COMMAND:
    288  1.32    briggs 					if (xs->retries)
    289  1.40  christos 						printf(", retrying");
    290  1.40  christos 					printf(", cmd 0x%x, info 0x%x",
    291  1.50     enami 					    xs->cmd->opcode, info);
    292   1.1   mycroft 					break;
    293   1.1   mycroft 				default:
    294  1.40  christos 					printf(", info = %d (decimal)", info);
    295   1.1   mycroft 				}
    296  1.25   mycroft 			}
    297  1.34   mycroft 			if (sense->extra_len != 0) {
    298  1.25   mycroft 				int n;
    299  1.40  christos 				printf(", data =");
    300  1.34   mycroft 				for (n = 0; n < sense->extra_len; n++)
    301  1.50     enami 					printf(" %02x",
    302  1.50     enami 					    sense->cmd_spec_info[n]);
    303   1.1   mycroft 			}
    304  1.40  christos 			printf("\n");
    305   1.1   mycroft 		}
    306  1.46    mjacob #endif
    307  1.50     enami 		return (error);
    308  1.22   mycroft 
    309   1.1   mycroft 	/*
    310   1.1   mycroft 	 * Not code 70, just report it
    311   1.1   mycroft 	 */
    312   1.1   mycroft 	default:
    313  1.47    bouyer 		sc_link->sc_print_addr(sc_link);
    314  1.50     enami 		printf("error code %d", sense->error_code & SSD_ERRCODE);
    315  1.22   mycroft 		if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
    316  1.47    bouyer 			struct scsipi_sense_data_unextended *usense =
    317  1.50     enami 			    (struct scsipi_sense_data_unextended *)sense;
    318  1.40  christos 			printf(" at block no. %d (decimal)",
    319  1.50     enami 			    _3btol(usense->block));
    320   1.1   mycroft 		}
    321  1.40  christos 		printf("\n");
    322  1.50     enami 		return (EIO);
    323   1.1   mycroft 	}
    324   1.1   mycroft }
    325   1.1   mycroft 
    326   1.1   mycroft /*
    327   1.1   mycroft  * Utility routines often used in SCSI stuff
    328   1.1   mycroft  */
    329   1.1   mycroft 
    330   1.1   mycroft 
    331   1.1   mycroft /*
    332   1.1   mycroft  * Print out the scsi_link structure's address info.
    333   1.1   mycroft  */
    334   1.1   mycroft void
    335  1.47    bouyer scsi_print_addr(sc_link)
    336  1.47    bouyer 	struct scsipi_link *sc_link;
    337   1.1   mycroft {
    338   1.1   mycroft 
    339  1.40  christos 	printf("%s(%s:%d:%d): ",
    340  1.50     enami 	    sc_link->device_softc ?
    341  1.50     enami 	    ((struct device *)sc_link->device_softc)->dv_xname : "probe",
    342  1.50     enami 	    ((struct device *)sc_link->adapter_softc)->dv_xname,
    343  1.50     enami 	    sc_link->scsipi_scsi.target, sc_link->scsipi_scsi.lun);
    344   1.1   mycroft }
    345