scsi_base.c revision 1.25 1 1.25 mycroft /* $NetBSD: scsi_base.c,v 1.25 1995/01/13 14:38:13 mycroft Exp $ */
2 1.14 cgd
3 1.1 mycroft /*
4 1.9 mycroft * Copyright (c) 1994 Charles 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.9 mycroft * This product includes software developed by Charles 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.1 mycroft
36 1.1 mycroft #include <sys/types.h>
37 1.1 mycroft #include <sys/param.h>
38 1.11 mycroft #include <sys/kernel.h>
39 1.1 mycroft #include <sys/buf.h>
40 1.1 mycroft #include <sys/uio.h>
41 1.1 mycroft #include <sys/malloc.h>
42 1.1 mycroft #include <sys/errno.h>
43 1.1 mycroft #include <sys/device.h>
44 1.2 mycroft
45 1.1 mycroft #include <scsi/scsi_all.h>
46 1.1 mycroft #include <scsi/scsi_disk.h>
47 1.1 mycroft #include <scsi/scsiconf.h>
48 1.1 mycroft
49 1.1 mycroft #ifdef DDB
50 1.1 mycroft int Debugger();
51 1.1 mycroft #else /* DDB */
52 1.1 mycroft #define Debugger()
53 1.1 mycroft #endif /* DDB */
54 1.1 mycroft
55 1.22 mycroft void scsi_error __P((struct scsi_xfer *, int));
56 1.22 mycroft
57 1.12 mycroft LIST_HEAD(xs_free_list, scsi_xfer) xs_free_list;
58 1.1 mycroft
59 1.1 mycroft /*
60 1.1 mycroft * Get a scsi transfer structure for the caller. Charge the structure
61 1.1 mycroft * to the device that is referenced by the sc_link structure. If the
62 1.1 mycroft * sc_link structure has no 'credits' then the device already has the
63 1.1 mycroft * maximum number or outstanding operations under way. In this stage,
64 1.1 mycroft * wait on the structure so that when one is freed, we are awoken again
65 1.1 mycroft * If the SCSI_NOSLEEP flag is set, then do not wait, but rather, return
66 1.1 mycroft * a NULL pointer, signifying that no slots were available
67 1.1 mycroft * Note in the link structure, that we are waiting on it.
68 1.1 mycroft */
69 1.1 mycroft
70 1.1 mycroft struct scsi_xfer *
71 1.22 mycroft scsi_get_xs(sc_link, flags)
72 1.2 mycroft struct scsi_link *sc_link; /* who to charge the xs to */
73 1.11 mycroft int flags; /* if this call can sleep */
74 1.1 mycroft {
75 1.2 mycroft struct scsi_xfer *xs;
76 1.11 mycroft int s;
77 1.1 mycroft
78 1.22 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("scsi_get_xs\n"));
79 1.1 mycroft s = splbio();
80 1.22 mycroft while (sc_link->openings <= 0) {
81 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("sleeping\n"));
82 1.22 mycroft if ((flags & SCSI_NOSLEEP) != 0) {
83 1.1 mycroft splx(s);
84 1.1 mycroft return 0;
85 1.1 mycroft }
86 1.1 mycroft sc_link->flags |= SDEV_WAITING;
87 1.12 mycroft (void) tsleep(sc_link, PRIBIO, "getxs", 0);
88 1.1 mycroft }
89 1.22 mycroft sc_link->openings--;
90 1.12 mycroft if (xs = xs_free_list.lh_first) {
91 1.12 mycroft LIST_REMOVE(xs, free_list);
92 1.1 mycroft splx(s);
93 1.1 mycroft } else {
94 1.1 mycroft splx(s);
95 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("making\n"));
96 1.12 mycroft xs = malloc(sizeof(*xs), M_DEVBUF,
97 1.22 mycroft ((flags & SCSI_NOSLEEP) != 0 ? M_NOWAIT : M_WAITOK));
98 1.12 mycroft if (!xs) {
99 1.1 mycroft sc_print_addr(sc_link);
100 1.1 mycroft printf("cannot allocate scsi xs\n");
101 1.12 mycroft return 0;
102 1.1 mycroft }
103 1.1 mycroft }
104 1.22 mycroft
105 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("returning\n"));
106 1.22 mycroft xs->flags = INUSE | flags;
107 1.11 mycroft return xs;
108 1.1 mycroft }
109 1.1 mycroft
110 1.1 mycroft /*
111 1.1 mycroft * Given a scsi_xfer struct, and a device (referenced through sc_link)
112 1.1 mycroft * return the struct to the free pool and credit the device with it
113 1.1 mycroft * If another process is waiting for an xs, do a wakeup, let it proceed
114 1.1 mycroft */
115 1.1 mycroft void
116 1.22 mycroft scsi_free_xs(xs, flags)
117 1.1 mycroft struct scsi_xfer *xs;
118 1.11 mycroft int flags;
119 1.1 mycroft {
120 1.22 mycroft struct scsi_link *sc_link = xs->sc_link;
121 1.22 mycroft
122 1.22 mycroft xs->flags &= ~INUSE;
123 1.12 mycroft LIST_INSERT_HEAD(&xs_free_list, xs, free_list);
124 1.1 mycroft
125 1.22 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("scsi_free_xs\n"));
126 1.1 mycroft /* if was 0 and someone waits, wake them up */
127 1.22 mycroft sc_link->openings++;
128 1.22 mycroft if ((sc_link->flags & SDEV_WAITING) != 0) {
129 1.3 mycroft sc_link->flags &= ~SDEV_WAITING;
130 1.22 mycroft wakeup(sc_link);
131 1.3 mycroft } else {
132 1.1 mycroft if (sc_link->device->start) {
133 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("calling private start()\n"));
134 1.17 mycroft (*(sc_link->device->start)) (sc_link->device_softc);
135 1.1 mycroft }
136 1.3 mycroft }
137 1.1 mycroft }
138 1.1 mycroft
139 1.1 mycroft /*
140 1.22 mycroft * Make a scsi_xfer, and return a pointer to it.
141 1.22 mycroft */
142 1.22 mycroft static __inline struct scsi_xfer *
143 1.22 mycroft scsi_make_xs(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
144 1.22 mycroft retries, timeout, bp, flags)
145 1.22 mycroft struct scsi_link *sc_link;
146 1.22 mycroft struct scsi_generic *scsi_cmd;
147 1.22 mycroft int cmdlen;
148 1.22 mycroft u_char *data_addr;
149 1.22 mycroft int datalen;
150 1.22 mycroft int retries;
151 1.22 mycroft int timeout;
152 1.22 mycroft struct buf *bp;
153 1.22 mycroft int flags;
154 1.22 mycroft {
155 1.22 mycroft struct scsi_xfer *xs;
156 1.22 mycroft
157 1.22 mycroft if ((xs = scsi_get_xs(sc_link, flags)) == NULL)
158 1.22 mycroft return NULL;
159 1.22 mycroft
160 1.22 mycroft /*
161 1.22 mycroft * Fill out the scsi_xfer structure. We don't know whose context
162 1.22 mycroft * the cmd is in, so copy it.
163 1.22 mycroft */
164 1.22 mycroft xs->sc_link = sc_link;
165 1.22 mycroft bcopy(scsi_cmd, &xs->cmdstore, cmdlen);
166 1.22 mycroft xs->cmd = &xs->cmdstore;
167 1.22 mycroft xs->cmdlen = cmdlen;
168 1.22 mycroft xs->data = data_addr;
169 1.22 mycroft xs->datalen = datalen;
170 1.22 mycroft xs->retries = retries;
171 1.22 mycroft xs->timeout = timeout;
172 1.22 mycroft xs->bp = bp;
173 1.22 mycroft
174 1.22 mycroft return xs;
175 1.22 mycroft }
176 1.22 mycroft
177 1.22 mycroft /*
178 1.1 mycroft * Find out from the device what its capacity is.
179 1.1 mycroft */
180 1.22 mycroft u_long
181 1.1 mycroft scsi_size(sc_link, flags)
182 1.1 mycroft struct scsi_link *sc_link;
183 1.11 mycroft int flags;
184 1.1 mycroft {
185 1.1 mycroft struct scsi_read_cap_data rdcap;
186 1.1 mycroft struct scsi_read_capacity scsi_cmd;
187 1.22 mycroft u_long size;
188 1.1 mycroft
189 1.1 mycroft /*
190 1.1 mycroft * make up a scsi command and ask the scsi driver to do
191 1.1 mycroft * it for you.
192 1.1 mycroft */
193 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
194 1.22 mycroft scsi_cmd.opcode = READ_CAPACITY;
195 1.1 mycroft
196 1.1 mycroft /*
197 1.1 mycroft * If the command works, interpret the result as a 4 byte
198 1.1 mycroft * number of blocks
199 1.1 mycroft */
200 1.22 mycroft if (scsi_scsi_cmd(sc_link, (struct scsi_generic *)&scsi_cmd,
201 1.22 mycroft sizeof(scsi_cmd), (u_char *)&rdcap, sizeof(rdcap),
202 1.2 mycroft 2, 20000, NULL, flags | SCSI_DATA_IN) != 0) {
203 1.1 mycroft sc_print_addr(sc_link);
204 1.1 mycroft printf("could not get size\n");
205 1.11 mycroft return 0;
206 1.1 mycroft } else {
207 1.1 mycroft size = rdcap.addr_0 + 1;
208 1.1 mycroft size += rdcap.addr_1 << 8;
209 1.1 mycroft size += rdcap.addr_2 << 16;
210 1.1 mycroft size += rdcap.addr_3 << 24;
211 1.1 mycroft }
212 1.11 mycroft return size;
213 1.1 mycroft }
214 1.1 mycroft
215 1.1 mycroft /*
216 1.1 mycroft * Get scsi driver to send a "are you ready?" command
217 1.1 mycroft */
218 1.2 mycroft int
219 1.1 mycroft scsi_test_unit_ready(sc_link, flags)
220 1.1 mycroft struct scsi_link *sc_link;
221 1.11 mycroft int flags;
222 1.1 mycroft {
223 1.1 mycroft struct scsi_test_unit_ready scsi_cmd;
224 1.1 mycroft
225 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
226 1.22 mycroft scsi_cmd.opcode = TEST_UNIT_READY;
227 1.1 mycroft
228 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
229 1.22 mycroft sizeof(scsi_cmd), 0, 0, 2, 10000, NULL, flags);
230 1.1 mycroft }
231 1.1 mycroft
232 1.1 mycroft /*
233 1.1 mycroft * Do a scsi operation, asking a device to run as SCSI-II if it can.
234 1.1 mycroft */
235 1.2 mycroft int
236 1.1 mycroft scsi_change_def(sc_link, flags)
237 1.1 mycroft struct scsi_link *sc_link;
238 1.11 mycroft int flags;
239 1.1 mycroft {
240 1.1 mycroft struct scsi_changedef scsi_cmd;
241 1.1 mycroft
242 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
243 1.22 mycroft scsi_cmd.opcode = CHANGE_DEFINITION;
244 1.1 mycroft scsi_cmd.how = SC_SCSI_2;
245 1.1 mycroft
246 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
247 1.2 mycroft sizeof(scsi_cmd), 0, 0, 2, 100000, NULL, flags);
248 1.1 mycroft }
249 1.1 mycroft
250 1.1 mycroft /*
251 1.1 mycroft * Do a scsi operation asking a device what it is
252 1.1 mycroft * Use the scsi_cmd routine in the switch table.
253 1.1 mycroft */
254 1.2 mycroft int
255 1.1 mycroft scsi_inquire(sc_link, inqbuf, flags)
256 1.1 mycroft struct scsi_link *sc_link;
257 1.1 mycroft struct scsi_inquiry_data *inqbuf;
258 1.11 mycroft int flags;
259 1.1 mycroft {
260 1.1 mycroft struct scsi_inquiry scsi_cmd;
261 1.1 mycroft
262 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
263 1.22 mycroft scsi_cmd.opcode = INQUIRY;
264 1.1 mycroft scsi_cmd.length = sizeof(struct scsi_inquiry_data);
265 1.1 mycroft
266 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
267 1.2 mycroft sizeof(scsi_cmd), (u_char *) inqbuf,
268 1.22 mycroft sizeof(struct scsi_inquiry_data), 2, 10000, NULL,
269 1.2 mycroft SCSI_DATA_IN | flags);
270 1.1 mycroft }
271 1.1 mycroft
272 1.1 mycroft /*
273 1.1 mycroft * Prevent or allow the user to remove the media
274 1.1 mycroft */
275 1.2 mycroft int
276 1.1 mycroft scsi_prevent(sc_link, type, flags)
277 1.1 mycroft struct scsi_link *sc_link;
278 1.11 mycroft int type, flags;
279 1.1 mycroft {
280 1.1 mycroft struct scsi_prevent scsi_cmd;
281 1.1 mycroft
282 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
283 1.22 mycroft scsi_cmd.opcode = PREVENT_ALLOW;
284 1.1 mycroft scsi_cmd.how = type;
285 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
286 1.2 mycroft sizeof(scsi_cmd), 0, 0, 2, 5000, NULL, flags);
287 1.1 mycroft }
288 1.1 mycroft
289 1.1 mycroft /*
290 1.1 mycroft * Get scsi driver to send a "start up" command
291 1.1 mycroft */
292 1.2 mycroft int
293 1.10 mycroft scsi_start(sc_link, type, flags)
294 1.1 mycroft struct scsi_link *sc_link;
295 1.11 mycroft int type, flags;
296 1.1 mycroft {
297 1.1 mycroft struct scsi_start_stop scsi_cmd;
298 1.1 mycroft
299 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
300 1.22 mycroft scsi_cmd.opcode = START_STOP;
301 1.22 mycroft scsi_cmd.byte2 = 0x00;
302 1.10 mycroft scsi_cmd.how = type;
303 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
304 1.10 mycroft sizeof(scsi_cmd), 0, 0, 2,
305 1.22 mycroft type == SSS_START ? 30000 : 10000, NULL, flags);
306 1.22 mycroft }
307 1.22 mycroft
308 1.22 mycroft int
309 1.22 mycroft scsi_start_and_wait(sc_link, n, flags)
310 1.22 mycroft struct scsi_link *sc_link;
311 1.22 mycroft int n;
312 1.22 mycroft int flags;
313 1.22 mycroft {
314 1.22 mycroft int silent = flags & SCSI_SILENT;
315 1.22 mycroft struct scsi_xfer *xs;
316 1.22 mycroft struct scsi_start_stop scsi_cmd;
317 1.22 mycroft int error;
318 1.22 mycroft
319 1.22 mycroft flags |= SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE;
320 1.22 mycroft
321 1.22 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
322 1.22 mycroft scsi_cmd.opcode = START_STOP;
323 1.22 mycroft scsi_cmd.byte2 = 0x01;
324 1.22 mycroft scsi_cmd.how = SSS_START;
325 1.22 mycroft
326 1.22 mycroft if ((xs = scsi_make_xs(sc_link, (struct scsi_generic *)&scsi_cmd,
327 1.22 mycroft sizeof(scsi_cmd), 0, 0, 2, 1000, NULL, flags)) == NULL)
328 1.22 mycroft return ENOMEM;
329 1.22 mycroft
330 1.22 mycroft if ((error = scsi_execute_xs(xs)) != EIO ||
331 1.22 mycroft xs->error != XS_SENSE ||
332 1.22 mycroft (xs->sense.error_code & SSD_ERRCODE) != 0x70 ||
333 1.22 mycroft (xs->sense.extended_flags & SSD_KEY) != 0x2)
334 1.22 mycroft goto out;
335 1.22 mycroft if (!silent) {
336 1.22 mycroft sc_print_addr(sc_link);
337 1.22 mycroft printf("waiting for device to come ready\n");
338 1.22 mycroft }
339 1.22 mycroft while (n--) {
340 1.22 mycroft if ((flags & SCSI_POLL) != 0)
341 1.22 mycroft delay(1000000);
342 1.22 mycroft else
343 1.22 mycroft tsleep(&lbolt, PRIBIO, "scisaw", 0);
344 1.22 mycroft if ((error = scsi_execute_xs(xs)) != EIO ||
345 1.22 mycroft xs->error != XS_SENSE ||
346 1.22 mycroft (xs->sense.error_code & SSD_ERRCODE) != 0x70 ||
347 1.22 mycroft (xs->sense.extended_flags & SSD_KEY) != 0x2) {
348 1.22 mycroft if (!silent) {
349 1.22 mycroft sc_print_addr(sc_link);
350 1.22 mycroft printf("ready\n");
351 1.22 mycroft }
352 1.22 mycroft goto out;
353 1.22 mycroft }
354 1.22 mycroft }
355 1.22 mycroft if (!silent) {
356 1.22 mycroft sc_print_addr(sc_link);
357 1.22 mycroft printf("not ready\n");
358 1.22 mycroft }
359 1.22 mycroft out:
360 1.22 mycroft scsi_free_xs(xs, SCSI_NOSLEEP);
361 1.22 mycroft return error;
362 1.1 mycroft }
363 1.1 mycroft
364 1.1 mycroft /*
365 1.1 mycroft * This routine is called by the scsi interrupt when the transfer is complete.
366 1.1 mycroft */
367 1.1 mycroft void
368 1.1 mycroft scsi_done(xs)
369 1.1 mycroft struct scsi_xfer *xs;
370 1.1 mycroft {
371 1.1 mycroft struct scsi_link *sc_link = xs->sc_link;
372 1.11 mycroft int error;
373 1.1 mycroft
374 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n"));
375 1.1 mycroft #ifdef SCSIDEBUG
376 1.22 mycroft if ((sc_link->flags & SDEV_DB1) != 0)
377 1.1 mycroft show_scsi_cmd(xs);
378 1.22 mycroft #endif /* SCSIDEBUG */
379 1.22 mycroft
380 1.1 mycroft /*
381 1.1 mycroft * If it's a user level request, bypass all usual completion processing,
382 1.1 mycroft * let the user work it out.. We take reponsibility for freeing the
383 1.1 mycroft * xs when the user returns. (and restarting the device's queue).
384 1.1 mycroft */
385 1.22 mycroft if ((xs->flags & SCSI_USER) != 0) {
386 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("calling user done()\n"));
387 1.1 mycroft scsi_user_done(xs); /* to take a copy of the sense etc. */
388 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("returned from user done()\n "));
389 1.19 mycroft
390 1.22 mycroft scsi_free_xs(xs, SCSI_NOSLEEP); /* restarts queue too */
391 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("returning to adapter\n"));
392 1.1 mycroft return;
393 1.1 mycroft }
394 1.22 mycroft
395 1.1 mycroft /*
396 1.1 mycroft * If the device has it's own done routine, call it first.
397 1.1 mycroft * If it returns a legit error value, return that, otherwise
398 1.1 mycroft * it wants us to continue with normal processing.
399 1.1 mycroft */
400 1.1 mycroft if (sc_link->device->done) {
401 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
402 1.11 mycroft error = (*sc_link->device->done) (xs);
403 1.22 mycroft if (error == EJUSTRETURN)
404 1.22 mycroft goto done;
405 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
406 1.1 mycroft }
407 1.22 mycroft if (xs->bp == NULL) {
408 1.1 mycroft /*
409 1.1 mycroft * if it's a normal upper level request, then ask
410 1.1 mycroft * the upper level code to handle error checking
411 1.1 mycroft * rather than doing it here at interrupt time
412 1.1 mycroft */
413 1.1 mycroft wakeup(xs);
414 1.1 mycroft return;
415 1.1 mycroft }
416 1.1 mycroft /*
417 1.1 mycroft * Go and handle errors now.
418 1.22 mycroft * If it returns ERESTART then we should RETRY
419 1.1 mycroft */
420 1.22 mycroft retry:
421 1.22 mycroft if (sc_err1(xs, 1) == ERESTART) {
422 1.22 mycroft switch ((*(sc_link->adapter->scsi_cmd)) (xs)) {
423 1.22 mycroft case SUCCESSFULLY_QUEUED:
424 1.1 mycroft return;
425 1.22 mycroft
426 1.22 mycroft case TRY_AGAIN_LATER:
427 1.22 mycroft xs->error = XS_BUSY;
428 1.22 mycroft case COMPLETE:
429 1.22 mycroft goto retry;
430 1.22 mycroft }
431 1.1 mycroft }
432 1.22 mycroft done:
433 1.22 mycroft scsi_free_xs(xs, SCSI_NOSLEEP);
434 1.1 mycroft }
435 1.1 mycroft
436 1.22 mycroft int
437 1.22 mycroft scsi_execute_xs(xs)
438 1.22 mycroft struct scsi_xfer *xs;
439 1.1 mycroft {
440 1.11 mycroft int error;
441 1.11 mycroft int s;
442 1.1 mycroft
443 1.22 mycroft xs->flags &= ~ITSDONE;
444 1.22 mycroft xs->error = XS_NOERROR;
445 1.22 mycroft xs->resid = xs->datalen;
446 1.1 mycroft
447 1.1 mycroft retry:
448 1.1 mycroft /*
449 1.1 mycroft * Do the transfer. If we are polling we will return:
450 1.1 mycroft * COMPLETE, Was poll, and scsi_done has been called
451 1.1 mycroft * TRY_AGAIN_LATER, Adapter short resources, try again
452 1.1 mycroft *
453 1.1 mycroft * if under full steam (interrupts) it will return:
454 1.1 mycroft * SUCCESSFULLY_QUEUED, will do a wakeup when complete
455 1.1 mycroft * TRY_AGAIN_LATER, (as for polling)
456 1.1 mycroft * After the wakeup, we must still check if it succeeded
457 1.1 mycroft *
458 1.1 mycroft * If we have a bp however, all the error proccessing
459 1.1 mycroft * and the buffer code both expect us to return straight
460 1.1 mycroft * to them, so as soon as the command is queued, return
461 1.1 mycroft */
462 1.22 mycroft switch ((*(xs->sc_link->adapter->scsi_cmd)) (xs)) {
463 1.1 mycroft case SUCCESSFULLY_QUEUED:
464 1.22 mycroft if (xs->bp)
465 1.22 mycroft return EJUSTRETURN;
466 1.1 mycroft s = splbio();
467 1.22 mycroft while ((xs->flags & ITSDONE) == 0)
468 1.4 mycroft tsleep(xs, PRIBIO + 1, "scsi_scsi_cmd", 0);
469 1.1 mycroft splx(s);
470 1.1 mycroft case COMPLETE: /* Polling command completed ok */
471 1.22 mycroft if (xs->bp)
472 1.22 mycroft return EJUSTRETURN;
473 1.22 mycroft doit:
474 1.24 mycroft SC_DEBUG(xs->sc_link, SDEV_DB3, ("back in cmd()\n"));
475 1.22 mycroft if ((error = sc_err1(xs, 0)) != ERESTART)
476 1.22 mycroft return error;
477 1.22 mycroft goto retry;
478 1.1 mycroft
479 1.1 mycroft case TRY_AGAIN_LATER: /* adapter resource shortage */
480 1.22 mycroft xs->error = XS_BUSY;
481 1.22 mycroft goto doit;
482 1.22 mycroft
483 1.1 mycroft default:
484 1.22 mycroft panic("scsi_execute_xs: invalid return code");
485 1.1 mycroft }
486 1.22 mycroft
487 1.22 mycroft #ifdef DIAGNOSTIC
488 1.22 mycroft panic("scsi_execute_xs: impossible");
489 1.22 mycroft #endif
490 1.22 mycroft }
491 1.22 mycroft
492 1.22 mycroft /*
493 1.22 mycroft * ask the scsi driver to perform a command for us.
494 1.22 mycroft * tell it where to read/write the data, and how
495 1.22 mycroft * long the data is supposed to be. If we have a buf
496 1.22 mycroft * to associate with the transfer, we need that too.
497 1.22 mycroft */
498 1.22 mycroft int
499 1.22 mycroft scsi_scsi_cmd(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
500 1.22 mycroft retries, timeout, bp, flags)
501 1.22 mycroft struct scsi_link *sc_link;
502 1.22 mycroft struct scsi_generic *scsi_cmd;
503 1.22 mycroft int cmdlen;
504 1.22 mycroft u_char *data_addr;
505 1.22 mycroft int datalen;
506 1.22 mycroft int retries;
507 1.22 mycroft int timeout;
508 1.22 mycroft struct buf *bp;
509 1.22 mycroft int flags;
510 1.22 mycroft {
511 1.22 mycroft struct scsi_xfer *xs;
512 1.22 mycroft int error;
513 1.22 mycroft
514 1.22 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n"));
515 1.22 mycroft
516 1.25 mycroft #ifdef DIAGNOSTIC
517 1.25 mycroft if (bp != 0 && (flags & SCSI_NOSLEEP) == 0)
518 1.25 mycroft panic("scsi_scsi_cmd: buffer without nosleep");
519 1.25 mycroft #endif
520 1.25 mycroft
521 1.22 mycroft if ((xs = scsi_make_xs(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
522 1.22 mycroft retries, timeout, bp, flags)) == NULL)
523 1.22 mycroft return ENOMEM;
524 1.22 mycroft
525 1.22 mycroft if ((error = scsi_execute_xs(xs)) == EJUSTRETURN)
526 1.22 mycroft return 0;
527 1.22 mycroft
528 1.1 mycroft /*
529 1.1 mycroft * we have finished with the xfer stuct, free it and
530 1.1 mycroft * check if anyone else needs to be started up.
531 1.1 mycroft */
532 1.22 mycroft scsi_free_xs(xs, flags);
533 1.11 mycroft return error;
534 1.1 mycroft }
535 1.1 mycroft
536 1.2 mycroft int
537 1.22 mycroft sc_err1(xs, async)
538 1.1 mycroft struct scsi_xfer *xs;
539 1.22 mycroft int async;
540 1.1 mycroft {
541 1.11 mycroft int error;
542 1.1 mycroft
543 1.1 mycroft SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%x \n", xs->error));
544 1.22 mycroft
545 1.1 mycroft /*
546 1.1 mycroft * If it has a buf, we might be working with
547 1.1 mycroft * a request from the buffer cache or some other
548 1.1 mycroft * piece of code that requires us to process
549 1.1 mycroft * errors at inetrrupt time. We have probably
550 1.1 mycroft * been called by scsi_done()
551 1.1 mycroft */
552 1.1 mycroft switch (xs->error) {
553 1.1 mycroft case XS_NOERROR: /* nearly always hit this one */
554 1.11 mycroft error = 0;
555 1.1 mycroft break;
556 1.1 mycroft
557 1.1 mycroft case XS_SENSE:
558 1.22 mycroft if ((error = scsi_interpret_sense(xs)) == ERESTART)
559 1.22 mycroft goto retry;
560 1.21 mycroft SC_DEBUG(xs->sc_link, SDEV_DB3,
561 1.21 mycroft ("scsi_interpret_sense returned %d\n", error));
562 1.1 mycroft break;
563 1.1 mycroft
564 1.1 mycroft case XS_BUSY:
565 1.22 mycroft if (xs->retries) {
566 1.22 mycroft if ((xs->flags & SCSI_POLL) != 0)
567 1.22 mycroft delay(1000000);
568 1.22 mycroft else if ((xs->flags & SCSI_NOSLEEP) == 0)
569 1.22 mycroft tsleep(&lbolt, PRIBIO, "scbusy", 0);
570 1.22 mycroft else
571 1.22 mycroft #if 0
572 1.22 mycroft timeout(scsi_requeue, xs, hz);
573 1.22 mycroft #else
574 1.22 mycroft goto lose;
575 1.22 mycroft #endif
576 1.22 mycroft }
577 1.1 mycroft case XS_TIMEOUT:
578 1.22 mycroft retry:
579 1.1 mycroft if (xs->retries--) {
580 1.1 mycroft xs->error = XS_NOERROR;
581 1.1 mycroft xs->flags &= ~ITSDONE;
582 1.22 mycroft return ERESTART;
583 1.1 mycroft }
584 1.1 mycroft case XS_DRIVER_STUFFUP:
585 1.22 mycroft lose:
586 1.22 mycroft error = EIO;
587 1.22 mycroft break;
588 1.22 mycroft
589 1.22 mycroft case XS_SELTIMEOUT:
590 1.22 mycroft /* XXX Disable device? */
591 1.11 mycroft error = EIO;
592 1.1 mycroft break;
593 1.21 mycroft
594 1.1 mycroft default:
595 1.1 mycroft sc_print_addr(xs->sc_link);
596 1.1 mycroft printf("unknown error category from scsi driver\n");
597 1.21 mycroft error = EIO;
598 1.21 mycroft break;
599 1.21 mycroft }
600 1.21 mycroft
601 1.22 mycroft scsi_error(xs, error);
602 1.22 mycroft return error;
603 1.22 mycroft }
604 1.22 mycroft
605 1.22 mycroft void
606 1.22 mycroft scsi_error(xs, error)
607 1.22 mycroft struct scsi_xfer *xs;
608 1.22 mycroft int error;
609 1.22 mycroft {
610 1.22 mycroft struct buf *bp = xs->bp;
611 1.22 mycroft
612 1.21 mycroft if (bp) {
613 1.21 mycroft if (error) {
614 1.22 mycroft bp->b_error = error;
615 1.21 mycroft bp->b_flags |= B_ERROR;
616 1.21 mycroft bp->b_resid = bp->b_bcount;
617 1.21 mycroft } else {
618 1.21 mycroft bp->b_error = 0;
619 1.22 mycroft bp->b_resid = xs->resid;
620 1.21 mycroft }
621 1.22 mycroft biodone(bp);
622 1.1 mycroft }
623 1.1 mycroft }
624 1.1 mycroft
625 1.1 mycroft /*
626 1.1 mycroft * Look at the returned sense and act on the error, determining
627 1.1 mycroft * the unix error number to pass back. (0 = report no error)
628 1.1 mycroft *
629 1.1 mycroft * THIS IS THE DEFAULT ERROR HANDLER
630 1.1 mycroft */
631 1.2 mycroft int
632 1.1 mycroft scsi_interpret_sense(xs)
633 1.1 mycroft struct scsi_xfer *xs;
634 1.1 mycroft {
635 1.1 mycroft struct scsi_sense_data *sense;
636 1.1 mycroft struct scsi_link *sc_link = xs->sc_link;
637 1.22 mycroft u_int8_t key;
638 1.22 mycroft u_int32_t info;
639 1.2 mycroft int error;
640 1.1 mycroft
641 1.22 mycroft static char *error_mes[] = {
642 1.22 mycroft "soft error (corrected)",
643 1.22 mycroft "not ready", "medium error",
644 1.22 mycroft "non-media hardware failure", "illegal request",
645 1.22 mycroft "unit attention", "readonly device",
646 1.22 mycroft "no data found", "vendor unique",
647 1.22 mycroft "copy aborted", "command aborted",
648 1.22 mycroft "search returned equal", "volume overflow",
649 1.22 mycroft "verify miscompare", "unknown error key"
650 1.1 mycroft };
651 1.1 mycroft
652 1.11 mycroft sense = &xs->sense;
653 1.1 mycroft #ifdef SCSIDEBUG
654 1.22 mycroft if ((sc_link->flags & SDEV_DB1) != 0) {
655 1.22 mycroft int count;
656 1.1 mycroft printf("code%x valid%x ",
657 1.1 mycroft sense->error_code & SSD_ERRCODE,
658 1.1 mycroft sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
659 1.1 mycroft printf("seg%x key%x ili%x eom%x fmark%x\n",
660 1.13 chopps sense->extended_segment,
661 1.13 chopps sense->extended_flags & SSD_KEY,
662 1.13 chopps sense->extended_flags & SSD_ILI ? 1 : 0,
663 1.13 chopps sense->extended_flags & SSD_EOM ? 1 : 0,
664 1.13 chopps sense->extended_flags & SSD_FILEMARK ? 1 : 0);
665 1.1 mycroft printf("info: %x %x %x %x followed by %d extra bytes\n",
666 1.13 chopps sense->extended_info[0],
667 1.13 chopps sense->extended_info[1],
668 1.13 chopps sense->extended_info[2],
669 1.13 chopps sense->extended_info[3],
670 1.13 chopps sense->extended_extra_len);
671 1.1 mycroft printf("extra: ");
672 1.22 mycroft for (count = 0; count < sense->extended_extra_len; count++)
673 1.22 mycroft printf("%x ", sense->extended_extra_bytes[count]);
674 1.1 mycroft printf("\n");
675 1.1 mycroft }
676 1.1 mycroft #endif /*SCSIDEBUG */
677 1.1 mycroft /*
678 1.1 mycroft * If the device has it's own error handler, call it first.
679 1.1 mycroft * If it returns a legit error value, return that, otherwise
680 1.1 mycroft * it wants us to continue with normal error processing.
681 1.1 mycroft */
682 1.1 mycroft if (sc_link->device->err_handler) {
683 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("calling private err_handler()\n"));
684 1.2 mycroft error = (*sc_link->device->err_handler) (xs);
685 1.2 mycroft if (error != -1)
686 1.2 mycroft return error; /* error >= 0 better ? */
687 1.1 mycroft }
688 1.1 mycroft /* otherwise use the default */
689 1.1 mycroft switch (sense->error_code & SSD_ERRCODE) {
690 1.1 mycroft /*
691 1.1 mycroft * If it's code 70, use the extended stuff and interpret the key
692 1.1 mycroft */
693 1.1 mycroft case 0x71: /* delayed error */
694 1.1 mycroft sc_print_addr(sc_link);
695 1.13 chopps key = sense->extended_flags & SSD_KEY;
696 1.1 mycroft printf(" DELAYED ERROR, key = 0x%x\n", key);
697 1.1 mycroft case 0x70:
698 1.22 mycroft if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
699 1.18 deraadt bcopy(sense->extended_info, &info, sizeof info);
700 1.16 deraadt info = ntohl(info);
701 1.16 deraadt } else
702 1.1 mycroft info = 0;
703 1.13 chopps key = sense->extended_flags & SSD_KEY;
704 1.1 mycroft
705 1.22 mycroft switch (key) {
706 1.23 mycroft case 0x0: /* NO SENSE */
707 1.22 mycroft case 0x1: /* RECOVERED ERROR */
708 1.22 mycroft if (xs->resid == xs->datalen)
709 1.22 mycroft xs->resid = 0; /* not short read */
710 1.22 mycroft case 0xc: /* EQUAL */
711 1.22 mycroft error = 0;
712 1.22 mycroft break;
713 1.22 mycroft case 0x2: /* NOT READY */
714 1.22 mycroft if ((sc_link->flags & SDEV_REMOVABLE) != 0)
715 1.22 mycroft sc_link->flags &= ~SDEV_MEDIA_LOADED;
716 1.22 mycroft if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
717 1.22 mycroft return 0;
718 1.22 mycroft if ((xs->flags & SCSI_SILENT) != 0)
719 1.22 mycroft return EIO;
720 1.22 mycroft error = EIO;
721 1.22 mycroft break;
722 1.22 mycroft case 0x5: /* ILLEGAL REQUEST */
723 1.22 mycroft if ((xs->flags & SCSI_IGNORE_ILLEGAL_REQUEST) != 0)
724 1.22 mycroft return 0;
725 1.22 mycroft error = EINVAL;
726 1.22 mycroft break;
727 1.22 mycroft case 0x6: /* UNIT ATTENTION */
728 1.22 mycroft if ((sc_link->flags & SDEV_REMOVABLE) != 0)
729 1.22 mycroft sc_link->flags &= ~SDEV_MEDIA_LOADED;
730 1.22 mycroft if ((xs->flags & SCSI_IGNORE_MEDIA_CHANGE) != 0 ||
731 1.22 mycroft /* XXX Should reupload any transient state. */
732 1.22 mycroft (sc_link->flags & SDEV_REMOVABLE) == 0)
733 1.22 mycroft return ERESTART;
734 1.22 mycroft if ((xs->flags & SCSI_SILENT) != 0)
735 1.22 mycroft return EIO;
736 1.22 mycroft error = EIO;
737 1.22 mycroft break;
738 1.22 mycroft case 0x7: /* DATA PROTECT */
739 1.22 mycroft error = EACCES;
740 1.22 mycroft break;
741 1.22 mycroft case 0x8: /* BLANK CHECK */
742 1.22 mycroft error = 0;
743 1.22 mycroft break;
744 1.22 mycroft case 0xd: /* VOLUME OVERFLOW */
745 1.22 mycroft error = ENOSPC;
746 1.22 mycroft break;
747 1.22 mycroft default:
748 1.22 mycroft error = EIO;
749 1.22 mycroft break;
750 1.22 mycroft }
751 1.22 mycroft
752 1.22 mycroft if (key) {
753 1.1 mycroft sc_print_addr(sc_link);
754 1.1 mycroft printf("%s", error_mes[key - 1]);
755 1.22 mycroft if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
756 1.1 mycroft switch (key) {
757 1.23 mycroft case 0x2: /* NOT READY */
758 1.23 mycroft case 0x5: /* ILLEGAL REQUEST */
759 1.23 mycroft case 0x6: /* UNIT ATTENTION */
760 1.1 mycroft case 0x7: /* DATA PROTECT */
761 1.1 mycroft break;
762 1.1 mycroft case 0x8: /* BLANK CHECK */
763 1.1 mycroft printf(", requested size: %d (decimal)",
764 1.1 mycroft info);
765 1.1 mycroft break;
766 1.1 mycroft default:
767 1.1 mycroft printf(", info = %d (decimal)", info);
768 1.1 mycroft }
769 1.25 mycroft }
770 1.25 mycroft if (sense->extended_extra_len != 0) {
771 1.25 mycroft int n;
772 1.25 mycroft printf(", data =");
773 1.25 mycroft for (n = 0; n < sense->extended_extra_len; n++)
774 1.25 mycroft printf(" %02x", sense->extended_extra_bytes[n]);
775 1.1 mycroft }
776 1.1 mycroft printf("\n");
777 1.1 mycroft }
778 1.22 mycroft return error;
779 1.22 mycroft
780 1.1 mycroft /*
781 1.1 mycroft * Not code 70, just report it
782 1.1 mycroft */
783 1.1 mycroft default:
784 1.22 mycroft sc_print_addr(sc_link);
785 1.22 mycroft printf("error code %d",
786 1.22 mycroft sense->error_code & SSD_ERRCODE);
787 1.22 mycroft if ((sense->error_code & SSD_ERRCODE_VALID) != 0) {
788 1.22 mycroft printf(" at block no. %d (decimal)",
789 1.22 mycroft (sense->XXX_unextended_blockhi << 16) +
790 1.22 mycroft (sense->XXX_unextended_blockmed << 8) +
791 1.22 mycroft (sense->XXX_unextended_blocklow));
792 1.1 mycroft }
793 1.22 mycroft printf("\n");
794 1.11 mycroft return EIO;
795 1.1 mycroft }
796 1.1 mycroft }
797 1.1 mycroft
798 1.1 mycroft /*
799 1.1 mycroft * Utility routines often used in SCSI stuff
800 1.1 mycroft */
801 1.1 mycroft
802 1.1 mycroft /*
803 1.1 mycroft * convert a physical address to 3 bytes,
804 1.1 mycroft * MSB at the lowest address,
805 1.1 mycroft * LSB at the highest.
806 1.1 mycroft */
807 1.1 mycroft void
808 1.1 mycroft lto3b(val, bytes)
809 1.22 mycroft u_int32_t val;
810 1.22 mycroft u_int8_t *bytes;
811 1.1 mycroft {
812 1.22 mycroft
813 1.1 mycroft *bytes++ = (val & 0xff0000) >> 16;
814 1.1 mycroft *bytes++ = (val & 0xff00) >> 8;
815 1.1 mycroft *bytes = val & 0xff;
816 1.1 mycroft }
817 1.1 mycroft
818 1.1 mycroft /*
819 1.1 mycroft * The reverse of lto3b
820 1.1 mycroft */
821 1.22 mycroft u_int32_t
822 1.1 mycroft _3btol(bytes)
823 1.22 mycroft u_int8_t *bytes;
824 1.1 mycroft {
825 1.22 mycroft u_int32_t rc;
826 1.22 mycroft
827 1.1 mycroft rc = (*bytes++ << 16);
828 1.1 mycroft rc += (*bytes++ << 8);
829 1.1 mycroft rc += *bytes;
830 1.22 mycroft return (rc);
831 1.1 mycroft }
832 1.1 mycroft
833 1.1 mycroft /*
834 1.1 mycroft * Print out the scsi_link structure's address info.
835 1.1 mycroft */
836 1.1 mycroft void
837 1.1 mycroft sc_print_addr(sc_link)
838 1.22 mycroft struct scsi_link *sc_link;
839 1.1 mycroft {
840 1.1 mycroft
841 1.17 mycroft printf("%s(%s:%d:%d): ",
842 1.22 mycroft sc_link->device_softc ?
843 1.22 mycroft ((struct device *)sc_link->device_softc)->dv_xname : "probe",
844 1.22 mycroft ((struct device *)sc_link->adapter_softc)->dv_xname,
845 1.22 mycroft sc_link->target, sc_link->lun);
846 1.1 mycroft }
847 1.1 mycroft
848 1.1 mycroft #ifdef SCSIDEBUG
849 1.1 mycroft /*
850 1.1 mycroft * Given a scsi_xfer, dump the request, in all it's glory
851 1.1 mycroft */
852 1.1 mycroft void
853 1.1 mycroft show_scsi_xs(xs)
854 1.1 mycroft struct scsi_xfer *xs;
855 1.1 mycroft {
856 1.1 mycroft printf("xs(0x%x): ", xs);
857 1.1 mycroft printf("flg(0x%x)", xs->flags);
858 1.1 mycroft printf("sc_link(0x%x)", xs->sc_link);
859 1.1 mycroft printf("retr(0x%x)", xs->retries);
860 1.1 mycroft printf("timo(0x%x)", xs->timeout);
861 1.1 mycroft printf("cmd(0x%x)", xs->cmd);
862 1.1 mycroft printf("len(0x%x)", xs->cmdlen);
863 1.1 mycroft printf("data(0x%x)", xs->data);
864 1.1 mycroft printf("len(0x%x)", xs->datalen);
865 1.1 mycroft printf("res(0x%x)", xs->resid);
866 1.1 mycroft printf("err(0x%x)", xs->error);
867 1.1 mycroft printf("bp(0x%x)", xs->bp);
868 1.1 mycroft show_scsi_cmd(xs);
869 1.1 mycroft }
870 1.1 mycroft
871 1.1 mycroft void
872 1.15 deraadt show_scsi_cmd(xs)
873 1.15 deraadt struct scsi_xfer *xs;
874 1.1 mycroft {
875 1.1 mycroft u_char *b = (u_char *) xs->cmd;
876 1.1 mycroft int i = 0;
877 1.1 mycroft
878 1.1 mycroft sc_print_addr(xs->sc_link);
879 1.1 mycroft printf("command: ");
880 1.1 mycroft
881 1.22 mycroft if ((xs->flags & SCSI_RESET) == 0) {
882 1.1 mycroft while (i < xs->cmdlen) {
883 1.1 mycroft if (i)
884 1.1 mycroft printf(",");
885 1.1 mycroft printf("%x", b[i++]);
886 1.1 mycroft }
887 1.1 mycroft printf("-[%d bytes]\n", xs->datalen);
888 1.1 mycroft if (xs->datalen)
889 1.1 mycroft show_mem(xs->data, min(64, xs->datalen));
890 1.2 mycroft } else
891 1.1 mycroft printf("-RESET-\n");
892 1.1 mycroft }
893 1.1 mycroft
894 1.1 mycroft void
895 1.1 mycroft show_mem(address, num)
896 1.24 mycroft u_char *address;
897 1.24 mycroft int num;
898 1.1 mycroft {
899 1.24 mycroft int x;
900 1.24 mycroft
901 1.1 mycroft printf("------------------------------");
902 1.24 mycroft for (x = 0; x < num; x++) {
903 1.24 mycroft if ((x % 16) == 0)
904 1.24 mycroft printf("\n%03d: ", x);
905 1.1 mycroft printf("%02x ", *address++);
906 1.1 mycroft }
907 1.1 mycroft printf("\n------------------------------\n");
908 1.1 mycroft }
909 1.1 mycroft #endif /*SCSIDEBUG */
910