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