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