/* * 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); }
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 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: * 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); }
/* * 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 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); }
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); }
/* * 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); }
static void ugen_create_link(char *p_path, char *node_name, di_node_t node, di_minor_t minor) { char *buf, s[MAXPATHLEN]; char *lasts = s; char *vid, *pid; char *minor_name; char ugen_RE[128]; devfsadm_enumerate_t ugen_rules[1]; char l_path[PATH_MAX]; int flags = 0; devfsadm_print(debug_mid, "ugen_create_link: p_path=%s name=%s\n", p_path, node_name); (void) strlcpy(s, node_name, sizeof (s)); /* get vid, pid and minor name strings */ vid = strtok_r(lasts, ".", &lasts); pid = strtok_r(NULL, ".", &lasts); minor_name = lasts; if ((vid == NULL) || (pid == NULL) || (minor_name == NULL)) { return; } /* create regular expression contain vid and pid */ (void) snprintf(ugen_RE, sizeof (ugen_RE), "^usb$/^%s\\.%s$/^([0-9]+)$", vid, pid); devfsadm_print(debug_mid, "ugen_create_link: ugen_RE=%s minor_name=%s\n", ugen_RE, minor_name); bzero(ugen_rules, sizeof (ugen_rules)); ugen_rules[0].re = ugen_RE; ugen_rules[0].subexp = 1; ugen_rules[0].flags = MATCH_ADDR; /* * build the physical path from the components. * find the logical usb id, and stuff it in buf */ if (devfsadm_enumerate_int(p_path, 0, &buf, ugen_rules, 1)) { devfsadm_print(debug_mid, "ugen_create_link: exit/continue\n"); return; } (void) snprintf(l_path, sizeof (l_path), "usb/%s.%s/%s/%s", vid, pid, buf, minor_name); devfsadm_print(debug_mid, "mklink %s -> %s\n", l_path, p_path); (void) devfsadm_mklink(l_path, node, minor, flags); free(buf); }
/* * 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_display". * * type=ddi_display fbs/\M0 fb\N0 */ static int display(di_minor_t minor, di_node_t node) { char l_path[PATH_MAX + 1], contents[PATH_MAX + 1], *buf; devfsadm_enumerate_t rules[1] = {"^fb([0-9]+)$", 1, MATCH_ALL}; char *mn = di_minor_name(minor); /* create fbs/\M0 primary link */ (void) strcpy(l_path, "fbs/"); (void) strcat(l_path, mn); (void) devfsadm_mklink(l_path, node, minor, 0); /* create fb\N0 which links to fbs/\M0 */ if (devfsadm_enumerate_int(l_path, 0, &buf, rules, 1)) { return (DEVFSADM_CONTINUE); } (void) strcpy(contents, l_path); (void) strcpy(l_path, "fb"); (void) strcat(l_path, buf); free(buf); (void) devfsadm_secondary_link(l_path, contents, 0); return (DEVFSADM_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); }
/* * This function is called for Smartcard card reader nodes * Handles minor node type "ddi_smartcard_reader" * type=ddi_smartcard_reader;name=card-reader scmi2c\N0 * Calls enumerate to assign logical card-reader id and then * devfsadm_mklink to make the link. */ static int ddi_cardreader(di_minor_t minor, di_node_t node) { char p_path[PATH_MAX +1], l_path[PATH_MAX +1]; char *buf; char *ptr; char *nn, *mn; devfsadm_enumerate_t rules[1] = {"^scmi2c([0-9]+)$", 1, MATCH_ALL}; nn = di_node_name(node); if (strcmp(nn, "card-reader")) { return (DEVFSADM_CONTINUE); } if (NULL == (ptr = di_devfs_path(node))) { return (DEVFSADM_CONTINUE); } (void) strcpy(p_path, ptr); (void) strcat(p_path, ":"); mn = di_minor_name(minor); (void) strcat(p_path, mn); di_devfs_path_free(ptr); if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { return (DEVFSADM_CONTINUE); } (void) snprintf(l_path, sizeof (l_path), "scmi2c%s", buf); free(buf); (void) devfsadm_mklink(l_path, node, minor, 0); return (DEVFSADM_CONTINUE); }
/* * This function is called for every usb minor node. * Calls enumerate to assign a logical usb id, and then * devfsadm_mklink to make the link. */ static int usb_process(di_minor_t minor, di_node_t node) { devfsadm_enumerate_t rules[1]; char *l_path, *p_path, *buf, *devfspath; char *minor_nm, *drvr_nm, *name = (char *)NULL; int i, index; int flags = 0; int create_secondary_link = 0; minor_nm = di_minor_name(minor); drvr_nm = di_driver_name(node); if ((minor_nm == NULL) || (drvr_nm == NULL)) { return (DEVFSADM_CONTINUE); } devfsadm_print(debug_mid, "usb_process: minor=%s node=%s type=%s\n", minor_nm, di_node_name(node), di_minor_nodetype(minor)); devfspath = di_devfs_path(node); if (devfspath == NULL) { devfsadm_print(debug_mid, "USB_process: devfspath is NULL\n"); return (DEVFSADM_CONTINUE); } l_path = (char *)malloc(PATH_MAX); if (l_path == NULL) { di_devfs_path_free(devfspath); devfsadm_print(debug_mid, "usb_process: malloc() failed\n"); return (DEVFSADM_CONTINUE); } p_path = (char *)malloc(PATH_MAX); if (p_path == NULL) { devfsadm_print(debug_mid, "usb_process: malloc() failed\n"); di_devfs_path_free(devfspath); free(l_path); return (DEVFSADM_CONTINUE); } (void) strcpy(p_path, devfspath); (void) strcat(p_path, ":"); (void) strcat(p_path, minor_nm); di_devfs_path_free(devfspath); devfsadm_print(debug_mid, "usb_process: path %s\n", p_path); for (i = 0; ; i++) { if ((driver_name_table[i].driver_name == NULL) || (strcmp(drvr_nm, driver_name_table[i].driver_name) == 0)) { index = driver_name_table[i].index; break; } } if (strcmp(di_minor_nodetype(minor), DDI_NT_UGEN) == 0) { ugen_create_link(p_path, minor_nm, node, minor); free(l_path); free(p_path); return (DEVFSADM_CONTINUE); } /* Figure out which rules to apply */ switch (index) { case DRIVER_HUBD: case DRIVER_OHCI: case DRIVER_EHCI: case DRIVER_UHCI: rules[0] = hub_rules[0]; /* For HUBs */ name = "hub"; break; case DRIVER_USB_AC: if (strcmp(minor_nm, "sound,audio") == 0) { rules[0] = audio_rules[0]; name = "audio"; /* For audio */ create_secondary_link = 1; } else if (strcmp(minor_nm, "sound,audioctl") == 0) { rules[0] = audio_control_rules[0]; name = "audio-control"; /* For audio */ create_secondary_link = 1; } else if (strcmp(minor_nm, "mux") == 0) { rules[0] = audio_mux_rules[0]; name = "audio-mux"; /* For audio */ } else { free(l_path); free(p_path); return (DEVFSADM_CONTINUE); } break; case DRIVER_USB_AS: rules[0] = audio_stream_rules[0]; name = "audio-stream"; /* For audio */ break; case DRIVER_VIDEO: rules[0] = video_rules[0]; name = "video"; /* For video */ create_secondary_link = 1; break; case DRIVER_HID: rules[0] = hid_rules[0]; name = "hid"; /* For HIDs */ break; case DRIVER_USB_MID: rules[0] = device_rules[0]; name = "device"; /* For other USB devices */ break; case DRIVER_DDIVS_USBC: rules[0] = ddivs_usbc_rules[0]; name = "device"; /* For other USB devices */ break; case DRIVER_SCSA2USB: rules[0] = mass_storage_rules[0]; name = "mass-storage"; /* For mass-storage devices */ break; case DRIVER_USBPRN: rules[0] = usbprn_rules[0]; name = "printer"; break; case DRIVER_HWAHC: if (strcmp(minor_nm, "hwahc") == 0) { rules[0] = whost_rules[0]; name = "whost"; /* For HWA HC */ } else if (strcmp(minor_nm, "hubd") == 0) { rules[0] = hub_rules[0]; name = "hub"; /* For HWA HC */ } else { free(l_path); free(p_path); return (DEVFSADM_CONTINUE); } break; case DRIVER_HWARC: rules[0] = hwarc_rules[0]; name = "hwarc"; /* For UWB HWA Radio Controllers */ break; case DRIVER_WUSB_CA: rules[0] = wusb_ca_rules[0]; name = "wusb_ca"; /* for wusb cable association */ break; default: devfsadm_print(debug_mid, "usb_process: unknown driver=%s\n", drvr_nm); free(l_path); free(p_path); return (DEVFSADM_CONTINUE); } /* * build the physical path from the components. * find the logical usb id, and stuff it in buf */ if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { devfsadm_print(debug_mid, "usb_process: exit/continue\n"); free(l_path); free(p_path); return (DEVFSADM_CONTINUE); } (void) snprintf(l_path, PATH_MAX, "usb/%s%s", name, buf); devfsadm_print(debug_mid, "usb_process: p_path=%s buf=%s\n", p_path, buf); free(buf); devfsadm_print(debug_mid, "mklink %s -> %s\n", l_path, p_path); (void) devfsadm_mklink(l_path, node, minor, flags); if (create_secondary_link) { /* * Create secondary links to make newly hotplugged * usb audio device the primary device. */ if (strcmp(name, "audio") == 0) { (void) devfsadm_secondary_link("audio", l_path, 0); } else if (strcmp(name, "audio-control") == 0) { (void) devfsadm_secondary_link("audioctl", l_path, 0); } else if (strcmp(name, "video") == 0) { (void) devfsadm_secondary_link(l_path + 4, l_path, 0); } } free(p_path); free(l_path); return (DEVFSADM_CONTINUE); }
/* * Called for all serial devices that are NOT onboard * Creates links of the form "/dev/term/[0..n]" * Schedules an update the sacadm (portmon). */ static int serial_port_create(di_minor_t minor, di_node_t node) { char l_path[MAXPATHLEN], p_path[MAXPATHLEN]; char *devfspath, *buf, *minor_name; int port_num; 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); } /* * verify dialout ports do not come in on this nodetype */ if (is_dialout(minor_name)) { devfsadm_errprint("%s: dialout device\n\t%s:%s\n", modname, devfspath, minor_name); di_devfs_path_free(devfspath); return (DEVFSADM_CONTINUE); } /* * add the minor name to the physical path so we can * enum the port# and create the the link. */ (void) strcpy(p_path, devfspath); (void) strcat(p_path, ":"); (void) strcat(p_path, minor_name); di_devfs_path_free(devfspath); if (devfsadm_enumerate_int(p_path, 0, &buf, port_rules, 1)) { devfsadm_errprint("%s:serial_port_create:" " enumerate_int() failed\n\t%s\n", modname, p_path); return (DEVFSADM_CONTINUE); } (void) strcpy(l_path, "term/"); (void) strcat(l_path, buf); (void) devfsadm_mklink(l_path, node, minor, 0); /* * update the portmon database if this port falls within * the valid range of ports. */ if ((port_num = parse_portno(buf)) != -1) { pma[port_num].flags |= HAS_PORT_DEVICE; } free(buf); return (DEVFSADM_CONTINUE); }