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