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