32#include "opt_printf.h"
42#include <sys/malloc.h>
43#include <sys/kernel.h>
50#include <sys/taskqueue.h>
54#include <sys/sysctl.h>
55#include <sys/kthread.h>
74#include <machine/stdarg.h>
79#define XPT_PRINT_MAXLEN 512
80#ifdef PRINTF_BUFR_SIZE
81#define XPT_PRINT_LEN PRINTF_BUFR_SIZE
83#define XPT_PRINT_LEN 128
91#ifndef CAM_MAX_HIGHPOWER
92#define CAM_MAX_HIGHPOWER 4
112 int buses_config_done;
122 u_int bus_generation;
125 struct callout boot_callout;
126 struct task boot_task;
127 struct root_hold_token xpt_rootmount;
129 struct mtx xpt_topo_lock;
130 struct taskqueue *xpt_taskq;
168 &
xsoftc.boot_delay, 0,
"Bus registration wait time");
171SYSCTL_INT(_kern_cam, OID_AUTO, announce_nosbuf, CTLFLAG_RWTUN,
172 &
xsoftc.announce_nosbuf, 0,
"Don't use sbuf for announcements");
207 .d_version = D_VERSION,
239 u_int32_t async_code,
268 u_int32_t new_priority);
277 u_int num_patterns,
struct cam_eb *bus);
295 struct cam_et *start_target,
298 struct cam_ed *start_device,
332 mtx_assert(&devq->
send_mtx, MA_OWNED);
360 make_dev(&
xpt_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600,
"xpt0");
370 if (((
flags & FWRITE) == 0) || ((
flags & FREAD) == 0))
376 if ((
flags & O_NONBLOCK) != 0) {
377 printf(
"%s: can't do nonblocking access\n", devtoname(dev));
385xptclose(
struct cdev *dev,
int flag,
int fmt,
struct thread *td)
398xptioctl(
struct cdev *dev, u_long cmd, caddr_t addr,
int flag,
struct thread *td)
402 if ((error =
xptdoioctl(dev, cmd, addr, flag, td)) == ENOTTY) {
409xptdoioctl(
struct cdev *dev, u_long cmd, caddr_t addr,
int flag,
struct thread *td)
427 inccb = (
union ccb *)addr;
428#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
430 inccb->
csio.bio = NULL;
490 bcopy(
ccb, inccb,
sizeof(
union ccb));
502 memset(&
ccb, 0,
sizeof(
ccb));
521 bcopy(&
ccb, inccb,
sizeof(
union ccb));
553 bzero(&mapinfo,
sizeof(mapinfo));
608 int base_periph_found;
613 base_periph_found = 0;
614#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
633 if (strcmp((*p_drv)->driver_name, name) == 0)
636 if (*p_drv == NULL) {
653 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL;
654 periph = TAILQ_NEXT(periph, unit_links)) {
663 if (periph != NULL) {
667 base_periph_found = 1;
669 for (i = 0, periph = SLIST_FIRST(&device->
periphs);
671 periph = SLIST_NEXT(periph, periph_links), i++) {
685 if (SLIST_NEXT(periph, periph_links))
722 if (periph == NULL) {
735 if (base_periph_found == 1) {
736 printf(
"xptioctl: pass driver is not in the "
738 printf(
"xptioctl: put \"device pass\" in "
739 "your kernel config file\n");
777 SET_FOREACH(pp, cam_xpt_proto_set) {
778 if ((*pp)->proto ==
proto)
789 if (done_ccb->
ccb_h.ppriv_ptr1 == NULL) {
809 if (TAILQ_EMPTY(&
xsoftc.ccb_scanq))
810 msleep(&
xsoftc.ccb_scanq, &
xsoftc.xpt_topo_lock, PRIBIO,
812 if ((
ccb = (
union ccb *)TAILQ_FIRST(&
xsoftc.ccb_scanq)) != NULL) {
869 if (
ccb->
ccb_h.ppriv_ptr1 == NULL) {
872 wakeup(&
xsoftc.ccb_scanq);
883 wakeup(&
xsoftc.ccb_scanq);
897 TAILQ_INIT(&
xsoftc.xpt_busses);
898 TAILQ_INIT(&
xsoftc.ccb_scanq);
899 STAILQ_INIT(&
xsoftc.highpowerq);
903 xsoftc.xpt_taskq = taskqueue_create(
"CAM XPT task", M_WAITOK,
904 taskqueue_thread_enqueue, &
xsoftc.xpt_taskq);
911 xsoftc.boot_delay = CAM_BOOT_DELAY;
934 printf(
"xpt_init: xpt_bus_register failed with errno %d,"
935 " failing attach\n", error);
947 printf(
"xpt_init: xpt_create_path failed with status %#x,"
948 " failing attach\n", status);
953 path, NULL, 0, xpt_sim);
962 mtx_init(&
cam_doneqs[i].cam_doneq_mtx,
"CAM doneq", NULL,
966 &
cam_proc, NULL, 0, 0,
"cam",
"doneq%d", i);
973 printf(
"xpt_init: Cannot init completion queues "
974 "- failing attach\n");
981 &
cam_proc, NULL, 0, 0,
"cam",
"async") != 0) {
982 printf(
"xpt_init: Cannot init async thread "
983 "- failing attach\n");
1000 if (periph == NULL) {
1001 printf(
"xptregister: periph was NULL!!\n");
1005 xpt_sim = (
struct cam_sim *)arg;
1006 xpt_sim->
softc = periph;
1008 periph->
softc = NULL;
1022 if (device != NULL) {
1025 SLIST_INSERT_HEAD(&device->
periphs, periph, periph_links);
1039 if (device != NULL) {
1057 printf(
"%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
1070 printf(
"%s%d: Unknown protocol device %d\n",
1075 printf(
"%s%d: Serial Number %.60s\n", periph->
periph_name,
1083 printf(
"%s%d: Command Queueing enabled\n",
1087 if (announce_string != NULL)
1094 char *announce_string)
1103 if (
xsoftc.announce_nosbuf != 0) {
1108 if (((
proto != NULL) && (
proto->ops->announce_sbuf == NULL)) ||
1114 sbuf_printf(sb,
"%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
1127 sbuf_printf(sb,
"%s%d: Unknown protocol device %d\n",
1132 sbuf_printf(sb,
"%s%d: Serial Number %.60s\n",
1141 sbuf_printf(sb,
"%s%d: Command Queueing enabled\n",
1145 if (announce_string != NULL)
1146 sbuf_printf(sb,
"%s%d: %s\n", periph->
periph_name,
1154 printf(
"%s%d: quirks=0x%b\n", periph->
periph_name,
1161 int quirks,
char *bit_string)
1163 if (
xsoftc.announce_nosbuf != 0) {
1169 sbuf_printf(sb,
"%s%d: quirks=0x%b\n", periph->
periph_name,
1181 printf(
"%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
1194 printf(
"%s%d: Unknown protocol device %d\n",
1199 printf(
" detached\n");
1211 if (
xsoftc.announce_nosbuf != 0) {
1216 if ((
proto != NULL) && (
proto->ops->denounce_sbuf == NULL)) {
1221 sbuf_printf(sb,
"%s%d at %s%d bus %d scbus%d target %d lun %jx\n",
1234 sbuf_printf(sb,
"%s%d: Unknown protocol device %d\n",
1239 sbuf_printf(sb,
" detached\n");
1252 memset(&cdai, 0,
sizeof(cdai));
1259 if (!strcmp(attr,
"GEOM::ident"))
1261 else if (!strcmp(attr,
"GEOM::physpath"))
1263 else if (strcmp(attr,
"GEOM::lunid") == 0 ||
1264 strcmp(attr,
"GEOM::lunname") == 0) {
1267 cdai.
buf = malloc(cdai.
bufsiz, M_CAMXPT, M_NOWAIT);
1268 if (cdai.
buf == NULL) {
1283 if (strcmp(attr,
"GEOM::lunid") == 0) {
1311 for (l = 0; l < idd->
length; l++)
1331 if ((idd->
length - 2) * 2 + 4 >= len) {
1335 for (l = 2, o = 0; l < idd->
length; l++) {
1336 if (l == 6 || l == 8 || l == 10 || l == 12)
1337 o += sprintf(buf + o,
"-");
1338 o += sprintf(buf + o,
"%02x",
1343 if (idd->
length * 2 < len) {
1344 for (l = 0; l < idd->
length; l++)
1345 sprintf(buf + l * 2,
"%02x",
1360 if ((
char *)cdai.
buf != buf)
1361 free(cdai.
buf, M_CAMXPT);
1384 if ((patterns == NULL) || (num_patterns == 0))
1387 for (i = 0; i < num_patterns; i++) {
1484 if ((patterns == NULL) || (num_patterns == 0))
1487 for (i = 0; i < num_patterns; i++) {
1600 if ((patterns == NULL) || (num_patterns == 0))
1609 for (i = 0; i < num_patterns; i++) {
1714 bzero(&cdm->
pos,
sizeof(cdm->
pos));
1754 mtx_unlock(&bus->
eb_mtx);
1790 mtx_unlock(&bus->
eb_mtx);
1798 mtx_unlock(&bus->
eb_mtx);
1847 bzero(&cdm->
pos,
sizeof(cdm->
pos));
1880 sizeof(
struct ata_params));
1914 mtx_unlock(&bus->
eb_mtx);
1923 mtx_unlock(&bus->
eb_mtx);
1960 bzero(&cdm->
pos,
sizeof(cdm->
pos));
2056 (*pdrv)->generation) {
2104 bzero(&cdm->
pos,
sizeof(cdm->
pos));
2118 if (strcmp((*pdrv)->driver_name,
2123 if (*pdrv == NULL) {
2136 (*pdrv)->generation;
2216 struct cam_eb *bus, *next_bus;
2224 bus = TAILQ_FIRST(&
xsoftc.xpt_busses);
2232 for (; bus != NULL; bus = next_bus) {
2233 retval = tr_func(bus, arg);
2239 next_bus = TAILQ_NEXT(bus, links);
2252 struct cam_et *target, *next_target;
2257 target = start_target;
2260 target = TAILQ_FIRST(&
bus->et_entries);
2261 if (target == NULL) {
2268 for (; target != NULL; target = next_target) {
2269 retval = tr_func(target, arg);
2275 next_target = TAILQ_NEXT(target, links);
2289 struct cam_ed *device, *next_device;
2295 device = start_device;
2298 device = TAILQ_FIRST(&
target->ed_entries);
2299 if (device == NULL) {
2300 mtx_unlock(&bus->
eb_mtx);
2304 mtx_unlock(&bus->
eb_mtx);
2306 for (; device != NULL; device = next_device) {
2308 retval = tr_func(device, arg);
2315 next_device = TAILQ_NEXT(device, links);
2318 mtx_unlock(&bus->
eb_mtx);
2336 periph = start_periph;
2340 periph = SLIST_FIRST(&device->
periphs);
2342 periph = SLIST_NEXT(periph, periph_links);
2343 if (periph == NULL) {
2344 mtx_unlock(&bus->
eb_mtx);
2349 mtx_unlock(&bus->
eb_mtx);
2352 for (; periph != NULL; periph = next_periph) {
2353 retval = tr_func(periph, arg);
2360 next_periph = SLIST_NEXT(periph, periph_links);
2361 while (next_periph != NULL &&
2363 next_periph = SLIST_NEXT(next_periph, periph_links);
2366 mtx_unlock(&bus->
eb_mtx);
2391 *pdrv != NULL; pdrv++) {
2392 retval = tr_func(pdrv, arg);
2412 periph = start_periph;
2415 periph = TAILQ_FIRST(&(*pdrv)->units);
2417 periph = TAILQ_NEXT(periph, unit_links);
2418 if (periph == NULL) {
2425 for (; periph != NULL; periph = next_periph) {
2427 retval = tr_func(periph, arg);
2434 next_periph = TAILQ_NEXT(periph, unit_links);
2435 while (next_periph != NULL &&
2437 next_periph = TAILQ_NEXT(next_periph, unit_links);
2561 memset(&cgd, 0,
sizeof(cgd));
2621 (
"xpt_action_default: func %#x %s\n", start_ccb->
ccb_h.
func_code,
2696 union ccb* abort_ccb;
2765 if (mtx && !mtx_owned(mtx))
2771 (
"Calling sim->sim_action(): func=%#x\n", start_ccb->
ccb_h.
func_code));
2774 (
"sim->sim_action returned: status=%#x\n", start_ccb->
ccb_h.
status));
2792 cgd = &start_ccb->
cgd;
2832 struct periph_list *periph_head;
2844 periph_head = &device->
periphs;
2845 cgdl = &start_ccb->
cgdl;
2853 if ((cgdl->
index != 0) &&
2863 for (nperiph = SLIST_FIRST(periph_head), i = 0;
2864 (nperiph != NULL) && (i <= cgdl->index);
2865 nperiph = SLIST_NEXT(nperiph, periph_links), i++) {
2866 if (i == cgdl->
index) {
2879 if (nperiph == NULL)
2895 cdm = &start_ccb->
cdm;
2955 struct async_list *async_head;
2958 csa = &start_ccb->
csa;
2966 cur_entry = SLIST_FIRST(async_head);
2967 while (cur_entry != NULL) {
2971 cur_entry = SLIST_NEXT(cur_entry, links);
2974 if (cur_entry != NULL) {
2979 added &= ~cur_entry->event_enable;
2981 SLIST_REMOVE(async_head, cur_entry,
2984 free(cur_entry, M_CAMXPT);
2990 cur_entry = malloc(
sizeof(*cur_entry), M_CAMXPT,
2992 if (cur_entry == NULL) {
2998 mtx_owned(path->
bus->
sim->
mtx)) ? 1 : 0;
3001 SLIST_INSERT_HEAD(async_head, cur_entry, links);
3012 crs = &start_ccb->
crs;
3025 "number of openings is now %d\n",
3045 callout_reset_sbt(&dev->
callout,
3132 STAILQ_INSERT_TAIL(&
cam_async.cam_doneq, &start_ccb->
ccb_h, sim_links.stqe);
3143 "%s: CCB type %#x %s not supported\n", __func__,
3153 (
"xpt_action_default: func= %#x %s status %#x\n",
3218 (
"%s: non-pollable sim", __func__));
3219 while (--timeout > 0) {
3248 if (new_priority < periph->scheduled_priority) {
3264 u_int32_t new_priority)
3267 u_int32_t old_priority;
3278 if (new_priority < old_priority) {
3282 (
"changed priority to %d\n",
3289 if (new_priority < old_priority)
3293 (
"Inserting onto queue\n"));
3307 periph->
flags &= ~CAM_PERIPH_RUN_TASK;
3343 taskqueue_enqueue(
xsoftc.xpt_taskq,
3351 (
"waking cam_periph_getccb()\n"));
3352 SLIST_INSERT_HEAD(&periph->ccb_list, &
ccb->
ccb_h,
3354 wakeup(&periph->ccb_list);
3358 (
"calling periph_start()\n"));
3381 union ccb *work_ccb;
3388 (
"running device %p\n", device));
3391 if (work_ccb == NULL) {
3392 printf(
"device on run queue with no ccbs???\n");
3398 if (
xsoftc.num_highpower <= 0) {
3406 STAILQ_INSERT_TAIL(&
xsoftc.highpowerq, device,
3445 work_ccb->
ccb_h.
flags &= ~CAM_TAG_ACTION_VALID;
3449 (
"device (%p) / path->device (%p) mismatch",
3462 if (mtx && !mtx_owned(mtx))
3491 bcopy(&(&src_ccb->
ccb_h)[1], &(&dst_ccb->
ccb_h)[1],
3497 u_int32_t priority, u_int32_t
flags)
3533 path = (
struct cam_path *)malloc(
sizeof(*path), M_CAMPATH, M_NOWAIT);
3541 free(path, M_CAMPATH);
3544 *new_path_ptr = path;
3584 struct cam_et *new_target;
3587 if (new_target == NULL) {
3590 target = new_target;
3594 if (target != NULL) {
3596 if (device == NULL) {
3598 struct cam_ed *new_device;
3604 if (new_device == NULL) {
3607 device = new_device;
3611 mtx_unlock(&bus->
eb_mtx);
3618 new_path->
periph = perph;
3619 new_path->
bus = bus;
3621 new_path->
device = device;
3639 new_path = (
struct cam_path *)malloc(
sizeof(*path), M_CAMPATH, M_NOWAIT);
3640 if (new_path == NULL)
3643 if (path->
bus != NULL)
3645 if (path->
target != NULL)
3647 if (path->
device != NULL)
3649 *new_path_ptr = new_path;
3657 if (path->
device != NULL) {
3661 if (path->
target != NULL) {
3665 if (path->
bus != NULL) {
3677 free(path, M_CAMPATH);
3682 uint32_t *periph_ref, uint32_t *target_ref, uint32_t *device_ref)
3722 if (path1->
bus != path2->
bus) {
3773 if (path->
device != dev) {
3794 printf(
"%s", sbuf_data(&sb));
3803 printf(
"(nopath): ");
3805 printf(
"(noperiph:%s%d:%d:%d:%jx): ", device->
sim->
sim_name,
3809 (uintmax_t)device->
lun_id);
3824 sbuf_vprintf(&sb, fmt, ap);
3828 printf(
"%s", sbuf_data(&sb));
3838 sbuf_new(&sb, str, str_len, 0);
3849 sbuf_printf(sb,
"(nopath): ");
3851 if (path->
periph != NULL)
3855 sbuf_printf(sb,
"(noperiph:");
3857 if (path->
bus != NULL)
3862 sbuf_printf(sb,
"nobus:");
3864 if (path->
target != NULL)
3867 sbuf_printf(sb,
"X:");
3869 if (path->
device != NULL)
3870 sbuf_printf(sb,
"%jx): ",
3873 sbuf_printf(sb,
"X): ");
3876 return(sbuf_len(sb));
3888 if (path->
target != NULL)
3897 if (path->
device != NULL)
3974 new_bus = (
struct cam_eb *)malloc(
sizeof(*new_bus),
3975 M_CAMXPT, M_NOWAIT|M_ZERO);
3976 if (new_bus == NULL) {
3981 mtx_init(&new_bus->
eb_mtx,
"CAM bus lock", NULL, MTX_DEF);
3982 TAILQ_INIT(&new_bus->et_entries);
3994 old_bus = TAILQ_FIRST(&
xsoftc.xpt_busses);
3995 while (old_bus != NULL
3997 old_bus = TAILQ_NEXT(old_bus, links);
3998 if (old_bus != NULL)
3999 TAILQ_INSERT_BEFORE(old_bus, new_bus, links);
4001 TAILQ_INSERT_TAIL(&
xsoftc.xpt_busses, new_bus, links);
4024 SET_FOREACH(xpt, cam_xpt_xport_set) {
4026 new_bus->
xport = *xpt;
4030 if (new_bus->
xport == NULL) {
4032 "No transport found for %d\n", cpi.
transport);
4034 free(path, M_CAMXPT);
4043 union ccb *scan_ccb;
4047 if (scan_ccb != NULL) {
4054 "Can't allocate CCB to scan bus\n");
4092 mtx_assert(&
xsoftc.xpt_topo_lock, MA_OWNED);
4094 bus = TAILQ_FIRST(&
xsoftc.xpt_busses);
4097 while (bus != NULL && bus->
path_id <= pathid) {
4100 bus = TAILQ_NEXT(bus, links);
4107 if (resource_string_value(
"scbus", pathid,
"at", &strval) == 0) {
4124 snprintf(buf,
sizeof(buf),
"%s%d", sim_name, sim_unit);
4125 if (strcmp(buf,
"xpt0") == 0 && sim_bus == 0)
4128 while ((resource_find_match(&i, &dname, &dunit,
"at", buf)) == 0) {
4129 if (strcmp(dname,
"scbus")) {
4135 if (resource_int_value(
"scbus", dunit,
"bus", &val) == 0) {
4136 if (sim_bus == val) {
4140 }
else if (sim_bus == 0) {
4145 printf(
"Ambiguous scbus configuration for %s%d "
4146 "bus %d, cannot wire down. The kernel "
4147 "config entry for scbus%d should "
4148 "specify a controller bus.\n"
4149 "Scbus will be assigned dynamically.\n",
4150 sim_name, sim_unit, sim_bus, dunit);
4164 switch (async_code) {
4180 return (
"AC_UNKNOWN");
4187 switch (async_code) {
4281 u_int32_t async_code;
4312 free(async_arg, M_CAMXPT);
4319 u_int32_t async_code,
4320 struct cam_path *path,
void *async_arg)
4325 cur_entry = SLIST_FIRST(async_head);
4326 while (cur_entry != NULL) {
4333 next_entry = SLIST_NEXT(cur_entry, links);
4345 cur_entry = next_entry;
4357 xpt_print(path,
"Can't allocate CCB to send %s\n",
4363 xpt_print(path,
"Can't allocate path to send %s\n",
4376 (
"xpt_async: func %#x %s aync_code %d %s\n",
4381 if (size > 0 && async_arg != NULL) {
4384 xpt_print(path,
"Can't allocate argument to send %s\n",
4392 }
else if (size < 0) {
4416 printf(
"%s called\n", __func__);
4426 mtx_assert(&devq->
send_mtx, MA_OWNED);
4428 (
"xpt_freeze_devq_device(%d) %u->%u\n", count,
4471 dev = (
struct cam_ed *)arg;
4474 mtx_assert(&devq->
send_mtx, MA_OWNED);
4501 (
"xpt_release_devq_device(%d, %d) %u->%u\n", count, run_queue,
4505 printf(
"xpt_release_devq(): requested %u > present %u\n",
4516 dev->
flags &= ~CAM_DEV_REL_ON_COMPLETE;
4523 dev->
flags &= ~CAM_DEV_REL_TIMEOUT_PENDING;
4545 printf(
"xpt_release_simq: requested 1 > present %u\n",
4567#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
4569 done_ccb->
csio.bio != NULL)
4570 biotrack(done_ccb->
csio.bio, __func__);
4574 (
"xpt_done: func= %#x %s status %#x\n",
4588 run = (queue->cam_doneq_sleep && STAILQ_EMPTY(&queue->cam_doneq));
4589 STAILQ_INSERT_TAIL(&queue->cam_doneq, &done_ccb->
ccb_h, sim_links.stqe);
4592 if (run && !dumping)
4593 wakeup(&queue->cam_doneq);
4601 (
"xpt_done_direct: status %#x\n", done_ccb->
ccb_h.
status));
4616 new_ccb = malloc(
sizeof(*new_ccb), M_CAMCCB, M_ZERO|M_WAITOK);
4625 new_ccb = malloc(
sizeof(*new_ccb), M_CAMCCB, M_ZERO|M_NOWAIT);
4639 uma_zfree(periph->
ccb_zone, free_ccb);
4641 free(free_ccb, M_CAMCCB);
4660 new_ccb = uma_zalloc(periph->
ccb_zone, M_ZERO|M_NOWAIT);
4663 new_ccb = malloc(
sizeof(*new_ccb), M_CAMCCB, M_ZERO|M_NOWAIT);
4665 if (new_ccb == NULL)
4682 new_ccb = uma_zalloc(periph->
ccb_zone, M_ZERO|M_WAITOK);
4685 new_ccb = malloc(
sizeof(*new_ccb), M_CAMCCB, M_ZERO|M_WAITOK);
4701 while ((ccb_h = SLIST_FIRST(&periph->ccb_list)) == NULL ||
4703 if (priority < periph->immediate_priority) {
4710 SLIST_REMOVE_HEAD(&periph->ccb_list,
periph_links.sle);
4711 return ((
union ccb *)ccb_h);
4728 KASSERT(bus->
refcount >= 1, (
"bus->refcount >= 1"));
4733 TAILQ_REMOVE(&
xsoftc.xpt_busses, bus, links);
4736 KASSERT(TAILQ_EMPTY(&bus->et_entries),
4737 (
"destroying bus, but target list is not empty"));
4739 mtx_destroy(&bus->
eb_mtx);
4740 free(bus, M_CAMXPT);
4746 struct cam_et *cur_target, *target;
4748 mtx_assert(&
xsoftc.xpt_topo_lock, MA_OWNED);
4750 target = (
struct cam_et *)malloc(
sizeof(*target), M_CAMXPT,
4755 TAILQ_INIT(&target->ed_entries);
4760 target->
luns = NULL;
4761 mtx_init(&target->
luns_mtx,
"CAM LUNs lock", NULL, MTX_DEF);
4770 cur_target = TAILQ_FIRST(&
bus->et_entries);
4772 cur_target = TAILQ_NEXT(cur_target, links);
4773 if (cur_target != NULL) {
4774 TAILQ_INSERT_BEFORE(cur_target, target, links);
4776 TAILQ_INSERT_TAIL(&
bus->et_entries, target, links);
4789 mtx_unlock(&bus->
eb_mtx);
4799 mtx_unlock(&bus->
eb_mtx);
4802 TAILQ_REMOVE(&bus->et_entries, target, links);
4804 mtx_unlock(&bus->
eb_mtx);
4805 KASSERT(TAILQ_EMPTY(&target->ed_entries),
4806 (
"destroying target, but device list is not empty"));
4810 free(target->
luns, M_CAMXPT);
4811 free(target, M_CAMXPT);
4832 struct cam_ed *device = context;
4836 free(device, M_CAMDEV);
4842 struct cam_ed *cur_device, *device;
4846 mtx_assert(&bus->
eb_mtx, MA_OWNED);
4855 device = (
struct cam_ed *)malloc(
sizeof(*device),
4856 M_CAMDEV, M_NOWAIT|M_ZERO);
4866 free(device, M_CAMDEV);
4869 SLIST_INIT(&device->
asyncs);
4876 mtx_init(&device->
device_mtx,
"CAM device lock", NULL, MTX_DEF);
4885 cur_device = TAILQ_FIRST(&
target->ed_entries);
4886 while (cur_device != NULL && cur_device->
lun_id <
lun_id)
4887 cur_device = TAILQ_NEXT(cur_device, links);
4888 if (cur_device != NULL)
4889 TAILQ_INSERT_BEFORE(cur_device, device, links);
4891 TAILQ_INSERT_TAIL(&
target->ed_entries, device, links);
4903 mtx_unlock(&bus->
eb_mtx);
4914 mtx_unlock(&bus->
eb_mtx);
4918 TAILQ_REMOVE(&device->
target->ed_entries, device,links);
4920 mtx_unlock(&bus->
eb_mtx);
4927 KASSERT(SLIST_EMPTY(&device->
periphs),
4928 (
"destroying device, but periphs list is not empty"));
4930 (
"destroying device while still queued for ccbs"));
4934 callout_stop(&device->
callout);
4948 free(device->
ext_inq, M_CAMXPT);
4979 for (bus = TAILQ_FIRST(&
xsoftc.xpt_busses);
4981 bus = TAILQ_NEXT(bus, links)) {
4997 for (target = TAILQ_FIRST(&
bus->et_entries);
4999 target = TAILQ_NEXT(target, links)) {
5014 for (device = TAILQ_FIRST(&
target->ed_entries);
5016 device = TAILQ_NEXT(device, links)) {
5035 device->
flags &= ~CAM_DEV_TAG_AFTER_COUNT;
5041 newopenings = min(device->
maxtags,
5045 memset(&crs, 0,
sizeof(crs));
5065 device->
flags &= ~CAM_DEV_TAG_AFTER_COUNT;
5071 memset(&crs, 0,
sizeof(crs));
5101 callout_init(&
xsoftc.boot_callout, 1);
5102 callout_reset_sbt(&
xsoftc.boot_callout, SBT_1MS *
xsoftc.boot_delay,
5113 if (taskqueue_start_threads(&
xsoftc.xpt_taskq, 1, PRIBIO,
"CAM taskq"))
5114 printf(
"xpt_config: failed to create taskqueue thread.\n");
5121 printf(
"xpt_config: xpt_create_path() failed for debug"
5122 " target %d:%d:%d, debugging disabled\n",
5134 "cam",
"scanner")) {
5135 printf(
"xpt_config: failed to create rescan thread.\n");
5143 if (
xsoftc.buses_to_config++ == 0)
5144 root_mount_hold_token(
"CAM", &
xsoftc.xpt_rootmount);
5161 if (--
xsoftc.buses_to_config == 0) {
5162 if (
xsoftc.buses_config_done == 0) {
5163 xsoftc.buses_config_done = 1;
5164 xsoftc.buses_to_config++;
5167 taskqueue_enqueue(taskqueue_thread, &
xsoftc.boot_task);
5169 root_mount_rel(&
xsoftc.xpt_rootmount);
5185 for (periph = SLIST_FIRST(&device->
periphs), i = 0; periph != NULL;
5186 periph = SLIST_NEXT(periph, periph_links), i++);
5188 periph = SLIST_FIRST(&device->
periphs);
5190 && (strncmp(periph->
periph_name,
"pass", 4) == 0))
5229 memset(&csa, 0,
sizeof(csa));
5239 (
"xpt_register_async: func %p\n", cbfunc));
5277 cpi = &work_ccb->
cpi;
5318 mtx_lock(&
xsoftc.xpt_topo_lock);
5324 mtx_unlock(&
xsoftc.xpt_topo_lock);
5339 struct mtx *mtx = NULL;
5341#if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
5345 csio = &((
union ccb *)
ccb_h)->csio;
5346 if (
csio->bio != NULL)
5347 biotrack(
csio->bio, __func__);
5352 struct highpowerlist *hphead;
5356 hphead = &
xsoftc.highpowerq;
5358 device = STAILQ_FIRST(hphead);
5368 if (device != NULL) {
5369 STAILQ_REMOVE_HEAD(hphead, highpowerq_entry);
5389 KASSERT(
sim, (
"sim missing for CAM_RELEASE_SIMQ request"));
5391 ccb_h->
status &= ~CAM_RELEASE_SIMQ;
5397 ccb_h->
status &= ~CAM_DEV_QFRZN;
5405 KASSERT(devq, (
"Periph disappeared with CCB %p %s request pending.",
5415 dev->
flags &= ~CAM_DEV_REL_ON_QUEUE_EMPTY;
5422 dev->
flags &= ~CAM_DEV_REL_ON_COMPLETE;
5471 STAILQ_INIT(&doneq);
5474 while (STAILQ_EMPTY(&queue->cam_doneq))
5477 STAILQ_CONCAT(&doneq, &queue->cam_doneq);
5480 while ((ccb_h = STAILQ_FIRST(&doneq)) != NULL) {
5481 STAILQ_REMOVE_HEAD(&doneq,
sim_links.stqe);
5496 STAILQ_INIT(&doneq);
5499 while (STAILQ_EMPTY(&queue->cam_doneq)) {
5500 queue->cam_doneq_sleep = 1;
5503 queue->cam_doneq_sleep = 0;
5505 STAILQ_CONCAT(&doneq, &queue->cam_doneq);
5508 THREAD_NO_SLEEPING();
5509 while ((ccb_h = STAILQ_FIRST(&doneq)) != NULL) {
5510 STAILQ_REMOVE_HEAD(&doneq,
sim_links.stqe);
5513 THREAD_SLEEPING_OK();
5530 while ((ccb_h = STAILQ_FIRST(&queue->cam_doneq)) != NULL) {
5531 STAILQ_REMOVE_HEAD(&queue->cam_doneq, sim_links.stqe);
5610 static char buffer[32];
5611 struct kv *walker =
map;
5613 while (walker->
name != NULL) {
5614 if (walker->
v == action)
5615 return (walker->
name);
5619 snprintf(buffer,
sizeof(buffer),
"%#x", action);
caddr_t cam_quirkmatch(caddr_t target, caddr_t quirk_table, int num_entries, int entry_size, cam_quirkmatch_t *comp_func)
#define CAM_TARGET_WILDCARD
#define CAM_PRIORITY_NORMAL
#define CAM_PRIORITY_NONE
#define CAM_UNQUEUED_INDEX
static __END_DECLS __inline void cam_init_pinfo(cam_pinfo *pinfo)
@ CAM_GDEVLIST_LIST_CHANGED
@ CAM_GDEVLIST_LAST_DEVICE
#define RELSIM_RELEASE_AFTER_TIMEOUT
#define RELSIM_ADJUST_OPENINGS
void ac_callback_t(void *softc, u_int32_t code, struct cam_path *path, void *args)
@ DEV_RESULT_UNCONFIGURED
#define CAM_TARGET_GENERATION
#define PROTO_VERSION_UNSPECIFIED
#define CAM_SCSI_DEVID_MAXLEN
#define CAM_DEV_GENERATION
#define XPT_FC_IS_DEV_QUEUED(ccb)
#define CAM_PERIPH_GENERATION
#define CAM_BUS_GENERATION
#define XPORT_VERSION_UNSPECIFIED
#define XPT_FC_IS_QUEUED(ccb)
@ CAM_DEV_MATCH_LIST_CHANGED
@ XPT_MMC_GET_TRAN_SETTINGS
@ XPT_MMC_SET_TRAN_SETTINGS
#define CDAI_TYPE_SERIAL_NUM
#define CAM_TAG_ACTION_NONE
#define CDAI_TYPE_PHYS_PATH
#define RELSIM_RELEASE_AFTER_CMDCMPLT
#define RELSIM_RELEASE_AFTER_QEMPTY
#define CDAI_TYPE_SCSI_DEVID
int cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp)
#define CAM_DEBUG_DEV(dev, flag, printfargs)
#define CAM_DEBUG_COMPILE
#define CAM_DEBUG(path, flag, printfargs)
#define CAM_DEBUG_PRINT(flag, printfargs)
static uintptr_t cam_iosched_delta_t(uintptr_t then)
static uintptr_t cam_iosched_now(void)
void cam_periph_release_locked(struct cam_periph *periph)
void periphdriver_init(int level)
u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t openings, u_int32_t arg, int getcount_only)
void cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
void cam_periph_doacquire(struct cam_periph *periph)
void cam_periph_release(struct cam_periph *periph)
int cam_periph_runccb(union ccb *ccb, int(*error_routine)(union ccb *ccb, cam_flags camflags, u_int32_t sense_flags), cam_flags camflags, u_int32_t sense_flags, struct devstat *ds)
struct periph_driver ** periph_drivers
int cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo, u_int maxmap)
cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, periph_oninv_t *periph_oninvalidate, periph_dtor_t *periph_dtor, periph_start_t *periph_start, char *name, cam_periph_type type, struct cam_path *path, ac_callback_t *ac_callback, ac_code code, void *arg)
#define cam_periph_assert(periph, what)
#define cam_periph_lock(periph)
#define CAM_PERIPH_DRV_EARLY
#define cam_periph_unlock(periph)
#define CAM_PERIPH_RUN_TASK
#define CAM_PERIPH_ANNOUNCED
#define cam_periph_sleep(periph, chan, priority, wmesg, timo)
void() periph_init_t(void)
u_int32_t cam_devq_resize(struct cam_devq *camq, int devices)
void cam_ccbq_fini(struct cam_ccbq *ccbq)
void camq_change_priority(struct camq *queue, int index, u_int32_t new_priority)
void camq_insert(struct camq *queue, cam_pinfo *new_entry)
u_int32_t cam_ccbq_resize(struct cam_ccbq *ccbq, int new_size)
cam_pinfo * camq_remove(struct camq *queue, int index)
int cam_ccbq_init(struct cam_ccbq *ccbq, int openings)
#define CAMQ_GET_PRIO(camq)
static __inline int cam_ccbq_pending_ccb_count(struct cam_ccbq *ccbq)
TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr)
static __inline union ccb * cam_ccbq_peek_ccb(struct cam_ccbq *ccbq, int index)
static __inline void cam_ccbq_send_ccb(struct cam_ccbq *queue, union ccb *send_ccb)
static __inline void cam_ccbq_release_opening(struct cam_ccbq *ccbq)
static __inline void cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb)
static __inline void cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb)
static __inline void cam_ccbq_ccb_done(struct cam_ccbq *ccbq, union ccb *done_ccb)
static __inline void cam_ccbq_take_opening(struct cam_ccbq *ccbq)
struct cam_sim * cam_sim_alloc(sim_action_func sim_action, sim_poll_func sim_poll, const char *sim_name, void *softc, u_int32_t unit, struct mtx *mtx, int max_dev_transactions, int max_tagged_dev_transactions, struct cam_devq *queue)
allocate a new sim and fill in the details
struct cam_devq * cam_simq_alloc(u_int32_t max_sim_transactions)
void cam_sim_release(struct cam_sim *sim)
void cam_sim_hold(struct cam_sim *sim)
static __inline bool cam_sim_pollable(const struct cam_sim *sim)
static struct proc * cam_proc
int xpt_bus_deregister(path_id_t pathid)
void xpt_acquire_device(struct cam_ed *device)
DECLARE_MODULE(cam, cam_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND)
static dev_match_ret xptbusmatch(struct dev_match_pattern *patterns, u_int num_patterns, struct cam_eb *bus)
static int xpt_async_process_tgt(struct cam_et *target, void *arg)
static periph_init_t xpt_periph_init
int xpt_targetfunc_t(struct cam_et *target, void *arg)
static int xptedtmatch(struct ccb_dev_match *cdm)
static void xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, struct cam_ed *device, void *async_arg)
static void xpt_done_process(struct ccb_hdr *ccb_h)
int xpt_path_comp_dev(struct cam_path *path, struct cam_ed *dev)
static xpt_periphfunc_t xptplistperiphfunc
union ccb * xpt_alloc_ccb(void)
void xpt_denounce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb)
void xpt_sim_poll(struct cam_sim *sim)
void xpt_print_path(struct cam_path *path)
static const char * xpt_async_string(u_int32_t async_code)
struct mtx * xpt_path_mtx(struct cam_path *path)
CAM_XPT_XPORT(xport_default)
int xpt_path_string(struct cam_path *path, char *str, size_t str_len)
void xpt_schedule(struct cam_periph *periph, u_int32_t new_priority)
void xpt_merge_ccb(union ccb *dst_ccb, union ccb *src_ccb)
cam_status xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph, path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
int xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
u_int32_t xpt_freeze_devq(struct cam_path *path, u_int count)
static struct cam_ed * xpt_find_device(struct cam_et *target, lun_id_t lun_id)
void xpt_start_tags(struct cam_path *path)
void xpt_setup_ccb_flags(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority, u_int32_t flags)
int32_t xpt_add_periph(struct cam_periph *periph)
static void xpt_async_process(struct cam_periph *periph, union ccb *ccb)
void xpt_unlock_buses(void)
void xpt_release_device(struct cam_ed *device)
void xpt_print(struct cam_path *path, const char *fmt,...)
void xpt_pollwait(union ccb *start_ccb, uint32_t timeout)
static struct xpt_proto * xpt_proto_find(cam_proto proto)
static struct periph_driver xpt_driver
static struct cam_ed * xpt_alloc_device_default(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
static void xpt_acquire_target(struct cam_et *target)
union ccb * cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
static int xptperiphtraverse(struct cam_ed *device, struct cam_periph *start_periph, xpt_periphfunc_t *tr_func, void *arg)
static struct cdevsw xpt_cdevsw
static void xpt_boot_delay(void *arg)
static int xptdevicetraverse(struct cam_et *target, struct cam_ed *start_device, xpt_devicefunc_t *tr_func, void *arg)
static void xpt_config(void *arg)
static void xpt_release_bus(struct cam_eb *bus)
void xpt_rescan(union ccb *ccb)
static xpt_busfunc_t xptedtbusfunc
void xpt_release_path(struct cam_path *path)
static int xpt_async_process_dev(struct cam_ed *device, void *arg)
static dev_match_ret xptperiphmatch(struct dev_match_pattern *patterns, u_int num_patterns, struct cam_periph *periph)
int xpt_path_comp(struct cam_path *path1, struct cam_path *path2)
path_id_t xpt_path_path_id(struct cam_path *path)
static int xpt_init(void *)
static int xpt_schedule_dev(struct camq *queue, cam_pinfo *dev_pinfo, u_int32_t new_priority)
MTX_SYSINIT(xpt_topo_init, &xsoftc.xpt_topo_lock, "XPT topology lock", MTX_DEF)
static xpt_busfunc_t xptdefbusfunc
void xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
void xpt_lock_buses(void)
static struct xpt_xport_ops xport_default_ops
static void xpt_run_allocq(struct cam_periph *periph, int sleep)
void xpt_announce_periph(struct cam_periph *periph, char *announce_string)
static void xpt_async_bcast(struct async_list *async_head, u_int32_t async_code, struct cam_path *path, void *async_arg)
void xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
PERIPHDRIVER_DECLARE(xpt, xpt_driver)
SYSINIT(xpt_hw_delay, SI_SUB_INT_CONFIG_HOOKS, SI_ORDER_ANY, xpt_ch_done, NULL)
SYSCTL_INT(_kern_cam, OID_AUTO, boot_delay, CTLFLAG_RDTUN, &xsoftc.boot_delay, 0, "Bus registration wait time")
static void xptaction(struct cam_sim *sim, union ccb *work_ccb)
static void camisr_runqueue(void)
u_int32_t xpt_freeze_simq(struct cam_sim *sim, u_int count)
static void xpt_async_td(void *)
void xpt_release_simq(struct cam_sim *sim, int run_queue)
void xpt_action(union ccb *start_ccb)
void xpt_done(union ccb *done_ccb)
void xpt_announce_quirks_sbuf(struct cam_periph *periph, struct sbuf *sb, int quirks, char *bit_string)
static __inline int xpt_schedule_devq(struct cam_devq *devq, struct cam_ed *dev)
u_int32_t __read_mostly cam_dflags
static xpt_targetfunc_t xptedttargetfunc
static d_ioctl_t xptdoioctl
#define CAM_MAX_HIGHPOWER
static int xptpdperiphtraverse(struct periph_driver **pdrv, struct cam_periph *start_periph, xpt_periphfunc_t *tr_func, void *arg)
static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus)
static xpt_devicefunc_t xptpassannouncefunc
cam_status xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg, struct cam_path *path)
static xpt_pdrvfunc_t xptplistpdrvfunc
static xpt_devicefunc_t xptsetasyncfunc
static void xpt_acquire_bus(struct cam_eb *bus)
static union ccb * xpt_get_ccb(struct cam_periph *periph)
struct cam_periph * xpt_periph
static xpt_periphfunc_t xptdefperiphfunc
uint32_t xpt_poll_setup(union ccb *start_ccb)
static xpt_devicefunc_t xptdefdevicefunc
lun_id_t xpt_path_lun_id(struct cam_path *path)
void xpt_denounce_periph(struct cam_periph *periph)
static void xpt_finishconfig_task(void *context, int pending)
static union ccb * xpt_get_ccb_nowait(struct cam_periph *periph)
int xpt_pdrvfunc_t(struct periph_driver **pdrv, void *arg)
struct cam_sim * xpt_path_sim(struct cam_path *path)
static xpt_targetfunc_t xptdeftargetfunc
u_int32_t cam_debug_delay
union ccb * xpt_alloc_ccb_nowait(void)
void xpt_print_device(struct cam_ed *device)
static void xpt_scanner_thread(void *dummy)
void xpt_free_path(struct cam_path *path)
void xpt_action_default(union ccb *start_ccb)
SYSCTL_UINT(_kern_cam, OID_AUTO, xpt_generation, CTLFLAG_RD, &xsoftc.xpt_generation, 0, "CAM peripheral generation count")
static int xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue)
int xpt_periphfunc_t(struct cam_periph *periph, void *arg)
struct cam_path * cam_dpath
static int xpt_for_all_devices(xpt_devicefunc_t *tr_func, void *arg)
void xpt_release_boot(void)
static struct cam_eb * xpt_find_bus(path_id_t path_id)
static struct xpt_softc xsoftc
static cam_status xptregister(struct cam_periph *periph, void *arg)
int xpt_bus_register(struct cam_sim *sim, device_t parent, uint32_t bus)
static void xpt_run_devq(struct cam_devq *devq)
static moduledata_t cam_moduledata
static struct cam_doneq cam_async
static int xptpdrvtraverse(struct periph_driver **start_pdrv, xpt_pdrvfunc_t *tr_func, void *arg)
static struct cam_doneq cam_doneqs[MAXCPU]
static callout_func_t xpt_release_devq_timeout
static int xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg)
static struct xpt_xport xport_default
static void xpt_rescan_done(struct cam_periph *periph, union ccb *done_ccb)
int xpt_path_sbuf(struct cam_path *path, struct sbuf *sb)
static void xptpoll(struct cam_sim *sim)
static __inline int device_is_queued(struct cam_ed *device)
static u_int __read_mostly cam_num_doneqs
cam_status xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph, path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
void xpt_stop_tags(struct cam_path *path)
static xpt_busfunc_t xptsetasyncbusfunc
int xpt_busfunc_t(struct cam_eb *bus, void *arg)
MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers")
static struct cam_et * xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
static int xptperiphlistmatch(struct ccb_dev_match *cdm)
struct cam_periph * xpt_path_periph(struct cam_path *path)
static d_ioctl_t xptioctl
static int cam_module_event_handler(module_t, int, void *)
void xpt_release_ccb(union ccb *free_ccb)
static void xpt_hold_boot_locked(void)
int xpt_devicefunc_t(struct cam_ed *device, void *arg)
void xpt_done_direct(union ccb *done_ccb)
int xpt_clone_path(struct cam_path **new_path_ptr, struct cam_path *path)
struct cam_ed * xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
const char * xpt_action_name(uint32_t action)
static void xpt_destroy_device(void *context, int pending)
target_id_t xpt_path_target_id(struct cam_path *path)
static xpt_periphfunc_t xptedtperiphfunc
static int xpt_async_size(u_int32_t async_code)
static int xptbustraverse(struct cam_eb *start_bus, xpt_busfunc_t *tr_func, void *arg)
void xpt_announce_quirks(struct cam_periph *periph, int quirks, char *bit_string)
_Static_assert(XPT_PRINT_LEN<=XPT_PRINT_MAXLEN, "XPT_PRINT_LEN is too large")
static dev_match_ret xptdevicematch(struct dev_match_pattern *patterns, u_int num_patterns, struct cam_ed *device)
device_t xpt_path_sim_device(const struct cam_path *path)
Return the device_t associated with the path.
static void xpt_release_target(struct cam_et *target)
static void xpt_run_allocq_task(void *context, int pending)
u_int32_t xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
static void xpt_done_td(void *)
static void xpt_ch_done(void *arg)
void xpt_release_devq(struct cam_path *path, u_int count, int run_queue)
static int xpttargettraverse(struct cam_eb *bus, struct cam_et *start_target, xpt_targetfunc_t *tr_func, void *arg)
void xpt_free_ccb(union ccb *free_ccb)
void xpt_announce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb, char *announce_string)
cam_status xpt_create_path_unlocked(struct cam_path **new_path_ptr, struct cam_periph *periph, path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
void xpt_path_counts(struct cam_path *path, uint32_t *bus_ref, uint32_t *periph_ref, uint32_t *target_ref, uint32_t *device_ref)
void xpt_remove_periph(struct cam_periph *periph)
static uint32_t xpt_freeze_devq_device(struct cam_ed *dev, u_int count)
static struct cam_et * xpt_find_target(struct cam_eb *bus, target_id_t target_id)
static path_id_t xptnextfreepathid(void)
static xpt_devicefunc_t xptedtdevicefunc
static d_close_t xptclose
#define xpt_path_unlock(path)
#define xpt_path_lock(path)
#define xpt_path_assert(path, what)
static void xpt_path_inq(struct ccb_pathinq *cpi, struct cam_path *path)
#define CAM_DEV_UNCONFIGURED
#define CAM_DEV_REL_ON_COMPLETE
#define CAM_DEV_REL_TIMEOUT_PENDING
#define CAM_DEV_TAG_AFTER_COUNT
#define CAM_DEV_REL_ON_QUEUE_EMPTY
int scsi_devid_is_lun_eui64(uint8_t *bufp)
int scsi_devid_is_lun_name(uint8_t *bufp)
int scsi_devid_is_lun_naa(uint8_t *bufp)
struct scsi_vpd_id_descriptor * scsi_get_devid(struct scsi_vpd_device_id *id, uint32_t page_len, scsi_devid_checkfn_t ck_fn)
int scsi_devid_match(uint8_t *lhs, size_t lhs_len, uint8_t *rhs, size_t rhs_len)
int scsi_devid_is_lun_t10(uint8_t *bufp)
int scsi_devid_is_lun_uuid(uint8_t *bufp)
int scsi_devid_is_lun_md5(uint8_t *bufp)
int scsi_static_inquiry_match(caddr_t inqbuffer, caddr_t table_entry)
#define SVPD_ID_CODESET_UTF8
#define SVPD_ID_TYPE_MASK
#define SVPD_ID_TYPE_UUID
#define SVPD_ID_CODESET_MASK
#define SVPD_ID_CODESET_ASCII
#define SVPD_DEVICE_ID_HDR_LEN
void(* callback)(void *arg, u_int32_t code, struct cam_path *path, void *args)
struct mtx_padalign cam_doneq_mtx
struct timeval last_reset
struct task device_destroy_task
u_int32_t tag_delay_count
struct periph_list periphs
struct nvme_namespace_data * nvme_data
struct ata_params ident_data
struct nvme_controller_data * nvme_cdata
u_int32_t tag_saved_openings
struct scsi_inquiry_data inq_data
struct timeval last_reset
struct scsi_report_luns_data * luns
struct cam_periph * periph
periph_start_t * periph_start
uint32_t scheduled_priority
struct task periph_run_task
uint32_t immediate_priority
int max_tagged_dev_openings
sim_action_func sim_action
struct ccb_dev_position pos
struct dev_match_result * matches
ccb_dev_match_status status
struct dev_match_pattern * patterns
struct ccb_dm_cookie cookie
dev_pos_type position_type
struct ata_params ident_data
struct scsi_inquiry_data inq_data
char periph_name[DEV_IDLEN]
ccb_getdevlist_status_e status
struct timeval last_reset
void(* cbfcnp)(struct cam_periph *, union ccb *)
u_int32_t base_transfer_speed
struct timeval last_reset
u_int32_t release_timeout
union match_pattern pattern
union match_result result
union device_match_pattern::@1 data
struct device_id_match_pattern devid_pat
struct scsi_static_inquiry_pattern inq_pat
struct scsi_inquiry_data inq_data
struct ata_params ident_data
char periph_name[DEV_IDLEN]
periph_pattern_flags flags
char periph_name[DEV_IDLEN]
xpt_proto_debug_out_func debug_out
struct xpt_proto_ops * ops
struct mtx xpt_highpower_lock
xpt_announce_periph_sbuf_func announce_sbuf
xpt_announce_periph_func announce
xpt_alloc_device_func alloc_device
struct xpt_xport_ops * ops
struct ccb_getdevlist cgdl
struct ccb_getdevstats cgds
struct ccb_calc_geometry ccg
struct ccb_pathstats cpis
u_int8_t cdb_bytes[IOCDBLEN]
struct bus_match_pattern bus_pattern
struct device_match_pattern device_pattern
struct periph_match_pattern periph_pattern
struct device_match_result device_result
struct bus_match_result bus_result
struct periph_match_result periph_result