FreeBSD/Linux Kernel Cross Reference
sys/cam/cam_periph.c
1 /*-
2 * Common functions for CAM "type" (peripheral) drivers.
3 *
4 * Copyright (c) 1997, 1998 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 1999, 2000 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification, immediately at the beginning of the file.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD: releng/6.2/sys/cam/cam_periph.c 163183 2006-10-09 21:44:23Z mjacob $");
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/types.h>
36 #include <sys/malloc.h>
37 #include <sys/kernel.h>
38 #include <sys/linker_set.h>
39 #include <sys/bio.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 #include <sys/buf.h>
43 #include <sys/proc.h>
44 #include <sys/devicestat.h>
45 #include <sys/bus.h>
46 #include <vm/vm.h>
47 #include <vm/vm_extern.h>
48
49 #include <cam/cam.h>
50 #include <cam/cam_ccb.h>
51 #include <cam/cam_xpt_periph.h>
52 #include <cam/cam_periph.h>
53 #include <cam/cam_debug.h>
54
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_message.h>
57 #include <cam/scsi/scsi_pass.h>
58
59 static u_int camperiphnextunit(struct periph_driver *p_drv,
60 u_int newunit, int wired,
61 path_id_t pathid, target_id_t target,
62 lun_id_t lun);
63 static u_int camperiphunit(struct periph_driver *p_drv,
64 path_id_t pathid, target_id_t target,
65 lun_id_t lun);
66 static void camperiphdone(struct cam_periph *periph,
67 union ccb *done_ccb);
68 static void camperiphfree(struct cam_periph *periph);
69 static int camperiphscsistatuserror(union ccb *ccb,
70 cam_flags camflags,
71 u_int32_t sense_flags,
72 union ccb *save_ccb,
73 int *openings,
74 u_int32_t *relsim_flags,
75 u_int32_t *timeout);
76 static int camperiphscsisenseerror(union ccb *ccb,
77 cam_flags camflags,
78 u_int32_t sense_flags,
79 union ccb *save_ccb,
80 int *openings,
81 u_int32_t *relsim_flags,
82 u_int32_t *timeout);
83
84 static int nperiph_drivers;
85 struct periph_driver **periph_drivers;
86
87 MALLOC_DEFINE(M_CAMPERIPH, "CAM periph", "CAM peripheral buffers");
88
89 static int periph_selto_delay = 1000;
90 TUNABLE_INT("kern.cam.periph_selto_delay", &periph_selto_delay);
91 static int periph_noresrc_delay = 500;
92 TUNABLE_INT("kern.cam.periph_noresrc_delay", &periph_noresrc_delay);
93 static int periph_busy_delay = 500;
94 TUNABLE_INT("kern.cam.periph_busy_delay", &periph_busy_delay);
95
96
97 void
98 periphdriver_register(void *data)
99 {
100 struct periph_driver **newdrivers, **old;
101 int ndrivers;
102
103 ndrivers = nperiph_drivers + 2;
104 newdrivers = malloc(sizeof(*newdrivers) * ndrivers, M_TEMP, M_WAITOK);
105 if (periph_drivers)
106 bcopy(periph_drivers, newdrivers,
107 sizeof(*newdrivers) * nperiph_drivers);
108 newdrivers[nperiph_drivers] = (struct periph_driver *)data;
109 newdrivers[nperiph_drivers + 1] = NULL;
110 old = periph_drivers;
111 periph_drivers = newdrivers;
112 if (old)
113 free(old, M_TEMP);
114 nperiph_drivers++;
115 }
116
117 cam_status
118 cam_periph_alloc(periph_ctor_t *periph_ctor,
119 periph_oninv_t *periph_oninvalidate,
120 periph_dtor_t *periph_dtor, periph_start_t *periph_start,
121 char *name, cam_periph_type type, struct cam_path *path,
122 ac_callback_t *ac_callback, ac_code code, void *arg)
123 {
124 struct periph_driver **p_drv;
125 struct cam_periph *periph;
126 struct cam_periph *cur_periph;
127 path_id_t path_id;
128 target_id_t target_id;
129 lun_id_t lun_id;
130 cam_status status;
131 u_int init_level;
132 int s;
133
134 init_level = 0;
135 /*
136 * Handle Hot-Plug scenarios. If there is already a peripheral
137 * of our type assigned to this path, we are likely waiting for
138 * final close on an old, invalidated, peripheral. If this is
139 * the case, queue up a deferred call to the peripheral's async
140 * handler. If it looks like a mistaken re-allocation, complain.
141 */
142 if ((periph = cam_periph_find(path, name)) != NULL) {
143
144 if ((periph->flags & CAM_PERIPH_INVALID) != 0
145 && (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) == 0) {
146 periph->flags |= CAM_PERIPH_NEW_DEV_FOUND;
147 periph->deferred_callback = ac_callback;
148 periph->deferred_ac = code;
149 return (CAM_REQ_INPROG);
150 } else {
151 printf("cam_periph_alloc: attempt to re-allocate "
152 "valid device %s%d rejected\n",
153 periph->periph_name, periph->unit_number);
154 }
155 return (CAM_REQ_INVALID);
156 }
157
158 periph = (struct cam_periph *)malloc(sizeof(*periph), M_CAMPERIPH,
159 M_NOWAIT);
160
161 if (periph == NULL)
162 return (CAM_RESRC_UNAVAIL);
163
164 init_level++;
165
166 for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
167 if (strcmp((*p_drv)->driver_name, name) == 0)
168 break;
169 }
170
171 path_id = xpt_path_path_id(path);
172 target_id = xpt_path_target_id(path);
173 lun_id = xpt_path_lun_id(path);
174 bzero(periph, sizeof(*periph));
175 cam_init_pinfo(&periph->pinfo);
176 periph->periph_start = periph_start;
177 periph->periph_dtor = periph_dtor;
178 periph->periph_oninval = periph_oninvalidate;
179 periph->type = type;
180 periph->periph_name = name;
181 periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id);
182 periph->immediate_priority = CAM_PRIORITY_NONE;
183 periph->refcount = 0;
184 SLIST_INIT(&periph->ccb_list);
185 status = xpt_create_path(&path, periph, path_id, target_id, lun_id);
186 if (status != CAM_REQ_CMP)
187 goto failure;
188
189 periph->path = path;
190 init_level++;
191
192 status = xpt_add_periph(periph);
193
194 if (status != CAM_REQ_CMP)
195 goto failure;
196
197 s = splsoftcam();
198 cur_periph = TAILQ_FIRST(&(*p_drv)->units);
199 while (cur_periph != NULL
200 && cur_periph->unit_number < periph->unit_number)
201 cur_periph = TAILQ_NEXT(cur_periph, unit_links);
202
203 if (cur_periph != NULL)
204 TAILQ_INSERT_BEFORE(cur_periph, periph, unit_links);
205 else {
206 TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links);
207 (*p_drv)->generation++;
208 }
209
210 splx(s);
211
212 init_level++;
213
214 status = periph_ctor(periph, arg);
215
216 if (status == CAM_REQ_CMP)
217 init_level++;
218
219 failure:
220 switch (init_level) {
221 case 4:
222 /* Initialized successfully */
223 break;
224 case 3:
225 s = splsoftcam();
226 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
227 splx(s);
228 xpt_remove_periph(periph);
229 /* FALLTHROUGH */
230 case 2:
231 xpt_free_path(periph->path);
232 /* FALLTHROUGH */
233 case 1:
234 free(periph, M_CAMPERIPH);
235 /* FALLTHROUGH */
236 case 0:
237 /* No cleanup to perform. */
238 break;
239 default:
240 panic("cam_periph_alloc: Unkown init level");
241 }
242 return(status);
243 }
244
245 /*
246 * Find a peripheral structure with the specified path, target, lun,
247 * and (optionally) type. If the name is NULL, this function will return
248 * the first peripheral driver that matches the specified path.
249 */
250 struct cam_periph *
251 cam_periph_find(struct cam_path *path, char *name)
252 {
253 struct periph_driver **p_drv;
254 struct cam_periph *periph;
255 int s;
256
257 for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
258
259 if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0))
260 continue;
261
262 s = splsoftcam();
263 TAILQ_FOREACH(periph, &(*p_drv)->units, unit_links) {
264 if (xpt_path_comp(periph->path, path) == 0) {
265 splx(s);
266 return(periph);
267 }
268 }
269 splx(s);
270 if (name != NULL)
271 return(NULL);
272 }
273 return(NULL);
274 }
275
276 cam_status
277 cam_periph_acquire(struct cam_periph *periph)
278 {
279 int s;
280
281 if (periph == NULL)
282 return(CAM_REQ_CMP_ERR);
283
284 s = splsoftcam();
285 periph->refcount++;
286 splx(s);
287
288 return(CAM_REQ_CMP);
289 }
290
291 void
292 cam_periph_release(struct cam_periph *periph)
293 {
294 int s;
295
296 if (periph == NULL)
297 return;
298
299 s = splsoftcam();
300 if ((--periph->refcount == 0)
301 && (periph->flags & CAM_PERIPH_INVALID)) {
302 camperiphfree(periph);
303 }
304 splx(s);
305
306 }
307
308 /*
309 * Look for the next unit number that is not currently in use for this
310 * peripheral type starting at "newunit". Also exclude unit numbers that
311 * are reserved by for future "hardwiring" unless we already know that this
312 * is a potential wired device. Only assume that the device is "wired" the
313 * first time through the loop since after that we'll be looking at unit
314 * numbers that did not match a wiring entry.
315 */
316 static u_int
317 camperiphnextunit(struct periph_driver *p_drv, u_int newunit, int wired,
318 path_id_t pathid, target_id_t target, lun_id_t lun)
319 {
320 struct cam_periph *periph;
321 char *periph_name;
322 int s;
323 int i, val, dunit, r;
324 const char *dname, *strval;
325
326 s = splsoftcam();
327 periph_name = p_drv->driver_name;
328 for (;;newunit++) {
329
330 for (periph = TAILQ_FIRST(&p_drv->units);
331 periph != NULL && periph->unit_number != newunit;
332 periph = TAILQ_NEXT(periph, unit_links))
333 ;
334
335 if (periph != NULL && periph->unit_number == newunit) {
336 if (wired != 0) {
337 xpt_print_path(periph->path);
338 printf("Duplicate Wired Device entry!\n");
339 xpt_print_path(periph->path);
340 printf("Second device (%s device at scbus%d "
341 "target %d lun %d) will not be wired\n",
342 periph_name, pathid, target, lun);
343 wired = 0;
344 }
345 continue;
346 }
347 if (wired)
348 break;
349
350 /*
351 * Don't match entries like "da 4" as a wired down
352 * device, but do match entries like "da 4 target 5"
353 * or even "da 4 scbus 1".
354 */
355 i = 0;
356 dname = periph_name;
357 for (;;) {
358 r = resource_find_dev(&i, dname, &dunit, NULL, NULL);
359 if (r != 0)
360 break;
361 /* if no "target" and no specific scbus, skip */
362 if (resource_int_value(dname, dunit, "target", &val) &&
363 (resource_string_value(dname, dunit, "at",&strval)||
364 strcmp(strval, "scbus") == 0))
365 continue;
366 if (newunit == dunit)
367 break;
368 }
369 if (r != 0)
370 break;
371 }
372 splx(s);
373 return (newunit);
374 }
375
376 static u_int
377 camperiphunit(struct periph_driver *p_drv, path_id_t pathid,
378 target_id_t target, lun_id_t lun)
379 {
380 u_int unit;
381 int wired, i, val, dunit;
382 const char *dname, *strval;
383 char pathbuf[32], *periph_name;
384
385 periph_name = p_drv->driver_name;
386 snprintf(pathbuf, sizeof(pathbuf), "scbus%d", pathid);
387 unit = 0;
388 i = 0;
389 dname = periph_name;
390 for (wired = 0; resource_find_dev(&i, dname, &dunit, NULL, NULL) == 0;
391 wired = 0) {
392 if (resource_string_value(dname, dunit, "at", &strval) == 0) {
393 if (strcmp(strval, pathbuf) != 0)
394 continue;
395 wired++;
396 }
397 if (resource_int_value(dname, dunit, "target", &val) == 0) {
398 if (val != target)
399 continue;
400 wired++;
401 }
402 if (resource_int_value(dname, dunit, "lun", &val) == 0) {
403 if (val != lun)
404 continue;
405 wired++;
406 }
407 if (wired != 0) {
408 unit = dunit;
409 break;
410 }
411 }
412
413 /*
414 * Either start from 0 looking for the next unit or from
415 * the unit number given in the resource config. This way,
416 * if we have wildcard matches, we don't return the same
417 * unit number twice.
418 */
419 unit = camperiphnextunit(p_drv, unit, wired, pathid, target, lun);
420
421 return (unit);
422 }
423
424 void
425 cam_periph_invalidate(struct cam_periph *periph)
426 {
427 int s;
428
429 s = splsoftcam();
430 /*
431 * We only call this routine the first time a peripheral is
432 * invalidated. The oninvalidate() routine is always called at
433 * splsoftcam().
434 */
435 if (((periph->flags & CAM_PERIPH_INVALID) == 0)
436 && (periph->periph_oninval != NULL))
437 periph->periph_oninval(periph);
438
439 periph->flags |= CAM_PERIPH_INVALID;
440 periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND;
441
442 if (periph->refcount == 0)
443 camperiphfree(periph);
444 else if (periph->refcount < 0)
445 printf("cam_invalidate_periph: refcount < 0!!\n");
446 splx(s);
447 }
448
449 static void
450 camperiphfree(struct cam_periph *periph)
451 {
452 int s;
453 struct periph_driver **p_drv;
454
455 for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
456 if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0)
457 break;
458 }
459 if (*p_drv == NULL) {
460 printf("camperiphfree: attempt to free non-existant periph\n");
461 return;
462 }
463
464 if (periph->periph_dtor != NULL)
465 periph->periph_dtor(periph);
466
467 s = splsoftcam();
468 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
469 (*p_drv)->generation++;
470 splx(s);
471
472 xpt_remove_periph(periph);
473
474 if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) {
475 union ccb ccb;
476 void *arg;
477
478 switch (periph->deferred_ac) {
479 case AC_FOUND_DEVICE:
480 ccb.ccb_h.func_code = XPT_GDEV_TYPE;
481 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
482 xpt_action(&ccb);
483 arg = &ccb;
484 break;
485 case AC_PATH_REGISTERED:
486 ccb.ccb_h.func_code = XPT_PATH_INQ;
487 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
488 xpt_action(&ccb);
489 arg = &ccb;
490 break;
491 default:
492 arg = NULL;
493 break;
494 }
495 periph->deferred_callback(NULL, periph->deferred_ac,
496 periph->path, arg);
497 }
498 xpt_free_path(periph->path);
499 free(periph, M_CAMPERIPH);
500 }
501
502 /*
503 * Wait interruptibly for an exclusive lock.
504 */
505 int
506 cam_periph_lock(struct cam_periph *periph, int priority)
507 {
508 int error;
509
510 /*
511 * Increment the reference count on the peripheral
512 * while we wait for our lock attempt to succeed
513 * to ensure the peripheral doesn't disappear out
514 * from under us while we sleep.
515 */
516 if (cam_periph_acquire(periph) != CAM_REQ_CMP)
517 return(ENXIO);
518
519 while ((periph->flags & CAM_PERIPH_LOCKED) != 0) {
520 periph->flags |= CAM_PERIPH_LOCK_WANTED;
521 if ((error = tsleep(periph, priority, "caplck", 0)) != 0) {
522 cam_periph_release(periph);
523 return error;
524 }
525 }
526
527 periph->flags |= CAM_PERIPH_LOCKED;
528 return 0;
529 }
530
531 /*
532 * Unlock and wake up any waiters.
533 */
534 void
535 cam_periph_unlock(struct cam_periph *periph)
536 {
537 periph->flags &= ~CAM_PERIPH_LOCKED;
538 if ((periph->flags & CAM_PERIPH_LOCK_WANTED) != 0) {
539 periph->flags &= ~CAM_PERIPH_LOCK_WANTED;
540 wakeup(periph);
541 }
542
543 cam_periph_release(periph);
544 }
545
546 /*
547 * Map user virtual pointers into kernel virtual address space, so we can
548 * access the memory. This won't work on physical pointers, for now it's
549 * up to the caller to check for that. (XXX KDM -- should we do that here
550 * instead?) This also only works for up to MAXPHYS memory. Since we use
551 * buffers to map stuff in and out, we're limited to the buffer size.
552 */
553 int
554 cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
555 {
556 int numbufs, i, j;
557 int flags[CAM_PERIPH_MAXMAPS];
558 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
559 u_int32_t lengths[CAM_PERIPH_MAXMAPS];
560 u_int32_t dirs[CAM_PERIPH_MAXMAPS];
561
562 switch(ccb->ccb_h.func_code) {
563 case XPT_DEV_MATCH:
564 if (ccb->cdm.match_buf_len == 0) {
565 printf("cam_periph_mapmem: invalid match buffer "
566 "length 0\n");
567 return(EINVAL);
568 }
569 if (ccb->cdm.pattern_buf_len > 0) {
570 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns;
571 lengths[0] = ccb->cdm.pattern_buf_len;
572 dirs[0] = CAM_DIR_OUT;
573 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches;
574 lengths[1] = ccb->cdm.match_buf_len;
575 dirs[1] = CAM_DIR_IN;
576 numbufs = 2;
577 } else {
578 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches;
579 lengths[0] = ccb->cdm.match_buf_len;
580 dirs[0] = CAM_DIR_IN;
581 numbufs = 1;
582 }
583 break;
584 case XPT_SCSI_IO:
585 case XPT_CONT_TARGET_IO:
586 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
587 return(0);
588
589 data_ptrs[0] = &ccb->csio.data_ptr;
590 lengths[0] = ccb->csio.dxfer_len;
591 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
592 numbufs = 1;
593 break;
594 default:
595 return(EINVAL);
596 break; /* NOTREACHED */
597 }
598
599 /*
600 * Check the transfer length and permissions first, so we don't
601 * have to unmap any previously mapped buffers.
602 */
603 for (i = 0; i < numbufs; i++) {
604
605 flags[i] = 0;
606
607 /*
608 * The userland data pointer passed in may not be page
609 * aligned. vmapbuf() truncates the address to a page
610 * boundary, so if the address isn't page aligned, we'll
611 * need enough space for the given transfer length, plus
612 * whatever extra space is necessary to make it to the page
613 * boundary.
614 */
615 if ((lengths[i] +
616 (((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK)) > DFLTPHYS){
617 printf("cam_periph_mapmem: attempt to map %lu bytes, "
618 "which is greater than DFLTPHYS(%d)\n",
619 (long)(lengths[i] +
620 (((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK)),
621 DFLTPHYS);
622 return(E2BIG);
623 }
624
625 if (dirs[i] & CAM_DIR_OUT) {
626 flags[i] = BIO_WRITE;
627 }
628
629 if (dirs[i] & CAM_DIR_IN) {
630 flags[i] = BIO_READ;
631 }
632
633 }
634
635 /* this keeps the current process from getting swapped */
636 /*
637 * XXX KDM should I use P_NOSWAP instead?
638 */
639 PHOLD(curproc);
640
641 for (i = 0; i < numbufs; i++) {
642 /*
643 * Get the buffer.
644 */
645 mapinfo->bp[i] = getpbuf(NULL);
646
647 /* save the buffer's data address */
648 mapinfo->bp[i]->b_saveaddr = mapinfo->bp[i]->b_data;
649
650 /* put our pointer in the data slot */
651 mapinfo->bp[i]->b_data = *data_ptrs[i];
652
653 /* set the transfer length, we know it's < DFLTPHYS */
654 mapinfo->bp[i]->b_bufsize = lengths[i];
655
656 /* set the direction */
657 mapinfo->bp[i]->b_iocmd = flags[i];
658
659 /*
660 * Map the buffer into kernel memory.
661 *
662 * Note that useracc() alone is not a sufficient test.
663 * vmapbuf() can still fail due to a smaller file mapped
664 * into a larger area of VM, or if userland races against
665 * vmapbuf() after the useracc() check.
666 */
667 if (vmapbuf(mapinfo->bp[i]) < 0) {
668 for (j = 0; j < i; ++j) {
669 *data_ptrs[j] = mapinfo->bp[j]->b_saveaddr;
670 vunmapbuf(mapinfo->bp[j]);
671 relpbuf(mapinfo->bp[j], NULL);
672 }
673 relpbuf(mapinfo->bp[i], NULL);
674 PRELE(curproc);
675 return(EACCES);
676 }
677
678 /* set our pointer to the new mapped area */
679 *data_ptrs[i] = mapinfo->bp[i]->b_data;
680
681 mapinfo->num_bufs_used++;
682 }
683
684 return(0);
685 }
686
687 /*
688 * Unmap memory segments mapped into kernel virtual address space by
689 * cam_periph_mapmem().
690 */
691 void
692 cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
693 {
694 int numbufs, i;
695 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
696
697 if (mapinfo->num_bufs_used <= 0) {
698 /* allow ourselves to be swapped once again */
699 PRELE(curproc);
700 return;
701 }
702
703 switch (ccb->ccb_h.func_code) {
704 case XPT_DEV_MATCH:
705 numbufs = min(mapinfo->num_bufs_used, 2);
706
707 if (numbufs == 1) {
708 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches;
709 } else {
710 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns;
711 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches;
712 }
713 break;
714 case XPT_SCSI_IO:
715 case XPT_CONT_TARGET_IO:
716 data_ptrs[0] = &ccb->csio.data_ptr;
717 numbufs = min(mapinfo->num_bufs_used, 1);
718 break;
719 default:
720 /* allow ourselves to be swapped once again */
721 PRELE(curproc);
722 return;
723 break; /* NOTREACHED */
724 }
725
726 for (i = 0; i < numbufs; i++) {
727 /* Set the user's pointer back to the original value */
728 *data_ptrs[i] = mapinfo->bp[i]->b_saveaddr;
729
730 /* unmap the buffer */
731 vunmapbuf(mapinfo->bp[i]);
732
733 /* release the buffer */
734 relpbuf(mapinfo->bp[i], NULL);
735 }
736
737 /* allow ourselves to be swapped once again */
738 PRELE(curproc);
739 }
740
741 union ccb *
742 cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
743 {
744 struct ccb_hdr *ccb_h;
745 int s;
746
747 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdgetccb\n"));
748
749 s = splsoftcam();
750
751 while (SLIST_FIRST(&periph->ccb_list) == NULL) {
752 if (periph->immediate_priority > priority)
753 periph->immediate_priority = priority;
754 xpt_schedule(periph, priority);
755 if ((SLIST_FIRST(&periph->ccb_list) != NULL)
756 && (SLIST_FIRST(&periph->ccb_list)->pinfo.priority == priority))
757 break;
758 tsleep(&periph->ccb_list, PRIBIO, "cgticb", 0);
759 }
760
761 ccb_h = SLIST_FIRST(&periph->ccb_list);
762 SLIST_REMOVE_HEAD(&periph->ccb_list, periph_links.sle);
763 splx(s);
764 return ((union ccb *)ccb_h);
765 }
766
767 void
768 cam_periph_ccbwait(union ccb *ccb)
769 {
770 int s;
771
772 s = splsoftcam();
773 if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX)
774 || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG))
775 tsleep(&ccb->ccb_h.cbfcnp, PRIBIO, "cbwait", 0);
776
777 splx(s);
778 }
779
780 int
781 cam_periph_ioctl(struct cam_periph *periph, int cmd, caddr_t addr,
782 int (*error_routine)(union ccb *ccb,
783 cam_flags camflags,
784 u_int32_t sense_flags))
785 {
786 union ccb *ccb;
787 int error;
788 int found;
789
790 error = found = 0;
791
792 switch(cmd){
793 case CAMGETPASSTHRU:
794 ccb = cam_periph_getccb(periph, /* priority */ 1);
795 xpt_setup_ccb(&ccb->ccb_h,
796 ccb->ccb_h.path,
797 /*priority*/1);
798 ccb->ccb_h.func_code = XPT_GDEVLIST;
799
800 /*
801 * Basically, the point of this is that we go through
802 * getting the list of devices, until we find a passthrough
803 * device. In the current version of the CAM code, the
804 * only way to determine what type of device we're dealing
805 * with is by its name.
806 */
807 while (found == 0) {
808 ccb->cgdl.index = 0;
809 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
810 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
811
812 /* we want the next device in the list */
813 xpt_action(ccb);
814 if (strncmp(ccb->cgdl.periph_name,
815 "pass", 4) == 0){
816 found = 1;
817 break;
818 }
819 }
820 if ((ccb->cgdl.status == CAM_GDEVLIST_LAST_DEVICE) &&
821 (found == 0)) {
822 ccb->cgdl.periph_name[0] = '\0';
823 ccb->cgdl.unit_number = 0;
824 break;
825 }
826 }
827
828 /* copy the result back out */
829 bcopy(ccb, addr, sizeof(union ccb));
830
831 /* and release the ccb */
832 xpt_release_ccb(ccb);
833
834 break;
835 default:
836 error = ENOTTY;
837 break;
838 }
839 return(error);
840 }
841
842 int
843 cam_periph_runccb(union ccb *ccb,
844 int (*error_routine)(union ccb *ccb,
845 cam_flags camflags,
846 u_int32_t sense_flags),
847 cam_flags camflags, u_int32_t sense_flags,
848 struct devstat *ds)
849 {
850 int error;
851
852 error = 0;
853
854 /*
855 * If the user has supplied a stats structure, and if we understand
856 * this particular type of ccb, record the transaction start.
857 */
858 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO))
859 devstat_start_transaction(ds, NULL);
860
861 xpt_action(ccb);
862
863 do {
864 cam_periph_ccbwait(ccb);
865 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
866 error = 0;
867 else if (error_routine != NULL)
868 error = (*error_routine)(ccb, camflags, sense_flags);
869 else
870 error = 0;
871
872 } while (error == ERESTART);
873
874 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
875 cam_release_devq(ccb->ccb_h.path,
876 /* relsim_flags */0,
877 /* openings */0,
878 /* timeout */0,
879 /* getcount_only */ FALSE);
880
881 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO))
882 devstat_end_transaction(ds,
883 ccb->csio.dxfer_len,
884 ccb->csio.tag_action & 0xf,
885 ((ccb->ccb_h.flags & CAM_DIR_MASK) ==
886 CAM_DIR_NONE) ? DEVSTAT_NO_DATA :
887 (ccb->ccb_h.flags & CAM_DIR_OUT) ?
888 DEVSTAT_WRITE :
889 DEVSTAT_READ, NULL, NULL);
890
891 return(error);
892 }
893
894 void
895 cam_freeze_devq(struct cam_path *path)
896 {
897 struct ccb_hdr ccb_h;
898
899 xpt_setup_ccb(&ccb_h, path, /*priority*/1);
900 ccb_h.func_code = XPT_NOOP;
901 ccb_h.flags = CAM_DEV_QFREEZE;
902 xpt_action((union ccb *)&ccb_h);
903 }
904
905 u_int32_t
906 cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
907 u_int32_t openings, u_int32_t timeout,
908 int getcount_only)
909 {
910 struct ccb_relsim crs;
911
912 xpt_setup_ccb(&crs.ccb_h, path,
913 /*priority*/1);
914 crs.ccb_h.func_code = XPT_REL_SIMQ;
915 crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0;
916 crs.release_flags = relsim_flags;
917 crs.openings = openings;
918 crs.release_timeout = timeout;
919 xpt_action((union ccb *)&crs);
920 return (crs.qfrozen_cnt);
921 }
922
923 #define saved_ccb_ptr ppriv_ptr0
924 static void
925 camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
926 {
927 union ccb *saved_ccb;
928 cam_status status;
929 int frozen;
930 int sense;
931 struct scsi_start_stop_unit *scsi_cmd;
932 u_int32_t relsim_flags, timeout;
933 u_int32_t qfrozen_cnt;
934 int xpt_done_ccb;
935
936 xpt_done_ccb = FALSE;
937 status = done_ccb->ccb_h.status;
938 frozen = (status & CAM_DEV_QFRZN) != 0;
939 sense = (status & CAM_AUTOSNS_VALID) != 0;
940 status &= CAM_STATUS_MASK;
941
942 timeout = 0;
943 relsim_flags = 0;
944 saved_ccb = (union ccb *)done_ccb->ccb_h.saved_ccb_ptr;
945
946 /*
947 * Unfreeze the queue once if it is already frozen..
948 */
949 if (frozen != 0) {
950 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
951 /*relsim_flags*/0,
952 /*openings*/0,
953 /*timeout*/0,
954 /*getcount_only*/0);
955 }
956
957 switch (status) {
958 case CAM_REQ_CMP:
959 {
960 /*
961 * If we have successfully taken a device from the not
962 * ready to ready state, re-scan the device and re-get
963 * the inquiry information. Many devices (mostly disks)
964 * don't properly report their inquiry information unless
965 * they are spun up.
966 *
967 * If we manually retrieved sense into a CCB and got
968 * something other than "NO SENSE" send the updated CCB
969 * back to the client via xpt_done() to be processed via
970 * the error recovery code again.
971 */
972 if (done_ccb->ccb_h.func_code == XPT_SCSI_IO) {
973 scsi_cmd = (struct scsi_start_stop_unit *)
974 &done_ccb->csio.cdb_io.cdb_bytes;
975
976 if (scsi_cmd->opcode == START_STOP_UNIT)
977 xpt_async(AC_INQ_CHANGED,
978 done_ccb->ccb_h.path, NULL);
979 if (scsi_cmd->opcode == REQUEST_SENSE) {
980 u_int sense_key;
981
982 sense_key = saved_ccb->csio.sense_data.flags;
983 sense_key &= SSD_KEY;
984 if (sense_key != SSD_KEY_NO_SENSE) {
985 saved_ccb->ccb_h.status |=
986 CAM_AUTOSNS_VALID;
987 #if 0
988 xpt_print_path(saved_ccb->ccb_h.path);
989 printf("Recovered Sense\n");
990 scsi_sense_print(&saved_ccb->csio);
991 cam_error_print(saved_ccb, CAM_ESF_ALL,
992 CAM_EPF_ALL);
993 #endif
994 xpt_done_ccb = TRUE;
995 }
996 }
997 }
998 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
999 sizeof(union ccb));
1000
1001 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
1002
1003 if (xpt_done_ccb == FALSE)
1004 xpt_action(done_ccb);
1005
1006 break;
1007 }
1008 case CAM_SCSI_STATUS_ERROR:
1009 scsi_cmd = (struct scsi_start_stop_unit *)
1010 &done_ccb->csio.cdb_io.cdb_bytes;
1011 if (sense != 0) {
1012 struct ccb_getdev cgd;
1013 struct scsi_sense_data *sense;
1014 int error_code, sense_key, asc, ascq;
1015 scsi_sense_action err_action;
1016
1017 sense = &done_ccb->csio.sense_data;
1018 scsi_extract_sense(sense, &error_code,
1019 &sense_key, &asc, &ascq);
1020
1021 /*
1022 * Grab the inquiry data for this device.
1023 */
1024 xpt_setup_ccb(&cgd.ccb_h, done_ccb->ccb_h.path,
1025 /*priority*/ 1);
1026 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1027 xpt_action((union ccb *)&cgd);
1028 err_action = scsi_error_action(&done_ccb->csio,
1029 &cgd.inq_data, 0);
1030
1031 /*
1032 * If the error is "invalid field in CDB",
1033 * and the load/eject flag is set, turn the
1034 * flag off and try again. This is just in
1035 * case the drive in question barfs on the
1036 * load eject flag. The CAM code should set
1037 * the load/eject flag by default for
1038 * removable media.
1039 */
1040
1041 /* XXX KDM
1042 * Should we check to see what the specific
1043 * scsi status is?? Or does it not matter
1044 * since we already know that there was an
1045 * error, and we know what the specific
1046 * error code was, and we know what the
1047 * opcode is..
1048 */
1049 if ((scsi_cmd->opcode == START_STOP_UNIT) &&
1050 ((scsi_cmd->how & SSS_LOEJ) != 0) &&
1051 (asc == 0x24) && (ascq == 0x00) &&
1052 (done_ccb->ccb_h.retry_count > 0)) {
1053
1054 scsi_cmd->how &= ~SSS_LOEJ;
1055
1056 xpt_action(done_ccb);
1057
1058 } else if ((done_ccb->ccb_h.retry_count > 1)
1059 && ((err_action & SS_MASK) != SS_FAIL)) {
1060
1061 /*
1062 * In this case, the error recovery
1063 * command failed, but we've got
1064 * some retries left on it. Give
1065 * it another try unless this is an
1066 * unretryable error.
1067 */
1068
1069 /* set the timeout to .5 sec */
1070 relsim_flags =
1071 RELSIM_RELEASE_AFTER_TIMEOUT;
1072 timeout = 500;
1073
1074 xpt_action(done_ccb);
1075
1076 break;
1077
1078 } else {
1079 /*
1080 * Perform the final retry with the original
1081 * CCB so that final error processing is
1082 * performed by the owner of the CCB.
1083 */
1084 bcopy(done_ccb->ccb_h.saved_ccb_ptr,
1085 done_ccb, sizeof(union ccb));
1086
1087 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
1088
1089 xpt_action(done_ccb);
1090 }
1091 } else {
1092 /*
1093 * Eh?? The command failed, but we don't
1094 * have any sense. What's up with that?
1095 * Fire the CCB again to return it to the
1096 * caller.
1097 */
1098 bcopy(done_ccb->ccb_h.saved_ccb_ptr,
1099 done_ccb, sizeof(union ccb));
1100
1101 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
1102
1103 xpt_action(done_ccb);
1104
1105 }
1106 break;
1107 default:
1108 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
1109 sizeof(union ccb));
1110
1111 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
1112
1113 xpt_action(done_ccb);
1114
1115 break;
1116 }
1117
1118 /* decrement the retry count */
1119 /*
1120 * XXX This isn't appropriate in all cases. Restructure,
1121 * so that the retry count is only decremented on an
1122 * actual retry. Remeber that the orignal ccb had its
1123 * retry count dropped before entering recovery, so
1124 * doing it again is a bug.
1125 */
1126 if (done_ccb->ccb_h.retry_count > 0)
1127 done_ccb->ccb_h.retry_count--;
1128
1129 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
1130 /*relsim_flags*/relsim_flags,
1131 /*openings*/0,
1132 /*timeout*/timeout,
1133 /*getcount_only*/0);
1134 if (xpt_done_ccb == TRUE)
1135 (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb);
1136 }
1137
1138 /*
1139 * Generic Async Event handler. Peripheral drivers usually
1140 * filter out the events that require personal attention,
1141 * and leave the rest to this function.
1142 */
1143 void
1144 cam_periph_async(struct cam_periph *periph, u_int32_t code,
1145 struct cam_path *path, void *arg)
1146 {
1147 switch (code) {
1148 case AC_LOST_DEVICE:
1149 cam_periph_invalidate(periph);
1150 break;
1151 case AC_SENT_BDR:
1152 case AC_BUS_RESET:
1153 {
1154 cam_periph_bus_settle(periph, scsi_delay);
1155 break;
1156 }
1157 default:
1158 break;
1159 }
1160 }
1161
1162 void
1163 cam_periph_bus_settle(struct cam_periph *periph, u_int bus_settle)
1164 {
1165 struct ccb_getdevstats cgds;
1166
1167 xpt_setup_ccb(&cgds.ccb_h, periph->path, /*priority*/1);
1168 cgds.ccb_h.func_code = XPT_GDEV_STATS;
1169 xpt_action((union ccb *)&cgds);
1170 cam_periph_freeze_after_event(periph, &cgds.last_reset, bus_settle);
1171 }
1172
1173 void
1174 cam_periph_freeze_after_event(struct cam_periph *periph,
1175 struct timeval* event_time, u_int duration_ms)
1176 {
1177 struct timeval delta;
1178 struct timeval duration_tv;
1179 int s;
1180
1181 s = splclock();
1182 microtime(&delta);
1183 splx(s);
1184 timevalsub(&delta, event_time);
1185 duration_tv.tv_sec = duration_ms / 1000;
1186 duration_tv.tv_usec = (duration_ms % 1000) * 1000;
1187 if (timevalcmp(&delta, &duration_tv, <)) {
1188 timevalsub(&duration_tv, &delta);
1189
1190 duration_ms = duration_tv.tv_sec * 1000;
1191 duration_ms += duration_tv.tv_usec / 1000;
1192 cam_freeze_devq(periph->path);
1193 cam_release_devq(periph->path,
1194 RELSIM_RELEASE_AFTER_TIMEOUT,
1195 /*reduction*/0,
1196 /*timeout*/duration_ms,
1197 /*getcount_only*/0);
1198 }
1199
1200 }
1201
1202 static int
1203 camperiphscsistatuserror(union ccb *ccb, cam_flags camflags,
1204 u_int32_t sense_flags, union ccb *save_ccb,
1205 int *openings, u_int32_t *relsim_flags,
1206 u_int32_t *timeout)
1207 {
1208 int error;
1209
1210 switch (ccb->csio.scsi_status) {
1211 case SCSI_STATUS_OK:
1212 case SCSI_STATUS_COND_MET:
1213 case SCSI_STATUS_INTERMED:
1214 case SCSI_STATUS_INTERMED_COND_MET:
1215 error = 0;
1216 break;
1217 case SCSI_STATUS_CMD_TERMINATED:
1218 case SCSI_STATUS_CHECK_COND:
1219 error = camperiphscsisenseerror(ccb,
1220 camflags,
1221 sense_flags,
1222 save_ccb,
1223 openings,
1224 relsim_flags,
1225 timeout);
1226 break;
1227 case SCSI_STATUS_QUEUE_FULL:
1228 {
1229 /* no decrement */
1230 struct ccb_getdevstats cgds;
1231
1232 /*
1233 * First off, find out what the current
1234 * transaction counts are.
1235 */
1236 xpt_setup_ccb(&cgds.ccb_h,
1237 ccb->ccb_h.path,
1238 /*priority*/1);
1239 cgds.ccb_h.func_code = XPT_GDEV_STATS;
1240 xpt_action((union ccb *)&cgds);
1241
1242 /*
1243 * If we were the only transaction active, treat
1244 * the QUEUE FULL as if it were a BUSY condition.
1245 */
1246 if (cgds.dev_active != 0) {
1247 int total_openings;
1248
1249 /*
1250 * Reduce the number of openings to
1251 * be 1 less than the amount it took
1252 * to get a queue full bounded by the
1253 * minimum allowed tag count for this
1254 * device.
1255 */
1256 total_openings = cgds.dev_active + cgds.dev_openings;
1257 *openings = cgds.dev_active;
1258 if (*openings < cgds.mintags)
1259 *openings = cgds.mintags;
1260 if (*openings < total_openings)
1261 *relsim_flags = RELSIM_ADJUST_OPENINGS;
1262 else {
1263 /*
1264 * Some devices report queue full for
1265 * temporary resource shortages. For
1266 * this reason, we allow a minimum
1267 * tag count to be entered via a
1268 * quirk entry to prevent the queue
1269 * count on these devices from falling
1270 * to a pessimisticly low value. We
1271 * still wait for the next successful
1272 * completion, however, before queueing
1273 * more transactions to the device.
1274 */
1275 *relsim_flags = RELSIM_RELEASE_AFTER_CMDCMPLT;
1276 }
1277 *timeout = 0;
1278 error = ERESTART;
1279 if (bootverbose) {
1280 xpt_print_path(ccb->ccb_h.path);
1281 printf("Queue Full\n");
1282 }
1283 break;
1284 }
1285 /* FALLTHROUGH */
1286 }
1287 case SCSI_STATUS_BUSY:
1288 /*
1289 * Restart the queue after either another
1290 * command completes or a 1 second timeout.
1291 */
1292 if (bootverbose) {
1293 xpt_print_path(ccb->ccb_h.path);
1294 printf("Device Busy\n");
1295 }
1296 if (ccb->ccb_h.retry_count > 0) {
1297 ccb->ccb_h.retry_count--;
1298 error = ERESTART;
1299 *relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT
1300 | RELSIM_RELEASE_AFTER_CMDCMPLT;
1301 *timeout = 1000;
1302 } else {
1303 error = EIO;
1304 }
1305 break;
1306 case SCSI_STATUS_RESERV_CONFLICT:
1307 xpt_print_path(ccb->ccb_h.path);
1308 printf("Reservation Conflict\n");
1309 error = EIO;
1310 break;
1311 default:
1312 xpt_print_path(ccb->ccb_h.path);
1313 printf("SCSI Status 0x%x\n", ccb->csio.scsi_status);
1314 error = EIO;
1315 break;
1316 }
1317 return (error);
1318 }
1319
1320 static int
1321 camperiphscsisenseerror(union ccb *ccb, cam_flags camflags,
1322 u_int32_t sense_flags, union ccb *save_ccb,
1323 int *openings, u_int32_t *relsim_flags,
1324 u_int32_t *timeout)
1325 {
1326 struct cam_periph *periph;
1327 int error;
1328
1329 periph = xpt_path_periph(ccb->ccb_h.path);
1330 if (periph->flags & CAM_PERIPH_RECOVERY_INPROG) {
1331
1332 /*
1333 * If error recovery is already in progress, don't attempt
1334 * to process this error, but requeue it unconditionally
1335 * and attempt to process it once error recovery has
1336 * completed. This failed command is probably related to
1337 * the error that caused the currently active error recovery
1338 * action so our current recovery efforts should also
1339 * address this command. Be aware that the error recovery
1340 * code assumes that only one recovery action is in progress
1341 * on a particular peripheral instance at any given time
1342 * (e.g. only one saved CCB for error recovery) so it is
1343 * imperitive that we don't violate this assumption.
1344 */
1345 error = ERESTART;
1346 } else {
1347 scsi_sense_action err_action;
1348 struct ccb_getdev cgd;
1349 const char *action_string;
1350 union ccb* print_ccb;
1351
1352 /* A description of the error recovery action performed */
1353 action_string = NULL;
1354
1355 /*
1356 * The location of the orignal ccb
1357 * for sense printing purposes.
1358 */
1359 print_ccb = ccb;
1360
1361 /*
1362 * Grab the inquiry data for this device.
1363 */
1364 xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path, /*priority*/ 1);
1365 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1366 xpt_action((union ccb *)&cgd);
1367
1368 if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)
1369 err_action = scsi_error_action(&ccb->csio,
1370 &cgd.inq_data,
1371 sense_flags);
1372 else if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1373 err_action = SS_REQSENSE;
1374 else
1375 err_action = SS_RETRY|SSQ_DECREMENT_COUNT|EIO;
1376
1377 error = err_action & SS_ERRMASK;
1378
1379 /*
1380 * If the recovery action will consume a retry,
1381 * make sure we actually have retries available.
1382 */
1383 if ((err_action & SSQ_DECREMENT_COUNT) != 0) {
1384 if (ccb->ccb_h.retry_count > 0)
1385 ccb->ccb_h.retry_count--;
1386 else {
1387 action_string = "Retries Exhausted";
1388 goto sense_error_done;
1389 }
1390 }
1391
1392 if ((err_action & SS_MASK) >= SS_START) {
1393 /*
1394 * Do common portions of commands that
1395 * use recovery CCBs.
1396 */
1397 if (save_ccb == NULL) {
1398 action_string = "No recovery CCB supplied";
1399 goto sense_error_done;
1400 }
1401 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1402 print_ccb = save_ccb;
1403 periph->flags |= CAM_PERIPH_RECOVERY_INPROG;
1404 }
1405
1406 switch (err_action & SS_MASK) {
1407 case SS_NOP:
1408 action_string = "No Recovery Action Needed";
1409 error = 0;
1410 break;
1411 case SS_RETRY:
1412 action_string = "Retrying Command (per Sense Data)";
1413 error = ERESTART;
1414 break;
1415 case SS_FAIL:
1416 action_string = "Unretryable error";
1417 break;
1418 case SS_START:
1419 {
1420 int le;
1421
1422 /*
1423 * Send a start unit command to the device, and
1424 * then retry the command.
1425 */
1426 action_string = "Attempting to Start Unit";
1427
1428 /*
1429 * Check for removable media and set
1430 * load/eject flag appropriately.
1431 */
1432 if (SID_IS_REMOVABLE(&cgd.inq_data))
1433 le = TRUE;
1434 else
1435 le = FALSE;
1436
1437 scsi_start_stop(&ccb->csio,
1438 /*retries*/1,
1439 camperiphdone,
1440 MSG_SIMPLE_Q_TAG,
1441 /*start*/TRUE,
1442 /*load/eject*/le,
1443 /*immediate*/FALSE,
1444 SSD_FULL_SIZE,
1445 /*timeout*/50000);
1446 break;
1447 }
1448 case SS_TUR:
1449 {
1450 /*
1451 * Send a Test Unit Ready to the device.
1452 * If the 'many' flag is set, we send 120
1453 * test unit ready commands, one every half
1454 * second. Otherwise, we just send one TUR.
1455 * We only want to do this if the retry
1456 * count has not been exhausted.
1457 */
1458 int retries;
1459
1460 if ((err_action & SSQ_MANY) != 0) {
1461 action_string = "Polling device for readiness";
1462 retries = 120;
1463 } else {
1464 action_string = "Testing device for readiness";
1465 retries = 1;
1466 }
1467 scsi_test_unit_ready(&ccb->csio,
1468 retries,
1469 camperiphdone,
1470 MSG_SIMPLE_Q_TAG,
1471 SSD_FULL_SIZE,
1472 /*timeout*/5000);
1473
1474 /*
1475 * Accomplish our 500ms delay by deferring
1476 * the release of our device queue appropriately.
1477 */
1478 *relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
1479 *timeout = 500;
1480 break;
1481 }
1482 case SS_REQSENSE:
1483 {
1484 /*
1485 * Send a Request Sense to the device. We
1486 * assume that we are in a contingent allegiance
1487 * condition so we do not tag this request.
1488 */
1489 scsi_request_sense(&ccb->csio, /*retries*/1,
1490 camperiphdone,
1491 &save_ccb->csio.sense_data,
1492 sizeof(save_ccb->csio.sense_data),
1493 CAM_TAG_ACTION_NONE,
1494 /*sense_len*/SSD_FULL_SIZE,
1495 /*timeout*/5000);
1496 break;
1497 }
1498 default:
1499 panic("Unhandled error action %x", err_action);
1500 }
1501
1502 if ((err_action & SS_MASK) >= SS_START) {
1503 /*
1504 * Drop the priority to 0 so that the recovery
1505 * CCB is the first to execute. Freeze the queue
1506 * after this command is sent so that we can
1507 * restore the old csio and have it queued in
1508 * the proper order before we release normal
1509 * transactions to the device.
1510 */
1511 ccb->ccb_h.pinfo.priority = 0;
1512 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1513 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1514 error = ERESTART;
1515 }
1516
1517 sense_error_done:
1518 if ((err_action & SSQ_PRINT_SENSE) != 0
1519 && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) {
1520 cam_error_print(print_ccb, CAM_ESF_ALL, CAM_EPF_ALL);
1521 xpt_print_path(ccb->ccb_h.path);
1522 if (bootverbose)
1523 scsi_sense_print(&print_ccb->csio);
1524 printf("%s\n", action_string);
1525 }
1526 }
1527 return (error);
1528 }
1529
1530 /*
1531 * Generic error handler. Peripheral drivers usually filter
1532 * out the errors that they handle in a unique mannor, then
1533 * call this function.
1534 */
1535 int
1536 cam_periph_error(union ccb *ccb, cam_flags camflags,
1537 u_int32_t sense_flags, union ccb *save_ccb)
1538 {
1539 const char *action_string;
1540 cam_status status;
1541 int frozen;
1542 int error, printed = 0;
1543 int openings;
1544 u_int32_t relsim_flags;
1545 u_int32_t timeout = 0;
1546
1547 action_string = NULL;
1548 status = ccb->ccb_h.status;
1549 frozen = (status & CAM_DEV_QFRZN) != 0;
1550 status &= CAM_STATUS_MASK;
1551 openings = relsim_flags = 0;
1552
1553 switch (status) {
1554 case CAM_REQ_CMP:
1555 error = 0;
1556 break;
1557 case CAM_SCSI_STATUS_ERROR:
1558 error = camperiphscsistatuserror(ccb,
1559 camflags,
1560 sense_flags,
1561 save_ccb,
1562 &openings,
1563 &relsim_flags,
1564 &timeout);
1565 break;
1566 case CAM_AUTOSENSE_FAIL:
1567 xpt_print_path(ccb->ccb_h.path);
1568 printf("AutoSense Failed\n");
1569 error = EIO; /* we have to kill the command */
1570 break;
1571 case CAM_REQ_CMP_ERR:
1572 if (bootverbose && printed == 0) {
1573 xpt_print_path(ccb->ccb_h.path);
1574 printf("Request completed with CAM_REQ_CMP_ERR\n");
1575 printed++;
1576 }
1577 /* FALLTHROUGH */
1578 case CAM_CMD_TIMEOUT:
1579 if (bootverbose && printed == 0) {
1580 xpt_print_path(ccb->ccb_h.path);
1581 printf("Command timed out\n");
1582 printed++;
1583 }
1584 /* FALLTHROUGH */
1585 case CAM_UNEXP_BUSFREE:
1586 if (bootverbose && printed == 0) {
1587 xpt_print_path(ccb->ccb_h.path);
1588 printf("Unexpected Bus Free\n");
1589 printed++;
1590 }
1591 /* FALLTHROUGH */
1592 case CAM_UNCOR_PARITY:
1593 if (bootverbose && printed == 0) {
1594 xpt_print_path(ccb->ccb_h.path);
1595 printf("Uncorrected Parity Error\n");
1596 printed++;
1597 }
1598 /* FALLTHROUGH */
1599 case CAM_DATA_RUN_ERR:
1600 if (bootverbose && printed == 0) {
1601 xpt_print_path(ccb->ccb_h.path);
1602 printf("Data Overrun\n");
1603 printed++;
1604 }
1605 error = EIO; /* we have to kill the command */
1606 /* decrement the number of retries */
1607 if (ccb->ccb_h.retry_count > 0) {
1608 ccb->ccb_h.retry_count--;
1609 error = ERESTART;
1610 } else {
1611 action_string = "Retries Exausted";
1612 error = EIO;
1613 }
1614 break;
1615 case CAM_UA_ABORT:
1616 case CAM_UA_TERMIO:
1617 case CAM_MSG_REJECT_REC:
1618 /* XXX Don't know that these are correct */
1619 error = EIO;
1620 break;
1621 case CAM_SEL_TIMEOUT:
1622 {
1623 struct cam_path *newpath;
1624
1625 if ((camflags & CAM_RETRY_SELTO) != 0) {
1626 if (ccb->ccb_h.retry_count > 0) {
1627
1628 ccb->ccb_h.retry_count--;
1629 error = ERESTART;
1630 if (bootverbose && printed == 0) {
1631 xpt_print_path(ccb->ccb_h.path);
1632 printf("Selection Timeout\n");
1633 printed++;
1634 }
1635
1636 /*
1637 * Wait a bit to give the device
1638 * time to recover before we try again.
1639 */
1640 relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
1641 timeout = periph_selto_delay;
1642 break;
1643 }
1644 }
1645 error = ENXIO;
1646 /* Should we do more if we can't create the path?? */
1647 if (xpt_create_path(&newpath, xpt_path_periph(ccb->ccb_h.path),
1648 xpt_path_path_id(ccb->ccb_h.path),
1649 xpt_path_target_id(ccb->ccb_h.path),
1650 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
1651 break;
1652
1653 /*
1654 * Let peripheral drivers know that this device has gone
1655 * away.
1656 */
1657 xpt_async(AC_LOST_DEVICE, newpath, NULL);
1658 xpt_free_path(newpath);
1659 break;
1660 }
1661 case CAM_REQ_INVALID:
1662 case CAM_PATH_INVALID:
1663 case CAM_DEV_NOT_THERE:
1664 case CAM_NO_HBA:
1665 case CAM_PROVIDE_FAIL:
1666 case CAM_REQ_TOO_BIG:
1667 case CAM_LUN_INVALID:
1668 case CAM_TID_INVALID:
1669 error = EINVAL;
1670 break;
1671 case CAM_SCSI_BUS_RESET:
1672 case CAM_BDR_SENT:
1673 /*
1674 * Commands that repeatedly timeout and cause these
1675 * kinds of error recovery actions, should return
1676 * CAM_CMD_TIMEOUT, which allows us to safely assume
1677 * that this command was an innocent bystander to
1678 * these events and should be unconditionally
1679 * retried.
1680 */
1681 if (bootverbose && printed == 0) {
1682 xpt_print_path(ccb->ccb_h.path);
1683 if (status == CAM_BDR_SENT)
1684 printf("Bus Device Reset sent\n");
1685 else
1686 printf("Bus Reset issued\n");
1687 printed++;
1688 }
1689 /* FALLTHROUGH */
1690 case CAM_REQUEUE_REQ:
1691 /* Unconditional requeue */
1692 error = ERESTART;
1693 if (bootverbose && printed == 0) {
1694 xpt_print_path(ccb->ccb_h.path);
1695 printf("Request Requeued\n");
1696 printed++;
1697 }
1698 break;
1699 case CAM_RESRC_UNAVAIL:
1700 /* Wait a bit for the resource shortage to abate. */
1701 timeout = periph_noresrc_delay;
1702 /* FALLTHROUGH */
1703 case CAM_BUSY:
1704 if (timeout == 0) {
1705 /* Wait a bit for the busy condition to abate. */
1706 timeout = periph_busy_delay;
1707 }
1708 relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
1709 /* FALLTHROUGH */
1710 default:
1711 /* decrement the number of retries */
1712 if (ccb->ccb_h.retry_count > 0) {
1713 ccb->ccb_h.retry_count--;
1714 error = ERESTART;
1715 if (bootverbose && printed == 0) {
1716 xpt_print_path(ccb->ccb_h.path);
1717 printf("CAM Status 0x%x\n", status);
1718 printed++;
1719 }
1720 } else {
1721 error = EIO;
1722 action_string = "Retries Exhausted";
1723 }
1724 break;
1725 }
1726
1727 /* Attempt a retry */
1728 if (error == ERESTART || error == 0) {
1729 if (frozen != 0)
1730 ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
1731
1732 if (error == ERESTART) {
1733 action_string = "Retrying Command";
1734 xpt_action(ccb);
1735 }
1736
1737 if (frozen != 0)
1738 cam_release_devq(ccb->ccb_h.path,
1739 relsim_flags,
1740 openings,
1741 timeout,
1742 /*getcount_only*/0);
1743 }
1744
1745 /*
1746 * If we have and error and are booting verbosely, whine
1747 * *unless* this was a non-retryable selection timeout.
1748 */
1749 if (error != 0 && bootverbose &&
1750 !(status == CAM_SEL_TIMEOUT && (camflags & CAM_RETRY_SELTO) == 0)) {
1751
1752
1753 if (action_string == NULL)
1754 action_string = "Unretryable Error";
1755 if (error != ERESTART) {
1756 xpt_print_path(ccb->ccb_h.path);
1757 printf("error %d\n", error);
1758 }
1759 xpt_print_path(ccb->ccb_h.path);
1760 printf("%s\n", action_string);
1761 }
1762
1763 return (error);
1764 }
Cache object: aa7d60568b808a99687fcb9c3b5a06cf
|