Home | History | Annotate | Download | only in i386
      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  1676       jpk  * Common Development and Distribution License (the "License").
      6  1676       jpk  * 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  9203      Mark  * 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 <ctype.h>
     33  5254    gavinm #include <sys/mc_amd.h>
     34  1676       jpk #include <bsm/devalloc.h>
     35  1676       jpk 
     36  1676       jpk extern int system_labeled;
     37     0    stevel 
     38     0    stevel static int lp(di_minor_t minor, di_node_t node);
     39     0    stevel static int serial_dialout(di_minor_t minor, di_node_t node);
     40     0    stevel static int serial(di_minor_t minor, di_node_t node);
     41     0    stevel static int diskette(di_minor_t minor, di_node_t node);
     42     0    stevel static int vt00(di_minor_t minor, di_node_t node);
     43     0    stevel static int kdmouse(di_minor_t minor, di_node_t node);
     44     0    stevel static int bmc(di_minor_t minor, di_node_t node);
     45   437       mws static int smbios(di_minor_t minor, di_node_t node);
     46     0    stevel static int agp_process(di_minor_t minor, di_node_t node);
     47  2820  kz151634 static int drm_node(di_minor_t minor, di_node_t node);
     48  1414     cindi static int mc_node(di_minor_t minor, di_node_t node);
     49  3446       mrj static int xsvc(di_minor_t minor, di_node_t node);
     50  5295    randyf static int srn(di_minor_t minor, di_node_t node);
     51  4581   sherrym static int ucode(di_minor_t minor, di_node_t node);
     52  9203      Mark static int heci(di_minor_t minor, di_node_t node);
     53  9203      Mark 
     54     0    stevel 
     55     0    stevel static devfsadm_create_t misc_cbt[] = {
     56     0    stevel 	{ "vt00", "ddi_display", NULL,
     57     0    stevel 	    TYPE_EXACT, ILEVEL_0,	vt00
     58  2820  kz151634 	},
     59  2820  kz151634 	{ "drm", "ddi_display:drm", NULL,
     60  2820  kz151634 	    TYPE_EXACT, ILEVEL_0,	drm_node
     61     0    stevel 	},
     62     0    stevel 	{ "mouse", "ddi_mouse", "mouse8042",
     63     0    stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse
     64     0    stevel 	},
     65     0    stevel 	{ "pseudo", "ddi_pseudo", "bmc",
     66     0    stevel 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc,
     67   437       mws 	},
     68   437       mws 	{ "pseudo", "ddi_pseudo", "smbios",
     69   437       mws 	    TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios,
     70     0    stevel 	},
     71     0    stevel 	{ "disk",  "ddi_block:diskette", NULL,
     72     0    stevel 	    TYPE_EXACT, ILEVEL_1, diskette
     73     0    stevel 	},
     74     0    stevel 	{ "parallel",  "ddi_printer", NULL,
     75     0    stevel 	    TYPE_EXACT, ILEVEL_1, lp
     76     0    stevel 	},
     77     0    stevel 	{ "serial", "ddi_serial:mb", NULL,
     78     0    stevel 	    TYPE_EXACT, ILEVEL_1, serial
     79     0    stevel 	},
     80     0    stevel 	{ "serial",  "ddi_serial:dialout,mb", NULL,
     81     0    stevel 	    TYPE_EXACT, ILEVEL_1, serial_dialout
     82     0    stevel 	},
     83  1414     cindi 	{ "agp", "ddi_agp:pseudo", NULL,
     84     0    stevel 	    TYPE_EXACT, ILEVEL_0, agp_process
     85     0    stevel 	},
     86  1414     cindi 	{ "agp", "ddi_agp:target", NULL,
     87     0    stevel 	    TYPE_EXACT, ILEVEL_0, agp_process
     88     0    stevel 	},
     89  1414     cindi 	{ "agp", "ddi_agp:cpugart", NULL,
     90     0    stevel 	    TYPE_EXACT, ILEVEL_0, agp_process
     91     0    stevel 	},
     92  1414     cindi 	{ "agp", "ddi_agp:master", NULL,
     93     0    stevel 	    TYPE_EXACT, ILEVEL_0, agp_process
     94  3446       mrj 	},
     95  3446       mrj 	{ "pseudo", "ddi_pseudo", NULL,
     96  3446       mrj 	    TYPE_EXACT, ILEVEL_0, xsvc
     97  5295    randyf 	},
     98  5295    randyf 	{ "pseudo", "ddi_pseudo", NULL,
     99  5295    randyf 	    TYPE_EXACT, ILEVEL_0, srn
    100  1414     cindi 	},
    101  1414     cindi 	{ "memory-controller", "ddi_mem_ctrl", NULL,
    102  1414     cindi 	    TYPE_EXACT, ILEVEL_0, mc_node
    103  4581   sherrym 	},
    104  4581   sherrym 	{ "pseudo", "ddi_pseudo", "ucode",
    105  4581   sherrym 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode,
    106  9203      Mark 	},
    107  9203      Mark 	{ "pseudo", "ddi_pseudo", "heci",
    108  9203      Mark 	    TYPE_EXACT | DRV_EXACT, ILEVEL_0, heci,
    109     0    stevel 	}
    110     0    stevel };
    111     0    stevel 
    112     0    stevel DEVFSADM_CREATE_INIT_V0(misc_cbt);
    113     0    stevel 
    114  2820  kz151634 static char *debug_mid = "misc_mid";
    115     0    stevel 
    116     0    stevel typedef enum {
    117     0    stevel 	DRIVER_AGPPSEUDO = 0,
    118     0    stevel 	DRIVER_AGPTARGET,
    119     0    stevel 	DRIVER_CPUGART,
    120  6393  cg149915 	DRIVER_AGPMASTER_DRM_I915,
    121  6393  cg149915 	DRIVER_AGPMASTER_DRM_RADEON,
    122  2820  kz151634 	DRIVER_AGPMASTER_VGATEXT,
    123     0    stevel 	DRIVER_UNKNOWN
    124     0    stevel } driver_defs_t;
    125     0    stevel 
    126     0    stevel typedef struct {
    127     0    stevel 	char	*driver_name;
    128     0    stevel 	int	index;
    129     0    stevel } driver_name_table_entry_t;
    130     0    stevel 
    131     0    stevel static driver_name_table_entry_t driver_name_table[] = {
    132     0    stevel 	{ "agpgart",		DRIVER_AGPPSEUDO },
    133     0    stevel 	{ "agptarget",		DRIVER_AGPTARGET },
    134     0    stevel 	{ "amd64_gart",		DRIVER_CPUGART },
    135  2820  kz151634 	/* AGP master device managed by drm driver */
    136  6393  cg149915 	{ "i915",		DRIVER_AGPMASTER_DRM_I915 },
    137  6393  cg149915 	{ "radeon",		DRIVER_AGPMASTER_DRM_RADEON },
    138  2820  kz151634 	{ "vgatext",		DRIVER_AGPMASTER_VGATEXT },
    139     0    stevel 	{ NULL,			DRIVER_UNKNOWN }
    140     0    stevel };
    141     0    stevel 
    142     0    stevel static devfsadm_enumerate_t agptarget_rules[1] =
    143     0    stevel 	{ "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL };
    144     0    stevel static devfsadm_enumerate_t cpugart_rules[1] =
    145     0    stevel 	{ "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL };
    146     0    stevel static devfsadm_enumerate_t agpmaster_rules[1] =
    147     0    stevel 	{  "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL };
    148     0    stevel 
    149     0    stevel static devfsadm_remove_t misc_remove_cbt[] = {
    150     0    stevel 	{ "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS,
    151  4581   sherrym 		ILEVEL_0, devfsadm_rm_all
    152  4581   sherrym 	},
    153  4581   sherrym 	{ "pseudo", "^ucode$", RM_ALWAYS | RM_PRE | RM_HOT,
    154     0    stevel 		ILEVEL_0, devfsadm_rm_all
    155     0    stevel 	}
    156     0    stevel };
    157     0    stevel 
    158     0    stevel DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt);
    159     0    stevel 
    160     0    stevel /*
    161     0    stevel  * Handles minor node type "ddi_display", in addition to generic processing
    162     0    stevel  * done by display().
    163     0    stevel  *
    164     0    stevel  * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility.
    165     0    stevel  */
    166     0    stevel /* ARGSUSED */
    167     0    stevel int
    168     0    stevel vt00(di_minor_t minor, di_node_t node)
    169     0    stevel {
    170     0    stevel 	(void) devfsadm_secondary_link("vt00", "fb", 0);
    171     0    stevel 	return (DEVFSADM_CONTINUE);
    172     0    stevel }
    173     0    stevel 
    174     0    stevel /*
    175     0    stevel  * type=ddi_block:diskette;addr=0,0;minor=c        diskette
    176     0    stevel  * type=ddi_block:diskette;addr=0,0;minor=c,raw    rdiskette
    177     0    stevel  * type=ddi_block:diskette;addr1=0;minor=c diskette\A2
    178     0    stevel  * type=ddi_block:diskette;addr1=0;minor=c,raw     rdiskette\A2
    179     0    stevel  */
    180     0    stevel static int
    181     0    stevel diskette(di_minor_t minor, di_node_t node)
    182     0    stevel {
    183  1676       jpk 	int flags = 0;
    184     0    stevel 	char *a2;
    185     0    stevel 	char link[PATH_MAX];
    186     0    stevel 	char *addr = di_bus_addr(node);
    187     0    stevel 	char *mn = di_minor_name(minor);
    188     0    stevel 
    189  1676       jpk 	if (system_labeled)
    190  1676       jpk 		flags = DA_ADD|DA_FLOPPY;
    191  1676       jpk 
    192     0    stevel 	if (strcmp(addr, "0,0") == 0) {
    193     0    stevel 		if (strcmp(mn, "c") == 0) {
    194  1676       jpk 			(void) devfsadm_mklink("diskette", node, minor, flags);
    195     0    stevel 		} else if (strcmp(mn, "c,raw") == 0) {
    196  1676       jpk 			(void) devfsadm_mklink("rdiskette", node, minor, flags);
    197     0    stevel 		}
    198     0    stevel 
    199     0    stevel 	}
    200     0    stevel 
    201     0    stevel 	if (addr[0] == '0') {
    202     0    stevel 		if ((a2 = strchr(addr, ',')) != NULL) {
    203     0    stevel 			a2++;
    204     0    stevel 			if (strcmp(mn, "c") == 0) {
    205     0    stevel 				(void) strcpy(link, "diskette");
    206     0    stevel 				(void) strcat(link, a2);
    207  1676       jpk 				(void) devfsadm_mklink(link, node, minor,
    208  1676       jpk 				    flags);
    209     0    stevel 			} else if (strcmp(mn, "c,raw") == 0) {
    210     0    stevel 				(void) strcpy(link, "rdiskette");
    211     0    stevel 				(void) strcat(link, a2);
    212  1676       jpk 				(void) devfsadm_mklink(link, node, minor,
    213  1676       jpk 				    flags);
    214     0    stevel 			}
    215     0    stevel 		}
    216     0    stevel 	}
    217     0    stevel 
    218     0    stevel 	return (DEVFSADM_CONTINUE);
    219     0    stevel }
    220     0    stevel 
    221     0    stevel /*
    222     0    stevel  * type=ddi_printer;name=lp;addr=1,3bc      lp0
    223     0    stevel  * type=ddi_printer;name=lp;addr=1,378      lp1
    224     0    stevel  * type=ddi_printer;name=lp;addr=1,278      lp2
    225     0    stevel  */
    226     0    stevel static int
    227     0    stevel lp(di_minor_t minor, di_node_t node)
    228     0    stevel {
    229     0    stevel 	char *addr = di_bus_addr(node);
    230     0    stevel 	char *buf;
    231     0    stevel 	char path[PATH_MAX + 1];
    232     0    stevel 	devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};
    233     0    stevel 
    234     0    stevel 	if (strcmp(addr, "1,3bc") == 0) {
    235     0    stevel 		(void) devfsadm_mklink("lp0", node, minor, 0);
    236     0    stevel 
    237     0    stevel 	} else if (strcmp(addr, "1,378") == 0) {
    238     0    stevel 		(void) devfsadm_mklink("lp1", node, minor, 0);
    239     0    stevel 
    240     0    stevel 	} else if (strcmp(addr, "1,278") == 0) {
    241     0    stevel 		(void) devfsadm_mklink("lp2", node, minor, 0);
    242     0    stevel 	}
    243     0    stevel 
    244     0    stevel 	if (strcmp(di_driver_name(node), "ecpp") != 0) {
    245     0    stevel 		return (DEVFSADM_CONTINUE);
    246     0    stevel 	}
    247     0    stevel 
    248     0    stevel 	if ((buf = di_devfs_path(node)) == NULL) {
    249     0    stevel 		return (DEVFSADM_CONTINUE);
    250     0    stevel 	}
    251     0    stevel 
    252     0    stevel 	(void) snprintf(path, sizeof (path), "%s:%s",
    253     0    stevel 	    buf, di_minor_name(minor));
    254     0    stevel 
    255     0    stevel 	di_devfs_path_free(buf);
    256     0    stevel 
    257     0    stevel 	if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
    258     0    stevel 		return (DEVFSADM_CONTINUE);
    259     0    stevel 	}
    260     0    stevel 
    261     0    stevel 	(void) snprintf(path, sizeof (path), "ecpp%s", buf);
    262     0    stevel 	free(buf);
    263     0    stevel 	(void) devfsadm_mklink(path, node, minor, 0);
    264     0    stevel 	return (DEVFSADM_CONTINUE);
    265     0    stevel }
    266     0    stevel 
    267     0    stevel /*
    268     0    stevel  * type=ddi_serial:mb;minor=a      tty00
    269     0    stevel  * type=ddi_serial:mb;minor=b      tty01
    270     0    stevel  * type=ddi_serial:mb;minor=c      tty02
    271     0    stevel  * type=ddi_serial:mb;minor=d      tty03
    272     0    stevel  */
    273     0    stevel static int
    274     0    stevel serial(di_minor_t minor, di_node_t node)
    275     0    stevel {
    276     0    stevel 
    277     0    stevel 	char *mn = di_minor_name(minor);
    278     0    stevel 	char link[PATH_MAX];
    279     0    stevel 
    280     0    stevel 	(void) strcpy(link, "tty");
    281     0    stevel 	(void) strcat(link, mn);
    282     0    stevel 	(void) devfsadm_mklink(link, node, minor, 0);
    283     0    stevel 
    284     0    stevel 	if (strcmp(mn, "a") == 0) {
    285     0    stevel 		(void) devfsadm_mklink("tty00", node, minor, 0);
    286     0    stevel 
    287     0    stevel 	} else if (strcmp(mn, "b") == 0) {
    288     0    stevel 		(void) devfsadm_mklink("tty01", node, minor, 0);
    289     0    stevel 
    290     0    stevel 	} else if (strcmp(mn, "c") == 0) {
    291     0    stevel 		(void) devfsadm_mklink("tty02", node, minor, 0);
    292     0    stevel 
    293     0    stevel 	} else if (strcmp(mn, "d") == 0) {
    294     0    stevel 		(void) devfsadm_mklink("tty03", node, minor, 0);
    295     0    stevel 	}
    296     0    stevel 	return (DEVFSADM_CONTINUE);
    297     0    stevel }
    298     0    stevel 
    299     0    stevel /*
    300     0    stevel  * type=ddi_serial:dialout,mb;minor=a,cu   ttyd0
    301     0    stevel  * type=ddi_serial:dialout,mb;minor=b,cu   ttyd1
    302     0    stevel  * type=ddi_serial:dialout,mb;minor=c,cu   ttyd2
    303     0    stevel  * type=ddi_serial:dialout,mb;minor=d,cu   ttyd3
    304     0    stevel  */
    305     0    stevel static int
    306     0    stevel serial_dialout(di_minor_t minor, di_node_t node)
    307     0    stevel {
    308     0    stevel 	char *mn = di_minor_name(minor);
    309     0    stevel 
    310     0    stevel 	if (strcmp(mn, "a,cu") == 0) {
    311     0    stevel 		(void) devfsadm_mklink("ttyd0", node, minor, 0);
    312     0    stevel 		(void) devfsadm_mklink("cua0", node, minor, 0);
    313     0    stevel 
    314     0    stevel 	} else if (strcmp(mn, "b,cu") == 0) {
    315     0    stevel 		(void) devfsadm_mklink("ttyd1", node, minor, 0);
    316     0    stevel 		(void) devfsadm_mklink("cua1", node, minor, 0);
    317     0    stevel 
    318     0    stevel 	} else if (strcmp(mn, "c,cu") == 0) {
    319     0    stevel 		(void) devfsadm_mklink("ttyd2", node, minor, 0);
    320     0    stevel 		(void) devfsadm_mklink("cua2", node, minor, 0);
    321     0    stevel 
    322     0    stevel 	} else if (strcmp(mn, "d,cu") == 0) {
    323     0    stevel 		(void) devfsadm_mklink("ttyd3", node, minor, 0);
    324     0    stevel 		(void) devfsadm_mklink("cua3", node, minor, 0);
    325     0    stevel 	}
    326     0    stevel 	return (DEVFSADM_CONTINUE);
    327     0    stevel }
    328     0    stevel 
    329     0    stevel static int
    330     0    stevel kdmouse(di_minor_t minor, di_node_t node)
    331     0    stevel {
    332     0    stevel 	(void) devfsadm_mklink("kdmouse", node, minor, 0);
    333     0    stevel 	return (DEVFSADM_CONTINUE);
    334     0    stevel }
    335     0    stevel 
    336     0    stevel static int
    337     0    stevel bmc(di_minor_t minor, di_node_t node)
    338     0    stevel {
    339     0    stevel 	(void) devfsadm_mklink("bmc", node, minor, 0);
    340     0    stevel 	return (DEVFSADM_CONTINUE);
    341     0    stevel }
    342   437       mws 
    343   437       mws static int
    344   437       mws smbios(di_minor_t minor, di_node_t node)
    345   437       mws {
    346   437       mws 	(void) devfsadm_mklink("smbios", node, minor, 0);
    347   437       mws 	return (DEVFSADM_CONTINUE);
    348   437       mws }
    349   437       mws 
    350     0    stevel static int
    351     0    stevel agp_process(di_minor_t minor, di_node_t node)
    352     0    stevel {
    353     0    stevel 	char *minor_nm, *drv_nm;
    354     0    stevel 	char *devfspath;
    355     0    stevel 	char *I_path, *p_path, *buf;
    356     0    stevel 	char *name = (char *)NULL;
    357     0    stevel 	int i, index;
    358     0    stevel 	devfsadm_enumerate_t rules[1];
    359     0    stevel 
    360     0    stevel 	minor_nm = di_minor_name(minor);
    361     0    stevel 	drv_nm = di_driver_name(node);
    362     0    stevel 
    363     0    stevel 	if ((minor_nm == NULL) || (drv_nm == NULL)) {
    364     0    stevel 		return (DEVFSADM_CONTINUE);
    365     0    stevel 	}
    366     0    stevel 
    367     0    stevel 	devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n",
    368  4581   sherrym 	    minor_nm, di_node_name(node));
    369     0    stevel 
    370     0    stevel 	devfspath = di_devfs_path(node);
    371     0    stevel 	if (devfspath == NULL) {
    372     0    stevel 		devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n");
    373     0    stevel 		return (DEVFSADM_CONTINUE);
    374     0    stevel 	}
    375     0    stevel 
    376     0    stevel 	I_path = (char *)malloc(PATH_MAX);
    377     0    stevel 
    378     0    stevel 	if (I_path == NULL) {
    379     0    stevel 		di_devfs_path_free(devfspath);
    380     0    stevel 		devfsadm_print(debug_mid,  "agp_process: malloc failed\n");
    381     0    stevel 		return (DEVFSADM_CONTINUE);
    382     0    stevel 	}
    383     0    stevel 
    384     0    stevel 	p_path = (char *)malloc(PATH_MAX);
    385     0    stevel 
    386     0    stevel 	if (p_path == NULL) {
    387     0    stevel 		devfsadm_print(debug_mid,  "agp_process: malloc failed\n");
    388     0    stevel 		di_devfs_path_free(devfspath);
    389     0    stevel 		free(I_path);
    390     0    stevel 		return (DEVFSADM_CONTINUE);
    391     0    stevel 	}
    392     0    stevel 
    393     0    stevel 	(void) strlcpy(p_path, devfspath, PATH_MAX);
    394     0    stevel 	(void) strlcat(p_path, ":", PATH_MAX);
    395     0    stevel 	(void) strlcat(p_path, minor_nm, PATH_MAX);
    396     0    stevel 	di_devfs_path_free(devfspath);
    397     0    stevel 
    398     0    stevel 	devfsadm_print(debug_mid, "agp_process: path %s\n", p_path);
    399     0    stevel 
    400     0    stevel 	for (i = 0; ; i++) {
    401     0    stevel 		if ((driver_name_table[i].driver_name == NULL) ||
    402     0    stevel 		    (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) {
    403     0    stevel 			index = driver_name_table[i].index;
    404     0    stevel 			break;
    405     0    stevel 		}
    406     0    stevel 	}
    407     0    stevel 	switch (index) {
    408     0    stevel 	case DRIVER_AGPPSEUDO:
    409     0    stevel 		devfsadm_print(debug_mid,
    410  4581   sherrym 		    "agp_process: psdeudo driver name\n");
    411     0    stevel 		name = "agpgart";
    412     0    stevel 		(void) snprintf(I_path, PATH_MAX, "%s", name);
    413     0    stevel 		devfsadm_print(debug_mid,
    414     0    stevel 		    "mklink %s -> %s\n", I_path, p_path);
    415     0    stevel 
    416     0    stevel 		(void) devfsadm_mklink(I_path, node, minor, 0);
    417     0    stevel 
    418     0    stevel 		free(I_path);
    419     0    stevel 		free(p_path);
    420     0    stevel 		return (DEVFSADM_CONTINUE);
    421     0    stevel 	case DRIVER_AGPTARGET:
    422     0    stevel 		devfsadm_print(debug_mid,
    423  4581   sherrym 		    "agp_process: target driver name\n");
    424     0    stevel 		rules[0] = agptarget_rules[0];
    425     0    stevel 		name = "agptarget";
    426     0    stevel 		break;
    427     0    stevel 	case DRIVER_CPUGART:
    428     0    stevel 		devfsadm_print(debug_mid,
    429  4581   sherrym 		    "agp_process: cpugart driver name\n");
    430     0    stevel 		rules[0] = cpugart_rules[0];
    431     0    stevel 		name = "cpugart";
    432     0    stevel 		break;
    433  6393  cg149915 	case DRIVER_AGPMASTER_DRM_I915:
    434  6393  cg149915 	case DRIVER_AGPMASTER_DRM_RADEON:
    435  2820  kz151634 	case DRIVER_AGPMASTER_VGATEXT:
    436     0    stevel 		devfsadm_print(debug_mid,
    437  4581   sherrym 		    "agp_process: agpmaster driver name\n");
    438     0    stevel 		rules[0] = agpmaster_rules[0];
    439     0    stevel 		name = "agpmaster";
    440     0    stevel 		break;
    441     0    stevel 	case DRIVER_UNKNOWN:
    442     0    stevel 		devfsadm_print(debug_mid,
    443  4581   sherrym 		    "agp_process: unknown driver name=%s\n", drv_nm);
    444     0    stevel 		free(I_path);
    445     0    stevel 		free(p_path);
    446     0    stevel 		return (DEVFSADM_CONTINUE);
    447     0    stevel 	}
    448     0    stevel 
    449     0    stevel 	if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) {
    450     0    stevel 		devfsadm_print(debug_mid, "agp_process: exit/coninue\n");
    451     0    stevel 		free(I_path);
    452     0    stevel 		free(p_path);
    453     0    stevel 		return (DEVFSADM_CONTINUE);
    454     0    stevel 	}
    455     0    stevel 
    456     0    stevel 
    457     0    stevel 	(void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf);
    458     0    stevel 
    459     0    stevel 	devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n",
    460  4581   sherrym 	    p_path, buf);
    461     0    stevel 
    462     0    stevel 	free(buf);
    463     0    stevel 
    464     0    stevel 	devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path);
    465     0    stevel 
    466     0    stevel 	(void) devfsadm_mklink(I_path, node, minor, 0);
    467     0    stevel 
    468     0    stevel 	free(p_path);
    469     0    stevel 	free(I_path);
    470     0    stevel 
    471     0    stevel 	return (DEVFSADM_CONTINUE);
    472  2820  kz151634 }
    473  2820  kz151634 
    474  2820  kz151634 static int
    475  2820  kz151634 drm_node(di_minor_t minor, di_node_t node)
    476  2820  kz151634 {
    477  2820  kz151634 	char *minor_nm, *drv_nm;
    478  2820  kz151634 	char *devfspath;
    479  2820  kz151634 	char *I_path, *p_path, *buf;
    480  2820  kz151634 	char *name = "card";
    481  2820  kz151634 
    482  2820  kz151634 	devfsadm_enumerate_t drm_rules[1] = {"^dri$/^card([0-9]+)$", 1,
    483  2820  kz151634 		MATCH_ALL };
    484  2820  kz151634 
    485  2820  kz151634 
    486  2820  kz151634 	minor_nm = di_minor_name(minor);
    487  2820  kz151634 	drv_nm = di_driver_name(node);
    488  2820  kz151634 	if ((minor_nm == NULL) || (drv_nm == NULL)) {
    489  2820  kz151634 		return (DEVFSADM_CONTINUE);
    490  2820  kz151634 	}
    491  2820  kz151634 
    492  2820  kz151634 	devfsadm_print(debug_mid, "drm_node: minor=%s node=%s type=%s\n",
    493  2820  kz151634 	    minor_nm, di_node_name(node), di_minor_nodetype(minor));
    494  2820  kz151634 
    495  2820  kz151634 	devfspath = di_devfs_path(node);
    496  2820  kz151634 	if (devfspath == NULL) {
    497  2820  kz151634 		devfsadm_print(debug_mid, "drm_node: devfspath is NULL\n");
    498  2820  kz151634 		return (DEVFSADM_CONTINUE);
    499  2820  kz151634 	}
    500  2820  kz151634 
    501  2820  kz151634 	I_path = (char *)malloc(PATH_MAX);
    502  2820  kz151634 
    503  2820  kz151634 	if (I_path == NULL) {
    504  2820  kz151634 		di_devfs_path_free(devfspath);
    505  2820  kz151634 		devfsadm_print(debug_mid,  "drm_node: malloc failed\n");
    506  2820  kz151634 		return (DEVFSADM_CONTINUE);
    507  2820  kz151634 	}
    508  2820  kz151634 
    509  2820  kz151634 	p_path = (char *)malloc(PATH_MAX);
    510  2820  kz151634 
    511  2820  kz151634 	if (p_path == NULL) {
    512  2820  kz151634 		devfsadm_print(debug_mid,  "drm_node: malloc failed\n");
    513  2820  kz151634 		di_devfs_path_free(devfspath);
    514  2820  kz151634 		free(I_path);
    515  2820  kz151634 		return (DEVFSADM_CONTINUE);
    516  2820  kz151634 	}
    517  2820  kz151634 
    518  2820  kz151634 	(void) strlcpy(p_path, devfspath, PATH_MAX);
    519  2820  kz151634 	(void) strlcat(p_path, ":", PATH_MAX);
    520  2820  kz151634 	(void) strlcat(p_path, minor_nm, PATH_MAX);
    521  2820  kz151634 	di_devfs_path_free(devfspath);
    522  2820  kz151634 
    523  2820  kz151634 	devfsadm_print(debug_mid, "drm_node: p_path %s\n", p_path);
    524  2820  kz151634 
    525  2820  kz151634 	if (devfsadm_enumerate_int(p_path, 0, &buf, drm_rules, 1)) {
    526  2820  kz151634 		free(p_path);
    527  2820  kz151634 		devfsadm_print(debug_mid, "drm_node: exit/coninue\n");
    528  2820  kz151634 		return (DEVFSADM_CONTINUE);
    529  2820  kz151634 	}
    530  2820  kz151634 	(void) snprintf(I_path, PATH_MAX, "dri/%s%s", name, buf);
    531  2820  kz151634 
    532  2820  kz151634 	devfsadm_print(debug_mid, "drm_node: p_path=%s buf=%s\n",
    533  4581   sherrym 	    p_path, buf);
    534  2820  kz151634 
    535  2820  kz151634 	free(buf);
    536  2820  kz151634 
    537  2820  kz151634 	devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path);
    538  2820  kz151634 	(void) devfsadm_mklink(I_path, node, minor, 0);
    539  2820  kz151634 
    540  2820  kz151634 	free(p_path);
    541  2820  kz151634 	free(I_path);
    542  2820  kz151634 
    543  2820  kz151634 	return (0);
    544     0    stevel }
    545  1414     cindi 
    546  1414     cindi /*
    547  1414     cindi  * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd
    548  1414     cindi  */
    549  1414     cindi static int
    550  1414     cindi mc_node(di_minor_t minor, di_node_t node)
    551  1414     cindi {
    552  1414     cindi 	const char *minorname = di_minor_name(minor);
    553  1414     cindi 	const char *busaddr = di_bus_addr(node);
    554  1414     cindi 	char linkpath[PATH_MAX];
    555  1414     cindi 	int unitaddr;
    556  1414     cindi 	char *c;
    557  1414     cindi 
    558  1414     cindi 	if (minorname == NULL || busaddr == NULL)
    559  1414     cindi 		return (DEVFSADM_CONTINUE);
    560  1414     cindi 
    561  1414     cindi 	errno = 0;
    562  1414     cindi 	unitaddr = strtol(busaddr, &c, 16);
    563  1414     cindi 
    564  5254    gavinm 	if (errno != 0)
    565  1414     cindi 		return (DEVFSADM_CONTINUE);
    566  1414     cindi 
    567  5254    gavinm 	if (unitaddr == 0) {
    568  5254    gavinm 		(void) snprintf(linkpath, sizeof (linkpath), "mc/mc");
    569  5254    gavinm 	} else if (unitaddr >= MC_AMD_DEV_OFFSET) {
    570  5254    gavinm 		(void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u",
    571  5254    gavinm 		    unitaddr - MC_AMD_DEV_OFFSET);
    572  5254    gavinm 	} else {
    573  7349    Adrian 		(void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u",
    574  7349    Adrian 		    minor->dev_minor);
    575  5254    gavinm 	}
    576  1414     cindi 	(void) devfsadm_mklink(linkpath, node, minor, 0);
    577  1414     cindi 	return (DEVFSADM_CONTINUE);
    578  1414     cindi }
    579  3446       mrj 
    580  3446       mrj /*
    581  3446       mrj  * Creates \M0 devlink for xsvc node
    582  3446       mrj  */
    583  3446       mrj static int
    584  3446       mrj xsvc(di_minor_t minor, di_node_t node)
    585  3446       mrj {
    586  3446       mrj 	char *mn;
    587  3446       mrj 
    588  3446       mrj 	if (strcmp(di_node_name(node), "xsvc") != 0)
    589  3446       mrj 		return (DEVFSADM_CONTINUE);
    590  3446       mrj 
    591  3446       mrj 	mn = di_minor_name(minor);
    592  3446       mrj 	if (mn == NULL)
    593  3446       mrj 		return (DEVFSADM_CONTINUE);
    594  3446       mrj 
    595  3446       mrj 	(void) devfsadm_mklink(mn, node, minor, 0);
    596  3446       mrj 	return (DEVFSADM_CONTINUE);
    597  3446       mrj }
    598  4581   sherrym 
    599  4581   sherrym /*
    600  5295    randyf  * Creates \M0 devlink for srn device
    601  5295    randyf  */
    602  5295    randyf static int
    603  5295    randyf srn(di_minor_t minor, di_node_t node)
    604  5295    randyf {
    605  5295    randyf 	char *mn;
    606  5295    randyf 
    607  5295    randyf 	if (strcmp(di_node_name(node), "srn") != 0)
    608  5295    randyf 		return (DEVFSADM_CONTINUE);
    609  5295    randyf 
    610  5295    randyf 	mn = di_minor_name(minor);
    611  5295    randyf 	if (mn == NULL)
    612  5295    randyf 		return (DEVFSADM_CONTINUE);
    613  5295    randyf 
    614  5295    randyf 	(void) devfsadm_mklink(mn, node, minor, 0);
    615  5295    randyf 	return (DEVFSADM_CONTINUE);
    616  5295    randyf }
    617  5295    randyf 
    618  5295    randyf /*
    619  4581   sherrym  *	/dev/ucode	->	/devices/pseudo/ucode@0:ucode
    620  4581   sherrym  */
    621  4581   sherrym static int
    622  4581   sherrym ucode(di_minor_t minor, di_node_t node)
    623  4581   sherrym {
    624  4581   sherrym 	(void) devfsadm_mklink("ucode", node, minor, 0);
    625  4581   sherrym 	return (DEVFSADM_CONTINUE);
    626  4581   sherrym }
    627  9203      Mark 
    628  9203      Mark static int
    629  9203      Mark heci(di_minor_t minor, di_node_t node)
    630  9203      Mark {
    631  9203      Mark 	if (strcmp(di_minor_name(minor), "AMT") == 0) {
    632  9203      Mark 		(void) devfsadm_mklink("heci", node, minor, 0);
    633  9203      Mark 	}
    634  9203      Mark 	return (DEVFSADM_CONTINUE);
    635  9203      Mark }
    636