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