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