/* * Onboard dialout devices * Creates links of the form "/dev/cua/[a..z]" */ static int onbrd_dialout_create(di_minor_t minor, di_node_t node) { char l_path[MAXPATHLEN], p_path[MAXPATHLEN]; char *devfspath, *buf, *mn; devfspath = di_devfs_path(node); if (devfspath == NULL) { devfsadm_errprint("%s: di_devfs_path() failed\n", modname); return (DEVFSADM_CONTINUE); } if ((mn = di_minor_name(minor)) == NULL) { devfsadm_errprint("%s: NULL minor name\n\t%s\n", modname, devfspath); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } /* * verify this is a dialout port */ if (!is_dialout(mn)) { devfsadm_errprint("%s: not a dialout device\n\t%s:%s\n", modname, devfspath, mn); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } (void) strcpy(p_path, devfspath); (void) strcat(p_path, ":"); (void) strcat(p_path, mn); di_devfs_path_free(devfspath); buf = NULL; #ifdef __i386 buf = check_compat_ports(p_path, mn); #endif /* * devfsadm_enumerate_char_start() is a private interface * for use by the ports module only. */ if (!buf && devfsadm_enumerate_char_start(p_path, 0, &buf, obport_rules, 1, start_id)) { devfsadm_errprint("%s: devfsadm_enumerate_char_start() failed" "\n\t%s\n", modname, p_path); return (DEVFSADM_CONTINUE); } /* * create the logical link */ (void) strcpy(l_path, "cua/"); (void) strcat(l_path, buf); (void) devfsadm_mklink(l_path, node, minor, 0); free(buf); return (DEVFSADM_CONTINUE); }
/* * PCMCIA dialout serial ports * Creates links of the form "/dev/cua/pcN", where N is the PCMCIA * socket number the device is plugged into. */ static int pcmcia_dialout_create(di_minor_t minor, di_node_t node) { char l_path[MAXPATHLEN]; char *devfspath; int socket, *intp; devfspath = di_devfs_path(node); if (devfspath == NULL) { devfsadm_errprint("%s: di_devfs_path() failed\n", modname); return (DEVFSADM_TERMINATE); } if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "socket", &intp) <= 0) { devfsadm_errprint("%s: failed socket lookup\n\t%s\n", modname, devfspath); di_devfs_path_free(devfspath); return (DEVFSADM_TERMINATE); } socket = PCMCIA_SOCKETNO(*intp); di_devfs_path_free(devfspath); (void) sprintf(l_path, "cua/pc%d", socket); (void) devfsadm_mklink(l_path, node, minor, 0); return (DEVFSADM_TERMINATE); }
/* * Discover an HBA node with matching path. * The di_node_t argument should be the root of the device tree. * This routine assumes the locks have been taken */ static int find_matching_hba(di_node_t node, void *arg) { int *propData, rval; walkarg_t *wa = (walkarg_t *)arg; char *devpath, fulldevpath[MAXPATHLEN]; /* Skip stub(instance -1) nodes */ if (IS_STUB_NODE(node)) { return (DI_WALK_CONTINUE); } rval = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "sm-hba-supported", &propData); if (rval < 0) { return (DI_WALK_CONTINUE); } else { if ((devpath = di_devfs_path(node)) == NULL) { /* still continue to see if there is matching one. */ return (DI_WALK_CONTINUE); } (void) snprintf(fulldevpath, MAXPATHLEN, "%s%s", DEVICES_DIR, devpath); if ((strstr(fulldevpath, wa->devpath)) != NULL) { *wa->flag = B_TRUE; /* Found a node. No need to walk any more. */ di_devfs_path_free(devpath); return (DI_WALK_TERMINATE); } di_devfs_path_free(devpath); } return (DI_WALK_CONTINUE); }
int nvme_open(di_minor_t minor) { char *devpath, *path; int fd; if ((devpath = di_devfs_minor_path(minor)) == NULL) err(-1, "nvme_open()"); if (asprintf(&path, "/devices%s", devpath) < 0) { di_devfs_path_free(devpath); err(-1, "nvme_open()"); } di_devfs_path_free(devpath); fd = open(path, O_RDWR); free(path); if (fd < 0) { if (debug) warn("nvme_open(%s)", path); return (-1); } return (fd); }
static int ses_callback(di_minor_t minor, di_node_t node) { char l_path[PATH_MAX]; char *buf; char *devfspath; char p_path[PATH_MAX]; devfsadm_enumerate_t re[] = {"^es$/^ses([0-9]+)$", 1, MATCH_ALL}; /* find devices path -- need to free mem */ if (NULL == (devfspath = di_devfs_path(node))) { return (DEVFSADM_CONTINUE); } (void) snprintf(p_path, sizeof (p_path), "%s:%s", devfspath, di_minor_name(minor)); /* find next number to use; buf is an ascii number */ if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) { /* free memory */ di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } (void) snprintf(l_path, sizeof (l_path), "es/ses%s", buf); (void) devfsadm_mklink(l_path, node, minor, 0); /* free memory */ free(buf); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); }
/* * Lights Out Management (LOM) serial ports * Creates links of the form "/dev/term/lom-console". */ static int lom_port_create(di_minor_t minor, di_node_t node) { char *devfspath; char *minor_name; devfspath = di_devfs_path(node); if (devfspath == NULL) { devfsadm_errprint("%s: di_devfs_path() failed\n", modname); return (DEVFSADM_CONTINUE); } if ((minor_name = di_minor_name(minor)) == NULL) { devfsadm_errprint("%s: NULL minor name\n\t%s\n", modname, devfspath); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } /* * if this is the LOM console serial port (i.e. the minor * name == lom-console ), create /dev/term/lom-console link and * then we are done with this node. */ if (strcmp(minor_name, "lom-console") == 0) { (void) devfsadm_mklink("term/lom-console", node, minor, 0); di_devfs_path_free(devfspath); return (DEVFSADM_TERMINATE); } /* This is not a LOM node, continue... */ di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); }
static int niu_asru_set(tnode_t *tn, di_node_t dn, topo_mod_t *mod) { char *path; nvlist_t *fmri; int e; if ((path = di_devfs_path(dn)) != NULL) { fmri = topo_mod_devfmri(mod, FM_DEV_SCHEME_VERSION, path, NULL); if (fmri == NULL) { topo_mod_dprintf(mod, "dev:///%s fmri creation failed.\n", path); di_devfs_path_free(path); return (-1); } di_devfs_path_free(path); } else { topo_mod_dprintf(mod, "NULL di_devfs_path.\n"); if (topo_prop_get_fmri(tn, TOPO_PGROUP_PROTOCOL, TOPO_PROP_RESOURCE, &fmri, &e) < 0) return (topo_mod_seterrno(mod, e)); } if (topo_node_asru_set(tn, fmri, 0, &e) < 0) { nvlist_free(fmri); return (topo_mod_seterrno(mod, e)); } nvlist_free(fmri); return (0); }
/* * Walk all "service" device nodes to find the one with the * matching glvc minor name */ static char * svc_name_to_glvc_dev_path(char *service) { di_node_t root_node, service_node; char *glvc_path; char *minor_name; di_minor_t minor; char *dev_path = NULL; if (service == NULL) return (NULL); /* Get device node */ root_node = di_init("/", DINFOCPYALL); if (root_node == DI_NODE_NIL) { return (dev_path); } service_node = di_drv_first_node("glvc", root_node); while (service_node != DI_NODE_NIL) { /* Make sure node name matches service name */ if (strcmp(service, di_node_name(service_node)) == 0) { /* Walk minor nodes */ minor = di_minor_next(service_node, DI_NODE_NIL); while (minor != DI_NODE_NIL) { glvc_path = di_devfs_minor_path(minor); minor_name = di_minor_name(minor); if (strcmp(minor_name, "glvc") == 0) { dev_path = malloc(strlen(glvc_path) + strlen(DEVICES_DIR) + 1); (void) strcpy(dev_path, DEVICES_DIR); (void) strcat(dev_path, glvc_path); di_devfs_path_free(glvc_path); break; } di_devfs_path_free(glvc_path); minor = di_minor_next(service_node, minor); } } if (dev_path != NULL) break; service_node = di_drv_next_node(service_node); } di_fini(root_node); return (dev_path); }
/* * Called for all dialout devices that are NOT onboard * Creates links of the form "/dev/cua/[0..n]" */ static int dialout_create(di_minor_t minor, di_node_t node) { char l_path[MAXPATHLEN], p_path[MAXPATHLEN]; char *devfspath, *buf, *mn; devfspath = di_devfs_path(node); if (devfspath == NULL) { devfsadm_errprint("%s: di_devfs_path() failed\n", modname); return (DEVFSADM_CONTINUE); } if ((mn = di_minor_name(minor)) == NULL) { devfsadm_errprint("%s: NULL minorname\n\t%s\n", modname, devfspath); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } if (!is_dialout(mn)) { devfsadm_errprint("%s: invalid minor name\n\t%s:%s\n", modname, devfspath, mn); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } (void) strcpy(p_path, devfspath); (void) strcat(p_path, ":"); (void) strcat(p_path, mn); di_devfs_path_free(devfspath); if (devfsadm_enumerate_int(p_path, 0, &buf, port_rules, 1)) { devfsadm_errprint("%s:dialout_create:" " enumerate_int() failed\n\t%s\n", modname, p_path); return (DEVFSADM_CONTINUE); } (void) strcpy(l_path, "cua/"); (void) strcat(l_path, buf); /* * add the minor name to the physical path so we can create * the link. */ (void) devfsadm_mklink(l_path, node, minor, 0); free(buf); return (DEVFSADM_CONTINUE); }
static int sunos_walk_minor_node_link(di_node_t node, void *args) { di_minor_t minor = DI_MINOR_NIL; char *minor_path; struct devlink_cbarg arg; struct node_args *nargs = (struct node_args *)args; di_devlink_handle_t devlink_hdl = nargs->dlink_hdl; /* walk each minor to find ugen devices */ while ((minor = di_minor_next(node, minor)) != DI_MINOR_NIL) { minor_path = di_devfs_minor_path(minor); arg.nargs = args; arg.myself = node; arg.minor = minor; (void) di_devlink_walk(devlink_hdl, "^usb/[0-9a-f]+[.][0-9a-f]+", minor_path, DI_PRIMARY_LINK, (void *)&arg, sunos_add_devices); di_devfs_path_free(minor_path); } /* switch to a different node */ nargs->last_ugenpath = NULL; return (DI_WALK_CONTINUE); }
static int mc_node(di_minor_t minor, di_node_t node) { char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath; char *minor_nm; minor_nm = di_minor_name(minor); if (minor_nm == NULL) { return (DEVFSADM_CONTINUE); } devfspath = di_devfs_path(node); (void) strcpy(path, devfspath); (void) strcat(path, ":"); (void) strcat(path, minor_nm); di_devfs_path_free(devfspath); /* build the physical path from the components */ if (devfsadm_enumerate_int(path, 0, &buf, mc_rules, 1)) { return (DEVFSADM_CONTINUE); } (void) strcpy(l_path, "mc/mc"); (void) strcat(l_path, buf); free(buf); (void) devfsadm_mklink(l_path, node, minor, 0); return (DEVFSADM_CONTINUE); }
static int fc_port(di_minor_t minor, di_node_t node) { devfsadm_enumerate_t rules[1] = {"fc/fp([0-9]+)$", 1, MATCH_ALL}; char *buf, path[PATH_MAX + 1]; char *ptr; if (NULL == (ptr = di_devfs_path(node))) { return (DEVFSADM_CONTINUE); } (void) strcpy(path, ptr); (void) strcat(path, ":"); (void) strcat(path, di_minor_name(minor)); di_devfs_path_free(ptr); if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) { return (DEVFSADM_CONTINUE); } (void) strcpy(path, "fc/fp"); (void) strcat(path, buf); free(buf); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * This function is called for every dcam1394 minor node. * Calls enumerate to assign a logical dcam1394 id, and then * devfsadm_mklink to make the link. */ static int dcam1394_process(di_minor_t minor, di_node_t node) { char m_name[PATH_MAX], restring0[DCAM_RE_STRING_LEN]; char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath; devfsadm_enumerate_t re[1]; (void) strcpy(m_name, di_minor_name(minor)); if (strcmp(di_driver_name(node), "dcam1394") != 0) { return (DEVFSADM_CONTINUE); } if (strncmp(m_name, "dcamctl", 7) == 0) { (void) snprintf(restring0, DCAM_RE_STRING_LEN, DCAM_CTL_LINK_RE); } else if (strncmp(m_name, "dcam", 4) == 0) { (void) snprintf(restring0, DCAM_RE_STRING_LEN, DCAM_STR_LINK_RE); } else { return (DEVFSADM_CONTINUE); } re[0].re = restring0; re[0].subexp = 1; re[0].flags = MATCH_ALL; devfsadm_print(debug_mid, "dcam1394_process: path %s\n", di_devfs_path(node)); (void) strcpy(p_path, devfspath = di_devfs_path(node)); (void) strcat(p_path, ":"); (void) strcat(p_path, di_minor_name(minor)); di_devfs_path_free(devfspath); /* * Build the physical path from the components, omitting * minor name field. Find the logical dcam1394 id, and * stuff it in buf. */ if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) { devfsadm_print(debug_mid, "dcam1394_process: exit/continue\n"); return (DEVFSADM_CONTINUE); } devfsadm_print(debug_mid, "dcam1394_process: p_path=%s buf=%s\n", p_path, buf); if (strncmp(di_minor_name(minor), "dcamctl", 7) == 0) (void) snprintf(l_path, PATH_MAX, "dcamctl%s", buf); else (void) snprintf(l_path, PATH_MAX, "dcam%s", buf); (void) devfsadm_mklink(l_path, node, minor, 0); free(buf); return (DEVFSADM_CONTINUE); }
/* * Handles: * minor node type "ddi_printer". * rules of the form: type=ddi_printer;name=bpp \M0 */ static int printer_create(di_minor_t minor, di_node_t node) { char *mn; char path[PATH_MAX + 1], *buf; devfsadm_enumerate_t rules[1] = {"^printers$/^([0-9]+)$", 1, MATCH_ALL}; mn = di_minor_name(minor); if (strcmp(di_driver_name(node), "bpp") == 0) { (void) devfsadm_mklink(mn, node, minor, 0); } if (NULL == (buf = di_devfs_path(node))) { return (DEVFSADM_CONTINUE); } (void) snprintf(path, sizeof (path), "%s:%s", buf, mn); di_devfs_path_free(buf); if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { return (DEVFSADM_CONTINUE); } (void) snprintf(path, sizeof (path), "printers/%s", buf); free(buf); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
static int gpio(di_minor_t minor, di_node_t node) { char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath; char *minor_nm, *drvr_nm; minor_nm = di_minor_name(minor); drvr_nm = di_driver_name(node); if ((minor_nm == NULL) || (drvr_nm == NULL)) { return (DEVFSADM_CONTINUE); } devfspath = di_devfs_path(node); (void) strcpy(p_path, devfspath); (void) strcat(p_path, ":"); (void) strcat(p_path, minor_nm); di_devfs_path_free(devfspath); /* build the physical path from the components */ if (devfsadm_enumerate_int(p_path, 0, &buf, gpio_rules, 1)) { return (DEVFSADM_CONTINUE); } (void) snprintf(l_path, sizeof (l_path), "%s%s", "gpio", buf); free(buf); (void) devfsadm_mklink(l_path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * Handles: * /dev/av/[0-9]+/(async|isoch) */ static int av_create(di_minor_t minor, di_node_t node) { devfsadm_enumerate_t rules[1] = {"^av$/^([0-9]+)$", 1, MATCH_ADDR}; char *minor_str; char path[PATH_MAX + 1]; char *buf; if ((buf = di_devfs_path(node)) == NULL) { return (DEVFSADM_CONTINUE); } minor_str = di_minor_name(minor); (void) snprintf(path, sizeof (path), "%s:%s", buf, minor_str); di_devfs_path_free(buf); if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { return (DEVFSADM_CONTINUE); } (void) snprintf(path, sizeof (path), "av/%s/%s", buf, minor_str); free(buf); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * Converts a libdevinfo node into a /devices path. Caller must free results. */ static char * get_rsrcname(di_node_t dinode) { int len; char *rsrcname; char *devfspath; char name[MAXPATHLEN]; if ((devfspath = di_devfs_path(dinode)) == NULL) { rcm_log_message(RCM_ERROR, "MPXIO: resource has null path.\n"); return (NULL); } len = snprintf(name, sizeof (name), "/devices%s", devfspath); di_devfs_path_free(devfspath); if (len >= sizeof (name)) { rcm_log_message(RCM_ERROR, "MPXIO: resource path too long.\n"); return (NULL); } if ((rsrcname = strdup(name)) == NULL) rcm_log_message(RCM_ERROR, "MPXIO: failed to allocate resource name (%s).\n", strerror(errno)); return (rsrcname); }
/* * Handles minor node type "ddi_parallel". * type=ddi_parallel;name=mcpp mcpp\N0 */ static int parallel(di_minor_t minor, di_node_t node) { char path[PATH_MAX + 1], *buf; devfsadm_enumerate_t rules[1] = {"mcpp([0-9]+)$", 1, MATCH_ALL}; if (strcmp(di_node_name(node), "mcpp") != 0) { return (DEVFSADM_CONTINUE); } if (NULL == (buf = di_devfs_path(node))) { return (DEVFSADM_CONTINUE); } (void) snprintf(path, sizeof (path), "%s:%s", buf, di_minor_name(minor)); di_devfs_path_free(buf); if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { return (DEVFSADM_CONTINUE); } (void) snprintf(path, sizeof (path), "mcpp%s", buf); free(buf); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * Walk all vldc device nodes to find the one with the * matching minor name */ static char * svc_name_to_vldc_dev_path(char *service) { di_node_t root_node, vldc_node; char *vldc_path; char *minor_name; di_minor_t minor; char *dev_path = NULL; /* Get device node */ root_node = di_init("/", DINFOCPYALL); if (root_node == DI_NODE_NIL) { return (dev_path); } vldc_node = di_drv_first_node("vldc", root_node); while (vldc_node != DI_NODE_NIL) { /* Walk minor nodes */ minor = di_minor_next(vldc_node, DI_NODE_NIL); while (minor != DI_NODE_NIL) { vldc_path = di_devfs_minor_path(minor); minor_name = di_minor_name(minor); if (strcmp(minor_name, service) == 0) { dev_path = malloc(strlen(vldc_path) + strlen(DEVICES_DIR) + 1); (void) strcpy(dev_path, DEVICES_DIR); (void) strcat(dev_path, vldc_path); di_devfs_path_free(vldc_path); break; } di_devfs_path_free(vldc_path); minor = di_minor_next(vldc_node, minor); } if (dev_path != NULL) break; vldc_node = di_drv_next_node(vldc_node); } di_fini(root_node); return (dev_path); }
/* * Remote System Controller (RSC) serial ports * Creates links of the form "/dev/rsc-control" | "/dev/term/rsc-console". */ static int rsc_port_create(di_minor_t minor, di_node_t node) { char *devfspath; char *minor_name; devfspath = di_devfs_path(node); if (devfspath == NULL) { devfsadm_errprint("%s: di_devfs_path() failed\n", modname); return (DEVFSADM_CONTINUE); } if ((minor_name = di_minor_name(minor)) == NULL) { devfsadm_errprint("%s: NULL minor name\n\t%s\n", modname, devfspath); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } /* * if this is the RSC console serial port (i.e. the minor name == ssp), * create /dev/term/rsc-console link and then we are done with this * node. */ if (strcmp(minor_name, "ssp") == 0) { (void) devfsadm_mklink("term/rsc-console", node, minor, 0); di_devfs_path_free(devfspath); return (DEVFSADM_TERMINATE); /* * else if this is the RSC control serial port (i.e. the minor name == * sspctl), create /dev/rsc-control link and then we are done with this * node. */ } else if (strcmp(minor_name, "sspctl") == 0) { (void) devfsadm_mklink("rsc-control", node, minor, 0); di_devfs_path_free(devfspath); return (DEVFSADM_TERMINATE); } /* This is not an RSC node, continue... */ di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); }
static int create_children(mmd_t *mdp, di_prom_handle_t ph, md_node_t *md_parent, di_node_t di_parent) { md_node_t *md_node; md_node_t *md_child; di_node_t di_child; char *path; int rv; path = di_devfs_path(di_parent); if (path == NULL) return (EIO); md_node = link_device_node(mdp, ph, di_parent, md_parent, path); di_devfs_path_free(path); if (md_node == NULL) { return (ENOMEM); } while ((di_child = di_child_node(di_parent)) != DI_NODE_NIL) { path = di_devfs_path(di_child); if (path != NULL) { md_child = link_device_node(mdp, ph, di_child, md_node, path); di_devfs_path_free(path); if (md_child == NULL) { return (ENOMEM); } } rv = create_peers(mdp, ph, md_node, di_child); if (rv != 0) return (rv); md_node = md_child; di_parent = di_child; } return (0); }
int wrsm(di_minor_t minor, di_node_t node) { const char *node_name = di_node_name(node); const char *minor_name = di_minor_name(minor); char path[PATH_MAX + 1]; if (minor_name == NULL || node_name == NULL) { return (DEVFSADM_CONTINUE); } if (strcmp(minor_name, "admin") == 0) { /* admin pseudo device */ (void) snprintf(path, sizeof (path), "%s%s", node_name, minor_name); } else if (strcmp(minor_name, "ctrl") == 0) { /* controller pseudo device */ dev_t dev = di_minor_devt(minor); minor_t dev_minor = minor(dev); (void) snprintf(path, sizeof (path), "%s%u", node_name, (uint_t)dev_minor); } else { /* * For hardware devices, the devlink must be * /dev/<node_name><portid>. devpath is of the format * ".../<node_name>@<portid>,0". Need to extract the * <portid> for use in bulding devlink. */ char devpath[PATH_MAX + 1]; char *devfs_path; int i; devfs_path = di_devfs_path(node); if (devfs_path == NULL) { return (DEVFSADM_CONTINUE); } (void) strcpy(devpath, devfs_path); di_devfs_path_free(devfs_path); for (i = strlen(devpath); devpath[i] != '@' && i > 0; i--) { if (devpath[i] == ',') { devpath[i] = 0; } } if (i == 0) { return (DEVFSADM_CONTINUE); } (void) snprintf(path, sizeof (path), "wci%s", &devpath[i+1]); } (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/*ARGSUSED*/ static int DEVprop_set(tnode_t *tn, did_t *pd, const char *dpnm, const char *tpgrp, const char *tpnm) { topo_mod_t *mp; char *dnpath; char *path, *fpath; int d, f; int err, e; mp = did_mod(pd); if ((dnpath = di_devfs_path(did_dinode(pd))) == NULL) { topo_mod_dprintf(mp, "NULL di_devfs_path.\n"); return (topo_mod_seterrno(mp, ETOPO_PROP_NOENT)); } if ((path = topo_mod_strdup(mp, dnpath)) == NULL) { di_devfs_path_free(dnpath); return (-1); } di_devfs_path_free(dnpath); /* The DEV path is modified for hostbridges */ if (strcmp(topo_node_name(tn), HOSTBRIDGE) == 0) { fpath = dev_for_hostbridge(did_mod(pd), path); } else { did_BDF(pd, NULL, &d, &f); fpath = dev_path_fix(mp, path, d, f); } if (fpath == NULL) return (-1); e = topo_prop_set_string(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, fpath, &err); topo_mod_strfree(mp, fpath); if (e != 0) return (topo_mod_seterrno(mp, err)); return (0); }
/* * Callback used by path2node(). */ static int p2n_cb(di_node_t node, void *arg) { int ret = DI_WALK_CONTINUE; cb_t *cbp = arg; char *phys_path = di_devfs_path(node); if (strcmp(cbp->cb_path, phys_path) == 0) { cbp->cb_node = node; ret = DI_WALK_TERMINATE; } di_devfs_path_free(phys_path); return (ret); }
static int devprop_set(tnode_t *tn, di_node_t dn, const char *tpgrp, const char *tpnm, topo_mod_t *mod) { char *path; int err, e; if ((path = di_devfs_path(dn)) == NULL) { topo_mod_dprintf(mod, "NULL di_devfs_path.\n"); return (topo_mod_seterrno(mod, ETOPO_PROP_NOENT)); } e = topo_prop_set_string(tn, tpgrp, tpnm, TOPO_PROP_IMMUTABLE, path, &err); di_devfs_path_free(path); if (e != 0) return (topo_mod_seterrno(mod, err)); return (0); }
/* * Release all the resources * Solaris version */ static void pci_system_solx_devfs_destroy( void ) { /* * The memory allocated for pci_sys & devices in create routines * will be freed in pci_system_cleanup. * Need to free system-specific allocations here. */ nexus_t *nexus, *next; for (nexus = nexus_list ; nexus != NULL ; nexus = next) { next = nexus->next; close(nexus->fd); free(nexus->path); free(nexus->dev_path); #ifdef __sparc { struct pci_device *dev; int i; for (i = 0; i < nexus->num_devices; i++) { dev = nexus->devlist[i]; if (MAPPING_DEV_PATH(dev)) di_devfs_path_free((char *) MAPPING_DEV_PATH(dev)); } } free(nexus->devlist); #endif free(nexus); } nexus_list = NULL; #ifdef __sparc if (di_phdl != DI_PROM_HANDLE_NIL) (void) di_prom_fini(di_phdl); #else if (xsvc_fd >= 0) { close(xsvc_fd); xsvc_fd = -1; } #endif }
/* * destroy_zfd_devs() and its helper destroy_cb() tears down any zfd instances * associated with this zone. If things went very wrong, we might have an * incorrect number of instances hanging around. This routine hunts down and * tries to remove all of them. Of course, if the fd is open, the instance will * not detach, which is a potential issue. */ static int destroy_cb(di_node_t node, void *arg) { struct cb_data *cb = (struct cb_data *)arg; char *prop_data; char *tmp; char devpath[MAXPATHLEN]; devctl_hdl_t hdl; if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zfd_zname", &prop_data) == -1) return (DI_WALK_CONTINUE); assert(prop_data != NULL); if (strcmp(prop_data, zone_name) != 0) { /* this is a zfd for a different zone */ return (DI_WALK_CONTINUE); } cb->found++; tmp = di_devfs_path(node); (void) snprintf(devpath, sizeof (devpath), "/devices/%s", tmp); di_devfs_path_free(tmp); if ((hdl = devctl_device_acquire(devpath, 0)) == NULL) { zerror(cb->zlogp, B_TRUE, "WARNING: zfd %s found, " "but it could not be controlled.", devpath); return (DI_WALK_CONTINUE); } if (devctl_device_remove(hdl) == 0) { cb->killed++; } else { zerror(cb->zlogp, B_TRUE, "WARNING: zfd %s found, " "but it could not be removed.", devpath); } devctl_release(hdl); return (DI_WALK_CONTINUE); }
/* * Handles links of the form: * type=ddi_pseudo;name=se;minor2=hdlc se_hdlc\N0 * type=ddi_pseudo;name=serial;minor2=hdlc se_hdlc\N0 */ static int se_hdlc_create(di_minor_t minor, di_node_t node) { devfsadm_enumerate_t rules[1] = {"^se_hdlc([0-9]+)$", 1, MATCH_ALL}; char *buf, path[PATH_MAX + 1]; char *ptr; char *mn; mn = di_minor_name(minor); /* minor node should be of the form: "?,hdlc" */ if (strcmp(mn + 1, ",hdlc") != 0) { return (DEVFSADM_CONTINUE); } if (NULL == (ptr = di_devfs_path(node))) { return (DEVFSADM_CONTINUE); } (void) strcpy(path, ptr); (void) strcat(path, ":"); (void) strcat(path, mn); di_devfs_path_free(ptr); if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) { return (DEVFSADM_CONTINUE); } (void) strcpy(path, "se_hdlc"); (void) strcat(path, buf); free(buf); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * This function is called for every ieee1394 minor node. * Calls enumerate to assign a logical ieee1394 id, and then * devfsadm_mklink to make the link. */ static int ieee1394_process(di_minor_t minor, di_node_t node) { char *buf, *devfspath; char l_path[PATH_MAX], p_path[PATH_MAX]; devfsadm_enumerate_t re[] = {"^1394/hba([0-9]+)$", 1, MATCH_ALL}; devfspath = di_devfs_path(node); devfsadm_print(debug_mid, "ieee1394_process: path %s\n", devfspath); (void) snprintf(p_path, sizeof (p_path), "%s:%s", devfspath, di_minor_name(minor)); di_devfs_path_free(devfspath); /* * Build the physical path from the components. Find the logical * ieee1394 HBA id, and stuff it in buf */ if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) { devfsadm_print(debug_mid, "ieee1394_process: exit/continue\n"); return (DEVFSADM_CONTINUE); } devfsadm_print(debug_mid, "ieee1394_process: p_path=%s buf=%s\n", p_path, buf); (void) snprintf(l_path, sizeof (l_path), "1394/hba%s", buf); free(buf); devfsadm_print(debug_mid, "mklink %s %s\n", l_path, p_path); (void) devfsadm_mklink(l_path, node, minor, 0); return (DEVFSADM_CONTINUE); }
static int find_sd_nodes(di_node_t node, di_minor_t minor, void *arg) { char *path; char devpath[MAXPATHLEN]; struct devices_ent *dep; path = di_devfs_path(node); if (*path == '/') { (void) strcpy(devpath, path+1); (void) strcat(devpath, ":"); (void) strcat(devpath, di_minor_name(minor)); dep = lookup_devices_sym(devpath); if (dep != NULL) { dep->issd = 1; } } di_devfs_path_free(path); return (DI_WALK_CONTINUE); }