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