Home | History | Annotate | Download | only in devfsadm
      1      0     stevel /*
      2      0     stevel  * CDDL HEADER START
      3      0     stevel  *
      4      0     stevel  * The contents of this file are subject to the terms of the
      5   1772   jl139090  * Common Development and Distribution License (the "License").
      6   1772   jl139090  * You may not use this file except in compliance with the License.
      7      0     stevel  *
      8      0     stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0     stevel  * or http://www.opensolaris.org/os/licensing.
     10      0     stevel  * See the License for the specific language governing permissions
     11      0     stevel  * and limitations under the License.
     12      0     stevel  *
     13      0     stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0     stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0     stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0     stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0     stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0     stevel  *
     19      0     stevel  * CDDL HEADER END
     20      0     stevel  */
     21      0     stevel /*
     22   8485      Peter  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23      0     stevel  * Use is subject to license terms.
     24      0     stevel  */
     25      0     stevel 
     26      0     stevel #include <regex.h>
     27      0     stevel #include <devfsadm.h>
     28      0     stevel #include <stdio.h>
     29      0     stevel #include <strings.h>
     30      0     stevel #include <stdlib.h>
     31      0     stevel #include <limits.h>
     32      0     stevel #include <sys/zone.h>
     33      0     stevel #include <sys/zcons.h>
     34      0     stevel #include <sys/cpuid_drv.h>
     35      0     stevel 
     36      0     stevel static int display(di_minor_t minor, di_node_t node);
     37      0     stevel static int parallel(di_minor_t minor, di_node_t node);
     38      0     stevel static int node_slash_minor(di_minor_t minor, di_node_t node);
     39      0     stevel static int driver_minor(di_minor_t minor, di_node_t node);
     40      0     stevel static int node_name(di_minor_t minor, di_node_t node);
     41      0     stevel static int minor_name(di_minor_t minor, di_node_t node);
     42    995   hx147065 static int wifi_minor_name(di_minor_t minor, di_node_t node);
     43      0     stevel static int conskbd(di_minor_t minor, di_node_t node);
     44      0     stevel static int consms(di_minor_t minor, di_node_t node);
     45      0     stevel static int power_button(di_minor_t minor, di_node_t node);
     46      0     stevel static int fc_port(di_minor_t minor, di_node_t node);
     47      0     stevel static int printer_create(di_minor_t minor, di_node_t node);
     48      0     stevel static int se_hdlc_create(di_minor_t minor, di_node_t node);
     49      0     stevel static int ppm(di_minor_t minor, di_node_t node);
     50      0     stevel static int gpio(di_minor_t minor, di_node_t node);
     51      0     stevel static int av_create(di_minor_t minor, di_node_t node);
     52      0     stevel static int tsalarm_create(di_minor_t minor, di_node_t node);
     53    467   sc121708 static int ntwdt_create(di_minor_t minor, di_node_t node);
     54      0     stevel static int zcons_create(di_minor_t minor, di_node_t node);
     55      0     stevel static int cpuid(di_minor_t minor, di_node_t node);
     56      0     stevel static int glvc(di_minor_t minor, di_node_t node);
     57      0     stevel static int ses_callback(di_minor_t minor, di_node_t node);
     58   1772   jl139090 static int kmdrv_create(di_minor_t minor, di_node_t node);
     59      0     stevel 
     60      0     stevel static devfsadm_create_t misc_cbt[] = {
     61   2621      llai1 	{ "pseudo", "ddi_pseudo", "(^sad$)",
     62      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_0, node_slash_minor
     63      0     stevel 	},
     64      0     stevel 	{ "pseudo", "ddi_pseudo", "zsh",
     65      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, driver_minor
     66      0     stevel 	},
     67      0     stevel 	{ "network", "ddi_network", NULL,
     68      0     stevel 	    TYPE_EXACT, ILEVEL_0, minor_name
     69    995   hx147065 	},
     70    995   hx147065 	{ "wifi", "ddi_network:wifi", NULL,
     71    995   hx147065 	    TYPE_EXACT, ILEVEL_0, wifi_minor_name
     72      0     stevel 	},
     73      0     stevel 	{ "display", "ddi_display", NULL,
     74      0     stevel 	    TYPE_EXACT, ILEVEL_0, display
     75      0     stevel 	},
     76      0     stevel 	{ "parallel", "ddi_parallel", NULL,
     77      0     stevel 	    TYPE_EXACT, ILEVEL_0, parallel
     78      0     stevel 	},
     79      0     stevel 	{ "enclosure", DDI_NT_SCSI_ENCLOSURE, NULL,
     80      0     stevel 	    TYPE_EXACT, ILEVEL_0, ses_callback
     81      0     stevel 	},
     82      0     stevel 	{ "pseudo", "ddi_pseudo", "(^winlock$)|(^pm$)",
     83      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_0, node_name
     84      0     stevel 	},
     85      0     stevel 	{ "pseudo", "ddi_pseudo", "conskbd",
     86      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, conskbd
     87      0     stevel 	},
     88      0     stevel 	{ "pseudo", "ddi_pseudo", "consms",
     89      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, consms
     90      0     stevel 	},
     91      0     stevel 	{ "pseudo", "ddi_pseudo", "rsm",
     92      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
     93      0     stevel 	},
     94      0     stevel 	{ "pseudo", "ddi_pseudo",
     95      0     stevel 	    "(^lockstat$)|(^SUNW,rtvc$)|(^vol$)|(^log$)|(^sy$)|"
     96   8023       Phil 	    "(^ksyms$)|(^clone$)|(^tl$)|(^tnf$)|(^kstat$)|(^mdesc$)|(^eeprom$)|"
     97   8023       Phil 	    "(^ptsl$)|(^mm$)|(^wc$)|(^dump$)|(^cn$)|(^svvslo$)|(^ptm$)|"
     98      0     stevel 	    "(^ptc$)|(^openeepr$)|(^poll$)|(^sysmsg$)|(^random$)|(^trapstat$)|"
     99      0     stevel 	    "(^cryptoadm$)|(^crypto$)|(^pool$)|(^poolctl$)|(^bl$)|(^kmdb$)|"
    100   3253        mec 	    "(^sysevent$)|(^kssl$)|(^physmem$)",
    101      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
    102      0     stevel 	},
    103      0     stevel 	{ "pseudo", "ddi_pseudo",
    104      0     stevel 	    "(^ip$)|(^tcp$)|(^udp$)|(^icmp$)|(^sctp$)|"
    105      0     stevel 	    "(^ip6$)|(^tcp6$)|(^udp6$)|(^icmp6$)|(^sctp6$)|"
    106      0     stevel 	    "(^rts$)|(^arp$)|(^ipsecah$)|(^ipsecesp$)|(^keysock$)|(^spdsock$)|"
    107  11042       Erik 	    "(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)",
    108      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name
    109      0     stevel 	},
    110      0     stevel 	{ "pseudo", "ddi_pseudo",
    111   2958   dr146992 	    "(^ipf$)|(^ipnat$)|(^ipstate$)|(^ipauth$)|"
    112      0     stevel 	    "(^ipsync$)|(^ipscan$)|(^iplookup$)",
    113      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name,
    114   7408  Sebastien 	},
    115   7408  Sebastien 	{ "pseudo", "ddi_pseudo", "dld",
    116   7408  Sebastien 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
    117      0     stevel 	},
    118      0     stevel 	{ "pseudo", "ddi_pseudo",
    119   9840    gdamore 	    "(^kdmouse$)|(^rootprop$)",
    120      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_0, node_name
    121      0     stevel 	},
    122      0     stevel 	{ "pseudo", "ddi_pseudo", "tod",
    123      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name
    124      0     stevel 	},
    125      0     stevel 	{ "pseudo", "ddi_pseudo", "envctrl(two)?",
    126      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
    127      0     stevel 	},
    128      0     stevel 	{ "pseudo", "ddi_pseudo", "fcode",
    129      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name,
    130      0     stevel 	},
    131      0     stevel 	{ "power_button", "ddi_power_button", NULL,
    132      0     stevel 	    TYPE_EXACT, ILEVEL_0, power_button,
    133      0     stevel 	},
    134      0     stevel 	{ "FC port", "ddi_ctl:devctl", "fp",
    135      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, fc_port
    136      0     stevel 	},
    137      0     stevel 	{ "printer", "ddi_printer", NULL,
    138      0     stevel 	    TYPE_EXACT, ILEVEL_0, printer_create
    139      0     stevel 	},
    140      0     stevel 	{ "pseudo", "ddi_pseudo", "se",
    141      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, se_hdlc_create
    142      0     stevel 	},
    143      0     stevel 	{ "ppm",  "ddi_ppm", NULL,
    144      0     stevel 	    TYPE_EXACT, ILEVEL_0, ppm
    145      0     stevel 	},
    146      0     stevel 	{ "pseudo", "ddi_pseudo", "gpio_87317",
    147      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, gpio
    148      0     stevel 	},
    149      0     stevel 	{ "pseudo", "ddi_pseudo", "sckmdrv",
    150   1772   jl139090 	    TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
    151   1772   jl139090 	},
    152   1772   jl139090 	{ "pseudo", "ddi_pseudo", "oplkmdrv",
    153   1772   jl139090 	    TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create,
    154      0     stevel 	},
    155      0     stevel 	{ "av", "^ddi_av:(isoch|async)$", NULL,
    156      0     stevel 	    TYPE_RE, ILEVEL_0, av_create,
    157      0     stevel 	},
    158      0     stevel 	{ "pseudo", "ddi_pseudo", "tsalarm",
    159      0     stevel 	    TYPE_EXACT | DRV_RE, ILEVEL_0, tsalarm_create,
    160    467   sc121708 	},
    161    467   sc121708 	{ "pseudo", "ddi_pseudo", "ntwdt",
    162    467   sc121708 	    TYPE_EXACT | DRV_RE, ILEVEL_0, ntwdt_create,
    163      0     stevel 	},
    164      0     stevel 	{ "pseudo", "ddi_pseudo", "daplt",
    165      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
    166      0     stevel 	},
    167      0     stevel 	{ "pseudo", "ddi_pseudo", "zcons",
    168      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, zcons_create,
    169      0     stevel 	},
    170      0     stevel 	{ "pseudo", "ddi_pseudo", CPUID_DRIVER_NAME,
    171      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, cpuid,
    172      0     stevel 	},
    173      0     stevel 	{ "pseudo", "ddi_pseudo", "glvc",
    174      0     stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, glvc,
    175   1772   jl139090 	},
    176   1772   jl139090 	{ "pseudo", "ddi_pseudo", "dm2s",
    177   1772   jl139090 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name,
    178   6007    thurlow 	},
    179   6007    thurlow 	{ "pseudo", "ddi_pseudo", "nsmb",
    180   6330    jc25722 	    TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
    181   6330    jc25722 	},
    182   6330    jc25722 	{ "pseudo", "ddi_pseudo", "mem_cache",
    183   6007    thurlow 	    TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
    184      0     stevel 	},
    185   7532       Sean 	{ "pseudo", "ddi_pseudo", "fm",
    186   7532       Sean 	    TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name,
    187  10346     wyllys 	},
    188  10346     wyllys 	{ "pseudo", "ddi_pseudo", "tpm",
    189  10346     wyllys 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name
    190  10346     wyllys 	},
    191      0     stevel };
    192      0     stevel 
    193      0     stevel DEVFSADM_CREATE_INIT_V0(misc_cbt);
    194      0     stevel 
    195      0     stevel static devfsadm_remove_t misc_remove_cbt[] = {
    196      0     stevel 	{ "pseudo", "^profile$",
    197      0     stevel 	    RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    198      0     stevel 	},
    199      0     stevel 	{ "pseudo", "^rsm$",
    200      0     stevel 	    RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    201      0     stevel 	},
    202      0     stevel 	{ "printer", "^printers/[0-9]+$",
    203      0     stevel 	    RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    204      0     stevel 	},
    205      0     stevel 	{ "av", "^av/[0-9]+/(async|isoch)$",
    206      0     stevel 	    RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    207      0     stevel 	},
    208      0     stevel 	{ "pseudo", "^daplt$",
    209      0     stevel 	    RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    210      0     stevel 	},
    211      0     stevel 	{ "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MASTER_NAME "|"
    212      0     stevel 		ZCONS_SLAVE_NAME ")$",
    213      0     stevel 	    RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    214      0     stevel 	},
    215   5084    johnlev 	{ "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT,
    216      0     stevel 	    ILEVEL_0, devfsadm_rm_all
    217      0     stevel 	},
    218      0     stevel 	{ "enclosure", "^es/ses[0-9]+$", RM_POST,
    219      0     stevel 		ILEVEL_0, devfsadm_rm_all
    220   4482   dr146992 	},
    221   4482   dr146992 	{ "pseudo", "^pfil$",
    222   4482   dr146992 	    RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    223  10346     wyllys 	},
    224  10346     wyllys 	{ "pseudo", "^tpm$",
    225  10346     wyllys 	    RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all
    226  10346     wyllys 	},
    227      0     stevel };
    228      0     stevel 
    229      0     stevel /* Rules for gpio devices */
    230      0     stevel static devfsadm_enumerate_t gpio_rules[1] =
    231      0     stevel 	{"^gpio([0-9]+)$", 1, MATCH_ALL};
    232      0     stevel 
    233      0     stevel DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt);
    234      0     stevel 
    235      0     stevel /*
    236      0     stevel  * Handles minor node type "ddi_display".
    237      0     stevel  *
    238      0     stevel  * type=ddi_display fbs/\M0 fb\N0
    239      0     stevel  */
    240      0     stevel static int
    241      0     stevel display(di_minor_t minor, di_node_t node)
    242      0     stevel {
    243      0     stevel 	char l_path[PATH_MAX + 1], contents[PATH_MAX + 1], *buf;
    244      0     stevel 	devfsadm_enumerate_t rules[1] = {"^fb([0-9]+)$", 1, MATCH_ALL};
    245      0     stevel 	char *mn = di_minor_name(minor);
    246      0     stevel 
    247      0     stevel 	/* create fbs/\M0 primary link */
    248      0     stevel 	(void) strcpy(l_path, "fbs/");
    249      0     stevel 	(void) strcat(l_path, mn);
    250      0     stevel 	(void) devfsadm_mklink(l_path, node, minor, 0);
    251      0     stevel 
    252      0     stevel 	/* create fb\N0 which links to fbs/\M0 */
    253      0     stevel 	if (devfsadm_enumerate_int(l_path, 0, &buf, rules, 1)) {
    254      0     stevel 		return (DEVFSADM_CONTINUE);
    255      0     stevel 	}
    256      0     stevel 	(void) strcpy(contents, l_path);
    257      0     stevel 	(void) strcpy(l_path, "fb");
    258      0     stevel 	(void) strcat(l_path, buf);
    259      0     stevel 	free(buf);
    260      0     stevel 	(void) devfsadm_secondary_link(l_path, contents, 0);
    261      0     stevel 	return (DEVFSADM_CONTINUE);
    262      0     stevel }
    263      0     stevel 
    264      0     stevel /*
    265      0     stevel  * Handles minor node type "ddi_parallel".
    266      0     stevel  * type=ddi_parallel;name=mcpp     mcpp\N0
    267      0     stevel  */
    268      0     stevel static int
    269      0     stevel parallel(di_minor_t minor, di_node_t node)
    270      0     stevel {
    271      0     stevel 	char path[PATH_MAX + 1], *buf;
    272      0     stevel 	devfsadm_enumerate_t rules[1] = {"mcpp([0-9]+)$", 1, MATCH_ALL};
    273      0     stevel 
    274      0     stevel 
    275      0     stevel 	if (strcmp(di_node_name(node), "mcpp") != 0) {
    276      0     stevel 		return (DEVFSADM_CONTINUE);
    277      0     stevel 	}
    278      0     stevel 
    279      0     stevel 	if (NULL == (buf = di_devfs_path(node))) {
    280      0     stevel 		return (DEVFSADM_CONTINUE);
    281      0     stevel 	}
    282      0     stevel 
    283      0     stevel 	(void) snprintf(path, sizeof (path), "%s:%s",
    284      0     stevel 	    buf, di_minor_name(minor));
    285      0     stevel 
    286      0     stevel 	di_devfs_path_free(buf);
    287      0     stevel 
    288      0     stevel 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
    289      0     stevel 		return (DEVFSADM_CONTINUE);
    290      0     stevel 	}
    291      0     stevel 	(void) snprintf(path, sizeof (path), "mcpp%s", buf);
    292      0     stevel 	free(buf);
    293      0     stevel 
    294      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    295      0     stevel 	return (DEVFSADM_CONTINUE);
    296      0     stevel }
    297      0     stevel 
    298      0     stevel static int
    299      0     stevel ses_callback(di_minor_t minor, di_node_t node)
    300      0     stevel {
    301      0     stevel 	char l_path[PATH_MAX];
    302      0     stevel 	char *buf;
    303      0     stevel 	char *devfspath;
    304      0     stevel 	char p_path[PATH_MAX];
    305      0     stevel 	devfsadm_enumerate_t re[] = {"^es$/^ses([0-9]+)$", 1, MATCH_ALL};
    306      0     stevel 
    307      0     stevel 	/* find devices path -- need to free mem */
    308      0     stevel 	if (NULL == (devfspath = di_devfs_path(node))) {
    309      0     stevel 		return (DEVFSADM_CONTINUE);
    310      0     stevel 	}
    311      0     stevel 
    312      0     stevel 	(void) snprintf(p_path, sizeof (p_path), "%s:%s", devfspath,
    313      0     stevel 	    di_minor_name(minor));
    314      0     stevel 
    315      0     stevel 
    316      0     stevel 	/* find next number to use; buf is an ascii number */
    317      0     stevel 	if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) {
    318      0     stevel 		/* free memory */
    319      0     stevel 		di_devfs_path_free(devfspath);
    320      0     stevel 		return (DEVFSADM_CONTINUE);
    321      0     stevel 	}
    322      0     stevel 
    323      0     stevel 	(void) snprintf(l_path, sizeof (l_path), "es/ses%s", buf);
    324      0     stevel 
    325      0     stevel 	(void) devfsadm_mklink(l_path, node, minor, 0);
    326      0     stevel 	/* free memory */
    327      0     stevel 	free(buf);
    328      0     stevel 	di_devfs_path_free(devfspath);
    329      0     stevel 	return (DEVFSADM_CONTINUE);
    330      0     stevel 
    331      0     stevel }
    332      0     stevel 
    333      0     stevel static int
    334      0     stevel node_slash_minor(di_minor_t minor, di_node_t node)
    335      0     stevel {
    336      0     stevel 
    337      0     stevel 	char path[PATH_MAX + 1];
    338      0     stevel 
    339      0     stevel 	(void) strcpy(path, di_node_name(node));
    340      0     stevel 	(void) strcat(path, "/");
    341      0     stevel 	(void) strcat(path, di_minor_name(minor));
    342      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    343      0     stevel 	return (DEVFSADM_CONTINUE);
    344      0     stevel }
    345      0     stevel 
    346      0     stevel static int
    347      0     stevel driver_minor(di_minor_t minor, di_node_t node)
    348      0     stevel {
    349      0     stevel 	char path[PATH_MAX + 1];
    350      0     stevel 
    351      0     stevel 	(void) strcpy(path, di_driver_name(node));
    352      0     stevel 	(void) strcat(path, di_minor_name(minor));
    353      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    354      0     stevel 	return (DEVFSADM_CONTINUE);
    355      0     stevel }
    356      0     stevel 
    357      0     stevel /*
    358      0     stevel  * Handles links of the form:
    359      0     stevel  * type=ddi_pseudo;name=xyz  \D
    360      0     stevel  */
    361      0     stevel static int
    362      0     stevel node_name(di_minor_t minor, di_node_t node)
    363      0     stevel {
    364      0     stevel 	(void) devfsadm_mklink(di_node_name(node), node, minor, 0);
    365      0     stevel 	return (DEVFSADM_CONTINUE);
    366      0     stevel }
    367      0     stevel 
    368      0     stevel /*
    369      0     stevel  * Handles links of the form:
    370      0     stevel  * type=ddi_pseudo;name=xyz  \M0
    371      0     stevel  */
    372      0     stevel static int
    373      0     stevel minor_name(di_minor_t minor, di_node_t node)
    374      0     stevel {
    375      0     stevel 	char *mn = di_minor_name(minor);
    376      0     stevel 
    377      0     stevel 	(void) devfsadm_mklink(mn, node, minor, 0);
    378      0     stevel 	if (strcmp(mn, "icmp") == 0) {
    379      0     stevel 		(void) devfsadm_mklink("rawip", node, minor, 0);
    380      0     stevel 	}
    381      0     stevel 	if (strcmp(mn, "icmp6") == 0) {
    382      0     stevel 		(void) devfsadm_mklink("rawip6", node, minor, 0);
    383      0     stevel 	}
    384      0     stevel 	if (strcmp(mn, "ipf") == 0) {
    385      0     stevel 		(void) devfsadm_mklink("ipl", node, minor, 0);
    386      0     stevel 	}
    387      0     stevel 	return (DEVFSADM_CONTINUE);
    388      0     stevel }
    389      0     stevel 
    390    995   hx147065 /*
    391    995   hx147065  * create links at /dev/wifi for wifi minor node
    392    995   hx147065  */
    393    995   hx147065 static int
    394    995   hx147065 wifi_minor_name(di_minor_t minor, di_node_t node)
    395    995   hx147065 {
    396    995   hx147065 	char buf[256];
    397    995   hx147065 	char *mn = di_minor_name(minor);
    398    995   hx147065 
    399    995   hx147065 	(void) snprintf(buf, sizeof (buf), "%s%s", "wifi/", mn);
    400    995   hx147065 	(void) devfsadm_mklink(buf, node, minor, 0);
    401    995   hx147065 
    402    995   hx147065 	return (DEVFSADM_CONTINUE);
    403    995   hx147065 }
    404      0     stevel 
    405      0     stevel static int
    406      0     stevel conskbd(di_minor_t minor, di_node_t node)
    407      0     stevel {
    408      0     stevel 	(void) devfsadm_mklink("kbd", node, minor, 0);
    409      0     stevel 	return (DEVFSADM_CONTINUE);
    410      0     stevel }
    411      0     stevel 
    412      0     stevel static int
    413      0     stevel consms(di_minor_t minor, di_node_t node)
    414      0     stevel {
    415      0     stevel 	(void) devfsadm_mklink("mouse", node, minor, 0);
    416      0     stevel 	return (DEVFSADM_CONTINUE);
    417      0     stevel }
    418      0     stevel 
    419      0     stevel static int
    420      0     stevel power_button(di_minor_t minor, di_node_t node)
    421      0     stevel {
    422      0     stevel 	(void) devfsadm_mklink("power_button", node, minor, 0);
    423      0     stevel 	return (DEVFSADM_CONTINUE);
    424      0     stevel }
    425      0     stevel 
    426      0     stevel static int
    427      0     stevel fc_port(di_minor_t minor, di_node_t node)
    428      0     stevel {
    429      0     stevel 	devfsadm_enumerate_t rules[1] = {"fc/fp([0-9]+)$", 1, MATCH_ALL};
    430      0     stevel 	char *buf, path[PATH_MAX + 1];
    431      0     stevel 	char *ptr;
    432      0     stevel 
    433      0     stevel 	if (NULL == (ptr = di_devfs_path(node))) {
    434      0     stevel 		return (DEVFSADM_CONTINUE);
    435      0     stevel 	}
    436      0     stevel 
    437      0     stevel 	(void) strcpy(path, ptr);
    438      0     stevel 	(void) strcat(path, ":");
    439      0     stevel 	(void) strcat(path, di_minor_name(minor));
    440      0     stevel 
    441      0     stevel 	di_devfs_path_free(ptr);
    442      0     stevel 
    443      0     stevel 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) {
    444      0     stevel 		return (DEVFSADM_CONTINUE);
    445      0     stevel 	}
    446      0     stevel 
    447      0     stevel 	(void) strcpy(path, "fc/fp");
    448      0     stevel 	(void) strcat(path, buf);
    449      0     stevel 	free(buf);
    450      0     stevel 
    451      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    452      0     stevel 	return (DEVFSADM_CONTINUE);
    453      0     stevel }
    454      0     stevel 
    455      0     stevel /*
    456      0     stevel  * Handles:
    457      0     stevel  *	minor node type "ddi_printer".
    458      0     stevel  * 	rules of the form: type=ddi_printer;name=bpp  \M0
    459      0     stevel  */
    460      0     stevel static int
    461      0     stevel printer_create(di_minor_t minor, di_node_t node)
    462      0     stevel {
    463      0     stevel 	char *mn;
    464      0     stevel 	char path[PATH_MAX + 1], *buf;
    465      0     stevel 	devfsadm_enumerate_t rules[1] = {"^printers$/^([0-9]+)$", 1, MATCH_ALL};
    466      0     stevel 
    467      0     stevel 	mn = di_minor_name(minor);
    468      0     stevel 
    469      0     stevel 	if (strcmp(di_driver_name(node), "bpp") == 0) {
    470      0     stevel 		(void) devfsadm_mklink(mn, node, minor, 0);
    471      0     stevel 	}
    472      0     stevel 
    473      0     stevel 	if (NULL == (buf = di_devfs_path(node))) {
    474      0     stevel 		return (DEVFSADM_CONTINUE);
    475      0     stevel 	}
    476      0     stevel 
    477      0     stevel 	(void) snprintf(path, sizeof (path), "%s:%s", buf, mn);
    478      0     stevel 	di_devfs_path_free(buf);
    479      0     stevel 
    480      0     stevel 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
    481      0     stevel 		return (DEVFSADM_CONTINUE);
    482      0     stevel 	}
    483      0     stevel 
    484      0     stevel 	(void) snprintf(path, sizeof (path), "printers/%s", buf);
    485      0     stevel 	free(buf);
    486      0     stevel 
    487      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    488      0     stevel 
    489      0     stevel 	return (DEVFSADM_CONTINUE);
    490      0     stevel }
    491      0     stevel 
    492      0     stevel /*
    493      0     stevel  * Handles links of the form:
    494      0     stevel  * type=ddi_pseudo;name=se;minor2=hdlc	se_hdlc\N0
    495      0     stevel  * type=ddi_pseudo;name=serial;minor2=hdlc	se_hdlc\N0
    496      0     stevel  */
    497      0     stevel static int
    498      0     stevel se_hdlc_create(di_minor_t minor, di_node_t node)
    499      0     stevel {
    500      0     stevel 	devfsadm_enumerate_t rules[1] = {"^se_hdlc([0-9]+)$", 1, MATCH_ALL};
    501      0     stevel 	char *buf, path[PATH_MAX + 1];
    502      0     stevel 	char *ptr;
    503      0     stevel 	char *mn;
    504      0     stevel 
    505      0     stevel 	mn = di_minor_name(minor);
    506      0     stevel 
    507      0     stevel 	/* minor node should be of the form: "?,hdlc" */
    508      0     stevel 	if (strcmp(mn + 1, ",hdlc") != 0) {
    509      0     stevel 		return (DEVFSADM_CONTINUE);
    510      0     stevel 	}
    511      0     stevel 
    512      0     stevel 	if (NULL == (ptr = di_devfs_path(node))) {
    513      0     stevel 		return (DEVFSADM_CONTINUE);
    514      0     stevel 	}
    515      0     stevel 
    516      0     stevel 	(void) strcpy(path, ptr);
    517      0     stevel 	(void) strcat(path, ":");
    518      0     stevel 	(void) strcat(path, mn);
    519      0     stevel 
    520      0     stevel 	di_devfs_path_free(ptr);
    521      0     stevel 
    522      0     stevel 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) {
    523      0     stevel 		return (DEVFSADM_CONTINUE);
    524      0     stevel 	}
    525      0     stevel 
    526      0     stevel 	(void) strcpy(path, "se_hdlc");
    527      0     stevel 	(void) strcat(path, buf);
    528      0     stevel 	free(buf);
    529      0     stevel 
    530      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    531      0     stevel 
    532      0     stevel 	return (DEVFSADM_CONTINUE);
    533      0     stevel }
    534      0     stevel 
    535      0     stevel static int
    536      0     stevel gpio(di_minor_t minor, di_node_t node)
    537      0     stevel {
    538      0     stevel 	char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath;
    539      0     stevel 	char *minor_nm, *drvr_nm;
    540      0     stevel 
    541      0     stevel 
    542      0     stevel 	minor_nm = di_minor_name(minor);
    543      0     stevel 	drvr_nm = di_driver_name(node);
    544      0     stevel 	if ((minor_nm == NULL) || (drvr_nm == NULL)) {
    545      0     stevel 		return (DEVFSADM_CONTINUE);
    546      0     stevel 	}
    547      0     stevel 
    548      0     stevel 	devfspath = di_devfs_path(node);
    549      0     stevel 
    550      0     stevel 	(void) strcpy(p_path, devfspath);
    551      0     stevel 	(void) strcat(p_path, ":");
    552      0     stevel 	(void) strcat(p_path, minor_nm);
    553      0     stevel 	di_devfs_path_free(devfspath);
    554      0     stevel 
    555      0     stevel 	/* build the physical path from the components */
    556      0     stevel 	if (devfsadm_enumerate_int(p_path, 0, &buf, gpio_rules, 1)) {
    557      0     stevel 		return (DEVFSADM_CONTINUE);
    558      0     stevel 	}
    559      0     stevel 
    560      0     stevel 	(void) snprintf(l_path, sizeof (l_path), "%s%s", "gpio", buf);
    561      0     stevel 
    562      0     stevel 	free(buf);
    563      0     stevel 
    564      0     stevel 	(void) devfsadm_mklink(l_path, node, minor, 0);
    565      0     stevel 
    566      0     stevel 	return (DEVFSADM_CONTINUE);
    567      0     stevel }
    568      0     stevel 
    569      0     stevel /*
    570      0     stevel  * Creates /dev/ppm nodes for Platform Specific PM module
    571      0     stevel  */
    572      0     stevel static int
    573      0     stevel ppm(di_minor_t minor, di_node_t node)
    574      0     stevel {
    575      0     stevel 	(void) devfsadm_mklink("ppm", node, minor, 0);
    576      0     stevel 	return (DEVFSADM_CONTINUE);
    577      0     stevel }
    578      0     stevel 
    579      0     stevel /*
    580      0     stevel  * Handles:
    581      0     stevel  *	/dev/av/[0-9]+/(async|isoch)
    582      0     stevel  */
    583      0     stevel static int
    584      0     stevel av_create(di_minor_t minor, di_node_t node)
    585      0     stevel {
    586      0     stevel 	devfsadm_enumerate_t rules[1] = {"^av$/^([0-9]+)$", 1, MATCH_ADDR};
    587      0     stevel 	char	*minor_str;
    588      0     stevel 	char	path[PATH_MAX + 1];
    589      0     stevel 	char	*buf;
    590      0     stevel 
    591      0     stevel 	if ((buf = di_devfs_path(node)) == NULL) {
    592      0     stevel 		return (DEVFSADM_CONTINUE);
    593      0     stevel 	}
    594      0     stevel 
    595      0     stevel 	minor_str = di_minor_name(minor);
    596      0     stevel 	(void) snprintf(path, sizeof (path), "%s:%s", buf, minor_str);
    597      0     stevel 	di_devfs_path_free(buf);
    598      0     stevel 
    599      0     stevel 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
    600      0     stevel 		return (DEVFSADM_CONTINUE);
    601      0     stevel 	}
    602      0     stevel 
    603      0     stevel 	(void) snprintf(path, sizeof (path), "av/%s/%s", buf, minor_str);
    604      0     stevel 	free(buf);
    605      0     stevel 
    606      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    607      0     stevel 
    608      0     stevel 	return (DEVFSADM_CONTINUE);
    609      0     stevel }
    610      0     stevel 
    611      0     stevel /*
    612      0     stevel  * Creates /dev/lom and /dev/tsalarm:ctl for tsalarm node
    613      0     stevel  */
    614      0     stevel static int
    615      0     stevel tsalarm_create(di_minor_t minor, di_node_t node)
    616      0     stevel {
    617      0     stevel 	char buf[PATH_MAX + 1];
    618      0     stevel 	char *mn = di_minor_name(minor);
    619      0     stevel 
    620      0     stevel 	(void) snprintf(buf, sizeof (buf), "%s%s", di_node_name(node), ":ctl");
    621      0     stevel 
    622      0     stevel 	(void) devfsadm_mklink(mn, node, minor, 0);
    623      0     stevel 	(void) devfsadm_mklink(buf, node, minor, 0);
    624      0     stevel 
    625      0     stevel 	return (DEVFSADM_CONTINUE);
    626      0     stevel }
    627      0     stevel 
    628    467   sc121708 /*
    629    467   sc121708  * Creates /dev/ntwdt for ntwdt node
    630    467   sc121708  */
    631    467   sc121708 static int
    632    467   sc121708 ntwdt_create(di_minor_t minor, di_node_t node)
    633    467   sc121708 {
    634    467   sc121708 	(void) devfsadm_mklink("ntwdt", node, minor, 0);
    635    467   sc121708 	return (DEVFSADM_CONTINUE);
    636    467   sc121708 }
    637    467   sc121708 
    638      0     stevel static int
    639      0     stevel zcons_create(di_minor_t minor, di_node_t node)
    640      0     stevel {
    641      0     stevel 	char	*minor_str;
    642      0     stevel 	char	*zonename;
    643      0     stevel 	char	path[MAXPATHLEN];
    644      0     stevel 
    645      0     stevel 	minor_str = di_minor_name(minor);
    646      0     stevel 
    647      0     stevel 	if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zonename",
    648      0     stevel 	    &zonename) == -1) {
    649      0     stevel 		return (DEVFSADM_CONTINUE);
    650      0     stevel 	}
    651      0     stevel 
    652      0     stevel 	(void) snprintf(path, sizeof (path), "zcons/%s/%s", zonename,
    653      0     stevel 	    minor_str);
    654      0     stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    655      0     stevel 
    656      0     stevel 	return (DEVFSADM_CONTINUE);
    657      0     stevel }
    658      0     stevel 
    659      0     stevel /*
    660      0     stevel  *	/dev/cpu/self/cpuid 	->	/devices/pseudo/cpuid@0:self
    661      0     stevel  */
    662      0     stevel static int
    663      0     stevel cpuid(di_minor_t minor, di_node_t node)
    664      0     stevel {
    665      0     stevel 	(void) devfsadm_mklink(CPUID_SELF_NAME, node, minor, 0);
    666      0     stevel 	return (DEVFSADM_CONTINUE);
    667      0     stevel }
    668      0     stevel 
    669      0     stevel /*
    670      0     stevel  * For device
    671      0     stevel  *      /dev/spfma -> /devices/virtual-devices/fma@5:glvc
    672      0     stevel  */
    673      0     stevel static int
    674      0     stevel glvc(di_minor_t minor, di_node_t node)
    675      0     stevel {
    676      0     stevel 	char node_name[MAXNAMELEN + 1];
    677      0     stevel 
    678      0     stevel 	(void) strcpy(node_name, di_node_name(node));
    679      0     stevel 
    680      0     stevel 	if (strncmp(node_name, "fma", 3) == 0) {
    681      0     stevel 		/* Only one fma channel */
    682      0     stevel 		(void) devfsadm_mklink("spfma", node, minor, 0);
    683      0     stevel 	}
    684      0     stevel 	return (DEVFSADM_CONTINUE);
    685      0     stevel }
    686   1772   jl139090 
    687   1772   jl139090 /*
    688   1772   jl139090  * Handles links of the form:
    689   1772   jl139090  * type=ddi_pseudo;name=sckmdrv		kmdrv\M0
    690   1772   jl139090  * type=ddi_pseudo;name=oplkmdrv	kmdrv\M0
    691   1772   jl139090  */
    692   1772   jl139090 static int
    693   1772   jl139090 kmdrv_create(di_minor_t minor, di_node_t node)
    694   1772   jl139090 {
    695   1772   jl139090 
    696   1772   jl139090 	(void) devfsadm_mklink("kmdrv", node, minor, 0);
    697   1772   jl139090 	return (DEVFSADM_CONTINUE);
    698   1772   jl139090 }
    699