scsi_base.c revision 1.11 1 1.1 mycroft /*
2 1.9 mycroft * Copyright (c) 1994 Charles Hannum. All rights reserved.
3 1.9 mycroft *
4 1.9 mycroft * Redistribution and use in source and binary forms, with or without
5 1.9 mycroft * modification, are permitted provided that the following conditions
6 1.9 mycroft * are met:
7 1.9 mycroft * 1. Redistributions of source code must retain the above copyright
8 1.9 mycroft * notice, this list of conditions and the following disclaimer.
9 1.9 mycroft * 2. Redistributions in binary form must reproduce the above copyright
10 1.9 mycroft * notice, this list of conditions and the following disclaimer in the
11 1.9 mycroft * documentation and/or other materials provided with the distribution.
12 1.9 mycroft * 3. All advertising materials mentioning features or use of this software
13 1.9 mycroft * must display the following acknowledgement:
14 1.9 mycroft * This product includes software developed by Charles Hannum.
15 1.9 mycroft * 4. The name of the author may not be used to endorse or promote products
16 1.9 mycroft * derived from this software without specific prior written permission.
17 1.9 mycroft *
18 1.9 mycroft * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.9 mycroft * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.9 mycroft * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.9 mycroft * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.9 mycroft * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.9 mycroft * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.9 mycroft * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.9 mycroft * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.9 mycroft * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 1.9 mycroft * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.9 mycroft *
29 1.11 mycroft * $Id: scsi_base.c,v 1.11 1994/04/11 03:53:45 mycroft Exp $
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.2 mycroft void sc_print_addr __P((struct scsi_link *sc_link));
56 1.1 mycroft
57 1.1 mycroft struct scsi_xfer *next_free_xs;
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.1 mycroft 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.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("get_xs\n"));
79 1.1 mycroft s = splbio();
80 1.1 mycroft while (!sc_link->opennings) {
81 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("sleeping\n"));
82 1.1 mycroft if (flags & SCSI_NOSLEEP) {
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.4 mycroft (void) tsleep(sc_link, PRIBIO, "get_xs", 0);
88 1.1 mycroft }
89 1.1 mycroft sc_link->opennings--;
90 1.1 mycroft if (xs = next_free_xs) {
91 1.1 mycroft next_free_xs = xs->next;
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.1 mycroft xs = malloc(sizeof(*xs), M_TEMP,
97 1.1 mycroft ((flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK));
98 1.1 mycroft if (xs == NULL) {
99 1.1 mycroft sc_print_addr(sc_link);
100 1.1 mycroft printf("cannot allocate scsi xs\n");
101 1.11 mycroft return NULL;
102 1.1 mycroft }
103 1.1 mycroft }
104 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("returning\n"));
105 1.1 mycroft xs->sc_link = sc_link;
106 1.11 mycroft return xs;
107 1.1 mycroft }
108 1.1 mycroft
109 1.1 mycroft /*
110 1.1 mycroft * Given a scsi_xfer struct, and a device (referenced through sc_link)
111 1.1 mycroft * return the struct to the free pool and credit the device with it
112 1.1 mycroft * If another process is waiting for an xs, do a wakeup, let it proceed
113 1.1 mycroft */
114 1.1 mycroft void
115 1.1 mycroft free_xs(xs, sc_link, flags)
116 1.1 mycroft struct scsi_xfer *xs;
117 1.1 mycroft struct scsi_link *sc_link; /* who to credit for returning it */
118 1.11 mycroft int flags;
119 1.1 mycroft {
120 1.1 mycroft xs->next = next_free_xs;
121 1.1 mycroft next_free_xs = xs;
122 1.1 mycroft
123 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("free_xs\n"));
124 1.1 mycroft /* if was 0 and someone waits, wake them up */
125 1.3 mycroft if ((!sc_link->opennings++) && (sc_link->flags & SDEV_WAITING)) {
126 1.3 mycroft sc_link->flags &= ~SDEV_WAITING;
127 1.3 mycroft wakeup(sc_link); /* remember, it wakes them ALL up */
128 1.3 mycroft } else {
129 1.1 mycroft if (sc_link->device->start) {
130 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("calling private start()\n"));
131 1.1 mycroft (*(sc_link->device->start)) (sc_link->dev_unit);
132 1.1 mycroft }
133 1.3 mycroft }
134 1.1 mycroft }
135 1.1 mycroft
136 1.1 mycroft /*
137 1.1 mycroft * Find out from the device what its capacity is.
138 1.1 mycroft */
139 1.1 mycroft u_int32
140 1.1 mycroft scsi_size(sc_link, flags)
141 1.1 mycroft struct scsi_link *sc_link;
142 1.11 mycroft int flags;
143 1.1 mycroft {
144 1.1 mycroft struct scsi_read_cap_data rdcap;
145 1.1 mycroft struct scsi_read_capacity scsi_cmd;
146 1.1 mycroft u_int32 size;
147 1.1 mycroft
148 1.1 mycroft /*
149 1.1 mycroft * make up a scsi command and ask the scsi driver to do
150 1.1 mycroft * it for you.
151 1.1 mycroft */
152 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
153 1.1 mycroft scsi_cmd.op_code = READ_CAPACITY;
154 1.1 mycroft
155 1.1 mycroft /*
156 1.1 mycroft * If the command works, interpret the result as a 4 byte
157 1.1 mycroft * number of blocks
158 1.1 mycroft */
159 1.2 mycroft if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
160 1.2 mycroft sizeof(scsi_cmd), (u_char *) & rdcap, sizeof(rdcap),
161 1.2 mycroft 2, 20000, NULL, flags | SCSI_DATA_IN) != 0) {
162 1.1 mycroft sc_print_addr(sc_link);
163 1.1 mycroft printf("could not get size\n");
164 1.11 mycroft return 0;
165 1.1 mycroft } else {
166 1.1 mycroft size = rdcap.addr_0 + 1;
167 1.1 mycroft size += rdcap.addr_1 << 8;
168 1.1 mycroft size += rdcap.addr_2 << 16;
169 1.1 mycroft size += rdcap.addr_3 << 24;
170 1.1 mycroft }
171 1.11 mycroft return size;
172 1.1 mycroft }
173 1.1 mycroft
174 1.1 mycroft /*
175 1.1 mycroft * Get scsi driver to send a "are you ready?" command
176 1.1 mycroft */
177 1.2 mycroft int
178 1.1 mycroft scsi_test_unit_ready(sc_link, flags)
179 1.1 mycroft struct scsi_link *sc_link;
180 1.11 mycroft int flags;
181 1.1 mycroft {
182 1.1 mycroft struct scsi_test_unit_ready scsi_cmd;
183 1.1 mycroft
184 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
185 1.1 mycroft scsi_cmd.op_code = TEST_UNIT_READY;
186 1.1 mycroft
187 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
188 1.2 mycroft sizeof(scsi_cmd), 0, 0, 2, 100000, NULL, flags);
189 1.1 mycroft }
190 1.1 mycroft
191 1.1 mycroft /*
192 1.1 mycroft * Do a scsi operation, asking a device to run as SCSI-II if it can.
193 1.1 mycroft */
194 1.2 mycroft int
195 1.1 mycroft scsi_change_def(sc_link, flags)
196 1.1 mycroft struct scsi_link *sc_link;
197 1.11 mycroft int flags;
198 1.1 mycroft {
199 1.1 mycroft struct scsi_changedef scsi_cmd;
200 1.1 mycroft
201 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
202 1.1 mycroft scsi_cmd.op_code = CHANGE_DEFINITION;
203 1.1 mycroft scsi_cmd.how = SC_SCSI_2;
204 1.1 mycroft
205 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
206 1.2 mycroft sizeof(scsi_cmd), 0, 0, 2, 100000, NULL, flags);
207 1.1 mycroft }
208 1.1 mycroft
209 1.1 mycroft /*
210 1.1 mycroft * Do a scsi operation asking a device what it is
211 1.1 mycroft * Use the scsi_cmd routine in the switch table.
212 1.1 mycroft */
213 1.2 mycroft int
214 1.1 mycroft scsi_inquire(sc_link, inqbuf, flags)
215 1.1 mycroft struct scsi_link *sc_link;
216 1.1 mycroft struct scsi_inquiry_data *inqbuf;
217 1.11 mycroft int flags;
218 1.1 mycroft {
219 1.1 mycroft struct scsi_inquiry scsi_cmd;
220 1.1 mycroft
221 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
222 1.1 mycroft scsi_cmd.op_code = INQUIRY;
223 1.1 mycroft scsi_cmd.length = sizeof(struct scsi_inquiry_data);
224 1.1 mycroft
225 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
226 1.2 mycroft sizeof(scsi_cmd), (u_char *) inqbuf,
227 1.2 mycroft sizeof(struct scsi_inquiry_data), 2, 100000, NULL,
228 1.2 mycroft SCSI_DATA_IN | flags);
229 1.1 mycroft }
230 1.1 mycroft
231 1.1 mycroft /*
232 1.1 mycroft * Prevent or allow the user to remove the media
233 1.1 mycroft */
234 1.2 mycroft int
235 1.1 mycroft scsi_prevent(sc_link, type, flags)
236 1.1 mycroft struct scsi_link *sc_link;
237 1.11 mycroft int type, flags;
238 1.1 mycroft {
239 1.1 mycroft struct scsi_prevent scsi_cmd;
240 1.1 mycroft
241 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
242 1.1 mycroft scsi_cmd.op_code = PREVENT_ALLOW;
243 1.1 mycroft scsi_cmd.how = type;
244 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
245 1.2 mycroft sizeof(scsi_cmd), 0, 0, 2, 5000, NULL, flags);
246 1.1 mycroft }
247 1.1 mycroft
248 1.1 mycroft /*
249 1.1 mycroft * Get scsi driver to send a "start up" command
250 1.1 mycroft */
251 1.2 mycroft int
252 1.10 mycroft scsi_start(sc_link, type, flags)
253 1.1 mycroft struct scsi_link *sc_link;
254 1.11 mycroft int type, flags;
255 1.1 mycroft {
256 1.1 mycroft struct scsi_start_stop scsi_cmd;
257 1.1 mycroft
258 1.1 mycroft bzero(&scsi_cmd, sizeof(scsi_cmd));
259 1.1 mycroft scsi_cmd.op_code = START_STOP;
260 1.10 mycroft scsi_cmd.how = type;
261 1.2 mycroft return scsi_scsi_cmd(sc_link, (struct scsi_generic *) &scsi_cmd,
262 1.10 mycroft sizeof(scsi_cmd), 0, 0, 2,
263 1.10 mycroft type == SSS_START ? 10000 : 2000, NULL, flags);
264 1.1 mycroft }
265 1.1 mycroft
266 1.1 mycroft /*
267 1.1 mycroft * This routine is called by the scsi interrupt when the transfer is complete.
268 1.1 mycroft */
269 1.1 mycroft void
270 1.1 mycroft scsi_done(xs)
271 1.1 mycroft struct scsi_xfer *xs;
272 1.1 mycroft {
273 1.1 mycroft struct scsi_link *sc_link = xs->sc_link;
274 1.1 mycroft struct buf *bp = xs->bp;
275 1.11 mycroft int error;
276 1.1 mycroft
277 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n"));
278 1.1 mycroft #ifdef SCSIDEBUG
279 1.1 mycroft if (sc_link->flags & SDEV_DB1)
280 1.1 mycroft show_scsi_cmd(xs);
281 1.1 mycroft #endif /*SCSIDEBUG */
282 1.1 mycroft /*
283 1.1 mycroft * If it's a user level request, bypass all usual completion processing,
284 1.1 mycroft * let the user work it out.. We take reponsibility for freeing the
285 1.1 mycroft * xs when the user returns. (and restarting the device's queue).
286 1.1 mycroft */
287 1.1 mycroft if (xs->flags & SCSI_USER) {
288 1.1 mycroft biodone(xs->bp);
289 1.1 mycroft #ifdef NOTNOW
290 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("calling user done()\n"));
291 1.1 mycroft scsi_user_done(xs); /* to take a copy of the sense etc. */
292 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("returned from user done()\n "));
293 1.1 mycroft #endif
294 1.1 mycroft free_xs(xs, sc_link, SCSI_NOSLEEP); /* restarts queue too */
295 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("returning to adapter\n"));
296 1.1 mycroft return;
297 1.1 mycroft }
298 1.1 mycroft /*
299 1.1 mycroft * If the device has it's own done routine, call it first.
300 1.1 mycroft * If it returns a legit error value, return that, otherwise
301 1.1 mycroft * it wants us to continue with normal processing.
302 1.1 mycroft */
303 1.1 mycroft
304 1.1 mycroft if (sc_link->device->done) {
305 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
306 1.11 mycroft error = (*sc_link->device->done) (xs);
307 1.11 mycroft if (error == -1) {
308 1.1 mycroft free_xs(xs, sc_link, SCSI_NOSLEEP); /*XXX */
309 1.1 mycroft return; /* it did it all, finish up */
310 1.1 mycroft }
311 1.11 mycroft if (error == -2)
312 1.1 mycroft return; /* it did it all, finish up */
313 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
314 1.1 mycroft }
315 1.1 mycroft if ((bp = xs->bp) == NULL) {
316 1.1 mycroft /*
317 1.1 mycroft * if it's a normal upper level request, then ask
318 1.1 mycroft * the upper level code to handle error checking
319 1.1 mycroft * rather than doing it here at interrupt time
320 1.1 mycroft */
321 1.1 mycroft wakeup(xs);
322 1.1 mycroft return;
323 1.1 mycroft }
324 1.1 mycroft /*
325 1.1 mycroft * Go and handle errors now.
326 1.1 mycroft * If it returns -1 then we should RETRY
327 1.1 mycroft */
328 1.11 mycroft if ((error = sc_err1(xs)) == -1) {
329 1.1 mycroft if ((*(sc_link->adapter->scsi_cmd)) (xs)
330 1.2 mycroft == SUCCESSFULLY_QUEUED) /* don't wake the job, ok? */
331 1.1 mycroft return;
332 1.1 mycroft xs->flags |= ITSDONE;
333 1.1 mycroft }
334 1.1 mycroft free_xs(xs, sc_link, SCSI_NOSLEEP); /* does a start if needed */
335 1.1 mycroft biodone(bp);
336 1.1 mycroft }
337 1.1 mycroft
338 1.1 mycroft /*
339 1.1 mycroft * ask the scsi driver to perform a command for us.
340 1.1 mycroft * tell it where to read/write the data, and how
341 1.1 mycroft * long the data is supposed to be. If we have a buf
342 1.1 mycroft * to associate with the transfer, we need that too.
343 1.1 mycroft */
344 1.2 mycroft int
345 1.1 mycroft scsi_scsi_cmd(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
346 1.1 mycroft retries, timeout, bp, flags)
347 1.1 mycroft struct scsi_link *sc_link;
348 1.1 mycroft struct scsi_generic *scsi_cmd;
349 1.1 mycroft u_int32 cmdlen;
350 1.1 mycroft u_char *data_addr;
351 1.1 mycroft u_int32 datalen;
352 1.11 mycroft int retries;
353 1.11 mycroft int timeout;
354 1.1 mycroft struct buf *bp;
355 1.11 mycroft int flags;
356 1.1 mycroft {
357 1.1 mycroft struct scsi_xfer *xs;
358 1.11 mycroft int error;
359 1.11 mycroft int s;
360 1.1 mycroft
361 1.2 mycroft if (bp)
362 1.2 mycroft flags |= SCSI_NOSLEEP;
363 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n"));
364 1.1 mycroft
365 1.1 mycroft xs = get_xs(sc_link, flags); /* should wait unless booting */
366 1.2 mycroft if (!xs)
367 1.11 mycroft return ENOMEM;
368 1.1 mycroft /*
369 1.1 mycroft * Fill out the scsi_xfer structure. We don't know whose context
370 1.1 mycroft * the cmd is in, so copy it.
371 1.1 mycroft */
372 1.11 mycroft bcopy(scsi_cmd, &xs->cmdstore, cmdlen);
373 1.1 mycroft xs->flags = INUSE | flags;
374 1.1 mycroft xs->sc_link = sc_link;
375 1.1 mycroft xs->retries = retries;
376 1.1 mycroft xs->timeout = timeout;
377 1.1 mycroft xs->cmd = &xs->cmdstore;
378 1.1 mycroft xs->cmdlen = cmdlen;
379 1.1 mycroft xs->data = data_addr;
380 1.1 mycroft xs->datalen = datalen;
381 1.1 mycroft xs->resid = datalen;
382 1.1 mycroft xs->bp = bp;
383 1.11 mycroft if ((flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) &&
384 1.11 mycroft ((caddr_t) data_addr < (caddr_t) KERNBASE)) {
385 1.1 mycroft if (bp) {
386 1.1 mycroft printf("Data buffered space not in kernel context\n");
387 1.1 mycroft #ifdef SCSIDEBUG
388 1.1 mycroft show_scsi_cmd(xs);
389 1.1 mycroft #endif /* SCSIDEBUG */
390 1.11 mycroft error = EFAULT;
391 1.1 mycroft goto bad;
392 1.1 mycroft }
393 1.1 mycroft xs->data = malloc(datalen, M_TEMP, M_WAITOK);
394 1.1 mycroft /* I think waiting is ok *//*XXX */
395 1.11 mycroft if (flags & SCSI_DATA_OUT)
396 1.1 mycroft bcopy(data_addr, xs->data, datalen);
397 1.11 mycroft else
398 1.1 mycroft bzero(xs->data, datalen);
399 1.1 mycroft }
400 1.1 mycroft retry:
401 1.1 mycroft xs->error = XS_NOERROR;
402 1.1 mycroft #ifdef SCSIDEBUG
403 1.2 mycroft if (sc_link->flags & SDEV_DB3)
404 1.2 mycroft show_scsi_xs(xs);
405 1.1 mycroft #endif /* SCSIDEBUG */
406 1.1 mycroft /*
407 1.1 mycroft * Do the transfer. If we are polling we will return:
408 1.1 mycroft * COMPLETE, Was poll, and scsi_done has been called
409 1.1 mycroft * TRY_AGAIN_LATER, Adapter short resources, try again
410 1.1 mycroft *
411 1.1 mycroft * if under full steam (interrupts) it will return:
412 1.1 mycroft * SUCCESSFULLY_QUEUED, will do a wakeup when complete
413 1.1 mycroft * TRY_AGAIN_LATER, (as for polling)
414 1.1 mycroft * After the wakeup, we must still check if it succeeded
415 1.1 mycroft *
416 1.1 mycroft * If we have a bp however, all the error proccessing
417 1.1 mycroft * and the buffer code both expect us to return straight
418 1.1 mycroft * to them, so as soon as the command is queued, return
419 1.1 mycroft */
420 1.11 mycroft error = (*(sc_link->adapter->scsi_cmd)) (xs);
421 1.1 mycroft
422 1.11 mycroft switch (error) {
423 1.1 mycroft case SUCCESSFULLY_QUEUED:
424 1.1 mycroft if (bp)
425 1.11 mycroft return error; /* will sleep (or not) elsewhere */
426 1.1 mycroft s = splbio();
427 1.1 mycroft while (!(xs->flags & ITSDONE))
428 1.4 mycroft tsleep(xs, PRIBIO + 1, "scsi_scsi_cmd", 0);
429 1.1 mycroft splx(s);
430 1.1 mycroft /* fall through to check success of completed command */
431 1.1 mycroft case COMPLETE: /* Polling command completed ok */
432 1.1 mycroft /*XXX*/ case HAD_ERROR: /* Polling command completed with error */
433 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("back in cmd()\n"));
434 1.11 mycroft if ((error = sc_err1(xs)) == -1)
435 1.1 mycroft goto retry;
436 1.1 mycroft break;
437 1.1 mycroft
438 1.1 mycroft case TRY_AGAIN_LATER: /* adapter resource shortage */
439 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB3, ("will try again \n"));
440 1.1 mycroft if (xs->retries--) {
441 1.1 mycroft xs->flags &= ~ITSDONE;
442 1.11 mycroft tsleep((caddr_t)&lbolt, PRIBIO, "scretry", 0);
443 1.1 mycroft goto retry;
444 1.1 mycroft }
445 1.1 mycroft default:
446 1.11 mycroft error = EIO;
447 1.1 mycroft }
448 1.1 mycroft /*
449 1.1 mycroft * If we had to copy the data out of the user's context,
450 1.1 mycroft * then do the other half (copy it back or whatever)
451 1.1 mycroft * and free the memory buffer
452 1.1 mycroft */
453 1.11 mycroft if ((flags & SCSI_DATA_IN) && (xs->data != data_addr)) {
454 1.11 mycroft bcopy(xs->data, data_addr, datalen);
455 1.1 mycroft free(xs->data, M_TEMP);
456 1.1 mycroft }
457 1.1 mycroft /*
458 1.1 mycroft * we have finished with the xfer stuct, free it and
459 1.1 mycroft * check if anyone else needs to be started up.
460 1.1 mycroft */
461 1.1 mycroft bad:
462 1.1 mycroft free_xs(xs, sc_link, flags); /* includes the 'start' op */
463 1.11 mycroft if (bp && error) {
464 1.11 mycroft bp->b_error = error;
465 1.1 mycroft bp->b_flags |= B_ERROR;
466 1.1 mycroft biodone(bp);
467 1.1 mycroft }
468 1.11 mycroft return error;
469 1.1 mycroft }
470 1.1 mycroft
471 1.2 mycroft int
472 1.1 mycroft sc_err1(xs)
473 1.1 mycroft struct scsi_xfer *xs;
474 1.1 mycroft {
475 1.1 mycroft struct buf *bp = xs->bp;
476 1.11 mycroft int error;
477 1.1 mycroft
478 1.1 mycroft SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%x \n", xs->error));
479 1.1 mycroft /*
480 1.1 mycroft * If it has a buf, we might be working with
481 1.1 mycroft * a request from the buffer cache or some other
482 1.1 mycroft * piece of code that requires us to process
483 1.1 mycroft * errors at inetrrupt time. We have probably
484 1.1 mycroft * been called by scsi_done()
485 1.1 mycroft */
486 1.1 mycroft switch (xs->error) {
487 1.1 mycroft case XS_NOERROR: /* nearly always hit this one */
488 1.11 mycroft error = 0;
489 1.1 mycroft if (bp) {
490 1.1 mycroft bp->b_error = 0;
491 1.1 mycroft bp->b_resid = 0;
492 1.1 mycroft }
493 1.1 mycroft break;
494 1.1 mycroft
495 1.1 mycroft case XS_SENSE:
496 1.1 mycroft if (bp) {
497 1.1 mycroft bp->b_error = 0;
498 1.1 mycroft bp->b_resid = 0;
499 1.11 mycroft if (error = scsi_interpret_sense(xs)) {
500 1.1 mycroft bp->b_flags |= B_ERROR;
501 1.11 mycroft bp->b_error = error;
502 1.1 mycroft bp->b_resid = bp->b_bcount;
503 1.1 mycroft }
504 1.1 mycroft SC_DEBUG(xs->sc_link, SDEV_DB3,
505 1.11 mycroft ("scsi_interpret_sense (bp) returned %d\n", error));
506 1.1 mycroft } else {
507 1.11 mycroft error = scsi_interpret_sense(xs);
508 1.1 mycroft SC_DEBUG(xs->sc_link, SDEV_DB3,
509 1.11 mycroft ("scsi_interpret_sense (no bp) returned %d\n", error));
510 1.1 mycroft }
511 1.1 mycroft break;
512 1.1 mycroft
513 1.1 mycroft case XS_BUSY:
514 1.1 mycroft /*should somehow arange for a 1 sec delay here (how?) */
515 1.1 mycroft case XS_TIMEOUT:
516 1.1 mycroft /*
517 1.1 mycroft * If we can, resubmit it to the adapter.
518 1.1 mycroft */
519 1.1 mycroft if (xs->retries--) {
520 1.1 mycroft xs->error = XS_NOERROR;
521 1.1 mycroft xs->flags &= ~ITSDONE;
522 1.1 mycroft goto retry;
523 1.1 mycroft }
524 1.1 mycroft /* fall through */
525 1.1 mycroft case XS_DRIVER_STUFFUP:
526 1.1 mycroft if (bp) {
527 1.1 mycroft bp->b_flags |= B_ERROR;
528 1.1 mycroft bp->b_error = EIO;
529 1.1 mycroft }
530 1.11 mycroft error = EIO;
531 1.1 mycroft break;
532 1.1 mycroft default:
533 1.11 mycroft error = EIO;
534 1.1 mycroft sc_print_addr(xs->sc_link);
535 1.1 mycroft printf("unknown error category from scsi driver\n");
536 1.1 mycroft }
537 1.11 mycroft return error;
538 1.1 mycroft retry:
539 1.11 mycroft return -1;
540 1.1 mycroft }
541 1.1 mycroft
542 1.1 mycroft /*
543 1.1 mycroft * Look at the returned sense and act on the error, determining
544 1.1 mycroft * the unix error number to pass back. (0 = report no error)
545 1.1 mycroft *
546 1.1 mycroft * THIS IS THE DEFAULT ERROR HANDLER
547 1.1 mycroft */
548 1.2 mycroft int
549 1.1 mycroft scsi_interpret_sense(xs)
550 1.1 mycroft struct scsi_xfer *xs;
551 1.1 mycroft {
552 1.1 mycroft struct scsi_sense_data *sense;
553 1.1 mycroft struct scsi_link *sc_link = xs->sc_link;
554 1.1 mycroft u_int32 key;
555 1.1 mycroft u_int32 silent;
556 1.1 mycroft u_int32 info;
557 1.2 mycroft int error;
558 1.1 mycroft
559 1.1 mycroft static char *error_mes[] =
560 1.1 mycroft {"soft error (corrected)",
561 1.1 mycroft "not ready", "medium error",
562 1.1 mycroft "non-media hardware failure", "illegal request",
563 1.1 mycroft "unit attention", "readonly device",
564 1.1 mycroft "no data found", "vendor unique",
565 1.1 mycroft "copy aborted", "command aborted",
566 1.1 mycroft "search returned equal", "volume overflow",
567 1.1 mycroft "verify miscompare", "unknown error key"
568 1.1 mycroft };
569 1.1 mycroft
570 1.1 mycroft /*
571 1.1 mycroft * If the flags say errs are ok, then always return ok.
572 1.1 mycroft */
573 1.1 mycroft if (xs->flags & SCSI_ERR_OK)
574 1.11 mycroft return 0;
575 1.1 mycroft
576 1.11 mycroft sense = &xs->sense;
577 1.1 mycroft #ifdef SCSIDEBUG
578 1.1 mycroft if (sc_link->flags & SDEV_DB1) {
579 1.1 mycroft u_int32 count = 0;
580 1.1 mycroft printf("code%x valid%x ",
581 1.1 mycroft sense->error_code & SSD_ERRCODE,
582 1.1 mycroft sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
583 1.1 mycroft printf("seg%x key%x ili%x eom%x fmark%x\n",
584 1.1 mycroft sense->ext.extended.segment,
585 1.1 mycroft sense->ext.extended.flags & SSD_KEY,
586 1.1 mycroft sense->ext.extended.flags & SSD_ILI ? 1 : 0,
587 1.1 mycroft sense->ext.extended.flags & SSD_EOM ? 1 : 0,
588 1.1 mycroft sense->ext.extended.flags & SSD_FILEMARK ? 1 : 0);
589 1.1 mycroft printf("info: %x %x %x %x followed by %d extra bytes\n",
590 1.1 mycroft sense->ext.extended.info[0],
591 1.1 mycroft sense->ext.extended.info[1],
592 1.1 mycroft sense->ext.extended.info[2],
593 1.1 mycroft sense->ext.extended.info[3],
594 1.1 mycroft sense->ext.extended.extra_len);
595 1.1 mycroft printf("extra: ");
596 1.2 mycroft while (count < sense->ext.extended.extra_len)
597 1.1 mycroft printf("%x ", sense->ext.extended.extra_bytes[count++]);
598 1.1 mycroft printf("\n");
599 1.1 mycroft }
600 1.1 mycroft #endif /*SCSIDEBUG */
601 1.1 mycroft /*
602 1.1 mycroft * If the device has it's own error handler, call it first.
603 1.1 mycroft * If it returns a legit error value, return that, otherwise
604 1.1 mycroft * it wants us to continue with normal error processing.
605 1.1 mycroft */
606 1.1 mycroft if (sc_link->device->err_handler) {
607 1.1 mycroft SC_DEBUG(sc_link, SDEV_DB2, ("calling private err_handler()\n"));
608 1.2 mycroft error = (*sc_link->device->err_handler) (xs);
609 1.2 mycroft if (error != -1)
610 1.2 mycroft return error; /* error >= 0 better ? */
611 1.1 mycroft }
612 1.1 mycroft /* otherwise use the default */
613 1.1 mycroft silent = (xs->flags & SCSI_SILENT);
614 1.1 mycroft switch (sense->error_code & SSD_ERRCODE) {
615 1.1 mycroft /*
616 1.1 mycroft * If it's code 70, use the extended stuff and interpret the key
617 1.1 mycroft */
618 1.1 mycroft case 0x71: /* delayed error */
619 1.1 mycroft sc_print_addr(sc_link);
620 1.1 mycroft key = sense->ext.extended.flags & SSD_KEY;
621 1.1 mycroft printf(" DELAYED ERROR, key = 0x%x\n", key);
622 1.1 mycroft case 0x70:
623 1.2 mycroft if (sense->error_code & SSD_ERRCODE_VALID)
624 1.1 mycroft info = ntohl(*((long *) sense->ext.extended.info));
625 1.2 mycroft else
626 1.1 mycroft info = 0;
627 1.1 mycroft key = sense->ext.extended.flags & SSD_KEY;
628 1.1 mycroft
629 1.1 mycroft if (key && !silent) {
630 1.1 mycroft sc_print_addr(sc_link);
631 1.1 mycroft printf("%s", error_mes[key - 1]);
632 1.1 mycroft if (sense->error_code & SSD_ERRCODE_VALID) {
633 1.1 mycroft switch (key) {
634 1.1 mycroft case 0x2: /* NOT READY */
635 1.1 mycroft case 0x5: /* ILLEGAL REQUEST */
636 1.1 mycroft case 0x6: /* UNIT ATTENTION */
637 1.1 mycroft case 0x7: /* DATA PROTECT */
638 1.1 mycroft break;
639 1.1 mycroft case 0x8: /* BLANK CHECK */
640 1.1 mycroft printf(", requested size: %d (decimal)",
641 1.1 mycroft info);
642 1.1 mycroft break;
643 1.1 mycroft default:
644 1.1 mycroft printf(", info = %d (decimal)", info);
645 1.1 mycroft }
646 1.1 mycroft }
647 1.1 mycroft printf("\n");
648 1.1 mycroft }
649 1.1 mycroft switch (key) {
650 1.1 mycroft case 0x0: /* NO SENSE */
651 1.1 mycroft case 0x1: /* RECOVERED ERROR */
652 1.1 mycroft if (xs->resid == xs->datalen)
653 1.1 mycroft xs->resid = 0; /* not short read */
654 1.1 mycroft case 0xc: /* EQUAL */
655 1.11 mycroft return 0;
656 1.1 mycroft case 0x2: /* NOT READY */
657 1.1 mycroft sc_link->flags &= ~SDEV_MEDIA_LOADED;
658 1.11 mycroft return EBUSY;
659 1.1 mycroft case 0x5: /* ILLEGAL REQUEST */
660 1.11 mycroft return EINVAL;
661 1.1 mycroft case 0x6: /* UNIT ATTENTION */
662 1.1 mycroft sc_link->flags &= ~SDEV_MEDIA_LOADED;
663 1.2 mycroft if (sc_link->flags & SDEV_OPEN)
664 1.11 mycroft return EIO;
665 1.2 mycroft else
666 1.1 mycroft return 0;
667 1.1 mycroft case 0x7: /* DATA PROTECT */
668 1.11 mycroft return EACCES;
669 1.1 mycroft case 0xd: /* VOLUME OVERFLOW */
670 1.11 mycroft return ENOSPC;
671 1.1 mycroft case 0x8: /* BLANK CHECK */
672 1.11 mycroft return 0;
673 1.1 mycroft default:
674 1.11 mycroft return EIO;
675 1.1 mycroft }
676 1.1 mycroft /*
677 1.1 mycroft * Not code 70, just report it
678 1.1 mycroft */
679 1.1 mycroft default:
680 1.1 mycroft if (!silent) {
681 1.1 mycroft sc_print_addr(sc_link);
682 1.1 mycroft printf("error code %d",
683 1.1 mycroft sense->error_code & SSD_ERRCODE);
684 1.1 mycroft if (sense->error_code & SSD_ERRCODE_VALID) {
685 1.1 mycroft printf(" at block no. %d (decimal)",
686 1.1 mycroft (sense->ext.unextended.blockhi << 16) +
687 1.1 mycroft (sense->ext.unextended.blockmed << 8) +
688 1.1 mycroft (sense->ext.unextended.blocklow));
689 1.1 mycroft }
690 1.1 mycroft printf("\n");
691 1.1 mycroft }
692 1.11 mycroft return EIO;
693 1.1 mycroft }
694 1.1 mycroft }
695 1.1 mycroft
696 1.1 mycroft /*
697 1.1 mycroft * Utility routines often used in SCSI stuff
698 1.1 mycroft */
699 1.1 mycroft
700 1.1 mycroft /*
701 1.1 mycroft * convert a physical address to 3 bytes,
702 1.1 mycroft * MSB at the lowest address,
703 1.1 mycroft * LSB at the highest.
704 1.1 mycroft */
705 1.1 mycroft void
706 1.1 mycroft lto3b(val, bytes)
707 1.1 mycroft int val;
708 1.1 mycroft u_char *bytes;
709 1.1 mycroft {
710 1.1 mycroft *bytes++ = (val & 0xff0000) >> 16;
711 1.1 mycroft *bytes++ = (val & 0xff00) >> 8;
712 1.1 mycroft *bytes = val & 0xff;
713 1.1 mycroft }
714 1.1 mycroft
715 1.1 mycroft /*
716 1.1 mycroft * The reverse of lto3b
717 1.1 mycroft */
718 1.1 mycroft int
719 1.1 mycroft _3btol(bytes)
720 1.1 mycroft u_char *bytes;
721 1.1 mycroft {
722 1.1 mycroft u_int32 rc;
723 1.1 mycroft rc = (*bytes++ << 16);
724 1.1 mycroft rc += (*bytes++ << 8);
725 1.1 mycroft rc += *bytes;
726 1.1 mycroft return ((int) rc);
727 1.1 mycroft }
728 1.1 mycroft
729 1.1 mycroft /*
730 1.1 mycroft * Print out the scsi_link structure's address info.
731 1.1 mycroft */
732 1.1 mycroft void
733 1.1 mycroft sc_print_addr(sc_link)
734 1.1 mycroft struct scsi_link *sc_link;
735 1.1 mycroft {
736 1.1 mycroft
737 1.1 mycroft printf("%s%d(%s:%d:%d): ",
738 1.1 mycroft sc_link->device->name, sc_link->dev_unit,
739 1.1 mycroft ((struct device *)sc_link->adapter_softc)->dv_xname,
740 1.1 mycroft sc_link->target, sc_link->lun);
741 1.1 mycroft }
742 1.1 mycroft
743 1.1 mycroft #ifdef SCSIDEBUG
744 1.1 mycroft /*
745 1.1 mycroft * Given a scsi_xfer, dump the request, in all it's glory
746 1.1 mycroft */
747 1.1 mycroft void
748 1.1 mycroft show_scsi_xs(xs)
749 1.1 mycroft struct scsi_xfer *xs;
750 1.1 mycroft {
751 1.1 mycroft printf("xs(0x%x): ", xs);
752 1.1 mycroft printf("flg(0x%x)", xs->flags);
753 1.1 mycroft printf("sc_link(0x%x)", xs->sc_link);
754 1.1 mycroft printf("retr(0x%x)", xs->retries);
755 1.1 mycroft printf("timo(0x%x)", xs->timeout);
756 1.1 mycroft printf("cmd(0x%x)", xs->cmd);
757 1.1 mycroft printf("len(0x%x)", xs->cmdlen);
758 1.1 mycroft printf("data(0x%x)", xs->data);
759 1.1 mycroft printf("len(0x%x)", xs->datalen);
760 1.1 mycroft printf("res(0x%x)", xs->resid);
761 1.1 mycroft printf("err(0x%x)", xs->error);
762 1.1 mycroft printf("bp(0x%x)", xs->bp);
763 1.1 mycroft show_scsi_cmd(xs);
764 1.1 mycroft }
765 1.1 mycroft
766 1.1 mycroft void
767 1.1 mycroft show_scsi_cmd(struct scsi_xfer *xs)
768 1.1 mycroft {
769 1.1 mycroft u_char *b = (u_char *) xs->cmd;
770 1.1 mycroft int i = 0;
771 1.1 mycroft
772 1.1 mycroft sc_print_addr(xs->sc_link);
773 1.1 mycroft printf("command: ");
774 1.1 mycroft
775 1.1 mycroft if (!(xs->flags & SCSI_RESET)) {
776 1.1 mycroft while (i < xs->cmdlen) {
777 1.1 mycroft if (i)
778 1.1 mycroft printf(",");
779 1.1 mycroft printf("%x", b[i++]);
780 1.1 mycroft }
781 1.1 mycroft printf("-[%d bytes]\n", xs->datalen);
782 1.1 mycroft if (xs->datalen)
783 1.1 mycroft show_mem(xs->data, min(64, xs->datalen));
784 1.2 mycroft } else
785 1.1 mycroft printf("-RESET-\n");
786 1.1 mycroft }
787 1.1 mycroft
788 1.1 mycroft void
789 1.1 mycroft show_mem(address, num)
790 1.1 mycroft unsigned char *address;
791 1.1 mycroft u_int32 num;
792 1.1 mycroft {
793 1.1 mycroft u_int32 x, y;
794 1.1 mycroft printf("------------------------------");
795 1.1 mycroft for (y = 0; y < num; y += 1) {
796 1.1 mycroft if (!(y % 16))
797 1.1 mycroft printf("\n%03d: ", y);
798 1.1 mycroft printf("%02x ", *address++);
799 1.1 mycroft }
800 1.1 mycroft printf("\n------------------------------\n");
801 1.1 mycroft }
802 1.1 mycroft #endif /*SCSIDEBUG */
803