/* * 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); }
/* * For the master device: * /dev/lofictl -> /devices/pseudo/lofi@0:ctl * For each other device * /dev/lofi/1 -> /devices/pseudo/lofi@0:1 * /dev/rlofi/1 -> /devices/pseudo/lofi@0:1,raw */ static int lofi(di_minor_t minor, di_node_t node) { dev_t dev; char mn[MAXNAMELEN + 1]; char blkname[MAXNAMELEN + 1]; char rawname[MAXNAMELEN + 1]; char path[PATH_MAX + 1]; (void) strcpy(mn, di_minor_name(minor)); if (strcmp(mn, "ctl") == 0) { (void) devfsadm_mklink(LOFI_CTL_NAME, node, minor, 0); } else { dev = di_minor_devt(minor); (void) snprintf(blkname, sizeof (blkname), "%d", (int)minor(dev)); (void) snprintf(rawname, sizeof (rawname), "%d,raw", (int)minor(dev)); if (strcmp(mn, blkname) == 0) { (void) snprintf(path, sizeof (path), "%s/%s", LOFI_BLOCK_NAME, blkname); } else if (strcmp(mn, rawname) == 0) { (void) snprintf(path, sizeof (path), "%s/%s", LOFI_CHAR_NAME, blkname); } else { return (DEVFSADM_CONTINUE); } (void) devfsadm_mklink(path, node, minor, 0); } return (DEVFSADM_CONTINUE); }
/* Make logical name for HBA based on driver and instance */ static int drv_to_hba_logid(di_node_t node, di_minor_t minor, void *arg) { int inst; char *drv, *mn, *log; pathm_t *ptp; const size_t loglen = MAXPATHLEN; ptp = (pathm_t *)arg; errno = 0; mn = di_minor_name(minor); drv = di_driver_name(node); inst = di_instance(node); log = calloc(1, loglen); if (mn != NULL && drv != NULL && inst != -1 && log != NULL) { /* Count does not include terminating NULL */ if (snprintf(log, loglen, "%s%d:%s", drv, inst, mn) < loglen) { ptp->ret = SCFGA_OK; ptp->log = log; return (DI_WALK_TERMINATE); } } S_FREE(log); return (DI_WALK_CONTINUE); }
/* * This function is called for every ramdisk minor node. * Calls enumerate to assign a logical ramdisk id, and then * devfsadm_mklink to make the link. * * For pseudo ramdisk devices: * * /dev/ramdiskctl -> /devices/pseudo/ramdisk@0:ctl * /dev/ramdisk/<name> -> /devices/pseudo/ramdisk@0:<name> * /dev/rramdisk/<name> -> /devices/pseudo/ramdisk@0:<name>,raw * * For OBP-created ramdisk devices: * * /dev/ramdisk/<name> -> /devices/ramdisk-<name>:a * /dev/rramdisk/<name> -> /devices/ramdisk-<name>:a,raw */ static int ramdisk(di_minor_t di_minor, di_node_t node) { char *name; char devnm[MAXNAMELEN + 1]; char path[PATH_MAX]; /* * If this is an OBP-created ramdisk use the node name, having first * stripped the "ramdisk-" prefix. For pseudo ramdisks use the minor * name, having first stripped any ",raw" suffix. */ if (di_nodeid(node) == DI_PROM_NODEID) { RD_STRIP_PREFIX(name, di_node_name(node)); (void) strlcpy(devnm, name, sizeof (devnm)); } else { (void) strlcpy(devnm, di_minor_name(di_minor), sizeof (devnm)); RD_STRIP_SUFFIX(devnm); } if (strcmp(devnm, RD_CTL_NODE) == 0) { (void) devfsadm_mklink(RD_CTL_NAME, node, di_minor, 0); } else { /* * Make the link in /dev/ramdisk or /dev/rramdisk. */ (void) snprintf(path, sizeof (path), "%s/%s", di_minor_spectype(di_minor) == S_IFBLK ? RD_BLOCK_NAME : RD_CHAR_NAME, devnm); (void) devfsadm_mklink(path, node, di_minor, 0); } return (DEVFSADM_CONTINUE); }
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); }
/* * 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); }
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); }
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); }
/* * 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); }
/* * 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); }
/* * 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); }
/* * Called by di_walk_minor() to walk the list * of ddi_network minor device nodes and add * the interface to the niclist. * * Returns: DI_WALK_CONTINUE or DI_WALK_TERMINATE. */ static int nic_process_minor_nodes(di_node_t node, di_minor_t minor, void *arg) { wlkreq_t *request = (wlkreq_t *)arg; niclist_t **niclist = request->wr_niclist; char *name; char *nodetype; int instance; int ret; /* * Look for network devices only. Unfortunately, our walk will * include nodes with nodetypes of NULL. */ nodetype = di_minor_nodetype(minor); if ((nodetype == NULL) || (strcmp(nodetype, DDI_NT_NET) != 0)) { return (DI_WALK_CONTINUE); } /* * In the case of DDM_MINOR minor nodes, the minor * name is the name of the driver. However, if the name * doesn't include the instance, then it's not one * one we're interested in. In the case of other * minor nodes, we should be able to get the driver name * and its instance from the node properties. If they are * not valid, then we're not interested in them. */ if (di_minor_type(minor) == DDM_MINOR) { name = di_minor_name(minor); if ((name == NULL) || (strlen(name) == 0) || (!isdigit(name[strlen(name) - 1]))) { return (DI_WALK_CONTINUE); } instance = -1; } else { name = di_driver_name(node); instance = di_instance(node); if ((name == NULL) || (strlen(name) == 0) || (instance == -1)) { return (DI_WALK_CONTINUE); } } /* * Add this one to the niclist. */ ret = nic_add(niclist, name, instance, request->wr_syserr); if (ret != ICFG_SUCCESS) { (*request->wr_err) = ret; return (DI_WALK_TERMINATE); } (*request->wr_numif)++; return (DI_WALK_CONTINUE); }
/* * /dev/xen/<foo> -> /devices/xendev/<whatever>:<foo> */ static int devxen(di_minor_t minor, di_node_t node) { char buf[256]; (void) snprintf(buf, sizeof (buf), "xen/%s", di_minor_name(minor)); (void) devfsadm_mklink(buf, node, minor, 0); return (DEVFSADM_CONTINUE); }
static int driver_minor(di_minor_t minor, di_node_t node) { char path[PATH_MAX + 1]; (void) strcpy(path, di_driver_name(node)); (void) strcat(path, di_minor_name(minor)); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
scfga_ret_t make_dyncomp( di_node_t node, const char *physpath, char **dyncompp, int *l_errnop) { char *devlink = NULL; scfga_ret_t ret; di_minor_t minor; char *path; char pathbuf[MAXPATHLEN]; int match_minor; if (*dyncompp != NULL) { return (SCFGA_LIB_ERR); } /* tag on minor name */ minor = di_minor_next(node, DI_MINOR_NIL); if (minor == DI_MINOR_NIL) { match_minor = 0; path = (char *)physpath; } else { match_minor = 1; (void) snprintf(pathbuf, MAXPATHLEN, "%s:%s", physpath, di_minor_name(minor)); path = pathbuf; } /* Get the corresponding devlink from the physical path */ ret = physpath_to_devlink(path, &devlink, l_errnop, match_minor); if (ret == SCFGA_OK) { assert(devlink != NULL); /* Create dynamic component. */ ret = devlink_to_dyncomp(devlink, dyncompp, l_errnop); S_FREE(devlink); if (ret == SCFGA_OK) { assert(*dyncompp != NULL); return (SCFGA_OK); } /* * Failed to get devlink based dynamic component. * Try driver and instance */ } ret = drv_to_dyncomp(node, physpath, dyncompp, l_errnop); assert(ret != SCFGA_OK || *dyncompp != NULL); return (ret); }
static int xdt(di_minor_t minor, di_node_t node) { char *mname = di_minor_name(minor); char path[MAXPATHLEN]; (void) snprintf(path, sizeof (path), "dtrace/provider/%s", mname); (void) devfsadm_mklink(path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * create links at /dev/wifi for wifi minor node */ static int wifi_minor_name(di_minor_t minor, di_node_t node) { char buf[256]; char *mn = di_minor_name(minor); (void) snprintf(buf, sizeof (buf), "%s%s", "wifi/", mn); (void) devfsadm_mklink(buf, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * Starcat sbbc node. We only really care about generating a /dev * link for the lone sbbc on the SC (as opposed to the potentially * numerous sbbcs on the domain), so only operate on instance 0. */ static int starcat_sbbc_node(di_minor_t minor, di_node_t node) { char *mn; if (di_instance(node) == 0) { mn = di_minor_name(minor); (void) devfsadm_mklink(mn, node, minor, 0); } return (DEVFSADM_CONTINUE); }
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); }
/* * 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); }
/* * Creates /dev/lom and /dev/tsalarm:ctl for tsalarm node */ static int tsalarm_create(di_minor_t minor, di_node_t node) { char buf[PATH_MAX + 1]; char *mn = di_minor_name(minor); (void) snprintf(buf, sizeof (buf), "%s%s", di_node_name(node), ":ctl"); (void) devfsadm_mklink(mn, node, minor, 0); (void) devfsadm_mklink(buf, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * 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); }
/* * Handles minor node type "ddi_other" * type=ddi_other;name=SUNW,pmc pmc * type=ddi_other;name=SUNW,mic mic\M0 */ static int ddi_other(di_minor_t minor, di_node_t node) { char path[PATH_MAX + 1]; char *nn = di_node_name(node); char *mn = di_minor_name(minor); if (strcmp(nn, "SUNW,pmc") == 0) { (void) devfsadm_mklink("pcm", node, minor, 0); } else if (strcmp(nn, "SUNW,mic") == 0) { (void) strcpy(path, "mic"); (void) strcat(path, mn); (void) devfsadm_mklink(path, node, minor, 0); } return (DEVFSADM_CONTINUE); }
/* * Handles links of the form: * type=ddi_pseudo;name=xyz \M0 */ static int minor_name(di_minor_t minor, di_node_t node) { char *mn = di_minor_name(minor); (void) devfsadm_mklink(mn, node, minor, 0); if (strcmp(mn, "icmp") == 0) { (void) devfsadm_mklink("rawip", node, minor, 0); } if (strcmp(mn, "icmp6") == 0) { (void) devfsadm_mklink("rawip6", node, minor, 0); } if (strcmp(mn, "ipf") == 0) { (void) devfsadm_mklink("ipl", node, minor, 0); } return (DEVFSADM_CONTINUE); }
/* * For the zfs control node: * /dev/zfs -> /devices/pseudo/zfs@0:zfs * For zvols: * /dev/zvol/dsk/<pool>/<dataset> -> /devices/pseudo/zfs@0:1 * /dev/zvol/rdsk/<pool>/<dataset> -> /devices/pseudo/zfs@0:1,raw */ static int zfs(di_minor_t minor, di_node_t node) { dev_t dev; int err; char mn[MAXNAMELEN + 1]; char blkname[MAXNAMELEN + 1]; char rawname[MAXNAMELEN + 1]; char path[PATH_MAX + 1]; char *name; (void) strcpy(mn, di_minor_name(minor)); if (strcmp(mn, ZFS_DRIVER) == 0) { (void) devfsadm_mklink(ZFS_DRIVER, node, minor, 0); } else { dev = di_minor_devt(minor); err = di_prop_lookup_strings(dev, node, ZVOL_PROP_NAME, &name); if (err < 0) { /* property not defined so can't do anything */ return (DEVFSADM_CONTINUE); } (void) snprintf(blkname, sizeof (blkname), "%dc", (int)minor(dev)); (void) snprintf(rawname, sizeof (rawname), "%dc,raw", (int)minor(dev)); /* * This is where the actual public name gets constructed. * Change the snprintf format to change the public * path that gets constructed. */ if (strcmp(mn, blkname) == 0) { (void) snprintf(path, sizeof (path), "%s/%s", ZVOL_DEV_DIR, name); } else if (strcmp(mn, rawname) == 0) { (void) snprintf(path, sizeof (path), "%s/%s", ZVOL_RDEV_DIR, name); } else { return (DEVFSADM_CONTINUE); } (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); }
/*ARGSUSED*/ static int chk_dev_fcn(di_node_t node, di_minor_t minor, void *arg) { char *mn; struct chk_dev *chkp = (struct chk_dev *)arg; mn = di_minor_name(minor); if (mn == NULL) return (DI_WALK_CONTINUE); if (strcmp(mn, chkp->c_minor) != 0) return (DI_WALK_CONTINUE); chkp->c_isblk = di_minor_spectype(minor) == S_IFBLK ? 1 : 0; return (DI_WALK_TERMINATE); }
static char * ctype(di_node_t node, di_minor_t minor) { char *type; char *name; type = di_minor_nodetype(minor); name = di_node_name(node); /* IDE disks use SCSI nexus as the type, so handle this special case */ if ((libdiskmgt_str_eq(type, DDI_NT_SCSI_NEXUS) || libdiskmgt_str_eq(type, DDI_PSEUDO)) && libdiskmgt_str_eq(name, "ide")) return (DM_CTYPE_ATA); if (libdiskmgt_str_eq(type, DDI_NT_FC_ATTACHMENT_POINT) || (libdiskmgt_str_eq(type, DDI_NT_NEXUS) && libdiskmgt_str_eq(name, "fp"))) return (DM_CTYPE_FIBRE); if (libdiskmgt_str_eq(type, DDI_NT_NVME_ATTACHMENT_POINT)) return (DM_CTYPE_NVME); if (libdiskmgt_str_eq(type, DDI_NT_SATA_NEXUS) || libdiskmgt_str_eq(type, DDI_NT_SATA_ATTACHMENT_POINT)) return (DM_CTYPE_SATA); if (libdiskmgt_str_eq(type, DDI_NT_SCSI_NEXUS) || libdiskmgt_str_eq(type, DDI_NT_SCSI_ATTACHMENT_POINT)) return (DM_CTYPE_SCSI); if (libdiskmgt_str_eq(di_minor_name(minor), "scsa2usb")) return (DM_CTYPE_USB); if (libdiskmgt_str_eq(type, DDI_PSEUDO) && libdiskmgt_str_eq(name, "xpvd")) return (DM_CTYPE_XEN); if (dm_debug) { (void) fprintf(stderr, "INFO: unknown controller type=%s name=%s\n", type, name); } return (DM_CTYPE_UNKNOWN); }