10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51772Sjl139090 * Common Development and Distribution License (the "License").
61772Sjl139090 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12675SGirish.Moodalbail@oracle.COM * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include <regex.h>
260Sstevel@tonic-gate #include <devfsadm.h>
270Sstevel@tonic-gate #include <stdio.h>
280Sstevel@tonic-gate #include <strings.h>
290Sstevel@tonic-gate #include <stdlib.h>
300Sstevel@tonic-gate #include <limits.h>
310Sstevel@tonic-gate #include <sys/zone.h>
320Sstevel@tonic-gate #include <sys/zcons.h>
330Sstevel@tonic-gate #include <sys/cpuid_drv.h>
340Sstevel@tonic-gate
350Sstevel@tonic-gate static int display(di_minor_t minor, di_node_t node);
360Sstevel@tonic-gate static int parallel(di_minor_t minor, di_node_t node);
370Sstevel@tonic-gate static int node_slash_minor(di_minor_t minor, di_node_t node);
380Sstevel@tonic-gate static int driver_minor(di_minor_t minor, di_node_t node);
390Sstevel@tonic-gate static int node_name(di_minor_t minor, di_node_t node);
400Sstevel@tonic-gate static int minor_name(di_minor_t minor, di_node_t node);
41995Shx147065 static int wifi_minor_name(di_minor_t minor, di_node_t node);
420Sstevel@tonic-gate static int conskbd(di_minor_t minor, di_node_t node);
430Sstevel@tonic-gate static int consms(di_minor_t minor, di_node_t node);
440Sstevel@tonic-gate static int power_button(di_minor_t minor, di_node_t node);
450Sstevel@tonic-gate static int fc_port(di_minor_t minor, di_node_t node);
460Sstevel@tonic-gate static int printer_create(di_minor_t minor, di_node_t node);
470Sstevel@tonic-gate static int se_hdlc_create(di_minor_t minor, di_node_t node);
480Sstevel@tonic-gate static int ppm(di_minor_t minor, di_node_t node);
490Sstevel@tonic-gate static int gpio(di_minor_t minor, di_node_t node);
500Sstevel@tonic-gate static int av_create(di_minor_t minor, di_node_t node);
510Sstevel@tonic-gate static int tsalarm_create(di_minor_t minor, di_node_t node);
52467Ssc121708 static int ntwdt_create(di_minor_t minor, di_node_t node);
530Sstevel@tonic-gate static int zcons_create(di_minor_t minor, di_node_t node);
540Sstevel@tonic-gate static int cpuid(di_minor_t minor, di_node_t node);
550Sstevel@tonic-gate static int glvc(di_minor_t minor, di_node_t node);
560Sstevel@tonic-gate static int ses_callback(di_minor_t minor, di_node_t node);
571772Sjl139090 static int kmdrv_create(di_minor_t minor, di_node_t node);
580Sstevel@tonic-gate
590Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = {
602621Sllai1 { "pseudo", "ddi_pseudo", "(^sad$)",
610Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_0, node_slash_minor
620Sstevel@tonic-gate },
630Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "zsh",
640Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, driver_minor
650Sstevel@tonic-gate },
660Sstevel@tonic-gate { "network", "ddi_network", NULL,
670Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, minor_name
680Sstevel@tonic-gate },
69995Shx147065 { "wifi", "ddi_network:wifi", NULL,
70995Shx147065 TYPE_EXACT, ILEVEL_0, wifi_minor_name
71995Shx147065 },
720Sstevel@tonic-gate { "display", "ddi_display", NULL,
730Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, display
740Sstevel@tonic-gate },
750Sstevel@tonic-gate { "parallel", "ddi_parallel", NULL,
760Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, parallel
770Sstevel@tonic-gate },
780Sstevel@tonic-gate { "enclosure", DDI_NT_SCSI_ENCLOSURE, NULL,
790Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, ses_callback
800Sstevel@tonic-gate },
810Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "(^winlock$)|(^pm$)",
820Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_0, node_name
830Sstevel@tonic-gate },
840Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "conskbd",
850Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, conskbd
860Sstevel@tonic-gate },
870Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "consms",
880Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, consms
890Sstevel@tonic-gate },
900Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "rsm",
910Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
920Sstevel@tonic-gate },
930Sstevel@tonic-gate { "pseudo", "ddi_pseudo",
940Sstevel@tonic-gate "(^lockstat$)|(^SUNW,rtvc$)|(^vol$)|(^log$)|(^sy$)|"
958023SPhil.Kirk@Sun.COM "(^ksyms$)|(^clone$)|(^tl$)|(^tnf$)|(^kstat$)|(^mdesc$)|(^eeprom$)|"
968023SPhil.Kirk@Sun.COM "(^ptsl$)|(^mm$)|(^wc$)|(^dump$)|(^cn$)|(^svvslo$)|(^ptm$)|"
970Sstevel@tonic-gate "(^ptc$)|(^openeepr$)|(^poll$)|(^sysmsg$)|(^random$)|(^trapstat$)|"
980Sstevel@tonic-gate "(^cryptoadm$)|(^crypto$)|(^pool$)|(^poolctl$)|(^bl$)|(^kmdb$)|"
993253Smec "(^sysevent$)|(^kssl$)|(^physmem$)",
1000Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
1010Sstevel@tonic-gate },
1020Sstevel@tonic-gate { "pseudo", "ddi_pseudo",
103*12675SGirish.Moodalbail@oracle.COM "(^ip$)|(^tcp$)|(^udp$)|(^icmp$)|"
104*12675SGirish.Moodalbail@oracle.COM "(^ip6$)|(^tcp6$)|(^udp6$)|(^icmp6$)|"
1050Sstevel@tonic-gate "(^rts$)|(^arp$)|(^ipsecah$)|(^ipsecesp$)|(^keysock$)|(^spdsock$)|"
10611042SErik.Nordmark@Sun.COM "(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)",
1070Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
1080Sstevel@tonic-gate },
1090Sstevel@tonic-gate { "pseudo", "ddi_pseudo",
1102958Sdr146992 "(^ipf$)|(^ipnat$)|(^ipstate$)|(^ipauth$)|"
1110Sstevel@tonic-gate "(^ipsync$)|(^ipscan$)|(^iplookup$)",
1120Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name,
1130Sstevel@tonic-gate },
1147408SSebastien.Roy@Sun.COM { "pseudo", "ddi_pseudo", "dld",
1157408SSebastien.Roy@Sun.COM TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
1167408SSebastien.Roy@Sun.COM },
1170Sstevel@tonic-gate { "pseudo", "ddi_pseudo",
1189840Sgdamore@opensolaris.org "(^kdmouse$)|(^rootprop$)",
1190Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_0, node_name
1200Sstevel@tonic-gate },
1210Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "tod",
1220Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
1230Sstevel@tonic-gate },
1240Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "envctrl(two)?",
1250Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
1260Sstevel@tonic-gate },
1270Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "fcode",
1280Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name,
1290Sstevel@tonic-gate },
1300Sstevel@tonic-gate { "power_button", "ddi_power_button", NULL,
1310Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, power_button,
1320Sstevel@tonic-gate },
1330Sstevel@tonic-gate { "FC port", "ddi_ctl:devctl", "fp",
1340Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, fc_port
1350Sstevel@tonic-gate },
1360Sstevel@tonic-gate { "printer", "ddi_printer", NULL,
1370Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, printer_create
1380Sstevel@tonic-gate },
1390Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "se",
1400Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, se_hdlc_create
1410Sstevel@tonic-gate },
1420Sstevel@tonic-gate { "ppm", "ddi_ppm", NULL,
1430Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, ppm
1440Sstevel@tonic-gate },
1450Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "gpio_87317",
1460Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, gpio
1470Sstevel@tonic-gate },
1480Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "sckmdrv",
1491772Sjl139090 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
1501772Sjl139090 },
1511772Sjl139090 { "pseudo", "ddi_pseudo", "oplkmdrv",
1521772Sjl139090 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
1530Sstevel@tonic-gate },
1540Sstevel@tonic-gate { "av", "^ddi_av:(isoch|async)$", NULL,
1550Sstevel@tonic-gate TYPE_RE, ILEVEL_0, av_create,
1560Sstevel@tonic-gate },
1570Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "tsalarm",
1580Sstevel@tonic-gate TYPE_EXACT | DRV_RE, ILEVEL_0, tsalarm_create,
1590Sstevel@tonic-gate },
160467Ssc121708 { "pseudo", "ddi_pseudo", "ntwdt",
161467Ssc121708 TYPE_EXACT | DRV_RE, ILEVEL_0, ntwdt_create,
162467Ssc121708 },
1630Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "daplt",
1640Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
1650Sstevel@tonic-gate },
1660Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "zcons",
1670Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, zcons_create,
1680Sstevel@tonic-gate },
1690Sstevel@tonic-gate { "pseudo", "ddi_pseudo", CPUID_DRIVER_NAME,
1700Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, cpuid,
1710Sstevel@tonic-gate },
1720Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "glvc",
1730Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, glvc,
1740Sstevel@tonic-gate },
1751772Sjl139090 { "pseudo", "ddi_pseudo", "dm2s",
1761772Sjl139090 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name,
1771772Sjl139090 },
1786007Sthurlow { "pseudo", "ddi_pseudo", "nsmb",
1796007Sthurlow TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
1806007Sthurlow },
1816330Sjc25722 { "pseudo", "ddi_pseudo", "mem_cache",
1826330Sjc25722 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
1836330Sjc25722 },
1847532SSean.Ye@Sun.COM { "pseudo", "ddi_pseudo", "fm",
1857532SSean.Ye@Sun.COM TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
18610346Swyllys.ingersoll@sun.com },
18710346Swyllys.ingersoll@sun.com { "pseudo", "ddi_pseudo", "tpm",
18810346Swyllys.ingersoll@sun.com TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
18910346Swyllys.ingersoll@sun.com },
1900Sstevel@tonic-gate };
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt);
1930Sstevel@tonic-gate
1940Sstevel@tonic-gate static devfsadm_remove_t misc_remove_cbt[] = {
1950Sstevel@tonic-gate { "pseudo", "^profile$",
1960Sstevel@tonic-gate RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
1970Sstevel@tonic-gate },
1980Sstevel@tonic-gate { "pseudo", "^rsm$",
1990Sstevel@tonic-gate RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
2000Sstevel@tonic-gate },
2010Sstevel@tonic-gate { "printer", "^printers/[0-9]+$",
2020Sstevel@tonic-gate RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
2030Sstevel@tonic-gate },
2040Sstevel@tonic-gate { "av", "^av/[0-9]+/(async|isoch)$",
2050Sstevel@tonic-gate RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
2060Sstevel@tonic-gate },
2070Sstevel@tonic-gate { "pseudo", "^daplt$",
2080Sstevel@tonic-gate RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
2090Sstevel@tonic-gate },
2100Sstevel@tonic-gate { "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MASTER_NAME "|"
2110Sstevel@tonic-gate ZCONS_SLAVE_NAME ")$",
2120Sstevel@tonic-gate RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
2130Sstevel@tonic-gate },
2145084Sjohnlev { "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT,
2150Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all
2160Sstevel@tonic-gate },
2170Sstevel@tonic-gate { "enclosure", "^es/ses[0-9]+$", RM_POST,
2180Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all
2194482Sdr146992 },
2204482Sdr146992 { "pseudo", "^pfil$",
2214482Sdr146992 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
22210346Swyllys.ingersoll@sun.com },
22310346Swyllys.ingersoll@sun.com { "pseudo", "^tpm$",
22410346Swyllys.ingersoll@sun.com RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
22510346Swyllys.ingersoll@sun.com },
226*12675SGirish.Moodalbail@oracle.COM { "pseudo", "^sctp|sctp6$",
227*12675SGirish.Moodalbail@oracle.COM RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_link
228*12675SGirish.Moodalbail@oracle.COM }
2290Sstevel@tonic-gate };
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate /* Rules for gpio devices */
2320Sstevel@tonic-gate static devfsadm_enumerate_t gpio_rules[1] =
2330Sstevel@tonic-gate {"^gpio([0-9]+)$", 1, MATCH_ALL};
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt);
2360Sstevel@tonic-gate
2370Sstevel@tonic-gate /*
2380Sstevel@tonic-gate * Handles minor node type "ddi_display".
2390Sstevel@tonic-gate *
2400Sstevel@tonic-gate * type=ddi_display fbs/\M0 fb\N0
2410Sstevel@tonic-gate */
2420Sstevel@tonic-gate static int
display(di_minor_t minor,di_node_t node)2430Sstevel@tonic-gate display(di_minor_t minor, di_node_t node)
2440Sstevel@tonic-gate {
2450Sstevel@tonic-gate char l_path[PATH_MAX + 1], contents[PATH_MAX + 1], *buf;
2460Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^fb([0-9]+)$", 1, MATCH_ALL};
2470Sstevel@tonic-gate char *mn = di_minor_name(minor);
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate /* create fbs/\M0 primary link */
2500Sstevel@tonic-gate (void) strcpy(l_path, "fbs/");
2510Sstevel@tonic-gate (void) strcat(l_path, mn);
2520Sstevel@tonic-gate (void) devfsadm_mklink(l_path, node, minor, 0);
2530Sstevel@tonic-gate
2540Sstevel@tonic-gate /* create fb\N0 which links to fbs/\M0 */
2550Sstevel@tonic-gate if (devfsadm_enumerate_int(l_path, 0, &buf, rules, 1)) {
2560Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2570Sstevel@tonic-gate }
2580Sstevel@tonic-gate (void) strcpy(contents, l_path);
2590Sstevel@tonic-gate (void) strcpy(l_path, "fb");
2600Sstevel@tonic-gate (void) strcat(l_path, buf);
2610Sstevel@tonic-gate free(buf);
2620Sstevel@tonic-gate (void) devfsadm_secondary_link(l_path, contents, 0);
2630Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2640Sstevel@tonic-gate }
2650Sstevel@tonic-gate
2660Sstevel@tonic-gate /*
2670Sstevel@tonic-gate * Handles minor node type "ddi_parallel".
2680Sstevel@tonic-gate * type=ddi_parallel;name=mcpp mcpp\N0
2690Sstevel@tonic-gate */
2700Sstevel@tonic-gate static int
parallel(di_minor_t minor,di_node_t node)2710Sstevel@tonic-gate parallel(di_minor_t minor, di_node_t node)
2720Sstevel@tonic-gate {
2730Sstevel@tonic-gate char path[PATH_MAX + 1], *buf;
2740Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"mcpp([0-9]+)$", 1, MATCH_ALL};
2750Sstevel@tonic-gate
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate if (strcmp(di_node_name(node), "mcpp") != 0) {
2780Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2790Sstevel@tonic-gate }
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate if (NULL == (buf = di_devfs_path(node))) {
2820Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s",
2860Sstevel@tonic-gate buf, di_minor_name(minor));
2870Sstevel@tonic-gate
2880Sstevel@tonic-gate di_devfs_path_free(buf);
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
2910Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "mcpp%s", buf);
2940Sstevel@tonic-gate free(buf);
2950Sstevel@tonic-gate
2960Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
2970Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate
3000Sstevel@tonic-gate static int
ses_callback(di_minor_t minor,di_node_t node)3010Sstevel@tonic-gate ses_callback(di_minor_t minor, di_node_t node)
3020Sstevel@tonic-gate {
3030Sstevel@tonic-gate char l_path[PATH_MAX];
3040Sstevel@tonic-gate char *buf;
3050Sstevel@tonic-gate char *devfspath;
3060Sstevel@tonic-gate char p_path[PATH_MAX];
3070Sstevel@tonic-gate devfsadm_enumerate_t re[] = {"^es$/^ses([0-9]+)$", 1, MATCH_ALL};
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate /* find devices path -- need to free mem */
3100Sstevel@tonic-gate if (NULL == (devfspath = di_devfs_path(node))) {
3110Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3120Sstevel@tonic-gate }
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate (void) snprintf(p_path, sizeof (p_path), "%s:%s", devfspath,
3150Sstevel@tonic-gate di_minor_name(minor));
3160Sstevel@tonic-gate
3170Sstevel@tonic-gate
3180Sstevel@tonic-gate /* find next number to use; buf is an ascii number */
3190Sstevel@tonic-gate if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) {
3200Sstevel@tonic-gate /* free memory */
3210Sstevel@tonic-gate di_devfs_path_free(devfspath);
3220Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate (void) snprintf(l_path, sizeof (l_path), "es/ses%s", buf);
3260Sstevel@tonic-gate
3270Sstevel@tonic-gate (void) devfsadm_mklink(l_path, node, minor, 0);
3280Sstevel@tonic-gate /* free memory */
3290Sstevel@tonic-gate free(buf);
3300Sstevel@tonic-gate di_devfs_path_free(devfspath);
3310Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate static int
node_slash_minor(di_minor_t minor,di_node_t node)3360Sstevel@tonic-gate node_slash_minor(di_minor_t minor, di_node_t node)
3370Sstevel@tonic-gate {
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate char path[PATH_MAX + 1];
3400Sstevel@tonic-gate
3410Sstevel@tonic-gate (void) strcpy(path, di_node_name(node));
3420Sstevel@tonic-gate (void) strcat(path, "/");
3430Sstevel@tonic-gate (void) strcat(path, di_minor_name(minor));
3440Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
3450Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate
3480Sstevel@tonic-gate static int
driver_minor(di_minor_t minor,di_node_t node)3490Sstevel@tonic-gate driver_minor(di_minor_t minor, di_node_t node)
3500Sstevel@tonic-gate {
3510Sstevel@tonic-gate char path[PATH_MAX + 1];
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate (void) strcpy(path, di_driver_name(node));
3540Sstevel@tonic-gate (void) strcat(path, di_minor_name(minor));
3550Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
3560Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3570Sstevel@tonic-gate }
3580Sstevel@tonic-gate
3590Sstevel@tonic-gate /*
3600Sstevel@tonic-gate * Handles links of the form:
3610Sstevel@tonic-gate * type=ddi_pseudo;name=xyz \D
3620Sstevel@tonic-gate */
3630Sstevel@tonic-gate static int
node_name(di_minor_t minor,di_node_t node)3640Sstevel@tonic-gate node_name(di_minor_t minor, di_node_t node)
3650Sstevel@tonic-gate {
3660Sstevel@tonic-gate (void) devfsadm_mklink(di_node_name(node), node, minor, 0);
3670Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3680Sstevel@tonic-gate }
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /*
3710Sstevel@tonic-gate * Handles links of the form:
3720Sstevel@tonic-gate * type=ddi_pseudo;name=xyz \M0
3730Sstevel@tonic-gate */
3740Sstevel@tonic-gate static int
minor_name(di_minor_t minor,di_node_t node)3750Sstevel@tonic-gate minor_name(di_minor_t minor, di_node_t node)
3760Sstevel@tonic-gate {
3770Sstevel@tonic-gate char *mn = di_minor_name(minor);
3780Sstevel@tonic-gate
3790Sstevel@tonic-gate (void) devfsadm_mklink(mn, node, minor, 0);
3800Sstevel@tonic-gate if (strcmp(mn, "icmp") == 0) {
3810Sstevel@tonic-gate (void) devfsadm_mklink("rawip", node, minor, 0);
3820Sstevel@tonic-gate }
3830Sstevel@tonic-gate if (strcmp(mn, "icmp6") == 0) {
3840Sstevel@tonic-gate (void) devfsadm_mklink("rawip6", node, minor, 0);
3850Sstevel@tonic-gate }
3860Sstevel@tonic-gate if (strcmp(mn, "ipf") == 0) {
3870Sstevel@tonic-gate (void) devfsadm_mklink("ipl", node, minor, 0);
3880Sstevel@tonic-gate }
3890Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate
392995Shx147065 /*
393995Shx147065 * create links at /dev/wifi for wifi minor node
394995Shx147065 */
395995Shx147065 static int
wifi_minor_name(di_minor_t minor,di_node_t node)396995Shx147065 wifi_minor_name(di_minor_t minor, di_node_t node)
397995Shx147065 {
398995Shx147065 char buf[256];
399995Shx147065 char *mn = di_minor_name(minor);
400995Shx147065
401995Shx147065 (void) snprintf(buf, sizeof (buf), "%s%s", "wifi/", mn);
402995Shx147065 (void) devfsadm_mklink(buf, node, minor, 0);
403995Shx147065
404995Shx147065 return (DEVFSADM_CONTINUE);
405995Shx147065 }
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate static int
conskbd(di_minor_t minor,di_node_t node)4080Sstevel@tonic-gate conskbd(di_minor_t minor, di_node_t node)
4090Sstevel@tonic-gate {
4100Sstevel@tonic-gate (void) devfsadm_mklink("kbd", node, minor, 0);
4110Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4120Sstevel@tonic-gate }
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate static int
consms(di_minor_t minor,di_node_t node)4150Sstevel@tonic-gate consms(di_minor_t minor, di_node_t node)
4160Sstevel@tonic-gate {
4170Sstevel@tonic-gate (void) devfsadm_mklink("mouse", node, minor, 0);
4180Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4190Sstevel@tonic-gate }
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate static int
power_button(di_minor_t minor,di_node_t node)4220Sstevel@tonic-gate power_button(di_minor_t minor, di_node_t node)
4230Sstevel@tonic-gate {
4240Sstevel@tonic-gate (void) devfsadm_mklink("power_button", node, minor, 0);
4250Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4260Sstevel@tonic-gate }
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate static int
fc_port(di_minor_t minor,di_node_t node)4290Sstevel@tonic-gate fc_port(di_minor_t minor, di_node_t node)
4300Sstevel@tonic-gate {
4310Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"fc/fp([0-9]+)$", 1, MATCH_ALL};
4320Sstevel@tonic-gate char *buf, path[PATH_MAX + 1];
4330Sstevel@tonic-gate char *ptr;
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate if (NULL == (ptr = di_devfs_path(node))) {
4360Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate
4390Sstevel@tonic-gate (void) strcpy(path, ptr);
4400Sstevel@tonic-gate (void) strcat(path, ":");
4410Sstevel@tonic-gate (void) strcat(path, di_minor_name(minor));
4420Sstevel@tonic-gate
4430Sstevel@tonic-gate di_devfs_path_free(ptr);
4440Sstevel@tonic-gate
4450Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) {
4460Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4470Sstevel@tonic-gate }
4480Sstevel@tonic-gate
4490Sstevel@tonic-gate (void) strcpy(path, "fc/fp");
4500Sstevel@tonic-gate (void) strcat(path, buf);
4510Sstevel@tonic-gate free(buf);
4520Sstevel@tonic-gate
4530Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
4540Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate /*
4580Sstevel@tonic-gate * Handles:
4590Sstevel@tonic-gate * minor node type "ddi_printer".
4600Sstevel@tonic-gate * rules of the form: type=ddi_printer;name=bpp \M0
4610Sstevel@tonic-gate */
4620Sstevel@tonic-gate static int
printer_create(di_minor_t minor,di_node_t node)4630Sstevel@tonic-gate printer_create(di_minor_t minor, di_node_t node)
4640Sstevel@tonic-gate {
4650Sstevel@tonic-gate char *mn;
4660Sstevel@tonic-gate char path[PATH_MAX + 1], *buf;
4670Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^printers$/^([0-9]+)$", 1, MATCH_ALL};
4680Sstevel@tonic-gate
4690Sstevel@tonic-gate mn = di_minor_name(minor);
4700Sstevel@tonic-gate
4710Sstevel@tonic-gate if (strcmp(di_driver_name(node), "bpp") == 0) {
4720Sstevel@tonic-gate (void) devfsadm_mklink(mn, node, minor, 0);
4730Sstevel@tonic-gate }
4740Sstevel@tonic-gate
4750Sstevel@tonic-gate if (NULL == (buf = di_devfs_path(node))) {
4760Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate
4790Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", buf, mn);
4800Sstevel@tonic-gate di_devfs_path_free(buf);
4810Sstevel@tonic-gate
4820Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
4830Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate
4860Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "printers/%s", buf);
4870Sstevel@tonic-gate free(buf);
4880Sstevel@tonic-gate
4890Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
4900Sstevel@tonic-gate
4910Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
4920Sstevel@tonic-gate }
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate /*
4950Sstevel@tonic-gate * Handles links of the form:
4960Sstevel@tonic-gate * type=ddi_pseudo;name=se;minor2=hdlc se_hdlc\N0
4970Sstevel@tonic-gate * type=ddi_pseudo;name=serial;minor2=hdlc se_hdlc\N0
4980Sstevel@tonic-gate */
4990Sstevel@tonic-gate static int
se_hdlc_create(di_minor_t minor,di_node_t node)5000Sstevel@tonic-gate se_hdlc_create(di_minor_t minor, di_node_t node)
5010Sstevel@tonic-gate {
5020Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^se_hdlc([0-9]+)$", 1, MATCH_ALL};
5030Sstevel@tonic-gate char *buf, path[PATH_MAX + 1];
5040Sstevel@tonic-gate char *ptr;
5050Sstevel@tonic-gate char *mn;
5060Sstevel@tonic-gate
5070Sstevel@tonic-gate mn = di_minor_name(minor);
5080Sstevel@tonic-gate
5090Sstevel@tonic-gate /* minor node should be of the form: "?,hdlc" */
5100Sstevel@tonic-gate if (strcmp(mn + 1, ",hdlc") != 0) {
5110Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate if (NULL == (ptr = di_devfs_path(node))) {
5150Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5160Sstevel@tonic-gate }
5170Sstevel@tonic-gate
5180Sstevel@tonic-gate (void) strcpy(path, ptr);
5190Sstevel@tonic-gate (void) strcat(path, ":");
5200Sstevel@tonic-gate (void) strcat(path, mn);
5210Sstevel@tonic-gate
5220Sstevel@tonic-gate di_devfs_path_free(ptr);
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) {
5250Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5260Sstevel@tonic-gate }
5270Sstevel@tonic-gate
5280Sstevel@tonic-gate (void) strcpy(path, "se_hdlc");
5290Sstevel@tonic-gate (void) strcat(path, buf);
5300Sstevel@tonic-gate free(buf);
5310Sstevel@tonic-gate
5320Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
5330Sstevel@tonic-gate
5340Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5350Sstevel@tonic-gate }
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate static int
gpio(di_minor_t minor,di_node_t node)5380Sstevel@tonic-gate gpio(di_minor_t minor, di_node_t node)
5390Sstevel@tonic-gate {
5400Sstevel@tonic-gate char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath;
5410Sstevel@tonic-gate char *minor_nm, *drvr_nm;
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate
5440Sstevel@tonic-gate minor_nm = di_minor_name(minor);
5450Sstevel@tonic-gate drvr_nm = di_driver_name(node);
5460Sstevel@tonic-gate if ((minor_nm == NULL) || (drvr_nm == NULL)) {
5470Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5480Sstevel@tonic-gate }
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate devfspath = di_devfs_path(node);
5510Sstevel@tonic-gate
5520Sstevel@tonic-gate (void) strcpy(p_path, devfspath);
5530Sstevel@tonic-gate (void) strcat(p_path, ":");
5540Sstevel@tonic-gate (void) strcat(p_path, minor_nm);
5550Sstevel@tonic-gate di_devfs_path_free(devfspath);
5560Sstevel@tonic-gate
5570Sstevel@tonic-gate /* build the physical path from the components */
5580Sstevel@tonic-gate if (devfsadm_enumerate_int(p_path, 0, &buf, gpio_rules, 1)) {
5590Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5600Sstevel@tonic-gate }
5610Sstevel@tonic-gate
5620Sstevel@tonic-gate (void) snprintf(l_path, sizeof (l_path), "%s%s", "gpio", buf);
5630Sstevel@tonic-gate
5640Sstevel@tonic-gate free(buf);
5650Sstevel@tonic-gate
5660Sstevel@tonic-gate (void) devfsadm_mklink(l_path, node, minor, 0);
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5690Sstevel@tonic-gate }
5700Sstevel@tonic-gate
5710Sstevel@tonic-gate /*
5720Sstevel@tonic-gate * Creates /dev/ppm nodes for Platform Specific PM module
5730Sstevel@tonic-gate */
5740Sstevel@tonic-gate static int
ppm(di_minor_t minor,di_node_t node)5750Sstevel@tonic-gate ppm(di_minor_t minor, di_node_t node)
5760Sstevel@tonic-gate {
5770Sstevel@tonic-gate (void) devfsadm_mklink("ppm", node, minor, 0);
5780Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5790Sstevel@tonic-gate }
5800Sstevel@tonic-gate
5810Sstevel@tonic-gate /*
5820Sstevel@tonic-gate * Handles:
5830Sstevel@tonic-gate * /dev/av/[0-9]+/(async|isoch)
5840Sstevel@tonic-gate */
5850Sstevel@tonic-gate static int
av_create(di_minor_t minor,di_node_t node)5860Sstevel@tonic-gate av_create(di_minor_t minor, di_node_t node)
5870Sstevel@tonic-gate {
5880Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^av$/^([0-9]+)$", 1, MATCH_ADDR};
5890Sstevel@tonic-gate char *minor_str;
5900Sstevel@tonic-gate char path[PATH_MAX + 1];
5910Sstevel@tonic-gate char *buf;
5920Sstevel@tonic-gate
5930Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) {
5940Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
5950Sstevel@tonic-gate }
5960Sstevel@tonic-gate
5970Sstevel@tonic-gate minor_str = di_minor_name(minor);
5980Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", buf, minor_str);
5990Sstevel@tonic-gate di_devfs_path_free(buf);
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
6020Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6030Sstevel@tonic-gate }
6040Sstevel@tonic-gate
6050Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "av/%s/%s", buf, minor_str);
6060Sstevel@tonic-gate free(buf);
6070Sstevel@tonic-gate
6080Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
6090Sstevel@tonic-gate
6100Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6110Sstevel@tonic-gate }
6120Sstevel@tonic-gate
6130Sstevel@tonic-gate /*
6140Sstevel@tonic-gate * Creates /dev/lom and /dev/tsalarm:ctl for tsalarm node
6150Sstevel@tonic-gate */
6160Sstevel@tonic-gate static int
tsalarm_create(di_minor_t minor,di_node_t node)6170Sstevel@tonic-gate tsalarm_create(di_minor_t minor, di_node_t node)
6180Sstevel@tonic-gate {
6190Sstevel@tonic-gate char buf[PATH_MAX + 1];
6200Sstevel@tonic-gate char *mn = di_minor_name(minor);
6210Sstevel@tonic-gate
6220Sstevel@tonic-gate (void) snprintf(buf, sizeof (buf), "%s%s", di_node_name(node), ":ctl");
6230Sstevel@tonic-gate
6240Sstevel@tonic-gate (void) devfsadm_mklink(mn, node, minor, 0);
6250Sstevel@tonic-gate (void) devfsadm_mklink(buf, node, minor, 0);
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate
630467Ssc121708 /*
631467Ssc121708 * Creates /dev/ntwdt for ntwdt node
632467Ssc121708 */
633467Ssc121708 static int
ntwdt_create(di_minor_t minor,di_node_t node)634467Ssc121708 ntwdt_create(di_minor_t minor, di_node_t node)
635467Ssc121708 {
636467Ssc121708 (void) devfsadm_mklink("ntwdt", node, minor, 0);
637467Ssc121708 return (DEVFSADM_CONTINUE);
638467Ssc121708 }
639467Ssc121708
6400Sstevel@tonic-gate static int
zcons_create(di_minor_t minor,di_node_t node)6410Sstevel@tonic-gate zcons_create(di_minor_t minor, di_node_t node)
6420Sstevel@tonic-gate {
6430Sstevel@tonic-gate char *minor_str;
6440Sstevel@tonic-gate char *zonename;
6450Sstevel@tonic-gate char path[MAXPATHLEN];
6460Sstevel@tonic-gate
6470Sstevel@tonic-gate minor_str = di_minor_name(minor);
6480Sstevel@tonic-gate
6490Sstevel@tonic-gate if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zonename",
6500Sstevel@tonic-gate &zonename) == -1) {
6510Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6520Sstevel@tonic-gate }
6530Sstevel@tonic-gate
6540Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "zcons/%s/%s", zonename,
6550Sstevel@tonic-gate minor_str);
6560Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
6570Sstevel@tonic-gate
6580Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6590Sstevel@tonic-gate }
6600Sstevel@tonic-gate
6610Sstevel@tonic-gate /*
6620Sstevel@tonic-gate * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self
6630Sstevel@tonic-gate */
6640Sstevel@tonic-gate static int
cpuid(di_minor_t minor,di_node_t node)6650Sstevel@tonic-gate cpuid(di_minor_t minor, di_node_t node)
6660Sstevel@tonic-gate {
6670Sstevel@tonic-gate (void) devfsadm_mklink(CPUID_SELF_NAME, node, minor, 0);
6680Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6690Sstevel@tonic-gate }
6700Sstevel@tonic-gate
6710Sstevel@tonic-gate /*
6720Sstevel@tonic-gate * For device
6730Sstevel@tonic-gate * /dev/spfma -> /devices/virtual-devices/fma@5:glvc
6740Sstevel@tonic-gate */
6750Sstevel@tonic-gate static int
glvc(di_minor_t minor,di_node_t node)6760Sstevel@tonic-gate glvc(di_minor_t minor, di_node_t node)
6770Sstevel@tonic-gate {
6780Sstevel@tonic-gate char node_name[MAXNAMELEN + 1];
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate (void) strcpy(node_name, di_node_name(node));
6810Sstevel@tonic-gate
6820Sstevel@tonic-gate if (strncmp(node_name, "fma", 3) == 0) {
6830Sstevel@tonic-gate /* Only one fma channel */
6840Sstevel@tonic-gate (void) devfsadm_mklink("spfma", node, minor, 0);
6850Sstevel@tonic-gate }
6860Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
6870Sstevel@tonic-gate }
6881772Sjl139090
6891772Sjl139090 /*
6901772Sjl139090 * Handles links of the form:
6911772Sjl139090 * type=ddi_pseudo;name=sckmdrv kmdrv\M0
6921772Sjl139090 * type=ddi_pseudo;name=oplkmdrv kmdrv\M0
6931772Sjl139090 */
6941772Sjl139090 static int
kmdrv_create(di_minor_t minor,di_node_t node)6951772Sjl139090 kmdrv_create(di_minor_t minor, di_node_t node)
6961772Sjl139090 {
6971772Sjl139090
6981772Sjl139090 (void) devfsadm_mklink("kmdrv", node, minor, 0);
6991772Sjl139090 return (DEVFSADM_CONTINUE);
7001772Sjl139090 }
701