2 * Implementation of the Common Access Method Transport (XPT) layer.
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/types.h>
37 #include <sys/malloc.h>
38 #include <sys/kernel.h>
41 #include <sys/fcntl.h>
43 #include <sys/interrupt.h>
45 #include <sys/taskqueue.h>
48 #include <sys/mutex.h>
49 #include <sys/sysctl.h>
50 #include <sys/kthread.h>
53 #include <pc98/pc98/pc98_machdep.h> /* geometry translation */
57 #include <cam/cam_ccb.h>
58 #include <cam/cam_periph.h>
59 #include <cam/cam_queue.h>
60 #include <cam/cam_sim.h>
61 #include <cam/cam_xpt.h>
62 #include <cam/cam_xpt_sim.h>
63 #include <cam/cam_xpt_periph.h>
64 #include <cam/cam_xpt_internal.h>
65 #include <cam/cam_debug.h>
67 #include <cam/scsi/scsi_all.h>
68 #include <cam/scsi/scsi_message.h>
69 #include <cam/scsi/scsi_pass.h>
70 #include <machine/stdarg.h> /* for xpt_print below */
74 * This is the maximum number of high powered commands (e.g. start unit)
75 * that can be outstanding at a particular time.
77 #ifndef CAM_MAX_HIGHPOWER
78 #define CAM_MAX_HIGHPOWER 4
81 /* Datastructures internal to the xpt layer */
82 MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers");
84 /* Object for defering XPT actions to a taskqueue */
97 u_int32_t xpt_generation;
99 /* number of high powered commands that can go through right now */
100 STAILQ_HEAD(highpowerlist, ccb_hdr) highpowerq;
103 /* queue for handling async rescan requests. */
104 TAILQ_HEAD(, ccb_hdr) ccb_scanq;
106 int buses_config_done;
108 /* Registered busses */
109 TAILQ_HEAD(,cam_eb) xpt_busses;
110 u_int bus_generation;
112 struct intr_config_hook *xpt_config_hook;
115 struct callout boot_callout;
117 struct mtx xpt_topo_lock;
123 DM_RET_FLAG_MASK = 0x0f,
126 DM_RET_DESCEND = 0x20,
128 DM_RET_ACTION_MASK = 0xf0
136 } xpt_traverse_depth;
138 struct xpt_traverse_config {
139 xpt_traverse_depth depth;
144 typedef int xpt_busfunc_t (struct cam_eb *bus, void *arg);
145 typedef int xpt_targetfunc_t (struct cam_et *target, void *arg);
146 typedef int xpt_devicefunc_t (struct cam_ed *device, void *arg);
147 typedef int xpt_periphfunc_t (struct cam_periph *periph, void *arg);
148 typedef int xpt_pdrvfunc_t (struct periph_driver **pdrv, void *arg);
150 /* Transport layer configuration information */
151 static struct xpt_softc xsoftc;
153 TUNABLE_INT("kern.cam.boot_delay", &xsoftc.boot_delay);
154 SYSCTL_INT(_kern_cam, OID_AUTO, boot_delay, CTLFLAG_RDTUN,
155 &xsoftc.boot_delay, 0, "Bus registration wait time");
157 /* Queues for our software interrupt handler */
158 typedef TAILQ_HEAD(cam_isrq, ccb_hdr) cam_isrq_t;
159 typedef TAILQ_HEAD(cam_simq, cam_sim) cam_simq_t;
160 static cam_simq_t cam_simq;
161 static struct mtx cam_simq_lock;
163 /* Pointers to software interrupt handlers */
164 static void *cambio_ih;
166 struct cam_periph *xpt_periph;
168 static periph_init_t xpt_periph_init;
170 static struct periph_driver xpt_driver =
172 xpt_periph_init, "xpt",
173 TAILQ_HEAD_INITIALIZER(xpt_driver.units), /* generation */ 0,
177 PERIPHDRIVER_DECLARE(xpt, xpt_driver);
179 static d_open_t xptopen;
180 static d_close_t xptclose;
181 static d_ioctl_t xptioctl;
183 static struct cdevsw xpt_cdevsw = {
184 .d_version = D_VERSION,
192 /* Storage for debugging datastructures */
194 struct cam_path *cam_dpath;
195 u_int32_t cam_dflags;
196 u_int32_t cam_debug_delay;
199 /* Our boot-time initialization hook */
200 static int cam_module_event_handler(module_t, int /*modeventtype_t*/, void *);
202 static moduledata_t cam_moduledata = {
204 cam_module_event_handler,
208 static int xpt_init(void *);
210 DECLARE_MODULE(cam, cam_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND);
211 MODULE_VERSION(cam, 1);
214 static void xpt_async_bcast(struct async_list *async_head,
215 u_int32_t async_code,
216 struct cam_path *path,
218 static path_id_t xptnextfreepathid(void);
219 static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus);
220 static union ccb *xpt_get_ccb(struct cam_ed *device);
221 static void xpt_run_dev_allocq(struct cam_eb *bus);
222 static void xpt_run_dev_sendq(struct cam_eb *bus);
223 static timeout_t xpt_release_devq_timeout;
224 static void xpt_release_simq_timeout(void *arg) __unused;
225 static void xpt_release_bus(struct cam_eb *bus);
226 static void xpt_release_devq_device(struct cam_ed *dev, cam_rl rl,
227 u_int count, int run_queue);
228 static struct cam_et*
229 xpt_alloc_target(struct cam_eb *bus, target_id_t target_id);
230 static void xpt_release_target(struct cam_et *target);
231 static struct cam_eb*
232 xpt_find_bus(path_id_t path_id);
233 static struct cam_et*
234 xpt_find_target(struct cam_eb *bus, target_id_t target_id);
235 static struct cam_ed*
236 xpt_find_device(struct cam_et *target, lun_id_t lun_id);
237 static void xpt_config(void *arg);
238 static xpt_devicefunc_t xptpassannouncefunc;
239 static void xptaction(struct cam_sim *sim, union ccb *work_ccb);
240 static void xptpoll(struct cam_sim *sim);
241 static void camisr(void *);
242 static void camisr_runqueue(void *);
243 static dev_match_ret xptbusmatch(struct dev_match_pattern *patterns,
244 u_int num_patterns, struct cam_eb *bus);
245 static dev_match_ret xptdevicematch(struct dev_match_pattern *patterns,
247 struct cam_ed *device);
248 static dev_match_ret xptperiphmatch(struct dev_match_pattern *patterns,
250 struct cam_periph *periph);
251 static xpt_busfunc_t xptedtbusfunc;
252 static xpt_targetfunc_t xptedttargetfunc;
253 static xpt_devicefunc_t xptedtdevicefunc;
254 static xpt_periphfunc_t xptedtperiphfunc;
255 static xpt_pdrvfunc_t xptplistpdrvfunc;
256 static xpt_periphfunc_t xptplistperiphfunc;
257 static int xptedtmatch(struct ccb_dev_match *cdm);
258 static int xptperiphlistmatch(struct ccb_dev_match *cdm);
259 static int xptbustraverse(struct cam_eb *start_bus,
260 xpt_busfunc_t *tr_func, void *arg);
261 static int xpttargettraverse(struct cam_eb *bus,
262 struct cam_et *start_target,
263 xpt_targetfunc_t *tr_func, void *arg);
264 static int xptdevicetraverse(struct cam_et *target,
265 struct cam_ed *start_device,
266 xpt_devicefunc_t *tr_func, void *arg);
267 static int xptperiphtraverse(struct cam_ed *device,
268 struct cam_periph *start_periph,
269 xpt_periphfunc_t *tr_func, void *arg);
270 static int xptpdrvtraverse(struct periph_driver **start_pdrv,
271 xpt_pdrvfunc_t *tr_func, void *arg);
272 static int xptpdperiphtraverse(struct periph_driver **pdrv,
273 struct cam_periph *start_periph,
274 xpt_periphfunc_t *tr_func,
276 static xpt_busfunc_t xptdefbusfunc;
277 static xpt_targetfunc_t xptdeftargetfunc;
278 static xpt_devicefunc_t xptdefdevicefunc;
279 static xpt_periphfunc_t xptdefperiphfunc;
280 static void xpt_finishconfig_task(void *context, int pending);
281 static int xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg);
282 static int xpt_for_all_devices(xpt_devicefunc_t *tr_func,
284 static void xpt_dev_async_default(u_int32_t async_code,
286 struct cam_et *target,
287 struct cam_ed *device,
289 static struct cam_ed * xpt_alloc_device_default(struct cam_eb *bus,
290 struct cam_et *target,
292 static xpt_devicefunc_t xptsetasyncfunc;
293 static xpt_busfunc_t xptsetasyncbusfunc;
294 static cam_status xptregister(struct cam_periph *periph,
296 static __inline int periph_is_queued(struct cam_periph *periph);
297 static __inline int device_is_alloc_queued(struct cam_ed *device);
298 static __inline int device_is_send_queued(struct cam_ed *device);
301 xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev)
305 if ((dev->drvq.entries > 0) &&
306 (dev->ccbq.devq_openings > 0) &&
307 (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL(
308 CAMQ_GET_PRIO(&dev->drvq))) == 0)) {
310 * The priority of a device waiting for CCB resources
311 * is that of the the highest priority peripheral driver
314 retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue,
315 &dev->alloc_ccb_entry.pinfo,
316 CAMQ_GET_PRIO(&dev->drvq));
325 xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
329 if ((dev->ccbq.queue.entries > 0) &&
330 (dev->ccbq.dev_openings > 0) &&
331 (cam_ccbq_frozen_top(&dev->ccbq) == 0)) {
333 * The priority of a device waiting for controller
334 * resources is that of the the highest priority CCB
338 xpt_schedule_dev(&bus->sim->devq->send_queue,
339 &dev->send_ccb_entry.pinfo,
340 CAMQ_GET_PRIO(&dev->ccbq.queue));
348 periph_is_queued(struct cam_periph *periph)
350 return (periph->pinfo.index != CAM_UNQUEUED_INDEX);
354 device_is_alloc_queued(struct cam_ed *device)
356 return (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
360 device_is_send_queued(struct cam_ed *device)
362 return (device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
368 make_dev(&xpt_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "xpt0");
372 xptdone(struct cam_periph *periph, union ccb *done_ccb)
374 /* Caller will release the CCB */
375 wakeup(&done_ccb->ccb_h.cbfcnp);
379 xptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
383 * Only allow read-write access.
385 if (((flags & FWRITE) == 0) || ((flags & FREAD) == 0))
389 * We don't allow nonblocking access.
391 if ((flags & O_NONBLOCK) != 0) {
392 printf("%s: can't do nonblocking access\n", devtoname(dev));
396 /* Mark ourselves open */
397 mtx_lock(&xsoftc.xpt_lock);
398 xsoftc.flags |= XPT_FLAG_OPEN;
399 mtx_unlock(&xsoftc.xpt_lock);
405 xptclose(struct cdev *dev, int flag, int fmt, struct thread *td)
408 /* Mark ourselves closed */
409 mtx_lock(&xsoftc.xpt_lock);
410 xsoftc.flags &= ~XPT_FLAG_OPEN;
411 mtx_unlock(&xsoftc.xpt_lock);
417 * Don't automatically grab the xpt softc lock here even though this is going
418 * through the xpt device. The xpt device is really just a back door for
419 * accessing other devices and SIMs, so the right thing to do is to grab
420 * the appropriate SIM lock once the bus/SIM is located.
423 xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
431 * For the transport layer CAMIOCOMMAND ioctl, we really only want
432 * to accept CCB types that don't quite make sense to send through a
433 * passthrough driver. XPT_PATH_INQ is an exception to this, as stated
441 inccb = (union ccb *)addr;
443 bus = xpt_find_bus(inccb->ccb_h.path_id);
449 switch(inccb->ccb_h.func_code) {
452 if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD)
453 || (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
462 ccb = xpt_alloc_ccb();
464 CAM_SIM_LOCK(bus->sim);
465 /* Ensure passed in target/lun supported on this bus. */
466 if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD) ||
467 (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
468 if (xpt_create_path(&ccb->ccb_h.path,
470 inccb->ccb_h.path_id,
472 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
474 CAM_SIM_UNLOCK(bus->sim);
478 xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
479 inccb->ccb_h.pinfo.priority);
480 ccb->ccb_h.func_code = XPT_PATH_INQ;
482 xpt_free_path(ccb->ccb_h.path);
483 if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD &&
484 inccb->ccb_h.target_id > ccb->cpi.max_target) ||
485 (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD &&
486 inccb->ccb_h.target_lun > ccb->cpi.max_lun)) {
488 CAM_SIM_UNLOCK(bus->sim);
494 * Create a path using the bus, target, and lun the
497 if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
498 inccb->ccb_h.path_id,
499 inccb->ccb_h.target_id,
500 inccb->ccb_h.target_lun) !=
503 CAM_SIM_UNLOCK(bus->sim);
507 /* Ensure all of our fields are correct */
508 xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
509 inccb->ccb_h.pinfo.priority);
510 xpt_merge_ccb(ccb, inccb);
511 ccb->ccb_h.cbfcnp = xptdone;
512 cam_periph_runccb(ccb, NULL, 0, 0, NULL);
513 bcopy(ccb, inccb, sizeof(union ccb));
514 xpt_free_path(ccb->ccb_h.path);
516 CAM_SIM_UNLOCK(bus->sim);
523 * This is an immediate CCB, so it's okay to
524 * allocate it on the stack.
527 CAM_SIM_LOCK(bus->sim);
530 * Create a path using the bus, target, and lun the
533 if (xpt_create_path(&ccb.ccb_h.path, xpt_periph,
534 inccb->ccb_h.path_id,
535 inccb->ccb_h.target_id,
536 inccb->ccb_h.target_lun) !=
539 CAM_SIM_UNLOCK(bus->sim);
542 /* Ensure all of our fields are correct */
543 xpt_setup_ccb(&ccb.ccb_h, ccb.ccb_h.path,
544 inccb->ccb_h.pinfo.priority);
545 xpt_merge_ccb(&ccb, inccb);
546 ccb.ccb_h.cbfcnp = xptdone;
548 CAM_SIM_UNLOCK(bus->sim);
549 bcopy(&ccb, inccb, sizeof(union ccb));
550 xpt_free_path(ccb.ccb_h.path);
554 case XPT_DEV_MATCH: {
555 struct cam_periph_map_info mapinfo;
556 struct cam_path *old_path;
559 * We can't deal with physical addresses for this
560 * type of transaction.
562 if (inccb->ccb_h.flags & CAM_DATA_PHYS) {
568 * Save this in case the caller had it set to
569 * something in particular.
571 old_path = inccb->ccb_h.path;
574 * We really don't need a path for the matching
575 * code. The path is needed because of the
576 * debugging statements in xpt_action(). They
577 * assume that the CCB has a valid path.
579 inccb->ccb_h.path = xpt_periph->path;
581 bzero(&mapinfo, sizeof(mapinfo));
584 * Map the pattern and match buffers into kernel
585 * virtual address space.
587 error = cam_periph_mapmem(inccb, &mapinfo);
590 inccb->ccb_h.path = old_path;
595 * This is an immediate CCB, we can send it on directly.
600 * Map the buffers back into user space.
602 cam_periph_unmapmem(inccb, &mapinfo);
604 inccb->ccb_h.path = old_path;
613 xpt_release_bus(bus);
617 * This is the getpassthru ioctl. It takes a XPT_GDEVLIST ccb as input,
618 * with the periphal driver name and unit name filled in. The other
619 * fields don't really matter as input. The passthrough driver name
620 * ("pass"), and unit number are passed back in the ccb. The current
621 * device generation number, and the index into the device peripheral
622 * driver list, and the status are also passed back. Note that
623 * since we do everything in one pass, unlike the XPT_GDEVLIST ccb,
624 * we never return a status of CAM_GDEVLIST_LIST_CHANGED. It is
625 * (or rather should be) impossible for the device peripheral driver
626 * list to change since we look at the whole thing in one pass, and
627 * we do it with lock protection.
630 case CAMGETPASSTHRU: {
632 struct cam_periph *periph;
633 struct periph_driver **p_drv;
636 u_int cur_generation;
637 int base_periph_found;
640 ccb = (union ccb *)addr;
641 unit = ccb->cgdl.unit_number;
642 name = ccb->cgdl.periph_name;
644 * Every 100 devices, we want to drop our lock protection to
645 * give the software interrupt handler a chance to run.
646 * Most systems won't run into this check, but this should
647 * avoid starvation in the software interrupt handler in
652 ccb = (union ccb *)addr;
654 base_periph_found = 0;
657 * Sanity check -- make sure we don't get a null peripheral
660 if (*ccb->cgdl.periph_name == '\0') {
665 /* Keep the list from changing while we traverse it */
666 mtx_lock(&xsoftc.xpt_topo_lock);
668 cur_generation = xsoftc.xpt_generation;
670 /* first find our driver in the list of drivers */
671 for (p_drv = periph_drivers; *p_drv != NULL; p_drv++)
672 if (strcmp((*p_drv)->driver_name, name) == 0)
675 if (*p_drv == NULL) {
676 mtx_unlock(&xsoftc.xpt_topo_lock);
677 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
678 ccb->cgdl.status = CAM_GDEVLIST_ERROR;
679 *ccb->cgdl.periph_name = '\0';
680 ccb->cgdl.unit_number = 0;
686 * Run through every peripheral instance of this driver
687 * and check to see whether it matches the unit passed
688 * in by the user. If it does, get out of the loops and
689 * find the passthrough driver associated with that
692 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL;
693 periph = TAILQ_NEXT(periph, unit_links)) {
695 if (periph->unit_number == unit) {
697 } else if (--splbreaknum == 0) {
698 mtx_unlock(&xsoftc.xpt_topo_lock);
699 mtx_lock(&xsoftc.xpt_topo_lock);
701 if (cur_generation != xsoftc.xpt_generation)
706 * If we found the peripheral driver that the user passed
707 * in, go through all of the peripheral drivers for that
708 * particular device and look for a passthrough driver.
710 if (periph != NULL) {
711 struct cam_ed *device;
714 base_periph_found = 1;
715 device = periph->path->device;
716 for (i = 0, periph = SLIST_FIRST(&device->periphs);
718 periph = SLIST_NEXT(periph, periph_links), i++) {
720 * Check to see whether we have a
721 * passthrough device or not.
723 if (strcmp(periph->periph_name, "pass") == 0) {
725 * Fill in the getdevlist fields.
727 strcpy(ccb->cgdl.periph_name,
728 periph->periph_name);
729 ccb->cgdl.unit_number =
731 if (SLIST_NEXT(periph, periph_links))
733 CAM_GDEVLIST_MORE_DEVS;
736 CAM_GDEVLIST_LAST_DEVICE;
737 ccb->cgdl.generation =
741 * Fill in some CCB header fields
742 * that the user may want.
745 periph->path->bus->path_id;
746 ccb->ccb_h.target_id =
747 periph->path->target->target_id;
748 ccb->ccb_h.target_lun =
749 periph->path->device->lun_id;
750 ccb->ccb_h.status = CAM_REQ_CMP;
757 * If the periph is null here, one of two things has
758 * happened. The first possibility is that we couldn't
759 * find the unit number of the particular peripheral driver
760 * that the user is asking about. e.g. the user asks for
761 * the passthrough driver for "da11". We find the list of
762 * "da" peripherals all right, but there is no unit 11.
763 * The other possibility is that we went through the list
764 * of peripheral drivers attached to the device structure,
765 * but didn't find one with the name "pass". Either way,
766 * we return ENOENT, since we couldn't find something.
768 if (periph == NULL) {
769 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
770 ccb->cgdl.status = CAM_GDEVLIST_ERROR;
771 *ccb->cgdl.periph_name = '\0';
772 ccb->cgdl.unit_number = 0;
775 * It is unfortunate that this is even necessary,
776 * but there are many, many clueless users out there.
777 * If this is true, the user is looking for the
778 * passthrough driver, but doesn't have one in his
781 if (base_periph_found == 1) {
782 printf("xptioctl: pass driver is not in the "
784 printf("xptioctl: put \"device pass\" in "
785 "your kernel config file\n");
788 mtx_unlock(&xsoftc.xpt_topo_lock);
800 cam_module_event_handler(module_t mod, int what, void *arg)
806 if ((error = xpt_init(NULL)) != 0)
819 xpt_rescan_done(struct cam_periph *periph, union ccb *done_ccb)
822 if (done_ccb->ccb_h.ppriv_ptr1 == NULL) {
823 xpt_free_path(done_ccb->ccb_h.path);
824 xpt_free_ccb(done_ccb);
826 done_ccb->ccb_h.cbfcnp = done_ccb->ccb_h.ppriv_ptr1;
827 (*done_ccb->ccb_h.cbfcnp)(periph, done_ccb);
832 /* thread to handle bus rescans */
834 xpt_scanner_thread(void *dummy)
841 if (TAILQ_EMPTY(&xsoftc.ccb_scanq))
842 msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO,
844 if ((ccb = (union ccb *)TAILQ_FIRST(&xsoftc.ccb_scanq)) != NULL) {
845 TAILQ_REMOVE(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe);
848 sim = ccb->ccb_h.path->bus->sim;
859 xpt_rescan(union ccb *ccb)
863 /* Prepare request */
864 if(ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD)
865 ccb->ccb_h.func_code = XPT_SCAN_BUS;
867 ccb->ccb_h.func_code = XPT_SCAN_LUN;
868 ccb->ccb_h.ppriv_ptr1 = ccb->ccb_h.cbfcnp;
869 ccb->ccb_h.cbfcnp = xpt_rescan_done;
870 xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_XPT);
871 /* Don't make duplicate entries for the same paths. */
873 if (ccb->ccb_h.ppriv_ptr1 == NULL) {
874 TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) {
875 if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) {
876 wakeup(&xsoftc.ccb_scanq);
878 xpt_print(ccb->ccb_h.path, "rescan already queued\n");
879 xpt_free_path(ccb->ccb_h.path);
885 TAILQ_INSERT_TAIL(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe);
886 xsoftc.buses_to_config++;
887 wakeup(&xsoftc.ccb_scanq);
891 /* Functions accessed by the peripheral drivers */
893 xpt_init(void *dummy)
895 struct cam_sim *xpt_sim;
896 struct cam_path *path;
897 struct cam_devq *devq;
900 TAILQ_INIT(&xsoftc.xpt_busses);
901 TAILQ_INIT(&cam_simq);
902 TAILQ_INIT(&xsoftc.ccb_scanq);
903 STAILQ_INIT(&xsoftc.highpowerq);
904 xsoftc.num_highpower = CAM_MAX_HIGHPOWER;
906 mtx_init(&cam_simq_lock, "CAM SIMQ lock", NULL, MTX_DEF);
907 mtx_init(&xsoftc.xpt_lock, "XPT lock", NULL, MTX_DEF);
908 mtx_init(&xsoftc.xpt_topo_lock, "XPT topology lock", NULL, MTX_DEF);
911 * The xpt layer is, itself, the equivelent of a SIM.
912 * Allow 16 ccbs in the ccb pool for it. This should
913 * give decent parallelism when we probe busses and
914 * perform other XPT functions.
916 devq = cam_simq_alloc(16);
917 xpt_sim = cam_sim_alloc(xptaction,
922 /*mtx*/&xsoftc.xpt_lock,
923 /*max_dev_transactions*/0,
924 /*max_tagged_dev_transactions*/0,
929 mtx_lock(&xsoftc.xpt_lock);
930 if ((status = xpt_bus_register(xpt_sim, NULL, 0)) != CAM_SUCCESS) {
931 mtx_unlock(&xsoftc.xpt_lock);
932 printf("xpt_init: xpt_bus_register failed with status %#x,"
933 " failing attach\n", status);
938 * Looking at the XPT from the SIM layer, the XPT is
939 * the equivelent of a peripheral driver. Allocate
940 * a peripheral driver entry for us.
942 if ((status = xpt_create_path(&path, NULL, CAM_XPT_PATH_ID,
944 CAM_LUN_WILDCARD)) != CAM_REQ_CMP) {
945 mtx_unlock(&xsoftc.xpt_lock);
946 printf("xpt_init: xpt_create_path failed with status %#x,"
947 " failing attach\n", status);
951 cam_periph_alloc(xptregister, NULL, NULL, NULL, "xpt", CAM_PERIPH_BIO,
952 path, NULL, 0, xpt_sim);
954 mtx_unlock(&xsoftc.xpt_lock);
955 /* Install our software interrupt handlers */
956 swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih);
958 * Register a callback for when interrupts are enabled.
960 xsoftc.xpt_config_hook =
961 (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook),
962 M_CAMXPT, M_NOWAIT | M_ZERO);
963 if (xsoftc.xpt_config_hook == NULL) {
964 printf("xpt_init: Cannot malloc config hook "
965 "- failing attach\n");
968 xsoftc.xpt_config_hook->ich_func = xpt_config;
969 if (config_intrhook_establish(xsoftc.xpt_config_hook) != 0) {
970 free (xsoftc.xpt_config_hook, M_CAMXPT);
971 printf("xpt_init: config_intrhook_establish failed "
972 "- failing attach\n");
979 xptregister(struct cam_periph *periph, void *arg)
981 struct cam_sim *xpt_sim;
983 if (periph == NULL) {
984 printf("xptregister: periph was NULL!!\n");
985 return(CAM_REQ_CMP_ERR);
988 xpt_sim = (struct cam_sim *)arg;
989 xpt_sim->softc = periph;
991 periph->softc = NULL;
997 xpt_add_periph(struct cam_periph *periph)
999 struct cam_ed *device;
1001 struct periph_list *periph_head;
1003 mtx_assert(periph->sim->mtx, MA_OWNED);
1005 device = periph->path->device;
1007 periph_head = &device->periphs;
1009 status = CAM_REQ_CMP;
1011 if (device != NULL) {
1013 * Make room for this peripheral
1014 * so it will fit in the queue
1015 * when it's scheduled to run
1017 status = camq_resize(&device->drvq,
1018 device->drvq.array_size + 1);
1020 device->generation++;
1022 SLIST_INSERT_HEAD(periph_head, periph, periph_links);
1025 mtx_lock(&xsoftc.xpt_topo_lock);
1026 xsoftc.xpt_generation++;
1027 mtx_unlock(&xsoftc.xpt_topo_lock);
1033 xpt_remove_periph(struct cam_periph *periph)
1035 struct cam_ed *device;
1037 mtx_assert(periph->sim->mtx, MA_OWNED);
1039 device = periph->path->device;
1041 if (device != NULL) {
1042 struct periph_list *periph_head;
1044 periph_head = &device->periphs;
1046 /* Release the slot for this peripheral */
1047 camq_resize(&device->drvq, device->drvq.array_size - 1);
1049 device->generation++;
1051 SLIST_REMOVE(periph_head, periph, cam_periph, periph_links);
1054 mtx_lock(&xsoftc.xpt_topo_lock);
1055 xsoftc.xpt_generation++;
1056 mtx_unlock(&xsoftc.xpt_topo_lock);
1061 xpt_announce_periph(struct cam_periph *periph, char *announce_string)
1063 struct ccb_pathinq cpi;
1064 struct ccb_trans_settings cts;
1065 struct cam_path *path;
1070 mtx_assert(periph->sim->mtx, MA_OWNED);
1072 path = periph->path;
1074 * To ensure that this is printed in one piece,
1075 * mask out CAM interrupts.
1077 printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n",
1078 periph->periph_name, periph->unit_number,
1079 path->bus->sim->sim_name,
1080 path->bus->sim->unit_number,
1081 path->bus->sim->bus_id,
1083 path->target->target_id,
1084 path->device->lun_id);
1085 printf("%s%d: ", periph->periph_name, periph->unit_number);
1086 if (path->device->protocol == PROTO_SCSI)
1087 scsi_print_inquiry(&path->device->inq_data);
1088 else if (path->device->protocol == PROTO_ATA ||
1089 path->device->protocol == PROTO_SATAPM)
1090 ata_print_ident(&path->device->ident_data);
1092 printf("Unknown protocol device\n");
1093 if (bootverbose && path->device->serial_num_len > 0) {
1094 /* Don't wrap the screen - print only the first 60 chars */
1095 printf("%s%d: Serial Number %.60s\n", periph->periph_name,
1096 periph->unit_number, path->device->serial_num);
1098 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
1099 cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1100 cts.type = CTS_TYPE_CURRENT_SETTINGS;
1101 xpt_action((union ccb*)&cts);
1102 if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1106 /* Ask the SIM for its base transfer speed */
1107 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
1108 cpi.ccb_h.func_code = XPT_PATH_INQ;
1109 xpt_action((union ccb *)&cpi);
1111 speed = cpi.base_transfer_speed;
1113 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
1114 struct ccb_trans_settings_spi *spi =
1115 &cts.xport_specific.spi;
1117 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0
1118 && spi->sync_offset != 0) {
1119 freq = scsi_calc_syncsrate(spi->sync_period);
1122 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
1123 speed *= (0x01 << spi->bus_width);
1125 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
1126 struct ccb_trans_settings_fc *fc =
1127 &cts.xport_specific.fc;
1129 if (fc->valid & CTS_FC_VALID_SPEED)
1130 speed = fc->bitrate;
1132 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SAS) {
1133 struct ccb_trans_settings_sas *sas =
1134 &cts.xport_specific.sas;
1136 if (sas->valid & CTS_SAS_VALID_SPEED)
1137 speed = sas->bitrate;
1139 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
1140 struct ccb_trans_settings_ata *ata =
1141 &cts.xport_specific.ata;
1143 if (ata->valid & CTS_ATA_VALID_MODE)
1144 speed = ata_mode2speed(ata->mode);
1146 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
1147 struct ccb_trans_settings_sata *sata =
1148 &cts.xport_specific.sata;
1150 if (sata->valid & CTS_SATA_VALID_REVISION)
1151 speed = ata_revision2speed(sata->revision);
1156 printf("%s%d: %d.%03dMB/s transfers",
1157 periph->periph_name, periph->unit_number,
1160 printf("%s%d: %dKB/s transfers", periph->periph_name,
1161 periph->unit_number, speed);
1162 /* Report additional information about SPI connections */
1163 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
1164 struct ccb_trans_settings_spi *spi;
1166 spi = &cts.xport_specific.spi;
1168 printf(" (%d.%03dMHz%s, offset %d", freq / 1000,
1170 (spi->ppr_options & MSG_EXT_PPR_DT_REQ) != 0
1174 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0
1175 && spi->bus_width > 0) {
1181 printf("%dbit)", 8 * (0x01 << spi->bus_width));
1182 } else if (freq != 0) {
1186 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
1187 struct ccb_trans_settings_fc *fc;
1189 fc = &cts.xport_specific.fc;
1190 if (fc->valid & CTS_FC_VALID_WWNN)
1191 printf(" WWNN 0x%llx", (long long) fc->wwnn);
1192 if (fc->valid & CTS_FC_VALID_WWPN)
1193 printf(" WWPN 0x%llx", (long long) fc->wwpn);
1194 if (fc->valid & CTS_FC_VALID_PORT)
1195 printf(" PortID 0x%x", fc->port);
1197 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
1198 struct ccb_trans_settings_ata *ata =
1199 &cts.xport_specific.ata;
1202 if (ata->valid & CTS_ATA_VALID_MODE)
1203 printf("%s, ", ata_mode2string(ata->mode));
1204 if ((ata->valid & CTS_ATA_VALID_ATAPI) && ata->atapi != 0)
1205 printf("ATAPI %dbytes, ", ata->atapi);
1206 if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
1207 printf("PIO %dbytes", ata->bytecount);
1210 if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
1211 struct ccb_trans_settings_sata *sata =
1212 &cts.xport_specific.sata;
1215 if (sata->valid & CTS_SATA_VALID_REVISION)
1216 printf("SATA %d.x, ", sata->revision);
1219 if (sata->valid & CTS_SATA_VALID_MODE)
1220 printf("%s, ", ata_mode2string(sata->mode));
1221 if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0)
1222 printf("ATAPI %dbytes, ", sata->atapi);
1223 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
1224 printf("PIO %dbytes", sata->bytecount);
1227 if (path->device->inq_flags & SID_CmdQue
1228 || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) {
1229 printf("\n%s%d: Command Queueing enabled",
1230 periph->periph_name, periph->unit_number);
1235 * We only want to print the caller's announce string if they've
1238 if (announce_string != NULL)
1239 printf("%s%d: %s\n", periph->periph_name,
1240 periph->unit_number, announce_string);
1243 static dev_match_ret
1244 xptbusmatch(struct dev_match_pattern *patterns, u_int num_patterns,
1247 dev_match_ret retval;
1250 retval = DM_RET_NONE;
1253 * If we aren't given something to match against, that's an error.
1256 return(DM_RET_ERROR);
1259 * If there are no match entries, then this bus matches no
1262 if ((patterns == NULL) || (num_patterns == 0))
1263 return(DM_RET_DESCEND | DM_RET_COPY);
1265 for (i = 0; i < num_patterns; i++) {
1266 struct bus_match_pattern *cur_pattern;
1269 * If the pattern in question isn't for a bus node, we
1270 * aren't interested. However, we do indicate to the
1271 * calling routine that we should continue descending the
1272 * tree, since the user wants to match against lower-level
1275 if (patterns[i].type != DEV_MATCH_BUS) {
1276 if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
1277 retval |= DM_RET_DESCEND;
1281 cur_pattern = &patterns[i].pattern.bus_pattern;
1284 * If they want to match any bus node, we give them any
1287 if (cur_pattern->flags == BUS_MATCH_ANY) {
1288 /* set the copy flag */
1289 retval |= DM_RET_COPY;
1292 * If we've already decided on an action, go ahead
1295 if ((retval & DM_RET_ACTION_MASK) != DM_RET_NONE)
1300 * Not sure why someone would do this...
1302 if (cur_pattern->flags == BUS_MATCH_NONE)
1305 if (((cur_pattern->flags & BUS_MATCH_PATH) != 0)
1306 && (cur_pattern->path_id != bus->path_id))
1309 if (((cur_pattern->flags & BUS_MATCH_BUS_ID) != 0)
1310 && (cur_pattern->bus_id != bus->sim->bus_id))
1313 if (((cur_pattern->flags & BUS_MATCH_UNIT) != 0)
1314 && (cur_pattern->unit_number != bus->sim->unit_number))
1317 if (((cur_pattern->flags & BUS_MATCH_NAME) != 0)
1318 && (strncmp(cur_pattern->dev_name, bus->sim->sim_name,
1323 * If we get to this point, the user definitely wants
1324 * information on this bus. So tell the caller to copy the
1327 retval |= DM_RET_COPY;
1330 * If the return action has been set to descend, then we
1331 * know that we've already seen a non-bus matching
1332 * expression, therefore we need to further descend the tree.
1333 * This won't change by continuing around the loop, so we
1334 * go ahead and return. If we haven't seen a non-bus
1335 * matching expression, we keep going around the loop until
1336 * we exhaust the matching expressions. We'll set the stop
1337 * flag once we fall out of the loop.
1339 if ((retval & DM_RET_ACTION_MASK) == DM_RET_DESCEND)
1344 * If the return action hasn't been set to descend yet, that means
1345 * we haven't seen anything other than bus matching patterns. So
1346 * tell the caller to stop descending the tree -- the user doesn't
1347 * want to match against lower level tree elements.
1349 if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
1350 retval |= DM_RET_STOP;
1355 static dev_match_ret
1356 xptdevicematch(struct dev_match_pattern *patterns, u_int num_patterns,
1357 struct cam_ed *device)
1359 dev_match_ret retval;
1362 retval = DM_RET_NONE;
1365 * If we aren't given something to match against, that's an error.
1368 return(DM_RET_ERROR);
1371 * If there are no match entries, then this device matches no
1374 if ((patterns == NULL) || (num_patterns == 0))
1375 return(DM_RET_DESCEND | DM_RET_COPY);
1377 for (i = 0; i < num_patterns; i++) {
1378 struct device_match_pattern *cur_pattern;
1381 * If the pattern in question isn't for a device node, we
1382 * aren't interested.
1384 if (patterns[i].type != DEV_MATCH_DEVICE) {
1385 if ((patterns[i].type == DEV_MATCH_PERIPH)
1386 && ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE))
1387 retval |= DM_RET_DESCEND;
1391 cur_pattern = &patterns[i].pattern.device_pattern;
1394 * If they want to match any device node, we give them any
1397 if (cur_pattern->flags == DEV_MATCH_ANY) {
1398 /* set the copy flag */
1399 retval |= DM_RET_COPY;
1403 * If we've already decided on an action, go ahead
1406 if ((retval & DM_RET_ACTION_MASK) != DM_RET_NONE)
1411 * Not sure why someone would do this...
1413 if (cur_pattern->flags == DEV_MATCH_NONE)
1416 if (((cur_pattern->flags & DEV_MATCH_PATH) != 0)
1417 && (cur_pattern->path_id != device->target->bus->path_id))
1420 if (((cur_pattern->flags & DEV_MATCH_TARGET) != 0)
1421 && (cur_pattern->target_id != device->target->target_id))
1424 if (((cur_pattern->flags & DEV_MATCH_LUN) != 0)
1425 && (cur_pattern->target_lun != device->lun_id))
1428 if (((cur_pattern->flags & DEV_MATCH_INQUIRY) != 0)
1429 && (cam_quirkmatch((caddr_t)&device->inq_data,
1430 (caddr_t)&cur_pattern->inq_pat,
1431 1, sizeof(cur_pattern->inq_pat),
1432 scsi_static_inquiry_match) == NULL))
1436 * If we get to this point, the user definitely wants
1437 * information on this device. So tell the caller to copy
1440 retval |= DM_RET_COPY;
1443 * If the return action has been set to descend, then we
1444 * know that we've already seen a peripheral matching
1445 * expression, therefore we need to further descend the tree.
1446 * This won't change by continuing around the loop, so we
1447 * go ahead and return. If we haven't seen a peripheral
1448 * matching expression, we keep going around the loop until
1449 * we exhaust the matching expressions. We'll set the stop
1450 * flag once we fall out of the loop.
1452 if ((retval & DM_RET_ACTION_MASK) == DM_RET_DESCEND)
1457 * If the return action hasn't been set to descend yet, that means
1458 * we haven't seen any peripheral matching patterns. So tell the
1459 * caller to stop descending the tree -- the user doesn't want to
1460 * match against lower level tree elements.
1462 if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
1463 retval |= DM_RET_STOP;
1469 * Match a single peripheral against any number of match patterns.
1471 static dev_match_ret
1472 xptperiphmatch(struct dev_match_pattern *patterns, u_int num_patterns,
1473 struct cam_periph *periph)
1475 dev_match_ret retval;
1479 * If we aren't given something to match against, that's an error.
1482 return(DM_RET_ERROR);
1485 * If there are no match entries, then this peripheral matches no
1488 if ((patterns == NULL) || (num_patterns == 0))
1489 return(DM_RET_STOP | DM_RET_COPY);
1492 * There aren't any nodes below a peripheral node, so there's no
1493 * reason to descend the tree any further.
1495 retval = DM_RET_STOP;
1497 for (i = 0; i < num_patterns; i++) {
1498 struct periph_match_pattern *cur_pattern;
1501 * If the pattern in question isn't for a peripheral, we
1502 * aren't interested.
1504 if (patterns[i].type != DEV_MATCH_PERIPH)
1507 cur_pattern = &patterns[i].pattern.periph_pattern;
1510 * If they want to match on anything, then we will do so.
1512 if (cur_pattern->flags == PERIPH_MATCH_ANY) {
1513 /* set the copy flag */
1514 retval |= DM_RET_COPY;
1517 * We've already set the return action to stop,
1518 * since there are no nodes below peripherals in
1525 * Not sure why someone would do this...
1527 if (cur_pattern->flags == PERIPH_MATCH_NONE)
1530 if (((cur_pattern->flags & PERIPH_MATCH_PATH) != 0)
1531 && (cur_pattern->path_id != periph->path->bus->path_id))
1535 * For the target and lun id's, we have to make sure the
1536 * target and lun pointers aren't NULL. The xpt peripheral
1537 * has a wildcard target and device.
1539 if (((cur_pattern->flags & PERIPH_MATCH_TARGET) != 0)
1540 && ((periph->path->target == NULL)
1541 ||(cur_pattern->target_id != periph->path->target->target_id)))
1544 if (((cur_pattern->flags & PERIPH_MATCH_LUN) != 0)
1545 && ((periph->path->device == NULL)
1546 || (cur_pattern->target_lun != periph->path->device->lun_id)))
1549 if (((cur_pattern->flags & PERIPH_MATCH_UNIT) != 0)
1550 && (cur_pattern->unit_number != periph->unit_number))
1553 if (((cur_pattern->flags & PERIPH_MATCH_NAME) != 0)
1554 && (strncmp(cur_pattern->periph_name, periph->periph_name,
1559 * If we get to this point, the user definitely wants
1560 * information on this peripheral. So tell the caller to
1561 * copy the data out.
1563 retval |= DM_RET_COPY;
1566 * The return action has already been set to stop, since
1567 * peripherals don't have any nodes below them in the EDT.
1573 * If we get to this point, the peripheral that was passed in
1574 * doesn't match any of the patterns.
1580 xptedtbusfunc(struct cam_eb *bus, void *arg)
1582 struct ccb_dev_match *cdm;
1583 dev_match_ret retval;
1585 cdm = (struct ccb_dev_match *)arg;
1588 * If our position is for something deeper in the tree, that means
1589 * that we've already seen this node. So, we keep going down.
1591 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1592 && (cdm->pos.cookie.bus == bus)
1593 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1594 && (cdm->pos.cookie.target != NULL))
1595 retval = DM_RET_DESCEND;
1597 retval = xptbusmatch(cdm->patterns, cdm->num_patterns, bus);
1600 * If we got an error, bail out of the search.
1602 if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
1603 cdm->status = CAM_DEV_MATCH_ERROR;
1608 * If the copy flag is set, copy this bus out.
1610 if (retval & DM_RET_COPY) {
1613 spaceleft = cdm->match_buf_len - (cdm->num_matches *
1614 sizeof(struct dev_match_result));
1617 * If we don't have enough space to put in another
1618 * match result, save our position and tell the
1619 * user there are more devices to check.
1621 if (spaceleft < sizeof(struct dev_match_result)) {
1622 bzero(&cdm->pos, sizeof(cdm->pos));
1623 cdm->pos.position_type =
1624 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS;
1626 cdm->pos.cookie.bus = bus;
1627 cdm->pos.generations[CAM_BUS_GENERATION]=
1628 xsoftc.bus_generation;
1629 cdm->status = CAM_DEV_MATCH_MORE;
1632 j = cdm->num_matches;
1634 cdm->matches[j].type = DEV_MATCH_BUS;
1635 cdm->matches[j].result.bus_result.path_id = bus->path_id;
1636 cdm->matches[j].result.bus_result.bus_id = bus->sim->bus_id;
1637 cdm->matches[j].result.bus_result.unit_number =
1638 bus->sim->unit_number;
1639 strncpy(cdm->matches[j].result.bus_result.dev_name,
1640 bus->sim->sim_name, DEV_IDLEN);
1644 * If the user is only interested in busses, there's no
1645 * reason to descend to the next level in the tree.
1647 if ((retval & DM_RET_ACTION_MASK) == DM_RET_STOP)
1651 * If there is a target generation recorded, check it to
1652 * make sure the target list hasn't changed.
1654 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1655 && (bus == cdm->pos.cookie.bus)
1656 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1657 && (cdm->pos.generations[CAM_TARGET_GENERATION] != 0)
1658 && (cdm->pos.generations[CAM_TARGET_GENERATION] !=
1660 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
1664 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1665 && (cdm->pos.cookie.bus == bus)
1666 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1667 && (cdm->pos.cookie.target != NULL))
1668 return(xpttargettraverse(bus,
1669 (struct cam_et *)cdm->pos.cookie.target,
1670 xptedttargetfunc, arg));
1672 return(xpttargettraverse(bus, NULL, xptedttargetfunc, arg));
1676 xptedttargetfunc(struct cam_et *target, void *arg)
1678 struct ccb_dev_match *cdm;
1680 cdm = (struct ccb_dev_match *)arg;
1683 * If there is a device list generation recorded, check it to
1684 * make sure the device list hasn't changed.
1686 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1687 && (cdm->pos.cookie.bus == target->bus)
1688 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1689 && (cdm->pos.cookie.target == target)
1690 && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
1691 && (cdm->pos.generations[CAM_DEV_GENERATION] != 0)
1692 && (cdm->pos.generations[CAM_DEV_GENERATION] !=
1693 target->generation)) {
1694 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
1698 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1699 && (cdm->pos.cookie.bus == target->bus)
1700 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1701 && (cdm->pos.cookie.target == target)
1702 && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
1703 && (cdm->pos.cookie.device != NULL))
1704 return(xptdevicetraverse(target,
1705 (struct cam_ed *)cdm->pos.cookie.device,
1706 xptedtdevicefunc, arg));
1708 return(xptdevicetraverse(target, NULL, xptedtdevicefunc, arg));
1712 xptedtdevicefunc(struct cam_ed *device, void *arg)
1715 struct ccb_dev_match *cdm;
1716 dev_match_ret retval;
1718 cdm = (struct ccb_dev_match *)arg;
1721 * If our position is for something deeper in the tree, that means
1722 * that we've already seen this node. So, we keep going down.
1724 if ((cdm->pos.position_type & CAM_DEV_POS_DEVICE)
1725 && (cdm->pos.cookie.device == device)
1726 && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
1727 && (cdm->pos.cookie.periph != NULL))
1728 retval = DM_RET_DESCEND;
1730 retval = xptdevicematch(cdm->patterns, cdm->num_patterns,
1733 if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
1734 cdm->status = CAM_DEV_MATCH_ERROR;
1739 * If the copy flag is set, copy this device out.
1741 if (retval & DM_RET_COPY) {
1744 spaceleft = cdm->match_buf_len - (cdm->num_matches *
1745 sizeof(struct dev_match_result));
1748 * If we don't have enough space to put in another
1749 * match result, save our position and tell the
1750 * user there are more devices to check.
1752 if (spaceleft < sizeof(struct dev_match_result)) {
1753 bzero(&cdm->pos, sizeof(cdm->pos));
1754 cdm->pos.position_type =
1755 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS |
1756 CAM_DEV_POS_TARGET | CAM_DEV_POS_DEVICE;
1758 cdm->pos.cookie.bus = device->target->bus;
1759 cdm->pos.generations[CAM_BUS_GENERATION]=
1760 xsoftc.bus_generation;
1761 cdm->pos.cookie.target = device->target;
1762 cdm->pos.generations[CAM_TARGET_GENERATION] =
1763 device->target->bus->generation;
1764 cdm->pos.cookie.device = device;
1765 cdm->pos.generations[CAM_DEV_GENERATION] =
1766 device->target->generation;
1767 cdm->status = CAM_DEV_MATCH_MORE;
1770 j = cdm->num_matches;
1772 cdm->matches[j].type = DEV_MATCH_DEVICE;
1773 cdm->matches[j].result.device_result.path_id =
1774 device->target->bus->path_id;
1775 cdm->matches[j].result.device_result.target_id =
1776 device->target->target_id;
1777 cdm->matches[j].result.device_result.target_lun =
1779 cdm->matches[j].result.device_result.protocol =
1781 bcopy(&device->inq_data,
1782 &cdm->matches[j].result.device_result.inq_data,
1783 sizeof(struct scsi_inquiry_data));
1784 bcopy(&device->ident_data,
1785 &cdm->matches[j].result.device_result.ident_data,
1786 sizeof(struct ata_params));
1788 /* Let the user know whether this device is unconfigured */
1789 if (device->flags & CAM_DEV_UNCONFIGURED)
1790 cdm->matches[j].result.device_result.flags =
1791 DEV_RESULT_UNCONFIGURED;
1793 cdm->matches[j].result.device_result.flags =
1798 * If the user isn't interested in peripherals, don't descend
1799 * the tree any further.
1801 if ((retval & DM_RET_ACTION_MASK) == DM_RET_STOP)
1805 * If there is a peripheral list generation recorded, make sure
1806 * it hasn't changed.
1808 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1809 && (device->target->bus == cdm->pos.cookie.bus)
1810 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1811 && (device->target == cdm->pos.cookie.target)
1812 && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
1813 && (device == cdm->pos.cookie.device)
1814 && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
1815 && (cdm->pos.generations[CAM_PERIPH_GENERATION] != 0)
1816 && (cdm->pos.generations[CAM_PERIPH_GENERATION] !=
1817 device->generation)){
1818 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
1822 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1823 && (cdm->pos.cookie.bus == device->target->bus)
1824 && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
1825 && (cdm->pos.cookie.target == device->target)
1826 && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
1827 && (cdm->pos.cookie.device == device)
1828 && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
1829 && (cdm->pos.cookie.periph != NULL))
1830 return(xptperiphtraverse(device,
1831 (struct cam_periph *)cdm->pos.cookie.periph,
1832 xptedtperiphfunc, arg));
1834 return(xptperiphtraverse(device, NULL, xptedtperiphfunc, arg));
1838 xptedtperiphfunc(struct cam_periph *periph, void *arg)
1840 struct ccb_dev_match *cdm;
1841 dev_match_ret retval;
1843 cdm = (struct ccb_dev_match *)arg;
1845 retval = xptperiphmatch(cdm->patterns, cdm->num_patterns, periph);
1847 if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
1848 cdm->status = CAM_DEV_MATCH_ERROR;
1853 * If the copy flag is set, copy this peripheral out.
1855 if (retval & DM_RET_COPY) {
1858 spaceleft = cdm->match_buf_len - (cdm->num_matches *
1859 sizeof(struct dev_match_result));
1862 * If we don't have enough space to put in another
1863 * match result, save our position and tell the
1864 * user there are more devices to check.
1866 if (spaceleft < sizeof(struct dev_match_result)) {
1867 bzero(&cdm->pos, sizeof(cdm->pos));
1868 cdm->pos.position_type =
1869 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS |
1870 CAM_DEV_POS_TARGET | CAM_DEV_POS_DEVICE |
1873 cdm->pos.cookie.bus = periph->path->bus;
1874 cdm->pos.generations[CAM_BUS_GENERATION]=
1875 xsoftc.bus_generation;
1876 cdm->pos.cookie.target = periph->path->target;
1877 cdm->pos.generations[CAM_TARGET_GENERATION] =
1878 periph->path->bus->generation;
1879 cdm->pos.cookie.device = periph->path->device;
1880 cdm->pos.generations[CAM_DEV_GENERATION] =
1881 periph->path->target->generation;
1882 cdm->pos.cookie.periph = periph;
1883 cdm->pos.generations[CAM_PERIPH_GENERATION] =
1884 periph->path->device->generation;
1885 cdm->status = CAM_DEV_MATCH_MORE;
1889 j = cdm->num_matches;
1891 cdm->matches[j].type = DEV_MATCH_PERIPH;
1892 cdm->matches[j].result.periph_result.path_id =
1893 periph->path->bus->path_id;
1894 cdm->matches[j].result.periph_result.target_id =
1895 periph->path->target->target_id;
1896 cdm->matches[j].result.periph_result.target_lun =
1897 periph->path->device->lun_id;
1898 cdm->matches[j].result.periph_result.unit_number =
1899 periph->unit_number;
1900 strncpy(cdm->matches[j].result.periph_result.periph_name,
1901 periph->periph_name, DEV_IDLEN);
1908 xptedtmatch(struct ccb_dev_match *cdm)
1912 cdm->num_matches = 0;
1915 * Check the bus list generation. If it has changed, the user
1916 * needs to reset everything and start over.
1918 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1919 && (cdm->pos.generations[CAM_BUS_GENERATION] != 0)
1920 && (cdm->pos.generations[CAM_BUS_GENERATION] != xsoftc.bus_generation)) {
1921 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
1925 if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
1926 && (cdm->pos.cookie.bus != NULL))
1927 ret = xptbustraverse((struct cam_eb *)cdm->pos.cookie.bus,
1928 xptedtbusfunc, cdm);
1930 ret = xptbustraverse(NULL, xptedtbusfunc, cdm);
1933 * If we get back 0, that means that we had to stop before fully
1934 * traversing the EDT. It also means that one of the subroutines
1935 * has set the status field to the proper value. If we get back 1,
1936 * we've fully traversed the EDT and copied out any matching entries.
1939 cdm->status = CAM_DEV_MATCH_LAST;
1945 xptplistpdrvfunc(struct periph_driver **pdrv, void *arg)
1947 struct ccb_dev_match *cdm;
1949 cdm = (struct ccb_dev_match *)arg;
1951 if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
1952 && (cdm->pos.cookie.pdrv == pdrv)
1953 && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
1954 && (cdm->pos.generations[CAM_PERIPH_GENERATION] != 0)
1955 && (cdm->pos.generations[CAM_PERIPH_GENERATION] !=
1956 (*pdrv)->generation)) {
1957 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
1961 if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
1962 && (cdm->pos.cookie.pdrv == pdrv)
1963 && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
1964 && (cdm->pos.cookie.periph != NULL))
1965 return(xptpdperiphtraverse(pdrv,
1966 (struct cam_periph *)cdm->pos.cookie.periph,
1967 xptplistperiphfunc, arg));
1969 return(xptpdperiphtraverse(pdrv, NULL,xptplistperiphfunc, arg));
1973 xptplistperiphfunc(struct cam_periph *periph, void *arg)
1975 struct ccb_dev_match *cdm;
1976 dev_match_ret retval;
1978 cdm = (struct ccb_dev_match *)arg;
1980 retval = xptperiphmatch(cdm->patterns, cdm->num_patterns, periph);
1982 if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
1983 cdm->status = CAM_DEV_MATCH_ERROR;
1988 * If the copy flag is set, copy this peripheral out.
1990 if (retval & DM_RET_COPY) {
1993 spaceleft = cdm->match_buf_len - (cdm->num_matches *
1994 sizeof(struct dev_match_result));
1997 * If we don't have enough space to put in another
1998 * match result, save our position and tell the
1999 * user there are more devices to check.
2001 if (spaceleft < sizeof(struct dev_match_result)) {
2002 struct periph_driver **pdrv;
2005 bzero(&cdm->pos, sizeof(cdm->pos));
2006 cdm->pos.position_type =
2007 CAM_DEV_POS_PDRV | CAM_DEV_POS_PDPTR |
2011 * This may look a bit non-sensical, but it is
2012 * actually quite logical. There are very few
2013 * peripheral drivers, and bloating every peripheral
2014 * structure with a pointer back to its parent
2015 * peripheral driver linker set entry would cost
2016 * more in the long run than doing this quick lookup.
2018 for (pdrv = periph_drivers; *pdrv != NULL; pdrv++) {
2019 if (strcmp((*pdrv)->driver_name,
2020 periph->periph_name) == 0)
2024 if (*pdrv == NULL) {
2025 cdm->status = CAM_DEV_MATCH_ERROR;
2029 cdm->pos.cookie.pdrv = pdrv;
2031 * The periph generation slot does double duty, as
2032 * does the periph pointer slot. They are used for
2033 * both edt and pdrv lookups and positioning.
2035 cdm->pos.cookie.periph = periph;
2036 cdm->pos.generations[CAM_PERIPH_GENERATION] =
2037 (*pdrv)->generation;
2038 cdm->status = CAM_DEV_MATCH_MORE;
2042 j = cdm->num_matches;
2044 cdm->matches[j].type = DEV_MATCH_PERIPH;
2045 cdm->matches[j].result.periph_result.path_id =
2046 periph->path->bus->path_id;
2049 * The transport layer peripheral doesn't have a target or
2052 if (periph->path->target)
2053 cdm->matches[j].result.periph_result.target_id =
2054 periph->path->target->target_id;
2056 cdm->matches[j].result.periph_result.target_id = -1;
2058 if (periph->path->device)
2059 cdm->matches[j].result.periph_result.target_lun =
2060 periph->path->device->lun_id;
2062 cdm->matches[j].result.periph_result.target_lun = -1;
2064 cdm->matches[j].result.periph_result.unit_number =
2065 periph->unit_number;
2066 strncpy(cdm->matches[j].result.periph_result.periph_name,
2067 periph->periph_name, DEV_IDLEN);
2074 xptperiphlistmatch(struct ccb_dev_match *cdm)
2078 cdm->num_matches = 0;
2081 * At this point in the edt traversal function, we check the bus
2082 * list generation to make sure that no busses have been added or
2083 * removed since the user last sent a XPT_DEV_MATCH ccb through.
2084 * For the peripheral driver list traversal function, however, we
2085 * don't have to worry about new peripheral driver types coming or
2086 * going; they're in a linker set, and therefore can't change
2087 * without a recompile.
2090 if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
2091 && (cdm->pos.cookie.pdrv != NULL))
2092 ret = xptpdrvtraverse(
2093 (struct periph_driver **)cdm->pos.cookie.pdrv,
2094 xptplistpdrvfunc, cdm);
2096 ret = xptpdrvtraverse(NULL, xptplistpdrvfunc, cdm);
2099 * If we get back 0, that means that we had to stop before fully
2100 * traversing the peripheral driver tree. It also means that one of
2101 * the subroutines has set the status field to the proper value. If
2102 * we get back 1, we've fully traversed the EDT and copied out any
2106 cdm->status = CAM_DEV_MATCH_LAST;
2112 xptbustraverse(struct cam_eb *start_bus, xpt_busfunc_t *tr_func, void *arg)
2114 struct cam_eb *bus, *next_bus;
2119 mtx_lock(&xsoftc.xpt_topo_lock);
2120 for (bus = (start_bus ? start_bus : TAILQ_FIRST(&xsoftc.xpt_busses));
2123 next_bus = TAILQ_NEXT(bus, links);
2125 mtx_unlock(&xsoftc.xpt_topo_lock);
2126 CAM_SIM_LOCK(bus->sim);
2127 retval = tr_func(bus, arg);
2128 CAM_SIM_UNLOCK(bus->sim);
2131 mtx_lock(&xsoftc.xpt_topo_lock);
2133 mtx_unlock(&xsoftc.xpt_topo_lock);
2139 xpt_sim_opened(struct cam_sim *sim)
2142 struct cam_et *target;
2143 struct cam_ed *device;
2144 struct cam_periph *periph;
2146 KASSERT(sim->refcount >= 1, ("sim->refcount >= 1"));
2147 mtx_assert(sim->mtx, MA_OWNED);
2149 mtx_lock(&xsoftc.xpt_topo_lock);
2150 TAILQ_FOREACH(bus, &xsoftc.xpt_busses, links) {
2151 if (bus->sim != sim)
2154 TAILQ_FOREACH(target, &bus->et_entries, links) {
2155 TAILQ_FOREACH(device, &target->ed_entries, links) {
2156 SLIST_FOREACH(periph, &device->periphs,
2158 if (periph->refcount > 0) {
2159 mtx_unlock(&xsoftc.xpt_topo_lock);
2167 mtx_unlock(&xsoftc.xpt_topo_lock);
2172 xpttargettraverse(struct cam_eb *bus, struct cam_et *start_target,
2173 xpt_targetfunc_t *tr_func, void *arg)
2175 struct cam_et *target, *next_target;
2179 for (target = (start_target ? start_target :
2180 TAILQ_FIRST(&bus->et_entries));
2181 target != NULL; target = next_target) {
2183 next_target = TAILQ_NEXT(target, links);
2185 retval = tr_func(target, arg);
2195 xptdevicetraverse(struct cam_et *target, struct cam_ed *start_device,
2196 xpt_devicefunc_t *tr_func, void *arg)
2198 struct cam_ed *device, *next_device;
2202 for (device = (start_device ? start_device :
2203 TAILQ_FIRST(&target->ed_entries));
2205 device = next_device) {
2207 next_device = TAILQ_NEXT(device, links);
2209 retval = tr_func(device, arg);
2219 xptperiphtraverse(struct cam_ed *device, struct cam_periph *start_periph,
2220 xpt_periphfunc_t *tr_func, void *arg)
2222 struct cam_periph *periph, *next_periph;
2227 for (periph = (start_periph ? start_periph :
2228 SLIST_FIRST(&device->periphs));
2230 periph = next_periph) {
2232 next_periph = SLIST_NEXT(periph, periph_links);
2234 retval = tr_func(periph, arg);
2243 xptpdrvtraverse(struct periph_driver **start_pdrv,
2244 xpt_pdrvfunc_t *tr_func, void *arg)
2246 struct periph_driver **pdrv;
2252 * We don't traverse the peripheral driver list like we do the
2253 * other lists, because it is a linker set, and therefore cannot be
2254 * changed during runtime. If the peripheral driver list is ever
2255 * re-done to be something other than a linker set (i.e. it can
2256 * change while the system is running), the list traversal should
2257 * be modified to work like the other traversal functions.
2259 for (pdrv = (start_pdrv ? start_pdrv : periph_drivers);
2260 *pdrv != NULL; pdrv++) {
2261 retval = tr_func(pdrv, arg);
2271 xptpdperiphtraverse(struct periph_driver **pdrv,
2272 struct cam_periph *start_periph,
2273 xpt_periphfunc_t *tr_func, void *arg)
2275 struct cam_periph *periph, *next_periph;
2280 for (periph = (start_periph ? start_periph :
2281 TAILQ_FIRST(&(*pdrv)->units)); periph != NULL;
2282 periph = next_periph) {
2284 next_periph = TAILQ_NEXT(periph, unit_links);
2286 retval = tr_func(periph, arg);
2294 xptdefbusfunc(struct cam_eb *bus, void *arg)
2296 struct xpt_traverse_config *tr_config;
2298 tr_config = (struct xpt_traverse_config *)arg;
2300 if (tr_config->depth == XPT_DEPTH_BUS) {
2301 xpt_busfunc_t *tr_func;
2303 tr_func = (xpt_busfunc_t *)tr_config->tr_func;
2305 return(tr_func(bus, tr_config->tr_arg));
2307 return(xpttargettraverse(bus, NULL, xptdeftargetfunc, arg));
2311 xptdeftargetfunc(struct cam_et *target, void *arg)
2313 struct xpt_traverse_config *tr_config;
2315 tr_config = (struct xpt_traverse_config *)arg;
2317 if (tr_config->depth == XPT_DEPTH_TARGET) {
2318 xpt_targetfunc_t *tr_func;
2320 tr_func = (xpt_targetfunc_t *)tr_config->tr_func;
2322 return(tr_func(target, tr_config->tr_arg));
2324 return(xptdevicetraverse(target, NULL, xptdefdevicefunc, arg));
2328 xptdefdevicefunc(struct cam_ed *device, void *arg)
2330 struct xpt_traverse_config *tr_config;
2332 tr_config = (struct xpt_traverse_config *)arg;
2334 if (tr_config->depth == XPT_DEPTH_DEVICE) {
2335 xpt_devicefunc_t *tr_func;
2337 tr_func = (xpt_devicefunc_t *)tr_config->tr_func;
2339 return(tr_func(device, tr_config->tr_arg));
2341 return(xptperiphtraverse(device, NULL, xptdefperiphfunc, arg));
2345 xptdefperiphfunc(struct cam_periph *periph, void *arg)
2347 struct xpt_traverse_config *tr_config;
2348 xpt_periphfunc_t *tr_func;
2350 tr_config = (struct xpt_traverse_config *)arg;
2352 tr_func = (xpt_periphfunc_t *)tr_config->tr_func;
2355 * Unlike the other default functions, we don't check for depth
2356 * here. The peripheral driver level is the last level in the EDT,
2357 * so if we're here, we should execute the function in question.
2359 return(tr_func(periph, tr_config->tr_arg));
2363 * Execute the given function for every bus in the EDT.
2366 xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg)
2368 struct xpt_traverse_config tr_config;
2370 tr_config.depth = XPT_DEPTH_BUS;
2371 tr_config.tr_func = tr_func;
2372 tr_config.tr_arg = arg;
2374 return(xptbustraverse(NULL, xptdefbusfunc, &tr_config));
2378 * Execute the given function for every device in the EDT.
2381 xpt_for_all_devices(xpt_devicefunc_t *tr_func, void *arg)
2383 struct xpt_traverse_config tr_config;
2385 tr_config.depth = XPT_DEPTH_DEVICE;
2386 tr_config.tr_func = tr_func;
2387 tr_config.tr_arg = arg;
2389 return(xptbustraverse(NULL, xptdefbusfunc, &tr_config));
2393 xptsetasyncfunc(struct cam_ed *device, void *arg)
2395 struct cam_path path;
2396 struct ccb_getdev cgd;
2397 struct ccb_setasync *csa = (struct ccb_setasync *)arg;
2400 * Don't report unconfigured devices (Wildcard devs,
2401 * devices only for target mode, device instances
2402 * that have been invalidated but are waiting for
2403 * their last reference count to be released).
2405 if ((device->flags & CAM_DEV_UNCONFIGURED) != 0)
2408 xpt_compile_path(&path,
2410 device->target->bus->path_id,
2411 device->target->target_id,
2413 xpt_setup_ccb(&cgd.ccb_h, &path, CAM_PRIORITY_NORMAL);
2414 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
2415 xpt_action((union ccb *)&cgd);
2416 csa->callback(csa->callback_arg,
2419 xpt_release_path(&path);
2425 xptsetasyncbusfunc(struct cam_eb *bus, void *arg)
2427 struct cam_path path;
2428 struct ccb_pathinq cpi;
2429 struct ccb_setasync *csa = (struct ccb_setasync *)arg;
2431 xpt_compile_path(&path, /*periph*/NULL,
2433 CAM_TARGET_WILDCARD,
2435 xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
2436 cpi.ccb_h.func_code = XPT_PATH_INQ;
2437 xpt_action((union ccb *)&cpi);
2438 csa->callback(csa->callback_arg,
2441 xpt_release_path(&path);
2447 xpt_action(union ccb *start_ccb)
2450 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_action\n"));
2452 start_ccb->ccb_h.status = CAM_REQ_INPROG;
2453 /* Compatibility for RL-unaware code. */
2454 if (CAM_PRIORITY_TO_RL(start_ccb->ccb_h.pinfo.priority) == 0)
2455 start_ccb->ccb_h.pinfo.priority += CAM_PRIORITY_NORMAL - 1;
2456 (*(start_ccb->ccb_h.path->bus->xport->action))(start_ccb);
2460 xpt_action_default(union ccb *start_ccb)
2463 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_action_default\n"));
2466 switch (start_ccb->ccb_h.func_code) {
2469 struct cam_ed *device;
2471 char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
2472 struct cam_path *path;
2474 path = start_ccb->ccb_h.path;
2478 * For the sake of compatibility with SCSI-1
2479 * devices that may not understand the identify
2480 * message, we include lun information in the
2481 * second byte of all commands. SCSI-1 specifies
2482 * that luns are a 3 bit value and reserves only 3
2483 * bits for lun information in the CDB. Later
2484 * revisions of the SCSI spec allow for more than 8
2485 * luns, but have deprecated lun information in the
2486 * CDB. So, if the lun won't fit, we must omit.
2488 * Also be aware that during initial probing for devices,
2489 * the inquiry information is unknown but initialized to 0.
2490 * This means that this code will be exercised while probing
2491 * devices with an ANSI revision greater than 2.
2493 device = start_ccb->ccb_h.path->device;
2494 if (device->protocol_version <= SCSI_REV_2
2495 && start_ccb->ccb_h.target_lun < 8
2496 && (start_ccb->ccb_h.flags & CAM_CDB_POINTER) == 0) {
2498 start_ccb->csio.cdb_io.cdb_bytes[1] |=
2499 start_ccb->ccb_h.target_lun << 5;
2501 start_ccb->csio.scsi_status = SCSI_STATUS_OK;
2502 CAM_DEBUG(path, CAM_DEBUG_CDB,("%s. CDB: %s\n",
2503 scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
2504 &path->device->inq_data),
2505 scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
2506 cdb_str, sizeof(cdb_str))));
2510 case XPT_CONT_TARGET_IO:
2511 start_ccb->csio.sense_resid = 0;
2512 start_ccb->csio.resid = 0;
2515 if (start_ccb->ccb_h.func_code == XPT_ATA_IO) {
2516 start_ccb->ataio.resid = 0;
2521 struct cam_path *path = start_ccb->ccb_h.path;
2524 frozen = cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
2525 path->device->sim->devq->alloc_openings += frozen;
2527 xpt_run_dev_allocq(path->bus);
2528 if (xpt_schedule_dev_sendq(path->bus, path->device))
2529 xpt_run_dev_sendq(path->bus);
2532 case XPT_CALC_GEOMETRY:
2534 struct cam_sim *sim;
2536 /* Filter out garbage */
2537 if (start_ccb->ccg.block_size == 0
2538 || start_ccb->ccg.volume_size == 0) {
2539 start_ccb->ccg.cylinders = 0;
2540 start_ccb->ccg.heads = 0;
2541 start_ccb->ccg.secs_per_track = 0;
2542 start_ccb->ccb_h.status = CAM_REQ_CMP;
2547 * In a PC-98 system, geometry translation depens on
2548 * the "real" device geometry obtained from mode page 4.
2549 * SCSI geometry translation is performed in the
2550 * initialization routine of the SCSI BIOS and the result
2551 * stored in host memory. If the translation is available
2552 * in host memory, use it. If not, rely on the default
2553 * translation the device driver performs.
2555 if (scsi_da_bios_params(&start_ccb->ccg) != 0) {
2556 start_ccb->ccb_h.status = CAM_REQ_CMP;
2560 sim = start_ccb->ccb_h.path->bus->sim;
2561 (*(sim->sim_action))(sim, start_ccb);
2566 union ccb* abort_ccb;
2568 abort_ccb = start_ccb->cab.abort_ccb;
2569 if (XPT_FC_IS_DEV_QUEUED(abort_ccb)) {
2571 if (abort_ccb->ccb_h.pinfo.index >= 0) {
2572 struct cam_ccbq *ccbq;
2573 struct cam_ed *device;
2575 device = abort_ccb->ccb_h.path->device;
2576 ccbq = &device->ccbq;
2577 device->sim->devq->alloc_openings -=
2578 cam_ccbq_remove_ccb(ccbq, abort_ccb);
2579 abort_ccb->ccb_h.status =
2580 CAM_REQ_ABORTED|CAM_DEV_QFRZN;
2581 xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
2582 xpt_done(abort_ccb);
2583 start_ccb->ccb_h.status = CAM_REQ_CMP;
2586 if (abort_ccb->ccb_h.pinfo.index == CAM_UNQUEUED_INDEX
2587 && (abort_ccb->ccb_h.status & CAM_SIM_QUEUED) == 0) {
2589 * We've caught this ccb en route to
2590 * the SIM. Flag it for abort and the
2591 * SIM will do so just before starting
2592 * real work on the CCB.
2594 abort_ccb->ccb_h.status =
2595 CAM_REQ_ABORTED|CAM_DEV_QFRZN;
2596 xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
2597 start_ccb->ccb_h.status = CAM_REQ_CMP;
2601 if (XPT_FC_IS_QUEUED(abort_ccb)
2602 && (abort_ccb->ccb_h.pinfo.index == CAM_DONEQ_INDEX)) {
2604 * It's already completed but waiting
2605 * for our SWI to get to it.
2607 start_ccb->ccb_h.status = CAM_UA_ABORT;
2611 * If we weren't able to take care of the abort request
2612 * in the XPT, pass the request down to the SIM for processing.
2616 case XPT_ACCEPT_TARGET_IO:
2618 case XPT_IMMED_NOTIFY:
2619 case XPT_NOTIFY_ACK:
2621 case XPT_IMMEDIATE_NOTIFY:
2622 case XPT_NOTIFY_ACKNOWLEDGE:
2623 case XPT_GET_SIM_KNOB:
2624 case XPT_SET_SIM_KNOB:
2626 struct cam_sim *sim;
2628 sim = start_ccb->ccb_h.path->bus->sim;
2629 (*(sim->sim_action))(sim, start_ccb);
2634 struct cam_sim *sim;
2636 sim = start_ccb->ccb_h.path->bus->sim;
2637 (*(sim->sim_action))(sim, start_ccb);
2640 case XPT_PATH_STATS:
2641 start_ccb->cpis.last_reset =
2642 start_ccb->ccb_h.path->bus->last_reset;
2643 start_ccb->ccb_h.status = CAM_REQ_CMP;
2649 dev = start_ccb->ccb_h.path->device;
2650 if ((dev->flags & CAM_DEV_UNCONFIGURED) != 0) {
2651 start_ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2653 struct ccb_getdev *cgd;
2657 cgd = &start_ccb->cgd;
2658 bus = cgd->ccb_h.path->bus;
2659 tar = cgd->ccb_h.path->target;
2660 cgd->protocol = dev->protocol;
2661 cgd->inq_data = dev->inq_data;
2662 cgd->ident_data = dev->ident_data;
2663 cgd->inq_flags = dev->inq_flags;
2664 cgd->ccb_h.status = CAM_REQ_CMP;
2665 cgd->serial_num_len = dev->serial_num_len;
2666 if ((dev->serial_num_len > 0)
2667 && (dev->serial_num != NULL))
2668 bcopy(dev->serial_num, cgd->serial_num,
2669 dev->serial_num_len);
2673 case XPT_GDEV_STATS:
2677 dev = start_ccb->ccb_h.path->device;
2678 if ((dev->flags & CAM_DEV_UNCONFIGURED) != 0) {
2679 start_ccb->ccb_h.status = CAM_DEV_NOT_THERE;
2681 struct ccb_getdevstats *cgds;
2685 cgds = &start_ccb->cgds;
2686 bus = cgds->ccb_h.path->bus;
2687 tar = cgds->ccb_h.path->target;
2688 cgds->dev_openings = dev->ccbq.dev_openings;
2689 cgds->dev_active = dev->ccbq.dev_active;
2690 cgds->devq_openings = dev->ccbq.devq_openings;
2691 cgds->devq_queued = dev->ccbq.queue.entries;
2692 cgds->held = dev->ccbq.held;
2693 cgds->last_reset = tar->last_reset;
2694 cgds->maxtags = dev->maxtags;
2695 cgds->mintags = dev->mintags;
2696 if (timevalcmp(&tar->last_reset, &bus->last_reset, <))
2697 cgds->last_reset = bus->last_reset;
2698 cgds->ccb_h.status = CAM_REQ_CMP;
2704 struct cam_periph *nperiph;
2705 struct periph_list *periph_head;
2706 struct ccb_getdevlist *cgdl;
2708 struct cam_ed *device;
2715 * Don't want anyone mucking with our data.
2717 device = start_ccb->ccb_h.path->device;
2718 periph_head = &device->periphs;
2719 cgdl = &start_ccb->cgdl;
2722 * Check and see if the list has changed since the user
2723 * last requested a list member. If so, tell them that the
2724 * list has changed, and therefore they need to start over
2725 * from the beginning.
2727 if ((cgdl->index != 0) &&
2728 (cgdl->generation != device->generation)) {
2729 cgdl->status = CAM_GDEVLIST_LIST_CHANGED;
2734 * Traverse the list of peripherals and attempt to find
2735 * the requested peripheral.
2737 for (nperiph = SLIST_FIRST(periph_head), i = 0;
2738 (nperiph != NULL) && (i <= cgdl->index);
2739 nperiph = SLIST_NEXT(nperiph, periph_links), i++) {
2740 if (i == cgdl->index) {
2741 strncpy(cgdl->periph_name,
2742 nperiph->periph_name,
2744 cgdl->unit_number = nperiph->unit_number;
2749 cgdl->status = CAM_GDEVLIST_ERROR;
2753 if (nperiph == NULL)
2754 cgdl->status = CAM_GDEVLIST_LAST_DEVICE;
2756 cgdl->status = CAM_GDEVLIST_MORE_DEVS;
2759 cgdl->generation = device->generation;
2761 cgdl->ccb_h.status = CAM_REQ_CMP;
2766 dev_pos_type position_type;
2767 struct ccb_dev_match *cdm;
2769 cdm = &start_ccb->cdm;
2772 * There are two ways of getting at information in the EDT.
2773 * The first way is via the primary EDT tree. It starts
2774 * with a list of busses, then a list of targets on a bus,
2775 * then devices/luns on a target, and then peripherals on a
2776 * device/lun. The "other" way is by the peripheral driver
2777 * lists. The peripheral driver lists are organized by
2778 * peripheral driver. (obviously) So it makes sense to
2779 * use the peripheral driver list if the user is looking
2780 * for something like "da1", or all "da" devices. If the
2781 * user is looking for something on a particular bus/target
2782 * or lun, it's generally better to go through the EDT tree.
2785 if (cdm->pos.position_type != CAM_DEV_POS_NONE)
2786 position_type = cdm->pos.position_type;
2790 position_type = CAM_DEV_POS_NONE;
2792 for (i = 0; i < cdm->num_patterns; i++) {
2793 if ((cdm->patterns[i].type == DEV_MATCH_BUS)
2794 ||(cdm->patterns[i].type == DEV_MATCH_DEVICE)){
2795 position_type = CAM_DEV_POS_EDT;
2800 if (cdm->num_patterns == 0)
2801 position_type = CAM_DEV_POS_EDT;
2802 else if (position_type == CAM_DEV_POS_NONE)
2803 position_type = CAM_DEV_POS_PDRV;
2806 switch(position_type & CAM_DEV_POS_TYPEMASK) {
2807 case CAM_DEV_POS_EDT:
2810 case CAM_DEV_POS_PDRV:
2811 xptperiphlistmatch(cdm);
2814 cdm->status = CAM_DEV_MATCH_ERROR;
2818 if (cdm->status == CAM_DEV_MATCH_ERROR)
2819 start_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
2821 start_ccb->ccb_h.status = CAM_REQ_CMP;
2827 struct ccb_setasync *csa;
2828 struct async_node *cur_entry;
2829 struct async_list *async_head;
2832 csa = &start_ccb->csa;
2833 added = csa->event_enable;
2834 async_head = &csa->ccb_h.path->device->asyncs;
2837 * If there is already an entry for us, simply
2840 cur_entry = SLIST_FIRST(async_head);
2841 while (cur_entry != NULL) {
2842 if ((cur_entry->callback_arg == csa->callback_arg)
2843 && (cur_entry->callback == csa->callback))
2845 cur_entry = SLIST_NEXT(cur_entry, links);
2848 if (cur_entry != NULL) {
2850 * If the request has no flags set,
2853 added &= ~cur_entry->event_enable;
2854 if (csa->event_enable == 0) {
2855 SLIST_REMOVE(async_head, cur_entry,
2857 xpt_release_device(csa->ccb_h.path->device);
2858 free(cur_entry, M_CAMXPT);
2860 cur_entry->event_enable = csa->event_enable;
2862 csa->event_enable = added;
2864 cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT,
2866 if (cur_entry == NULL) {
2867 csa->ccb_h.status = CAM_RESRC_UNAVAIL;
2870 cur_entry->event_enable = csa->event_enable;
2871 cur_entry->callback_arg = csa->callback_arg;
2872 cur_entry->callback = csa->callback;
2873 SLIST_INSERT_HEAD(async_head, cur_entry, links);
2874 xpt_acquire_device(csa->ccb_h.path->device);
2876 start_ccb->ccb_h.status = CAM_REQ_CMP;
2881 struct ccb_relsim *crs;
2884 crs = &start_ccb->crs;
2885 dev = crs->ccb_h.path->device;
2888 crs->ccb_h.status = CAM_DEV_NOT_THERE;
2892 if ((crs->release_flags & RELSIM_ADJUST_OPENINGS) != 0) {
2894 if (INQ_DATA_TQ_ENABLED(&dev->inq_data)) {
2895 /* Don't ever go below one opening */
2896 if (crs->openings > 0) {
2897 xpt_dev_ccbq_resize(crs->ccb_h.path,
2901 xpt_print(crs->ccb_h.path,
2902 "tagged openings now %d\n",
2909 if ((crs->release_flags & RELSIM_RELEASE_AFTER_TIMEOUT) != 0) {
2911 if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) {
2914 * Just extend the old timeout and decrement
2915 * the freeze count so that a single timeout
2916 * is sufficient for releasing the queue.
2918 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
2919 callout_stop(&dev->callout);
2922 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
2925 callout_reset(&dev->callout,
2926 (crs->release_timeout * hz) / 1000,
2927 xpt_release_devq_timeout, dev);
2929 dev->flags |= CAM_DEV_REL_TIMEOUT_PENDING;
2933 if ((crs->release_flags & RELSIM_RELEASE_AFTER_CMDCMPLT) != 0) {
2935 if ((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0) {
2937 * Decrement the freeze count so that a single
2938 * completion is still sufficient to unfreeze
2941 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
2944 dev->flags |= CAM_DEV_REL_ON_COMPLETE;
2945 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
2949 if ((crs->release_flags & RELSIM_RELEASE_AFTER_QEMPTY) != 0) {
2951 if ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
2952 || (dev->ccbq.dev_active == 0)) {
2954 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
2957 dev->flags |= CAM_DEV_REL_ON_QUEUE_EMPTY;
2958 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
2962 if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) {
2963 xpt_release_devq_rl(crs->ccb_h.path, /*runlevel*/
2964 (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ?
2965 crs->release_timeout : 0,
2966 /*count*/1, /*run_queue*/TRUE);
2968 start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt[0];
2969 start_ccb->ccb_h.status = CAM_REQ_CMP;
2974 #ifdef CAM_DEBUG_DELAY
2975 cam_debug_delay = CAM_DEBUG_DELAY;
2977 cam_dflags = start_ccb->cdbg.flags;
2978 if (cam_dpath != NULL) {
2979 xpt_free_path(cam_dpath);
2983 if (cam_dflags != CAM_DEBUG_NONE) {
2984 if (xpt_create_path(&cam_dpath, xpt_periph,
2985 start_ccb->ccb_h.path_id,
2986 start_ccb->ccb_h.target_id,
2987 start_ccb->ccb_h.target_lun) !=
2989 start_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
2990 cam_dflags = CAM_DEBUG_NONE;
2992 start_ccb->ccb_h.status = CAM_REQ_CMP;
2993 xpt_print(cam_dpath, "debugging flags now %x\n",
2998 start_ccb->ccb_h.status = CAM_REQ_CMP;
3000 #else /* !CAMDEBUG */
3001 start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
3002 #endif /* CAMDEBUG */
3005 case XPT_FREEZE_QUEUE:
3007 struct ccb_relsim *crs = &start_ccb->crs;
3009 xpt_freeze_devq_rl(crs->ccb_h.path, /*runlevel*/
3010 (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ?
3011 crs->release_timeout : 0, /*count*/1);
3012 start_ccb->ccb_h.status = CAM_REQ_CMP;
3016 if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0)
3017 xpt_freeze_devq(start_ccb->ccb_h.path, 1);
3018 start_ccb->ccb_h.status = CAM_REQ_CMP;
3025 start_ccb->ccb_h.status = CAM_PROVIDE_FAIL;
3031 xpt_polled_action(union ccb *start_ccb)
3034 struct cam_sim *sim;
3035 struct cam_devq *devq;
3039 timeout = start_ccb->ccb_h.timeout;
3040 sim = start_ccb->ccb_h.path->bus->sim;
3042 dev = start_ccb->ccb_h.path->device;
3044 mtx_assert(sim->mtx, MA_OWNED);
3047 * Steal an opening so that no other queued requests
3048 * can get it before us while we simulate interrupts.
3050 dev->ccbq.devq_openings--;
3051 dev->ccbq.dev_openings--;
3053 while(((devq != NULL && devq->send_openings <= 0) ||
3054 dev->ccbq.dev_openings < 0) && (--timeout > 0)) {
3056 (*(sim->sim_poll))(sim);
3057 camisr_runqueue(&sim->sim_doneq);
3060 dev->ccbq.devq_openings++;
3061 dev->ccbq.dev_openings++;
3064 xpt_action(start_ccb);
3065 while(--timeout > 0) {
3066 (*(sim->sim_poll))(sim);
3067 camisr_runqueue(&sim->sim_doneq);
3068 if ((start_ccb->ccb_h.status & CAM_STATUS_MASK)
3075 * XXX Is it worth adding a sim_timeout entry
3076 * point so we can attempt recovery? If
3077 * this is only used for dumps, I don't think
3080 start_ccb->ccb_h.status = CAM_CMD_TIMEOUT;
3083 start_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
3088 * Schedule a peripheral driver to receive a ccb when it's
3089 * target device has space for more transactions.
3092 xpt_schedule(struct cam_periph *perph, u_int32_t new_priority)
3094 struct cam_ed *device;
3097 mtx_assert(perph->sim->mtx, MA_OWNED);
3099 CAM_DEBUG(perph->path, CAM_DEBUG_TRACE, ("xpt_schedule\n"));
3100 device = perph->path->device;
3101 if (periph_is_queued(perph)) {
3102 /* Simply reorder based on new priority */
3103 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
3104 (" change priority to %d\n", new_priority));
3105 if (new_priority < perph->pinfo.priority) {
3106 camq_change_priority(&device->drvq,
3109 runq = xpt_schedule_dev_allocq(perph->path->bus, device);
3112 /* New entry on the queue */
3113 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
3114 (" added periph to queue\n"));
3115 perph->pinfo.priority = new_priority;
3116 perph->pinfo.generation = ++device->drvq.generation;
3117 camq_insert(&device->drvq, &perph->pinfo);
3118 runq = xpt_schedule_dev_allocq(perph->path->bus, device);
3121 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
3122 (" calling xpt_run_devq\n"));
3123 xpt_run_dev_allocq(perph->path->bus);
3129 * Schedule a device to run on a given queue.
3130 * If the device was inserted as a new entry on the queue,
3131 * return 1 meaning the device queue should be run. If we
3132 * were already queued, implying someone else has already
3133 * started the queue, return 0 so the caller doesn't attempt
3137 xpt_schedule_dev(struct camq *queue, cam_pinfo *pinfo,
3138 u_int32_t new_priority)
3141 u_int32_t old_priority;
3143 CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_schedule_dev\n"));
3145 old_priority = pinfo->priority;
3148 * Are we already queued?
3150 if (pinfo->index != CAM_UNQUEUED_INDEX) {
3151 /* Simply reorder based on new priority */
3152 if (new_priority < old_priority) {
3153 camq_change_priority(queue, pinfo->index,
3155 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3156 ("changed priority to %d\n",
3162 /* New entry on the queue */
3163 if (new_priority < old_priority)
3164 pinfo->priority = new_priority;
3166 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3167 ("Inserting onto queue\n"));
3168 pinfo->generation = ++queue->generation;
3169 camq_insert(queue, pinfo);
3176 xpt_run_dev_allocq(struct cam_eb *bus)
3178 struct cam_devq *devq;
3180 CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq\n"));
3181 devq = bus->sim->devq;
3183 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3184 (" qfrozen_cnt == 0x%x, entries == %d, "
3185 "openings == %d, active == %d\n",
3186 devq->alloc_queue.qfrozen_cnt[0],
3187 devq->alloc_queue.entries,
3188 devq->alloc_openings,
3189 devq->alloc_active));
3191 devq->alloc_queue.qfrozen_cnt[0]++;
3192 while ((devq->alloc_queue.entries > 0)
3193 && (devq->alloc_openings > 0)
3194 && (devq->alloc_queue.qfrozen_cnt[0] <= 1)) {
3195 struct cam_ed_qinfo *qinfo;
3196 struct cam_ed *device;
3197 union ccb *work_ccb;
3198 struct cam_periph *drv;
3201 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue,
3203 device = qinfo->device;
3204 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3205 ("running device %p\n", device));
3207 drvq = &device->drvq;
3210 if (drvq->entries <= 0) {
3211 panic("xpt_run_dev_allocq: "
3212 "Device on queue without any work to do");
3215 if ((work_ccb = xpt_get_ccb(device)) != NULL) {
3216 devq->alloc_openings--;
3217 devq->alloc_active++;
3218 drv = (struct cam_periph*)camq_remove(drvq, CAMQ_HEAD);
3219 xpt_setup_ccb(&work_ccb->ccb_h, drv->path,
3220 drv->pinfo.priority);
3221 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3222 ("calling periph start\n"));
3223 drv->periph_start(drv, work_ccb);
3226 * Malloc failure in alloc_ccb
3229 * XXX add us to a list to be run from free_ccb
3230 * if we don't have any ccbs active on this
3231 * device queue otherwise we may never get run
3237 /* We may have more work. Attempt to reschedule. */
3238 xpt_schedule_dev_allocq(bus, device);
3240 devq->alloc_queue.qfrozen_cnt[0]--;
3244 xpt_run_dev_sendq(struct cam_eb *bus)
3246 struct cam_devq *devq;
3248 CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_sendq\n"));
3250 devq = bus->sim->devq;
3252 devq->send_queue.qfrozen_cnt[0]++;
3253 while ((devq->send_queue.entries > 0)
3254 && (devq->send_openings > 0)
3255 && (devq->send_queue.qfrozen_cnt[0] <= 1)) {
3256 struct cam_ed_qinfo *qinfo;
3257 struct cam_ed *device;
3258 union ccb *work_ccb;
3259 struct cam_sim *sim;
3261 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue,
3263 device = qinfo->device;
3264 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
3265 ("running device %p\n", device));
3267 work_ccb = cam_ccbq_peek_ccb(&device->ccbq, CAMQ_HEAD);
3268 if (work_ccb == NULL) {
3269 printf("device on run queue with no ccbs???\n");
3273 if ((work_ccb->ccb_h.flags & CAM_HIGH_POWER) != 0) {
3275 mtx_lock(&xsoftc.xpt_lock);
3276 if (xsoftc.num_highpower <= 0) {
3278 * We got a high power command, but we
3279 * don't have any available slots. Freeze
3280 * the device queue until we have a slot
3283 xpt_freeze_devq(work_ccb->ccb_h.path, 1);
3284 STAILQ_INSERT_TAIL(&xsoftc.highpowerq,
3288 mtx_unlock(&xsoftc.xpt_lock);
3292 * Consume a high power slot while
3295 xsoftc.num_highpower--;
3297 mtx_unlock(&xsoftc.xpt_lock);
3299 cam_ccbq_remove_ccb(&device->ccbq, work_ccb);
3300 cam_ccbq_send_ccb(&device->ccbq, work_ccb);
3302 devq->send_openings--;
3303 devq->send_active++;
3305 xpt_schedule_dev_sendq(bus, device);
3307 if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){
3309 * The client wants to freeze the queue
3310 * after this CCB is sent.
3312 xpt_freeze_devq(work_ccb->ccb_h.path, 1);
3315 /* In Target mode, the peripheral driver knows best... */
3316 if (work_ccb->ccb_h.func_code == XPT_SCSI_IO) {
3317 if ((device->inq_flags & SID_CmdQue) != 0
3318 && work_ccb->csio.tag_action != CAM_TAG_ACTION_NONE)
3319 work_ccb->ccb_h.flags |= CAM_TAG_ACTION_VALID;
3322 * Clear this in case of a retried CCB that
3323 * failed due to a rejected tag.
3325 work_ccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
3329 * Device queues can be shared among multiple sim instances
3330 * that reside on different busses. Use the SIM in the queue
3331 * CCB's path, rather than the one in the bus that was passed
3332 * into this function.
3334 sim = work_ccb->ccb_h.path->bus->sim;
3335 (*(sim->sim_action))(sim, work_ccb);
3337 devq->send_queue.qfrozen_cnt[0]--;
3341 * This function merges stuff from the slave ccb into the master ccb, while
3342 * keeping important fields in the master ccb constant.
3345 xpt_merge_ccb(union ccb *master_ccb, union ccb *slave_ccb)
3349 * Pull fields that are valid for peripheral drivers to set
3350 * into the master CCB along with the CCB "payload".
3352 master_ccb->ccb_h.retry_count = slave_ccb->ccb_h.retry_count;
3353 master_ccb->ccb_h.func_code = slave_ccb->ccb_h.func_code;
3354 master_ccb->ccb_h.timeout = slave_ccb->ccb_h.timeout;
3355 master_ccb->ccb_h.flags = slave_ccb->ccb_h.flags;
3356 bcopy(&(&slave_ccb->ccb_h)[1], &(&master_ccb->ccb_h)[1],
3357 sizeof(union ccb) - sizeof(struct ccb_hdr));
3361 xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
3364 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_setup_ccb\n"));
3365 ccb_h->pinfo.priority = priority;
3367 ccb_h->path_id = path->bus->path_id;
3369 ccb_h->target_id = path->target->target_id;
3371 ccb_h->target_id = CAM_TARGET_WILDCARD;
3373 ccb_h->target_lun = path->device->lun_id;
3374 ccb_h->pinfo.generation = ++path->device->ccbq.queue.generation;
3376 ccb_h->target_lun = CAM_TARGET_WILDCARD;
3378 ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
3382 /* Path manipulation functions */
3384 xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph,
3385 path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
3387 struct cam_path *path;
3390 path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_NOWAIT);
3393 status = CAM_RESRC_UNAVAIL;
3396 status = xpt_compile_path(path, perph, path_id, target_id, lun_id);
3397 if (status != CAM_REQ_CMP) {
3398 free(path, M_CAMXPT);
3401 *new_path_ptr = path;
3406 xpt_create_path_unlocked(struct cam_path **new_path_ptr,
3407 struct cam_periph *periph, path_id_t path_id,
3408 target_id_t target_id, lun_id_t lun_id)
3410 struct cam_path *path;
3411 struct cam_eb *bus = NULL;
3413 int need_unlock = 0;
3415 path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_WAITOK);
3417 if (path_id != CAM_BUS_WILDCARD) {
3418 bus = xpt_find_bus(path_id);
3421 CAM_SIM_LOCK(bus->sim);
3424 status = xpt_compile_path(path, periph, path_id, target_id, lun_id);
3426 CAM_SIM_UNLOCK(bus->sim);
3427 if (status != CAM_REQ_CMP) {
3428 free(path, M_CAMXPT);
3431 *new_path_ptr = path;
3436 xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,
3437 path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
3440 struct cam_et *target;
3441 struct cam_ed *device;
3444 status = CAM_REQ_CMP; /* Completed without error */
3445 target = NULL; /* Wildcarded */
3446 device = NULL; /* Wildcarded */
3449 * We will potentially modify the EDT, so block interrupts
3450 * that may attempt to create cam paths.
3452 bus = xpt_find_bus(path_id);
3454 status = CAM_PATH_INVALID;
3456 target = xpt_find_target(bus, target_id);
3457 if (target == NULL) {
3459 struct cam_et *new_target;
3461 new_target = xpt_alloc_target(bus, target_id);
3462 if (new_target == NULL) {
3463 status = CAM_RESRC_UNAVAIL;
3465 target = new_target;
3468 if (target != NULL) {
3469 device = xpt_find_device(target, lun_id);
3470 if (device == NULL) {
3472 struct cam_ed *new_device;
3475 (*(bus->xport->alloc_device))(bus,
3478 if (new_device == NULL) {
3479 status = CAM_RESRC_UNAVAIL;
3481 device = new_device;
3488 * Only touch the user's data if we are successful.
3490 if (status == CAM_REQ_CMP) {
3491 new_path->periph = perph;
3492 new_path->bus = bus;
3493 new_path->target = target;
3494 new_path->device = device;
3495 CAM_DEBUG(new_path, CAM_DEBUG_TRACE, ("xpt_compile_path\n"));
3498 xpt_release_device(device);
3500 xpt_release_target(target);
3502 xpt_release_bus(bus);
3508 xpt_release_path(struct cam_path *path)
3510 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n"));
3511 if (path->device != NULL) {
3512 xpt_release_device(path->device);
3513 path->device = NULL;
3515 if (path->target != NULL) {
3516 xpt_release_target(path->target);
3517 path->target = NULL;
3519 if (path->bus != NULL) {
3520 xpt_release_bus(path->bus);
3526 xpt_free_path(struct cam_path *path)
3529 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_free_path\n"));
3530 xpt_release_path(path);
3531 free(path, M_CAMXPT);
3536 * Return -1 for failure, 0 for exact match, 1 for match with wildcards
3537 * in path1, 2 for match with wildcards in path2.
3540 xpt_path_comp(struct cam_path *path1, struct cam_path *path2)
3544 if (path1->bus != path2->bus) {
3545 if (path1->bus->path_id == CAM_BUS_WILDCARD)
3547 else if (path2->bus->path_id == CAM_BUS_WILDCARD)
3552 if (path1->target != path2->target) {
3553 if (path1->target->target_id == CAM_TARGET_WILDCARD) {
3556 } else if (path2->target->target_id == CAM_TARGET_WILDCARD)
3561 if (path1->device != path2->device) {
3562 if (path1->device->lun_id == CAM_LUN_WILDCARD) {
3565 } else if (path2->device->lun_id == CAM_LUN_WILDCARD)
3574 xpt_print_path(struct cam_path *path)
3578 printf("(nopath): ");
3580 if (path->periph != NULL)
3581 printf("(%s%d:", path->periph->periph_name,
3582 path->periph->unit_number);
3584 printf("(noperiph:");
3586 if (path->bus != NULL)
3587 printf("%s%d:%d:", path->bus->sim->sim_name,
3588 path->bus->sim->unit_number,
3589 path->bus->sim->bus_id);
3593 if (path->target != NULL)
3594 printf("%d:", path->target->target_id);
3598 if (path->device != NULL)
3599 printf("%d): ", path->device->lun_id);
3606 xpt_print(struct cam_path *path, const char *fmt, ...)
3609 xpt_print_path(path);
3616 xpt_path_string(struct cam_path *path, char *str, size_t str_len)
3621 if (path != NULL && path->bus != NULL)
3622 mtx_assert(path->bus->sim->mtx, MA_OWNED);
3625 sbuf_new(&sb, str, str_len, 0);
3628 sbuf_printf(&sb, "(nopath): ");
3630 if (path->periph != NULL)
3631 sbuf_printf(&sb, "(%s%d:", path->periph->periph_name,
3632 path->periph->unit_number);
3634 sbuf_printf(&sb, "(noperiph:");
3636 if (path->bus != NULL)
3637 sbuf_printf(&sb, "%s%d:%d:", path->bus->sim->sim_name,
3638 path->bus->sim->unit_number,
3639 path->bus->sim->bus_id);
3641 sbuf_printf(&sb, "nobus:");
3643 if (path->target != NULL)
3644 sbuf_printf(&sb, "%d:", path->target->target_id);
3646 sbuf_printf(&sb, "X:");
3648 if (path->device != NULL)
3649 sbuf_printf(&sb, "%d): ", path->device->lun_id);
3651 sbuf_printf(&sb, "X): ");
3655 return(sbuf_len(&sb));
3659 xpt_path_path_id(struct cam_path *path)
3661 mtx_assert(path->bus->sim->mtx, MA_OWNED);
3663 return(path->bus->path_id);
3667 xpt_path_target_id(struct cam_path *path)
3669 mtx_assert(path->bus->sim->mtx, MA_OWNED);
3671 if (path->target != NULL)
3672 return (path->target->target_id);
3674 return (CAM_TARGET_WILDCARD);
3678 xpt_path_lun_id(struct cam_path *path)
3680 mtx_assert(path->bus->sim->mtx, MA_OWNED);
3682 if (path->device != NULL)
3683 return (path->device->lun_id);
3685 return (CAM_LUN_WILDCARD);
3689 xpt_path_sim(struct cam_path *path)
3692 return (path->bus->sim);
3696 xpt_path_periph(struct cam_path *path)
3698 mtx_assert(path->bus->sim->mtx, MA_OWNED);
3700 return (path->periph);
3704 * Release a CAM control block for the caller. Remit the cost of the structure
3705 * to the device referenced by the path. If the this device had no 'credits'
3706 * and peripheral drivers have registered async callbacks for this notification
3710 xpt_release_ccb(union ccb *free_ccb)
3712 struct cam_path *path;
3713 struct cam_ed *device;
3715 struct cam_sim *sim;
3717 CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_release_ccb\n"));
3718 path = free_ccb->ccb_h.path;
3719 device = path->device;
3723 mtx_assert(sim->mtx, MA_OWNED);
3725 cam_ccbq_release_opening(&device->ccbq);
3726 if (device->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) {
3727 device->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
3728 cam_ccbq_resize(&device->ccbq,
3729 device->ccbq.dev_openings + device->ccbq.dev_active);
3731 if (sim->ccb_count > sim->max_ccbs) {
3732 xpt_free_ccb(free_ccb);
3735 SLIST_INSERT_HEAD(&sim->ccb_freeq, &free_ccb->ccb_h,
3738 if (sim->devq == NULL) {
3741 sim->devq->alloc_openings++;
3742 sim->devq->alloc_active--;
3743 if (device_is_alloc_queued(device) == 0)
3744 xpt_schedule_dev_allocq(bus, device);
3745 xpt_run_dev_allocq(bus);
3748 /* Functions accessed by SIM drivers */
3750 static struct xpt_xport xport_default = {
3751 .alloc_device = xpt_alloc_device_default,
3752 .action = xpt_action_default,
3753 .async = xpt_dev_async_default,
3757 * A sim structure, listing the SIM entry points and instance
3758 * identification info is passed to xpt_bus_register to hook the SIM
3759 * into the CAM framework. xpt_bus_register creates a cam_eb entry
3760 * for this new bus and places it in the array of busses and assigns
3761 * it a path_id. The path_id may be influenced by "hard wiring"
3762 * information specified by the user. Once interrupt services are
3763 * available, the bus will be probed.
3766 xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
3768 struct cam_eb *new_bus;
3769 struct cam_eb *old_bus;
3770 struct ccb_pathinq cpi;
3771 struct cam_path *path;
3774 mtx_assert(sim->mtx, MA_OWNED);
3777 new_bus = (struct cam_eb *)malloc(sizeof(*new_bus),
3778 M_CAMXPT, M_NOWAIT);
3779 if (new_bus == NULL) {
3780 /* Couldn't satisfy request */
3781 return (CAM_RESRC_UNAVAIL);
3783 path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_NOWAIT);
3785 free(new_bus, M_CAMXPT);
3786 return (CAM_RESRC_UNAVAIL);
3789 if (strcmp(sim->sim_name, "xpt") != 0) {
3791 xptpathid(sim->sim_name, sim->unit_number, sim->bus_id);
3794 TAILQ_INIT(&new_bus->et_entries);
3795 new_bus->path_id = sim->path_id;
3798 timevalclear(&new_bus->last_reset);
3800 new_bus->refcount = 1; /* Held until a bus_deregister event */
3801 new_bus->generation = 0;
3803 mtx_lock(&xsoftc.xpt_topo_lock);
3804 old_bus = TAILQ_FIRST(&xsoftc.xpt_busses);
3805 while (old_bus != NULL
3806 && old_bus->path_id < new_bus->path_id)
3807 old_bus = TAILQ_NEXT(old_bus, links);
3808 if (old_bus != NULL)
3809 TAILQ_INSERT_BEFORE(old_bus, new_bus, links);
3811 TAILQ_INSERT_TAIL(&xsoftc.xpt_busses, new_bus, links);
3812 xsoftc.bus_generation++;
3813 mtx_unlock(&xsoftc.xpt_topo_lock);
3816 * Set a default transport so that a PATH_INQ can be issued to
3817 * the SIM. This will then allow for probing and attaching of
3818 * a more appropriate transport.
3820 new_bus->xport = &xport_default;
3822 status = xpt_compile_path(path, /*periph*/NULL, sim->path_id,
3823 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
3824 if (status != CAM_REQ_CMP)
3825 printf("xpt_compile_path returned %d\n", status);
3827 xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
3828 cpi.ccb_h.func_code = XPT_PATH_INQ;
3829 xpt_action((union ccb *)&cpi);
3831 if (cpi.ccb_h.status == CAM_REQ_CMP) {
3832 switch (cpi.transport) {
3839 new_bus->xport = scsi_get_xport();
3843 new_bus->xport = ata_get_xport();
3846 new_bus->xport = &xport_default;
3851 /* Notify interested parties */
3852 if (sim->path_id != CAM_XPT_PATH_ID) {
3853 union ccb *scan_ccb;
3855 xpt_async(AC_PATH_REGISTERED, path, &cpi);
3856 /* Initiate bus rescan. */
3857 scan_ccb = xpt_alloc_ccb_nowait();
3858 scan_ccb->ccb_h.path = path;
3859 scan_ccb->ccb_h.func_code = XPT_SCAN_BUS;
3860 scan_ccb->crcn.flags = 0;
3861 xpt_rescan(scan_ccb);
3863 xpt_free_path(path);
3864 return (CAM_SUCCESS);
3868 xpt_bus_deregister(path_id_t pathid)
3870 struct cam_path bus_path;
3873 status = xpt_compile_path(&bus_path, NULL, pathid,
3874 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
3875 if (status != CAM_REQ_CMP)
3878 xpt_async(AC_LOST_DEVICE, &bus_path, NULL);
3879 xpt_async(AC_PATH_DEREGISTERED, &bus_path, NULL);
3881 /* Release the reference count held while registered. */
3882 xpt_release_bus(bus_path.bus);
3883 xpt_release_path(&bus_path);
3885 return (CAM_REQ_CMP);
3889 xptnextfreepathid(void)
3896 mtx_lock(&xsoftc.xpt_topo_lock);
3897 bus = TAILQ_FIRST(&xsoftc.xpt_busses);
3899 /* Find an unoccupied pathid */
3900 while (bus != NULL && bus->path_id <= pathid) {
3901 if (bus->path_id == pathid)
3903 bus = TAILQ_NEXT(bus, links);
3905 mtx_unlock(&xsoftc.xpt_topo_lock);
3908 * Ensure that this pathid is not reserved for
3909 * a bus that may be registered in the future.
3911 if (resource_string_value("scbus", pathid, "at", &strval) == 0) {
3913 /* Start the search over */
3914 mtx_lock(&xsoftc.xpt_topo_lock);
3921 xptpathid(const char *sim_name, int sim_unit, int sim_bus)
3928 pathid = CAM_XPT_PATH_ID;
3929 snprintf(buf, sizeof(buf), "%s%d", sim_name, sim_unit);
3931 while ((resource_find_match(&i, &dname, &dunit, "at", buf)) == 0) {
3932 if (strcmp(dname, "scbus")) {
3933 /* Avoid a bit of foot shooting. */
3936 if (dunit < 0) /* unwired?! */
3938 if (resource_int_value("scbus", dunit, "bus", &val) == 0) {
3939 if (sim_bus == val) {
3943 } else if (sim_bus == 0) {
3944 /* Unspecified matches bus 0 */
3948 printf("Ambiguous scbus configuration for %s%d "
3949 "bus %d, cannot wire down. The kernel "
3950 "config entry for scbus%d should "
3951 "specify a controller bus.\n"
3952 "Scbus will be assigned dynamically.\n",
3953 sim_name, sim_unit, sim_bus, dunit);
3958 if (pathid == CAM_XPT_PATH_ID)
3959 pathid = xptnextfreepathid();
3964 xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
3967 struct cam_et *target, *next_target;
3968 struct cam_ed *device, *next_device;
3970 mtx_assert(path->bus->sim->mtx, MA_OWNED);
3972 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_async\n"));
3975 * Most async events come from a CAM interrupt context. In
3976 * a few cases, the error recovery code at the peripheral layer,
3977 * which may run from our SWI or a process context, may signal
3978 * deferred events with a call to xpt_async.
3983 if (async_code == AC_BUS_RESET) {
3984 /* Update our notion of when the last reset occurred */
3985 microtime(&bus->last_reset);
3988 for (target = TAILQ_FIRST(&bus->et_entries);
3990 target = next_target) {
3992 next_target = TAILQ_NEXT(target, links);
3994 if (path->target != target
3995 && path->target->target_id != CAM_TARGET_WILDCARD
3996 && target->target_id != CAM_TARGET_WILDCARD)
3999 if (async_code == AC_SENT_BDR) {
4000 /* Update our notion of when the last reset occurred */
4001 microtime(&path->target->last_reset);
4004 for (device = TAILQ_FIRST(&target->ed_entries);
4006 device = next_device) {
4008 next_device = TAILQ_NEXT(device, links);
4010 if (path->device != device
4011 && path->device->lun_id != CAM_LUN_WILDCARD
4012 && device->lun_id != CAM_LUN_WILDCARD)
4015 * The async callback could free the device.
4016 * If it is a broadcast async, it doesn't hold
4017 * device reference, so take our own reference.
4019 xpt_acquire_device(device);
4020 (*(bus->xport->async))(async_code, bus,
4024 xpt_async_bcast(&device->asyncs, async_code,
4026 xpt_release_device(device);
4031 * If this wasn't a fully wildcarded async, tell all
4032 * clients that want all async events.
4034 if (bus != xpt_periph->path->bus)
4035 xpt_async_bcast(&xpt_periph->path->device->asyncs, async_code,
4040 xpt_async_bcast(struct async_list *async_head,
4041 u_int32_t async_code,
4042 struct cam_path *path, void *async_arg)
4044 struct async_node *cur_entry;
4046 cur_entry = SLIST_FIRST(async_head);
4047 while (cur_entry != NULL) {
4048 struct async_node *next_entry;
4050 * Grab the next list entry before we call the current
4051 * entry's callback. This is because the callback function
4052 * can delete its async callback entry.
4054 next_entry = SLIST_NEXT(cur_entry, links);
4055 if ((cur_entry->event_enable & async_code) != 0)
4056 cur_entry->callback(cur_entry->callback_arg,
4059 cur_entry = next_entry;
4064 xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus,
4065 struct cam_et *target, struct cam_ed *device,
4068 printf("xpt_dev_async called\n");
4072 xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl, u_int count)
4074 struct cam_ed *dev = path->device;
4076 mtx_assert(path->bus->sim->mtx, MA_OWNED);
4077 dev->sim->devq->alloc_openings +=
4078 cam_ccbq_freeze(&dev->ccbq, rl, count);
4079 /* Remove frozen device from allocq. */
4080 if (device_is_alloc_queued(dev) &&
4081 cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL(
4082 CAMQ_GET_PRIO(&dev->drvq)))) {
4083 camq_remove(&dev->sim->devq->alloc_queue,
4084 dev->alloc_ccb_entry.pinfo.index);
4086 /* Remove frozen device from sendq. */
4087 if (device_is_send_queued(dev) &&
4088 cam_ccbq_frozen_top(&dev->ccbq)) {
4089 camq_remove(&dev->sim->devq->send_queue,
4090 dev->send_ccb_entry.pinfo.index);
4092 return (dev->ccbq.queue.qfrozen_cnt[rl]);
4096 xpt_freeze_devq(struct cam_path *path, u_int count)
4099 return (xpt_freeze_devq_rl(path, 0, count));
4103 xpt_freeze_simq(struct cam_sim *sim, u_int count)
4106 mtx_assert(sim->mtx, MA_OWNED);
4107 sim->devq->send_queue.qfrozen_cnt[0] += count;
4108 return (sim->devq->send_queue.qfrozen_cnt[0]);
4112 xpt_release_devq_timeout(void *arg)
4114 struct cam_ed *device;
4116 device = (struct cam_ed *)arg;
4118 xpt_release_devq_device(device, /*rl*/0, /*count*/1, /*run_queue*/TRUE);
4122 xpt_release_devq(struct cam_path *path, u_int count, int run_queue)
4124 mtx_assert(path->bus->sim->mtx, MA_OWNED);
4126 xpt_release_devq_device(path->device, /*rl*/0, count, run_queue);
4130 xpt_release_devq_rl(struct cam_path *path, cam_rl rl, u_int count, int run_queue)
4132 mtx_assert(path->bus->sim->mtx, MA_OWNED);
4134 xpt_release_devq_device(path->device, rl, count, run_queue);
4138 xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, u_int count, int run_queue)
4141 if (count > dev->ccbq.queue.qfrozen_cnt[rl]) {
4143 printf("xpt_release_devq(%d): requested %u > present %u\n",
4144 rl, count, dev->ccbq.queue.qfrozen_cnt[rl]);
4146 count = dev->ccbq.queue.qfrozen_cnt[rl];
4148 dev->sim->devq->alloc_openings -=
4149 cam_ccbq_release(&dev->ccbq, rl, count);
4150 if (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL(
4151 CAMQ_GET_PRIO(&dev->drvq))) == 0) {
4152 if (xpt_schedule_dev_allocq(dev->target->bus, dev))
4153 xpt_run_dev_allocq(dev->target->bus);
4155 if (cam_ccbq_frozen_top(&dev->ccbq) == 0) {
4157 * No longer need to wait for a successful
4158 * command completion.
4160 dev->flags &= ~CAM_DEV_REL_ON_COMPLETE;
4162 * Remove any timeouts that might be scheduled
4163 * to release this queue.
4165 if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) {
4166 callout_stop(&dev->callout);
4167 dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING;
4172 * Now that we are unfrozen schedule the
4173 * device so any pending transactions are
4176 if (xpt_schedule_dev_sendq(dev->target->bus, dev))
4177 xpt_run_dev_sendq(dev->target->bus);
4182 xpt_release_simq(struct cam_sim *sim, int run_queue)
4186 mtx_assert(sim->mtx, MA_OWNED);
4187 sendq = &(sim->devq->send_queue);
4188 if (sendq->qfrozen_cnt[0] <= 0) {
4190 printf("xpt_release_simq: requested 1 > present %u\n",
4191 sendq->qfrozen_cnt[0]);
4194 sendq->qfrozen_cnt[0]--;
4195 if (sendq->qfrozen_cnt[0] == 0) {
4197 * If there is a timeout scheduled to release this
4198 * sim queue, remove it. The queue frozen count is
4201 if ((sim->flags & CAM_SIM_REL_TIMEOUT_PENDING) != 0){
4202 callout_stop(&sim->callout);
4203 sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING;
4209 * Now that we are unfrozen run the send queue.
4211 bus = xpt_find_bus(sim->path_id);
4212 xpt_run_dev_sendq(bus);
4213 xpt_release_bus(bus);
4219 * XXX Appears to be unused.
4222 xpt_release_simq_timeout(void *arg)
4224 struct cam_sim *sim;
4226 sim = (struct cam_sim *)arg;
4227 xpt_release_simq(sim, /* run_queue */ TRUE);
4231 xpt_done(union ccb *done_ccb)
4233 struct cam_sim *sim;
4236 CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n"));
4237 if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) {
4239 * Queue up the request for handling by our SWI handler
4240 * any of the "non-immediate" type of ccbs.
4242 sim = done_ccb->ccb_h.path->bus->sim;
4243 TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h,
4245 done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
4246 if ((sim->flags & CAM_SIM_ON_DONEQ) == 0) {
4247 mtx_lock(&cam_simq_lock);
4248 first = TAILQ_EMPTY(&cam_simq);
4249 TAILQ_INSERT_TAIL(&cam_simq, sim, links);
4250 mtx_unlock(&cam_simq_lock);
4251 sim->flags |= CAM_SIM_ON_DONEQ;
4253 swi_sched(cambio_ih, 0);
4263 new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_ZERO|M_WAITOK);
4268 xpt_alloc_ccb_nowait()
4272 new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_ZERO|M_NOWAIT);
4277 xpt_free_ccb(union ccb *free_ccb)
4279 free(free_ccb, M_CAMXPT);
4284 /* Private XPT functions */
4287 * Get a CAM control block for the caller. Charge the structure to the device
4288 * referenced by the path. If the this device has no 'credits' then the
4289 * device already has the maximum number of outstanding operations under way
4290 * and we return NULL. If we don't have sufficient resources to allocate more
4291 * ccbs, we also return NULL.
4294 xpt_get_ccb(struct cam_ed *device)
4297 struct cam_sim *sim;
4300 if ((new_ccb = (union ccb *)SLIST_FIRST(&sim->ccb_freeq)) == NULL) {
4301 new_ccb = xpt_alloc_ccb_nowait();
4302 if (new_ccb == NULL) {
4305 if ((sim->flags & CAM_SIM_MPSAFE) == 0)
4306 callout_handle_init(&new_ccb->ccb_h.timeout_ch);
4307 SLIST_INSERT_HEAD(&sim->ccb_freeq, &new_ccb->ccb_h,
4311 cam_ccbq_take_opening(&device->ccbq);
4312 SLIST_REMOVE_HEAD(&sim->ccb_freeq, xpt_links.sle);
4317 xpt_release_bus(struct cam_eb *bus)
4320 if ((--bus->refcount == 0)
4321 && (TAILQ_FIRST(&bus->et_entries) == NULL)) {
4322 mtx_lock(&xsoftc.xpt_topo_lock);
4323 TAILQ_REMOVE(&xsoftc.xpt_busses, bus, links);
4324 xsoftc.bus_generation++;
4325 mtx_unlock(&xsoftc.xpt_topo_lock);
4326 cam_sim_release(bus->sim);
4327 free(bus, M_CAMXPT);
4331 static struct cam_et *
4332 xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
4334 struct cam_et *target;
4336 target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, M_NOWAIT);
4337 if (target != NULL) {
4338 struct cam_et *cur_target;
4340 TAILQ_INIT(&target->ed_entries);
4342 target->target_id = target_id;
4343 target->refcount = 1;
4344 target->generation = 0;
4345 timevalclear(&target->last_reset);
4347 * Hold a reference to our parent bus so it
4348 * will not go away before we do.
4352 /* Insertion sort into our bus's target list */
4353 cur_target = TAILQ_FIRST(&bus->et_entries);
4354 while (cur_target != NULL && cur_target->target_id < target_id)
4355 cur_target = TAILQ_NEXT(cur_target, links);
4357 if (cur_target != NULL) {
4358 TAILQ_INSERT_BEFORE(cur_target, target, links);
4360 TAILQ_INSERT_TAIL(&bus->et_entries, target, links);
4368 xpt_release_target(struct cam_et *target)
4371 if ((--target->refcount == 0)
4372 && (TAILQ_FIRST(&target->ed_entries) == NULL)) {
4373 TAILQ_REMOVE(&target->bus->et_entries, target, links);
4374 target->bus->generation++;
4375 xpt_release_bus(target->bus);
4376 free(target, M_CAMXPT);
4380 static struct cam_ed *
4381 xpt_alloc_device_default(struct cam_eb *bus, struct cam_et *target,
4384 struct cam_ed *device, *cur_device;
4386 device = xpt_alloc_device(bus, target, lun_id);
4390 device->mintags = 1;
4391 device->maxtags = 1;
4392 bus->sim->max_ccbs += device->ccbq.devq_openings;
4393 cur_device = TAILQ_FIRST(&target->ed_entries);
4394 while (cur_device != NULL && cur_device->lun_id < lun_id)
4395 cur_device = TAILQ_NEXT(cur_device, links);
4396 if (cur_device != NULL) {
4397 TAILQ_INSERT_BEFORE(cur_device, device, links);
4399 TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
4401 target->generation++;
4407 xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
4409 struct cam_ed *device;
4410 struct cam_devq *devq;
4413 /* Make space for us in the device queue on our bus */
4414 devq = bus->sim->devq;
4415 status = cam_devq_resize(devq, devq->alloc_queue.array_size + 1);
4417 if (status != CAM_REQ_CMP) {
4420 device = (struct cam_ed *)malloc(sizeof(*device),
4421 M_CAMXPT, M_NOWAIT);
4424 if (device != NULL) {
4425 cam_init_pinfo(&device->alloc_ccb_entry.pinfo);
4426 device->alloc_ccb_entry.device = device;
4427 cam_init_pinfo(&device->send_ccb_entry.pinfo);
4428 device->send_ccb_entry.device = device;
4429 device->target = target;
4430 device->lun_id = lun_id;
4431 device->sim = bus->sim;
4432 /* Initialize our queues */
4433 if (camq_init(&device->drvq, 0) != 0) {
4434 free(device, M_CAMXPT);
4437 if (cam_ccbq_init(&device->ccbq,
4438 bus->sim->max_dev_openings) != 0) {
4439 camq_fini(&device->drvq);
4440 free(device, M_CAMXPT);
4443 SLIST_INIT(&device->asyncs);
4444 SLIST_INIT(&device->periphs);
4445 device->generation = 0;
4446 device->owner = NULL;
4447 device->flags = CAM_DEV_UNCONFIGURED;
4448 device->tag_delay_count = 0;
4449 device->tag_saved_openings = 0;
4450 device->refcount = 1;
4451 callout_init_mtx(&device->callout, bus->sim->mtx, 0);
4454 * Hold a reference to our parent target so it
4455 * will not go away before we do.
4464 xpt_acquire_device(struct cam_ed *device)
4471 xpt_release_device(struct cam_ed *device)
4474 if (--device->refcount == 0) {
4475 struct cam_devq *devq;
4477 if (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX
4478 || device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX)
4479 panic("Removing device while still queued for ccbs");
4481 if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0)
4482 callout_stop(&device->callout);
4484 TAILQ_REMOVE(&device->target->ed_entries, device,links);
4485 device->target->generation++;
4486 device->target->bus->sim->max_ccbs -= device->ccbq.devq_openings;
4487 /* Release our slot in the devq */
4488 devq = device->target->bus->sim->devq;
4489 cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
4490 camq_fini(&device->drvq);
4491 cam_ccbq_fini(&device->ccbq);
4492 xpt_release_target(device->target);
4493 free(device, M_CAMXPT);
4498 xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
4506 diff = newopenings - (dev->ccbq.dev_active + dev->ccbq.dev_openings);
4507 result = cam_ccbq_resize(&dev->ccbq, newopenings);
4508 if (result == CAM_REQ_CMP && (diff < 0)) {
4509 dev->flags |= CAM_DEV_RESIZE_QUEUE_NEEDED;
4511 if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
4512 || (dev->inq_flags & SID_CmdQue) != 0)
4513 dev->tag_saved_openings = newopenings;
4514 /* Adjust the global limit */
4515 dev->sim->max_ccbs += diff;
4519 static struct cam_eb *
4520 xpt_find_bus(path_id_t path_id)
4524 mtx_lock(&xsoftc.xpt_topo_lock);
4525 for (bus = TAILQ_FIRST(&xsoftc.xpt_busses);
4527 bus = TAILQ_NEXT(bus, links)) {
4528 if (bus->path_id == path_id) {
4533 mtx_unlock(&xsoftc.xpt_topo_lock);
4537 static struct cam_et *
4538 xpt_find_target(struct cam_eb *bus, target_id_t target_id)
4540 struct cam_et *target;
4542 for (target = TAILQ_FIRST(&bus->et_entries);
4544 target = TAILQ_NEXT(target, links)) {
4545 if (target->target_id == target_id) {
4553 static struct cam_ed *
4554 xpt_find_device(struct cam_et *target, lun_id_t lun_id)
4556 struct cam_ed *device;
4558 for (device = TAILQ_FIRST(&target->ed_entries);
4560 device = TAILQ_NEXT(device, links)) {
4561 if (device->lun_id == lun_id) {
4570 xpt_start_tags(struct cam_path *path)
4572 struct ccb_relsim crs;
4573 struct cam_ed *device;
4574 struct cam_sim *sim;
4577 device = path->device;
4578 sim = path->bus->sim;
4579 device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
4580 xpt_freeze_devq(path, /*count*/1);
4581 device->inq_flags |= SID_CmdQue;
4582 if (device->tag_saved_openings != 0)
4583 newopenings = device->tag_saved_openings;
4585 newopenings = min(device->maxtags,
4586 sim->max_tagged_dev_openings);
4587 xpt_dev_ccbq_resize(path, newopenings);
4588 xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
4589 crs.ccb_h.func_code = XPT_REL_SIMQ;
4590 crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
4592 = crs.release_timeout
4595 xpt_action((union ccb *)&crs);
4599 xpt_stop_tags(struct cam_path *path)
4601 struct ccb_relsim crs;
4602 struct cam_ed *device;
4603 struct cam_sim *sim;
4605 device = path->device;
4606 sim = path->bus->sim;
4607 device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
4608 device->tag_delay_count = 0;
4609 xpt_freeze_devq(path, /*count*/1);
4610 device->inq_flags &= ~SID_CmdQue;
4611 xpt_dev_ccbq_resize(path, sim->max_dev_openings);
4612 xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
4613 crs.ccb_h.func_code = XPT_REL_SIMQ;
4614 crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
4616 = crs.release_timeout
4619 xpt_action((union ccb *)&crs);
4623 xpt_boot_delay(void *arg)
4630 xpt_config(void *arg)
4633 * Now that interrupts are enabled, go find our devices
4637 /* Setup debugging flags and path */
4638 #ifdef CAM_DEBUG_FLAGS
4639 cam_dflags = CAM_DEBUG_FLAGS;
4640 #else /* !CAM_DEBUG_FLAGS */
4641 cam_dflags = CAM_DEBUG_NONE;
4642 #endif /* CAM_DEBUG_FLAGS */
4643 #ifdef CAM_DEBUG_BUS
4644 if (cam_dflags != CAM_DEBUG_NONE) {
4646 * Locking is specifically omitted here. No SIMs have
4647 * registered yet, so xpt_create_path will only be searching
4648 * empty lists of targets and devices.
4650 if (xpt_create_path(&cam_dpath, xpt_periph,
4651 CAM_DEBUG_BUS, CAM_DEBUG_TARGET,
4652 CAM_DEBUG_LUN) != CAM_REQ_CMP) {
4653 printf("xpt_config: xpt_create_path() failed for debug"
4654 " target %d:%d:%d, debugging disabled\n",
4655 CAM_DEBUG_BUS, CAM_DEBUG_TARGET, CAM_DEBUG_LUN);
4656 cam_dflags = CAM_DEBUG_NONE;
4660 #else /* !CAM_DEBUG_BUS */
4662 #endif /* CAM_DEBUG_BUS */
4663 #endif /* CAMDEBUG */
4665 periphdriver_init(1);
4667 callout_init(&xsoftc.boot_callout, 1);
4668 callout_reset(&xsoftc.boot_callout, hz * xsoftc.boot_delay / 1000,
4669 xpt_boot_delay, NULL);
4670 /* Fire up rescan thread. */
4671 if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
4672 printf("xpt_init: failed to create rescan thread\n");
4680 xsoftc.buses_to_config++;
4685 xpt_release_boot(void)
4688 xsoftc.buses_to_config--;
4689 if (xsoftc.buses_to_config == 0 && xsoftc.buses_config_done == 0) {
4690 struct xpt_task *task;
4692 xsoftc.buses_config_done = 1;
4694 /* Call manually because we don't have any busses */
4695 task = malloc(sizeof(struct xpt_task), M_CAMXPT, M_NOWAIT);
4697 TASK_INIT(&task->task, 0, xpt_finishconfig_task, task);
4698 taskqueue_enqueue(taskqueue_thread, &task->task);
4705 * If the given device only has one peripheral attached to it, and if that
4706 * peripheral is the passthrough driver, announce it. This insures that the
4707 * user sees some sort of announcement for every peripheral in their system.
4710 xptpassannouncefunc(struct cam_ed *device, void *arg)
4712 struct cam_periph *periph;
4715 for (periph = SLIST_FIRST(&device->periphs), i = 0; periph != NULL;
4716 periph = SLIST_NEXT(periph, periph_links), i++);
4718 periph = SLIST_FIRST(&device->periphs);
4720 && (strncmp(periph->periph_name, "pass", 4) == 0))
4721 xpt_announce_periph(periph, NULL);
4727 xpt_finishconfig_task(void *context, int pending)
4730 periphdriver_init(2);
4732 * Check for devices with no "standard" peripheral driver
4733 * attached. For any devices like that, announce the
4734 * passthrough driver so the user will see something.
4736 xpt_for_all_devices(xptpassannouncefunc, NULL);
4738 /* Release our hook so that the boot can continue. */
4739 config_intrhook_disestablish(xsoftc.xpt_config_hook);
4740 free(xsoftc.xpt_config_hook, M_CAMXPT);
4741 xsoftc.xpt_config_hook = NULL;
4743 free(context, M_CAMXPT);
4747 xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg,
4748 struct cam_path *path)
4750 struct ccb_setasync csa;
4755 mtx_lock(&xsoftc.xpt_lock);
4756 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
4757 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
4758 if (status != CAM_REQ_CMP) {
4759 mtx_unlock(&xsoftc.xpt_lock);
4765 xpt_setup_ccb(&csa.ccb_h, path, CAM_PRIORITY_NORMAL);
4766 csa.ccb_h.func_code = XPT_SASYNC_CB;
4767 csa.event_enable = event;
4768 csa.callback = cbfunc;
4769 csa.callback_arg = cbarg;
4770 xpt_action((union ccb *)&csa);
4771 status = csa.ccb_h.status;
4773 xpt_free_path(path);
4774 mtx_unlock(&xsoftc.xpt_lock);
4776 if ((status == CAM_REQ_CMP) &&
4777 (csa.event_enable & AC_FOUND_DEVICE)) {
4779 * Get this peripheral up to date with all
4780 * the currently existing devices.
4782 xpt_for_all_devices(xptsetasyncfunc, &csa);
4784 if ((status == CAM_REQ_CMP) &&
4785 (csa.event_enable & AC_PATH_REGISTERED)) {
4787 * Get this peripheral up to date with all
4788 * the currently existing busses.
4790 xpt_for_all_busses(xptsetasyncbusfunc, &csa);
4797 xptaction(struct cam_sim *sim, union ccb *work_ccb)
4799 CAM_DEBUG(work_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xptaction\n"));
4801 switch (work_ccb->ccb_h.func_code) {
4802 /* Common cases first */
4803 case XPT_PATH_INQ: /* Path routing inquiry */
4805 struct ccb_pathinq *cpi;
4807 cpi = &work_ccb->cpi;
4808 cpi->version_num = 1; /* XXX??? */
4809 cpi->hba_inquiry = 0;
4810 cpi->target_sprt = 0;
4812 cpi->hba_eng_cnt = 0;
4813 cpi->max_target = 0;
4815 cpi->initiator_id = 0;
4816 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
4817 strncpy(cpi->hba_vid, "", HBA_IDLEN);
4818 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
4819 cpi->unit_number = sim->unit_number;
4820 cpi->bus_id = sim->bus_id;
4821 cpi->base_transfer_speed = 0;
4822 cpi->protocol = PROTO_UNSPECIFIED;
4823 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
4824 cpi->transport = XPORT_UNSPECIFIED;
4825 cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
4826 cpi->ccb_h.status = CAM_REQ_CMP;
4831 work_ccb->ccb_h.status = CAM_REQ_INVALID;
4838 * The xpt as a "controller" has no interrupt sources, so polling
4842 xptpoll(struct cam_sim *sim)
4847 xpt_lock_buses(void)
4849 mtx_lock(&xsoftc.xpt_topo_lock);
4853 xpt_unlock_buses(void)
4855 mtx_unlock(&xsoftc.xpt_topo_lock);
4862 struct cam_sim *sim;
4864 mtx_lock(&cam_simq_lock);
4866 while (!TAILQ_EMPTY(&cam_simq)) {
4867 TAILQ_CONCAT(&queue, &cam_simq, links);
4868 mtx_unlock(&cam_simq_lock);
4870 while ((sim = TAILQ_FIRST(&queue)) != NULL) {
4871 TAILQ_REMOVE(&queue, sim, links);
4873 sim->flags &= ~CAM_SIM_ON_DONEQ;
4874 camisr_runqueue(&sim->sim_doneq);
4875 CAM_SIM_UNLOCK(sim);
4877 mtx_lock(&cam_simq_lock);
4879 mtx_unlock(&cam_simq_lock);
4883 camisr_runqueue(void *V_queue)
4885 cam_isrq_t *queue = V_queue;
4886 struct ccb_hdr *ccb_h;
4888 while ((ccb_h = TAILQ_FIRST(queue)) != NULL) {
4891 TAILQ_REMOVE(queue, ccb_h, sim_links.tqe);
4892 ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
4894 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE,
4899 if (ccb_h->flags & CAM_HIGH_POWER) {
4900 struct highpowerlist *hphead;
4901 union ccb *send_ccb;
4903 mtx_lock(&xsoftc.xpt_lock);
4904 hphead = &xsoftc.highpowerq;
4906 send_ccb = (union ccb *)STAILQ_FIRST(hphead);
4909 * Increment the count since this command is done.
4911 xsoftc.num_highpower++;
4914 * Any high powered commands queued up?
4916 if (send_ccb != NULL) {
4918 STAILQ_REMOVE_HEAD(hphead, xpt_links.stqe);
4919 mtx_unlock(&xsoftc.xpt_lock);
4921 xpt_release_devq(send_ccb->ccb_h.path,
4922 /*count*/1, /*runqueue*/TRUE);
4924 mtx_unlock(&xsoftc.xpt_lock);
4927 if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
4930 dev = ccb_h->path->device;
4932 cam_ccbq_ccb_done(&dev->ccbq, (union ccb *)ccb_h);
4933 ccb_h->path->bus->sim->devq->send_active--;
4934 ccb_h->path->bus->sim->devq->send_openings++;
4937 if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0
4938 && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ)
4939 || ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
4940 && (dev->ccbq.dev_active == 0))) {
4941 xpt_release_devq(ccb_h->path, /*count*/1,
4942 /*run_queue*/FALSE);
4945 if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
4946 && (--dev->tag_delay_count == 0))
4947 xpt_start_tags(ccb_h->path);
4950 if (ccb_h->status & CAM_RELEASE_SIMQ) {
4951 xpt_release_simq(ccb_h->path->bus->sim,
4953 ccb_h->status &= ~CAM_RELEASE_SIMQ;
4957 if ((ccb_h->flags & CAM_DEV_QFRZDIS)
4958 && (ccb_h->status & CAM_DEV_QFRZN)) {
4959 xpt_release_devq(ccb_h->path, /*count*/1,
4961 ccb_h->status &= ~CAM_DEV_QFRZN;
4963 xpt_run_dev_sendq(ccb_h->path->bus);
4966 /* Call the peripheral driver's callback */
4967 (*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);