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