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