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