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 51676Sjpk * Common Development and Distribution License (the "License"). 61676Sjpk * 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*11615SJimmy.Vetayases@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #include <regex.h> 270Sstevel@tonic-gate #include <devfsadm.h> 280Sstevel@tonic-gate #include <stdio.h> 290Sstevel@tonic-gate #include <strings.h> 300Sstevel@tonic-gate #include <stdlib.h> 310Sstevel@tonic-gate #include <limits.h> 320Sstevel@tonic-gate #include <ctype.h> 335254Sgavinm #include <sys/mc_amd.h> 341676Sjpk #include <bsm/devalloc.h> 351676Sjpk 361676Sjpk extern int system_labeled; 370Sstevel@tonic-gate 380Sstevel@tonic-gate static int lp(di_minor_t minor, di_node_t node); 390Sstevel@tonic-gate static int serial_dialout(di_minor_t minor, di_node_t node); 400Sstevel@tonic-gate static int serial(di_minor_t minor, di_node_t node); 410Sstevel@tonic-gate static int diskette(di_minor_t minor, di_node_t node); 420Sstevel@tonic-gate static int vt00(di_minor_t minor, di_node_t node); 430Sstevel@tonic-gate static int kdmouse(di_minor_t minor, di_node_t node); 440Sstevel@tonic-gate static int bmc(di_minor_t minor, di_node_t node); 45437Smws static int smbios(di_minor_t minor, di_node_t node); 460Sstevel@tonic-gate static int agp_process(di_minor_t minor, di_node_t node); 472820Skz151634 static int drm_node(di_minor_t minor, di_node_t node); 481414Scindi static int mc_node(di_minor_t minor, di_node_t node); 493446Smrj static int xsvc(di_minor_t minor, di_node_t node); 505295Srandyf static int srn(di_minor_t minor, di_node_t node); 514581Ssherrym static int ucode(di_minor_t minor, di_node_t node); 529203SMark.Logan@Sun.COM static int heci(di_minor_t minor, di_node_t node); 539203SMark.Logan@Sun.COM 540Sstevel@tonic-gate 550Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = { 560Sstevel@tonic-gate { "vt00", "ddi_display", NULL, 570Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, vt00 580Sstevel@tonic-gate }, 592820Skz151634 { "drm", "ddi_display:drm", NULL, 602820Skz151634 TYPE_EXACT, ILEVEL_0, drm_node 612820Skz151634 }, 620Sstevel@tonic-gate { "mouse", "ddi_mouse", "mouse8042", 630Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse 640Sstevel@tonic-gate }, 650Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "bmc", 660Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc, 670Sstevel@tonic-gate }, 68437Smws { "pseudo", "ddi_pseudo", "smbios", 69437Smws TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios, 70437Smws }, 71*11615SJimmy.Vetayases@Sun.COM /* floppies share the same class, but not link regex, as hard disks */ 720Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL, 730Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette 740Sstevel@tonic-gate }, 750Sstevel@tonic-gate { "parallel", "ddi_printer", NULL, 760Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, lp 770Sstevel@tonic-gate }, 780Sstevel@tonic-gate { "serial", "ddi_serial:mb", NULL, 790Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial 800Sstevel@tonic-gate }, 810Sstevel@tonic-gate { "serial", "ddi_serial:dialout,mb", NULL, 820Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial_dialout 830Sstevel@tonic-gate }, 841414Scindi { "agp", "ddi_agp:pseudo", NULL, 850Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 860Sstevel@tonic-gate }, 871414Scindi { "agp", "ddi_agp:target", NULL, 880Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 890Sstevel@tonic-gate }, 901414Scindi { "agp", "ddi_agp:cpugart", NULL, 910Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 920Sstevel@tonic-gate }, 931414Scindi { "agp", "ddi_agp:master", NULL, 940Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 951414Scindi }, 963446Smrj { "pseudo", "ddi_pseudo", NULL, 973446Smrj TYPE_EXACT, ILEVEL_0, xsvc 983446Smrj }, 995295Srandyf { "pseudo", "ddi_pseudo", NULL, 1005295Srandyf TYPE_EXACT, ILEVEL_0, srn 1015295Srandyf }, 1021414Scindi { "memory-controller", "ddi_mem_ctrl", NULL, 1031414Scindi TYPE_EXACT, ILEVEL_0, mc_node 1044581Ssherrym }, 1054581Ssherrym { "pseudo", "ddi_pseudo", "ucode", 1064581Ssherrym TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode, 1079203SMark.Logan@Sun.COM }, 1089203SMark.Logan@Sun.COM { "pseudo", "ddi_pseudo", "heci", 1099203SMark.Logan@Sun.COM TYPE_EXACT | DRV_EXACT, ILEVEL_0, heci, 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate }; 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt); 1140Sstevel@tonic-gate 1152820Skz151634 static char *debug_mid = "misc_mid"; 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate typedef enum { 1180Sstevel@tonic-gate DRIVER_AGPPSEUDO = 0, 1190Sstevel@tonic-gate DRIVER_AGPTARGET, 1200Sstevel@tonic-gate DRIVER_CPUGART, 1216393Scg149915 DRIVER_AGPMASTER_DRM_I915, 1226393Scg149915 DRIVER_AGPMASTER_DRM_RADEON, 1232820Skz151634 DRIVER_AGPMASTER_VGATEXT, 1240Sstevel@tonic-gate DRIVER_UNKNOWN 1250Sstevel@tonic-gate } driver_defs_t; 1260Sstevel@tonic-gate 1270Sstevel@tonic-gate typedef struct { 1280Sstevel@tonic-gate char *driver_name; 1290Sstevel@tonic-gate int index; 1300Sstevel@tonic-gate } driver_name_table_entry_t; 1310Sstevel@tonic-gate 1320Sstevel@tonic-gate static driver_name_table_entry_t driver_name_table[] = { 1330Sstevel@tonic-gate { "agpgart", DRIVER_AGPPSEUDO }, 1340Sstevel@tonic-gate { "agptarget", DRIVER_AGPTARGET }, 1350Sstevel@tonic-gate { "amd64_gart", DRIVER_CPUGART }, 1362820Skz151634 /* AGP master device managed by drm driver */ 1376393Scg149915 { "i915", DRIVER_AGPMASTER_DRM_I915 }, 1386393Scg149915 { "radeon", DRIVER_AGPMASTER_DRM_RADEON }, 1392820Skz151634 { "vgatext", DRIVER_AGPMASTER_VGATEXT }, 1400Sstevel@tonic-gate { NULL, DRIVER_UNKNOWN } 1410Sstevel@tonic-gate }; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate static devfsadm_enumerate_t agptarget_rules[1] = 1440Sstevel@tonic-gate { "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL }; 1450Sstevel@tonic-gate static devfsadm_enumerate_t cpugart_rules[1] = 1460Sstevel@tonic-gate { "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL }; 1470Sstevel@tonic-gate static devfsadm_enumerate_t agpmaster_rules[1] = 1480Sstevel@tonic-gate { "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL }; 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate static devfsadm_remove_t misc_remove_cbt[] = { 1510Sstevel@tonic-gate { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS, 1520Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all 1534581Ssherrym }, 1544581Ssherrym { "pseudo", "^ucode$", RM_ALWAYS | RM_PRE | RM_HOT, 1554581Ssherrym ILEVEL_0, devfsadm_rm_all 156*11615SJimmy.Vetayases@Sun.COM }, 157*11615SJimmy.Vetayases@Sun.COM { "mouse", "^kdmouse$", RM_ALWAYS | RM_PRE, 158*11615SJimmy.Vetayases@Sun.COM ILEVEL_0, devfsadm_rm_all 159*11615SJimmy.Vetayases@Sun.COM }, 160*11615SJimmy.Vetayases@Sun.COM { "disk", "^(diskette|rdiskette)([0-9]*)$", 161*11615SJimmy.Vetayases@Sun.COM RM_ALWAYS | RM_PRE, ILEVEL_1, devfsadm_rm_all 162*11615SJimmy.Vetayases@Sun.COM }, 163*11615SJimmy.Vetayases@Sun.COM { "parallel", "^(lp|ecpp)([0-9]+)$", RM_ALWAYS | RM_PRE, 164*11615SJimmy.Vetayases@Sun.COM ILEVEL_1, devfsadm_rm_all 165*11615SJimmy.Vetayases@Sun.COM }, 166*11615SJimmy.Vetayases@Sun.COM { "serial", "^(tty|ttyd)([0-9]+)$", RM_ALWAYS | RM_PRE, 167*11615SJimmy.Vetayases@Sun.COM ILEVEL_1, devfsadm_rm_all 168*11615SJimmy.Vetayases@Sun.COM }, 169*11615SJimmy.Vetayases@Sun.COM { "serial", "^tty[a-z]$", RM_ALWAYS | RM_PRE, 170*11615SJimmy.Vetayases@Sun.COM ILEVEL_1, devfsadm_rm_all 1710Sstevel@tonic-gate } 1720Sstevel@tonic-gate }; 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate /* 1770Sstevel@tonic-gate * Handles minor node type "ddi_display", in addition to generic processing 1780Sstevel@tonic-gate * done by display(). 1790Sstevel@tonic-gate * 1800Sstevel@tonic-gate * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility. 1810Sstevel@tonic-gate */ 1820Sstevel@tonic-gate /* ARGSUSED */ 1830Sstevel@tonic-gate int 1840Sstevel@tonic-gate vt00(di_minor_t minor, di_node_t node) 1850Sstevel@tonic-gate { 1860Sstevel@tonic-gate (void) devfsadm_secondary_link("vt00", "fb", 0); 1870Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate /* 1910Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c diskette 1920Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette 1930Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c diskette\A2 1940Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2 1950Sstevel@tonic-gate */ 1960Sstevel@tonic-gate static int 1970Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node) 1980Sstevel@tonic-gate { 1991676Sjpk int flags = 0; 2000Sstevel@tonic-gate char *a2; 2010Sstevel@tonic-gate char link[PATH_MAX]; 2020Sstevel@tonic-gate char *addr = di_bus_addr(node); 2030Sstevel@tonic-gate char *mn = di_minor_name(minor); 2040Sstevel@tonic-gate 2051676Sjpk if (system_labeled) 2061676Sjpk flags = DA_ADD|DA_FLOPPY; 2071676Sjpk 2080Sstevel@tonic-gate if (strcmp(addr, "0,0") == 0) { 2090Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 2101676Sjpk (void) devfsadm_mklink("diskette", node, minor, flags); 2110Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 2121676Sjpk (void) devfsadm_mklink("rdiskette", node, minor, flags); 2130Sstevel@tonic-gate } 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate if (addr[0] == '0') { 2180Sstevel@tonic-gate if ((a2 = strchr(addr, ',')) != NULL) { 2190Sstevel@tonic-gate a2++; 2200Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 2210Sstevel@tonic-gate (void) strcpy(link, "diskette"); 2220Sstevel@tonic-gate (void) strcat(link, a2); 2231676Sjpk (void) devfsadm_mklink(link, node, minor, 2241676Sjpk flags); 2250Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 2260Sstevel@tonic-gate (void) strcpy(link, "rdiskette"); 2270Sstevel@tonic-gate (void) strcat(link, a2); 2281676Sjpk (void) devfsadm_mklink(link, node, minor, 2291676Sjpk flags); 2300Sstevel@tonic-gate } 2310Sstevel@tonic-gate } 2320Sstevel@tonic-gate } 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate /* 2380Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,3bc lp0 2390Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,378 lp1 2400Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,278 lp2 2410Sstevel@tonic-gate */ 2420Sstevel@tonic-gate static int 2430Sstevel@tonic-gate lp(di_minor_t minor, di_node_t node) 2440Sstevel@tonic-gate { 2450Sstevel@tonic-gate char *addr = di_bus_addr(node); 2460Sstevel@tonic-gate char *buf; 2470Sstevel@tonic-gate char path[PATH_MAX + 1]; 2480Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 2490Sstevel@tonic-gate 2500Sstevel@tonic-gate if (strcmp(addr, "1,3bc") == 0) { 2510Sstevel@tonic-gate (void) devfsadm_mklink("lp0", node, minor, 0); 2520Sstevel@tonic-gate 2530Sstevel@tonic-gate } else if (strcmp(addr, "1,378") == 0) { 2540Sstevel@tonic-gate (void) devfsadm_mklink("lp1", node, minor, 0); 2550Sstevel@tonic-gate 2560Sstevel@tonic-gate } else if (strcmp(addr, "1,278") == 0) { 2570Sstevel@tonic-gate (void) devfsadm_mklink("lp2", node, minor, 0); 2580Sstevel@tonic-gate } 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) { 2610Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) { 2650Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2660Sstevel@tonic-gate } 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", 2690Sstevel@tonic-gate buf, di_minor_name(minor)); 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate di_devfs_path_free(buf); 2720Sstevel@tonic-gate 2730Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 2740Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2750Sstevel@tonic-gate } 2760Sstevel@tonic-gate 2770Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf); 2780Sstevel@tonic-gate free(buf); 2790Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0); 2800Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2810Sstevel@tonic-gate } 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate /* 2840Sstevel@tonic-gate * type=ddi_serial:mb;minor=a tty00 2850Sstevel@tonic-gate * type=ddi_serial:mb;minor=b tty01 2860Sstevel@tonic-gate * type=ddi_serial:mb;minor=c tty02 2870Sstevel@tonic-gate * type=ddi_serial:mb;minor=d tty03 2880Sstevel@tonic-gate */ 2890Sstevel@tonic-gate static int 2900Sstevel@tonic-gate serial(di_minor_t minor, di_node_t node) 2910Sstevel@tonic-gate { 2920Sstevel@tonic-gate 2930Sstevel@tonic-gate char *mn = di_minor_name(minor); 2940Sstevel@tonic-gate char link[PATH_MAX]; 2950Sstevel@tonic-gate 2960Sstevel@tonic-gate (void) strcpy(link, "tty"); 2970Sstevel@tonic-gate (void) strcat(link, mn); 2980Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate if (strcmp(mn, "a") == 0) { 3010Sstevel@tonic-gate (void) devfsadm_mklink("tty00", node, minor, 0); 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate } else if (strcmp(mn, "b") == 0) { 3040Sstevel@tonic-gate (void) devfsadm_mklink("tty01", node, minor, 0); 3050Sstevel@tonic-gate 3060Sstevel@tonic-gate } else if (strcmp(mn, "c") == 0) { 3070Sstevel@tonic-gate (void) devfsadm_mklink("tty02", node, minor, 0); 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate } else if (strcmp(mn, "d") == 0) { 3100Sstevel@tonic-gate (void) devfsadm_mklink("tty03", node, minor, 0); 3110Sstevel@tonic-gate } 3120Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3130Sstevel@tonic-gate } 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate /* 3160Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=a,cu ttyd0 3170Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=b,cu ttyd1 3180Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=c,cu ttyd2 3190Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=d,cu ttyd3 3200Sstevel@tonic-gate */ 3210Sstevel@tonic-gate static int 3220Sstevel@tonic-gate serial_dialout(di_minor_t minor, di_node_t node) 3230Sstevel@tonic-gate { 3240Sstevel@tonic-gate char *mn = di_minor_name(minor); 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate if (strcmp(mn, "a,cu") == 0) { 3270Sstevel@tonic-gate (void) devfsadm_mklink("ttyd0", node, minor, 0); 3280Sstevel@tonic-gate (void) devfsadm_mklink("cua0", node, minor, 0); 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate } else if (strcmp(mn, "b,cu") == 0) { 3310Sstevel@tonic-gate (void) devfsadm_mklink("ttyd1", node, minor, 0); 3320Sstevel@tonic-gate (void) devfsadm_mklink("cua1", node, minor, 0); 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate } else if (strcmp(mn, "c,cu") == 0) { 3350Sstevel@tonic-gate (void) devfsadm_mklink("ttyd2", node, minor, 0); 3360Sstevel@tonic-gate (void) devfsadm_mklink("cua2", node, minor, 0); 3370Sstevel@tonic-gate 3380Sstevel@tonic-gate } else if (strcmp(mn, "d,cu") == 0) { 3390Sstevel@tonic-gate (void) devfsadm_mklink("ttyd3", node, minor, 0); 3400Sstevel@tonic-gate (void) devfsadm_mklink("cua3", node, minor, 0); 3410Sstevel@tonic-gate } 3420Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3430Sstevel@tonic-gate } 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate static int 3460Sstevel@tonic-gate kdmouse(di_minor_t minor, di_node_t node) 3470Sstevel@tonic-gate { 3480Sstevel@tonic-gate (void) devfsadm_mklink("kdmouse", node, minor, 0); 3490Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate static int 3530Sstevel@tonic-gate bmc(di_minor_t minor, di_node_t node) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate (void) devfsadm_mklink("bmc", node, minor, 0); 3560Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3570Sstevel@tonic-gate } 358437Smws 359437Smws static int 360437Smws smbios(di_minor_t minor, di_node_t node) 361437Smws { 362437Smws (void) devfsadm_mklink("smbios", node, minor, 0); 363437Smws return (DEVFSADM_CONTINUE); 364437Smws } 365437Smws 3660Sstevel@tonic-gate static int 3670Sstevel@tonic-gate agp_process(di_minor_t minor, di_node_t node) 3680Sstevel@tonic-gate { 3690Sstevel@tonic-gate char *minor_nm, *drv_nm; 3700Sstevel@tonic-gate char *devfspath; 3710Sstevel@tonic-gate char *I_path, *p_path, *buf; 3720Sstevel@tonic-gate char *name = (char *)NULL; 3730Sstevel@tonic-gate int i, index; 3740Sstevel@tonic-gate devfsadm_enumerate_t rules[1]; 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate minor_nm = di_minor_name(minor); 3770Sstevel@tonic-gate drv_nm = di_driver_name(node); 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate if ((minor_nm == NULL) || (drv_nm == NULL)) { 3800Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n", 3844581Ssherrym minor_nm, di_node_name(node)); 3850Sstevel@tonic-gate 3860Sstevel@tonic-gate devfspath = di_devfs_path(node); 3870Sstevel@tonic-gate if (devfspath == NULL) { 3880Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n"); 3890Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3900Sstevel@tonic-gate } 3910Sstevel@tonic-gate 3920Sstevel@tonic-gate I_path = (char *)malloc(PATH_MAX); 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate if (I_path == NULL) { 3950Sstevel@tonic-gate di_devfs_path_free(devfspath); 3960Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 3970Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3980Sstevel@tonic-gate } 3990Sstevel@tonic-gate 4000Sstevel@tonic-gate p_path = (char *)malloc(PATH_MAX); 4010Sstevel@tonic-gate 4020Sstevel@tonic-gate if (p_path == NULL) { 4030Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 4040Sstevel@tonic-gate di_devfs_path_free(devfspath); 4050Sstevel@tonic-gate free(I_path); 4060Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4070Sstevel@tonic-gate } 4080Sstevel@tonic-gate 4090Sstevel@tonic-gate (void) strlcpy(p_path, devfspath, PATH_MAX); 4100Sstevel@tonic-gate (void) strlcat(p_path, ":", PATH_MAX); 4110Sstevel@tonic-gate (void) strlcat(p_path, minor_nm, PATH_MAX); 4120Sstevel@tonic-gate di_devfs_path_free(devfspath); 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: path %s\n", p_path); 4150Sstevel@tonic-gate 4160Sstevel@tonic-gate for (i = 0; ; i++) { 4170Sstevel@tonic-gate if ((driver_name_table[i].driver_name == NULL) || 4180Sstevel@tonic-gate (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) { 4190Sstevel@tonic-gate index = driver_name_table[i].index; 4200Sstevel@tonic-gate break; 4210Sstevel@tonic-gate } 4220Sstevel@tonic-gate } 4230Sstevel@tonic-gate switch (index) { 4240Sstevel@tonic-gate case DRIVER_AGPPSEUDO: 4250Sstevel@tonic-gate devfsadm_print(debug_mid, 4264581Ssherrym "agp_process: psdeudo driver name\n"); 4270Sstevel@tonic-gate name = "agpgart"; 4280Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "%s", name); 4290Sstevel@tonic-gate devfsadm_print(debug_mid, 4300Sstevel@tonic-gate "mklink %s -> %s\n", I_path, p_path); 4310Sstevel@tonic-gate 4320Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate free(I_path); 4350Sstevel@tonic-gate free(p_path); 4360Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4370Sstevel@tonic-gate case DRIVER_AGPTARGET: 4380Sstevel@tonic-gate devfsadm_print(debug_mid, 4394581Ssherrym "agp_process: target driver name\n"); 4400Sstevel@tonic-gate rules[0] = agptarget_rules[0]; 4410Sstevel@tonic-gate name = "agptarget"; 4420Sstevel@tonic-gate break; 4430Sstevel@tonic-gate case DRIVER_CPUGART: 4440Sstevel@tonic-gate devfsadm_print(debug_mid, 4454581Ssherrym "agp_process: cpugart driver name\n"); 4460Sstevel@tonic-gate rules[0] = cpugart_rules[0]; 4470Sstevel@tonic-gate name = "cpugart"; 4480Sstevel@tonic-gate break; 4496393Scg149915 case DRIVER_AGPMASTER_DRM_I915: 4506393Scg149915 case DRIVER_AGPMASTER_DRM_RADEON: 4512820Skz151634 case DRIVER_AGPMASTER_VGATEXT: 4520Sstevel@tonic-gate devfsadm_print(debug_mid, 4534581Ssherrym "agp_process: agpmaster driver name\n"); 4540Sstevel@tonic-gate rules[0] = agpmaster_rules[0]; 4550Sstevel@tonic-gate name = "agpmaster"; 4560Sstevel@tonic-gate break; 4570Sstevel@tonic-gate case DRIVER_UNKNOWN: 4580Sstevel@tonic-gate devfsadm_print(debug_mid, 4594581Ssherrym "agp_process: unknown driver name=%s\n", drv_nm); 4600Sstevel@tonic-gate free(I_path); 4610Sstevel@tonic-gate free(p_path); 4620Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4630Sstevel@tonic-gate } 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { 4660Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: exit/coninue\n"); 4670Sstevel@tonic-gate free(I_path); 4680Sstevel@tonic-gate free(p_path); 4690Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4700Sstevel@tonic-gate } 4710Sstevel@tonic-gate 4720Sstevel@tonic-gate 4730Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf); 4740Sstevel@tonic-gate 4750Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n", 4764581Ssherrym p_path, buf); 4770Sstevel@tonic-gate 4780Sstevel@tonic-gate free(buf); 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 4810Sstevel@tonic-gate 4820Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate free(p_path); 4850Sstevel@tonic-gate free(I_path); 4860Sstevel@tonic-gate 4870Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4880Sstevel@tonic-gate } 4891414Scindi 4902820Skz151634 static int 4912820Skz151634 drm_node(di_minor_t minor, di_node_t node) 4922820Skz151634 { 4932820Skz151634 char *minor_nm, *drv_nm; 4942820Skz151634 char *devfspath; 4952820Skz151634 char *I_path, *p_path, *buf; 4962820Skz151634 char *name = "card"; 4972820Skz151634 4982820Skz151634 devfsadm_enumerate_t drm_rules[1] = {"^dri$/^card([0-9]+)$", 1, 4992820Skz151634 MATCH_ALL }; 5002820Skz151634 5012820Skz151634 5022820Skz151634 minor_nm = di_minor_name(minor); 5032820Skz151634 drv_nm = di_driver_name(node); 5042820Skz151634 if ((minor_nm == NULL) || (drv_nm == NULL)) { 5052820Skz151634 return (DEVFSADM_CONTINUE); 5062820Skz151634 } 5072820Skz151634 5082820Skz151634 devfsadm_print(debug_mid, "drm_node: minor=%s node=%s type=%s\n", 5092820Skz151634 minor_nm, di_node_name(node), di_minor_nodetype(minor)); 5102820Skz151634 5112820Skz151634 devfspath = di_devfs_path(node); 5122820Skz151634 if (devfspath == NULL) { 5132820Skz151634 devfsadm_print(debug_mid, "drm_node: devfspath is NULL\n"); 5142820Skz151634 return (DEVFSADM_CONTINUE); 5152820Skz151634 } 5162820Skz151634 5172820Skz151634 I_path = (char *)malloc(PATH_MAX); 5182820Skz151634 5192820Skz151634 if (I_path == NULL) { 5202820Skz151634 di_devfs_path_free(devfspath); 5212820Skz151634 devfsadm_print(debug_mid, "drm_node: malloc failed\n"); 5222820Skz151634 return (DEVFSADM_CONTINUE); 5232820Skz151634 } 5242820Skz151634 5252820Skz151634 p_path = (char *)malloc(PATH_MAX); 5262820Skz151634 5272820Skz151634 if (p_path == NULL) { 5282820Skz151634 devfsadm_print(debug_mid, "drm_node: malloc failed\n"); 5292820Skz151634 di_devfs_path_free(devfspath); 5302820Skz151634 free(I_path); 5312820Skz151634 return (DEVFSADM_CONTINUE); 5322820Skz151634 } 5332820Skz151634 5342820Skz151634 (void) strlcpy(p_path, devfspath, PATH_MAX); 5352820Skz151634 (void) strlcat(p_path, ":", PATH_MAX); 5362820Skz151634 (void) strlcat(p_path, minor_nm, PATH_MAX); 5372820Skz151634 di_devfs_path_free(devfspath); 5382820Skz151634 5392820Skz151634 devfsadm_print(debug_mid, "drm_node: p_path %s\n", p_path); 5402820Skz151634 5412820Skz151634 if (devfsadm_enumerate_int(p_path, 0, &buf, drm_rules, 1)) { 5422820Skz151634 free(p_path); 5432820Skz151634 devfsadm_print(debug_mid, "drm_node: exit/coninue\n"); 5442820Skz151634 return (DEVFSADM_CONTINUE); 5452820Skz151634 } 5462820Skz151634 (void) snprintf(I_path, PATH_MAX, "dri/%s%s", name, buf); 5472820Skz151634 5482820Skz151634 devfsadm_print(debug_mid, "drm_node: p_path=%s buf=%s\n", 5494581Ssherrym p_path, buf); 5502820Skz151634 5512820Skz151634 free(buf); 5522820Skz151634 5532820Skz151634 devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 5542820Skz151634 (void) devfsadm_mklink(I_path, node, minor, 0); 5552820Skz151634 5562820Skz151634 free(p_path); 5572820Skz151634 free(I_path); 5582820Skz151634 5592820Skz151634 return (0); 5602820Skz151634 } 5612820Skz151634 5621414Scindi /* 5631414Scindi * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd 5641414Scindi */ 5651414Scindi static int 5661414Scindi mc_node(di_minor_t minor, di_node_t node) 5671414Scindi { 5681414Scindi const char *minorname = di_minor_name(minor); 5691414Scindi const char *busaddr = di_bus_addr(node); 5701414Scindi char linkpath[PATH_MAX]; 5711414Scindi int unitaddr; 5721414Scindi char *c; 5731414Scindi 5741414Scindi if (minorname == NULL || busaddr == NULL) 5751414Scindi return (DEVFSADM_CONTINUE); 5761414Scindi 5771414Scindi errno = 0; 5781414Scindi unitaddr = strtol(busaddr, &c, 16); 5791414Scindi 5805254Sgavinm if (errno != 0) 5811414Scindi return (DEVFSADM_CONTINUE); 5821414Scindi 5835254Sgavinm if (unitaddr == 0) { 5845254Sgavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc"); 5855254Sgavinm } else if (unitaddr >= MC_AMD_DEV_OFFSET) { 5865254Sgavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 5875254Sgavinm unitaddr - MC_AMD_DEV_OFFSET); 5885254Sgavinm } else { 5897349SAdrian.Frost@Sun.COM (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 5907349SAdrian.Frost@Sun.COM minor->dev_minor); 5915254Sgavinm } 5921414Scindi (void) devfsadm_mklink(linkpath, node, minor, 0); 5931414Scindi return (DEVFSADM_CONTINUE); 5941414Scindi } 5953446Smrj 5963446Smrj /* 5973446Smrj * Creates \M0 devlink for xsvc node 5983446Smrj */ 5993446Smrj static int 6003446Smrj xsvc(di_minor_t minor, di_node_t node) 6013446Smrj { 6023446Smrj char *mn; 6033446Smrj 6043446Smrj if (strcmp(di_node_name(node), "xsvc") != 0) 6053446Smrj return (DEVFSADM_CONTINUE); 6063446Smrj 6073446Smrj mn = di_minor_name(minor); 6083446Smrj if (mn == NULL) 6093446Smrj return (DEVFSADM_CONTINUE); 6103446Smrj 6113446Smrj (void) devfsadm_mklink(mn, node, minor, 0); 6123446Smrj return (DEVFSADM_CONTINUE); 6133446Smrj } 6144581Ssherrym 6154581Ssherrym /* 6165295Srandyf * Creates \M0 devlink for srn device 6175295Srandyf */ 6185295Srandyf static int 6195295Srandyf srn(di_minor_t minor, di_node_t node) 6205295Srandyf { 6215295Srandyf char *mn; 6225295Srandyf 6235295Srandyf if (strcmp(di_node_name(node), "srn") != 0) 6245295Srandyf return (DEVFSADM_CONTINUE); 6255295Srandyf 6265295Srandyf mn = di_minor_name(minor); 6275295Srandyf if (mn == NULL) 6285295Srandyf return (DEVFSADM_CONTINUE); 6295295Srandyf 6305295Srandyf (void) devfsadm_mklink(mn, node, minor, 0); 6315295Srandyf return (DEVFSADM_CONTINUE); 6325295Srandyf } 6335295Srandyf 6345295Srandyf /* 6354581Ssherrym * /dev/ucode -> /devices/pseudo/ucode@0:ucode 6364581Ssherrym */ 6374581Ssherrym static int 6384581Ssherrym ucode(di_minor_t minor, di_node_t node) 6394581Ssherrym { 6404581Ssherrym (void) devfsadm_mklink("ucode", node, minor, 0); 6414581Ssherrym return (DEVFSADM_CONTINUE); 6424581Ssherrym } 6439203SMark.Logan@Sun.COM 6449203SMark.Logan@Sun.COM static int 6459203SMark.Logan@Sun.COM heci(di_minor_t minor, di_node_t node) 6469203SMark.Logan@Sun.COM { 6479203SMark.Logan@Sun.COM if (strcmp(di_minor_name(minor), "AMT") == 0) { 6489203SMark.Logan@Sun.COM (void) devfsadm_mklink("heci", node, minor, 0); 6499203SMark.Logan@Sun.COM } 6509203SMark.Logan@Sun.COM return (DEVFSADM_CONTINUE); 6519203SMark.Logan@Sun.COM } 652