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