17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2294ee2d0fSJimmy Vetayases * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*989f2807SJerry Jelinek * Copyright 2012 Joyent, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <regex.h> 287c478bd9Sstevel@tonic-gate #include <devfsadm.h> 297c478bd9Sstevel@tonic-gate #include <stdio.h> 307c478bd9Sstevel@tonic-gate #include <strings.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 327c478bd9Sstevel@tonic-gate #include <limits.h> 337c478bd9Sstevel@tonic-gate #include <ctype.h> 3420c794b3Sgavinm #include <sys/mc_amd.h> 3545916cd2Sjpk #include <bsm/devalloc.h> 3645916cd2Sjpk 3745916cd2Sjpk extern int system_labeled; 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate static int lp(di_minor_t minor, di_node_t node); 407c478bd9Sstevel@tonic-gate static int serial_dialout(di_minor_t minor, di_node_t node); 417c478bd9Sstevel@tonic-gate static int serial(di_minor_t minor, di_node_t node); 427c478bd9Sstevel@tonic-gate static int diskette(di_minor_t minor, di_node_t node); 437c478bd9Sstevel@tonic-gate static int vt00(di_minor_t minor, di_node_t node); 447c478bd9Sstevel@tonic-gate static int kdmouse(di_minor_t minor, di_node_t node); 45*989f2807SJerry Jelinek static int ipmi(di_minor_t minor, di_node_t node); 4684ab085aSmws static int smbios(di_minor_t minor, di_node_t node); 477c478bd9Sstevel@tonic-gate static int agp_process(di_minor_t minor, di_node_t node); 4860405de4Skz static int drm_node(di_minor_t minor, di_node_t node); 497aec1d6eScindi static int mc_node(di_minor_t minor, di_node_t node); 50ae115bc7Smrj static int xsvc(di_minor_t minor, di_node_t node); 512df1fe9cSrandyf static int srn(di_minor_t minor, di_node_t node); 522449e17fSsherrym static int ucode(di_minor_t minor, di_node_t node); 53617e2443SMark Logan static int heci(di_minor_t minor, di_node_t node); 54617e2443SMark Logan 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = { 577c478bd9Sstevel@tonic-gate { "vt00", "ddi_display", NULL, 587c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, vt00 597c478bd9Sstevel@tonic-gate }, 6060405de4Skz { "drm", "ddi_display:drm", NULL, 6160405de4Skz TYPE_EXACT, ILEVEL_0, drm_node 6260405de4Skz }, 637c478bd9Sstevel@tonic-gate { "mouse", "ddi_mouse", "mouse8042", 647c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse 657c478bd9Sstevel@tonic-gate }, 66*989f2807SJerry Jelinek { "pseudo", "ddi_pseudo", "ipmi", 67*989f2807SJerry Jelinek TYPE_EXACT | DRV_EXACT, ILEVEL_0, ipmi, 687c478bd9Sstevel@tonic-gate }, 6984ab085aSmws { "pseudo", "ddi_pseudo", "smbios", 7084ab085aSmws TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios, 7184ab085aSmws }, 7294ee2d0fSJimmy Vetayases /* floppies share the same class, but not link regex, as hard disks */ 737c478bd9Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL, 747c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette 757c478bd9Sstevel@tonic-gate }, 767c478bd9Sstevel@tonic-gate { "parallel", "ddi_printer", NULL, 777c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, lp 787c478bd9Sstevel@tonic-gate }, 797c478bd9Sstevel@tonic-gate { "serial", "ddi_serial:mb", NULL, 807c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial 817c478bd9Sstevel@tonic-gate }, 827c478bd9Sstevel@tonic-gate { "serial", "ddi_serial:dialout,mb", NULL, 837c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial_dialout 847c478bd9Sstevel@tonic-gate }, 857aec1d6eScindi { "agp", "ddi_agp:pseudo", NULL, 867c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 877c478bd9Sstevel@tonic-gate }, 887aec1d6eScindi { "agp", "ddi_agp:target", NULL, 897c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 907c478bd9Sstevel@tonic-gate }, 917aec1d6eScindi { "agp", "ddi_agp:cpugart", NULL, 927c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 937c478bd9Sstevel@tonic-gate }, 947aec1d6eScindi { "agp", "ddi_agp:master", NULL, 957c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 967aec1d6eScindi }, 97ae115bc7Smrj { "pseudo", "ddi_pseudo", NULL, 98ae115bc7Smrj TYPE_EXACT, ILEVEL_0, xsvc 99ae115bc7Smrj }, 1002df1fe9cSrandyf { "pseudo", "ddi_pseudo", NULL, 1012df1fe9cSrandyf TYPE_EXACT, ILEVEL_0, srn 1022df1fe9cSrandyf }, 1037aec1d6eScindi { "memory-controller", "ddi_mem_ctrl", NULL, 1047aec1d6eScindi TYPE_EXACT, ILEVEL_0, mc_node 1052449e17fSsherrym }, 1062449e17fSsherrym { "pseudo", "ddi_pseudo", "ucode", 1072449e17fSsherrym TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode, 108617e2443SMark Logan }, 109617e2443SMark Logan { "pseudo", "ddi_pseudo", "heci", 110617e2443SMark Logan TYPE_EXACT | DRV_EXACT, ILEVEL_0, heci, 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate }; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt); 1157c478bd9Sstevel@tonic-gate 11660405de4Skz static char *debug_mid = "misc_mid"; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate typedef enum { 1197c478bd9Sstevel@tonic-gate DRIVER_AGPPSEUDO = 0, 1207c478bd9Sstevel@tonic-gate DRIVER_AGPTARGET, 1217c478bd9Sstevel@tonic-gate DRIVER_CPUGART, 122e57b9183Scg DRIVER_AGPMASTER_DRM_I915, 123e57b9183Scg DRIVER_AGPMASTER_DRM_RADEON, 12460405de4Skz DRIVER_AGPMASTER_VGATEXT, 1257c478bd9Sstevel@tonic-gate DRIVER_UNKNOWN 1267c478bd9Sstevel@tonic-gate } driver_defs_t; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate typedef struct { 1297c478bd9Sstevel@tonic-gate char *driver_name; 1307c478bd9Sstevel@tonic-gate int index; 1317c478bd9Sstevel@tonic-gate } driver_name_table_entry_t; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate static driver_name_table_entry_t driver_name_table[] = { 1347c478bd9Sstevel@tonic-gate { "agpgart", DRIVER_AGPPSEUDO }, 1357c478bd9Sstevel@tonic-gate { "agptarget", DRIVER_AGPTARGET }, 1367c478bd9Sstevel@tonic-gate { "amd64_gart", DRIVER_CPUGART }, 13760405de4Skz /* AGP master device managed by drm driver */ 138e57b9183Scg { "i915", DRIVER_AGPMASTER_DRM_I915 }, 139e57b9183Scg { "radeon", DRIVER_AGPMASTER_DRM_RADEON }, 14060405de4Skz { "vgatext", DRIVER_AGPMASTER_VGATEXT }, 1417c478bd9Sstevel@tonic-gate { NULL, DRIVER_UNKNOWN } 1427c478bd9Sstevel@tonic-gate }; 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t agptarget_rules[1] = 1457c478bd9Sstevel@tonic-gate { "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL }; 1467c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t cpugart_rules[1] = 1477c478bd9Sstevel@tonic-gate { "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL }; 1487c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t agpmaster_rules[1] = 1497c478bd9Sstevel@tonic-gate { "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL }; 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate static devfsadm_remove_t misc_remove_cbt[] = { 1527c478bd9Sstevel@tonic-gate { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS, 1537c478bd9Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all 1542449e17fSsherrym }, 1552449e17fSsherrym { "pseudo", "^ucode$", RM_ALWAYS | RM_PRE | RM_HOT, 1562449e17fSsherrym ILEVEL_0, devfsadm_rm_all 15794ee2d0fSJimmy Vetayases }, 15894ee2d0fSJimmy Vetayases { "mouse", "^kdmouse$", RM_ALWAYS | RM_PRE, 15994ee2d0fSJimmy Vetayases ILEVEL_0, devfsadm_rm_all 16094ee2d0fSJimmy Vetayases }, 16194ee2d0fSJimmy Vetayases { "disk", "^(diskette|rdiskette)([0-9]*)$", 16294ee2d0fSJimmy Vetayases RM_ALWAYS | RM_PRE, ILEVEL_1, devfsadm_rm_all 16394ee2d0fSJimmy Vetayases }, 16494ee2d0fSJimmy Vetayases { "parallel", "^(lp|ecpp)([0-9]+)$", RM_ALWAYS | RM_PRE, 16594ee2d0fSJimmy Vetayases ILEVEL_1, devfsadm_rm_all 16694ee2d0fSJimmy Vetayases }, 16794ee2d0fSJimmy Vetayases { "serial", "^(tty|ttyd)([0-9]+)$", RM_ALWAYS | RM_PRE, 16894ee2d0fSJimmy Vetayases ILEVEL_1, devfsadm_rm_all 16994ee2d0fSJimmy Vetayases }, 17094ee2d0fSJimmy Vetayases { "serial", "^tty[a-z]$", RM_ALWAYS | RM_PRE, 17194ee2d0fSJimmy Vetayases ILEVEL_1, devfsadm_rm_all 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate }; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate /* 1787c478bd9Sstevel@tonic-gate * Handles minor node type "ddi_display", in addition to generic processing 1797c478bd9Sstevel@tonic-gate * done by display(). 1807c478bd9Sstevel@tonic-gate * 1817c478bd9Sstevel@tonic-gate * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility. 1827c478bd9Sstevel@tonic-gate */ 1837c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1847c478bd9Sstevel@tonic-gate int 1857c478bd9Sstevel@tonic-gate vt00(di_minor_t minor, di_node_t node) 1867c478bd9Sstevel@tonic-gate { 1877c478bd9Sstevel@tonic-gate (void) devfsadm_secondary_link("vt00", "fb", 0); 1887c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* 1927c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c diskette 1937c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette 1947c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c diskette\A2 1957c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate static int 1987c478bd9Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node) 1997c478bd9Sstevel@tonic-gate { 20045916cd2Sjpk int flags = 0; 2017c478bd9Sstevel@tonic-gate char *a2; 2027c478bd9Sstevel@tonic-gate char link[PATH_MAX]; 2037c478bd9Sstevel@tonic-gate char *addr = di_bus_addr(node); 2047c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 2057c478bd9Sstevel@tonic-gate 20645916cd2Sjpk if (system_labeled) 20745916cd2Sjpk flags = DA_ADD|DA_FLOPPY; 20845916cd2Sjpk 2097c478bd9Sstevel@tonic-gate if (strcmp(addr, "0,0") == 0) { 2107c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 21145916cd2Sjpk (void) devfsadm_mklink("diskette", node, minor, flags); 2127c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 21345916cd2Sjpk (void) devfsadm_mklink("rdiskette", node, minor, flags); 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate if (addr[0] == '0') { 2197c478bd9Sstevel@tonic-gate if ((a2 = strchr(addr, ',')) != NULL) { 2207c478bd9Sstevel@tonic-gate a2++; 2217c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 2227c478bd9Sstevel@tonic-gate (void) strcpy(link, "diskette"); 2237c478bd9Sstevel@tonic-gate (void) strcat(link, a2); 22445916cd2Sjpk (void) devfsadm_mklink(link, node, minor, 22545916cd2Sjpk flags); 2267c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 2277c478bd9Sstevel@tonic-gate (void) strcpy(link, "rdiskette"); 2287c478bd9Sstevel@tonic-gate (void) strcat(link, a2); 22945916cd2Sjpk (void) devfsadm_mklink(link, node, minor, 23045916cd2Sjpk flags); 2317c478bd9Sstevel@tonic-gate } 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate /* 2397c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,3bc lp0 2407c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,378 lp1 2417c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,278 lp2 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate static int 2447c478bd9Sstevel@tonic-gate lp(di_minor_t minor, di_node_t node) 2457c478bd9Sstevel@tonic-gate { 2467c478bd9Sstevel@tonic-gate char *addr = di_bus_addr(node); 2477c478bd9Sstevel@tonic-gate char *buf; 2487c478bd9Sstevel@tonic-gate char path[PATH_MAX + 1]; 2497c478bd9Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate if (strcmp(addr, "1,3bc") == 0) { 2527c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp0", node, minor, 0); 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate } else if (strcmp(addr, "1,378") == 0) { 2557c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp1", node, minor, 0); 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate } else if (strcmp(addr, "1,278") == 0) { 2587c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp2", node, minor, 0); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) { 2627c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) { 2667c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", 2707c478bd9Sstevel@tonic-gate buf, di_minor_name(minor)); 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate di_devfs_path_free(buf); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 2757c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf); 2797c478bd9Sstevel@tonic-gate free(buf); 2807c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0); 2817c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate /* 2857c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=a tty00 2867c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=b tty01 2877c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=c tty02 2887c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=d tty03 2897c478bd9Sstevel@tonic-gate */ 2907c478bd9Sstevel@tonic-gate static int 2917c478bd9Sstevel@tonic-gate serial(di_minor_t minor, di_node_t node) 2927c478bd9Sstevel@tonic-gate { 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 2957c478bd9Sstevel@tonic-gate char link[PATH_MAX]; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate (void) strcpy(link, "tty"); 2987c478bd9Sstevel@tonic-gate (void) strcat(link, mn); 2997c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate if (strcmp(mn, "a") == 0) { 3027c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty00", node, minor, 0); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "b") == 0) { 3057c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty01", node, minor, 0); 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c") == 0) { 3087c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty02", node, minor, 0); 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "d") == 0) { 3117c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty03", node, minor, 0); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate /* 3177c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=a,cu ttyd0 3187c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=b,cu ttyd1 3197c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=c,cu ttyd2 3207c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=d,cu ttyd3 3217c478bd9Sstevel@tonic-gate */ 3227c478bd9Sstevel@tonic-gate static int 3237c478bd9Sstevel@tonic-gate serial_dialout(di_minor_t minor, di_node_t node) 3247c478bd9Sstevel@tonic-gate { 3257c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate if (strcmp(mn, "a,cu") == 0) { 3287c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd0", node, minor, 0); 3297c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua0", node, minor, 0); 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "b,cu") == 0) { 3327c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd1", node, minor, 0); 3337c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua1", node, minor, 0); 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,cu") == 0) { 3367c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd2", node, minor, 0); 3377c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua2", node, minor, 0); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "d,cu") == 0) { 3407c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd3", node, minor, 0); 3417c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua3", node, minor, 0); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate static int 3477c478bd9Sstevel@tonic-gate kdmouse(di_minor_t minor, di_node_t node) 3487c478bd9Sstevel@tonic-gate { 3497c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("kdmouse", node, minor, 0); 3507c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate static int 354*989f2807SJerry Jelinek ipmi(di_minor_t minor, di_node_t node) 3557c478bd9Sstevel@tonic-gate { 356*989f2807SJerry Jelinek /* 357*989f2807SJerry Jelinek * Follow convention from other systems, and include an instance#, 358*989f2807SJerry Jelinek * even though there will only be one. 359*989f2807SJerry Jelinek */ 360*989f2807SJerry Jelinek (void) devfsadm_mklink("ipmi0", node, minor, 0); 3617c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3627c478bd9Sstevel@tonic-gate } 36384ab085aSmws 36484ab085aSmws static int 36584ab085aSmws smbios(di_minor_t minor, di_node_t node) 36684ab085aSmws { 36784ab085aSmws (void) devfsadm_mklink("smbios", node, minor, 0); 36884ab085aSmws return (DEVFSADM_CONTINUE); 36984ab085aSmws } 37084ab085aSmws 3717c478bd9Sstevel@tonic-gate static int 3727c478bd9Sstevel@tonic-gate agp_process(di_minor_t minor, di_node_t node) 3737c478bd9Sstevel@tonic-gate { 3747c478bd9Sstevel@tonic-gate char *minor_nm, *drv_nm; 3757c478bd9Sstevel@tonic-gate char *devfspath; 3767c478bd9Sstevel@tonic-gate char *I_path, *p_path, *buf; 3777c478bd9Sstevel@tonic-gate char *name = (char *)NULL; 3787c478bd9Sstevel@tonic-gate int i, index; 3797c478bd9Sstevel@tonic-gate devfsadm_enumerate_t rules[1]; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate minor_nm = di_minor_name(minor); 3827c478bd9Sstevel@tonic-gate drv_nm = di_driver_name(node); 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate if ((minor_nm == NULL) || (drv_nm == NULL)) { 3857c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n", 3892449e17fSsherrym minor_nm, di_node_name(node)); 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate devfspath = di_devfs_path(node); 3927c478bd9Sstevel@tonic-gate if (devfspath == NULL) { 3937c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n"); 3947c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate I_path = (char *)malloc(PATH_MAX); 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate if (I_path == NULL) { 4007c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 4017c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 4027c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate p_path = (char *)malloc(PATH_MAX); 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate if (p_path == NULL) { 4087c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 4097c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 4107c478bd9Sstevel@tonic-gate free(I_path); 4117c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4127c478bd9Sstevel@tonic-gate } 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate (void) strlcpy(p_path, devfspath, PATH_MAX); 4157c478bd9Sstevel@tonic-gate (void) strlcat(p_path, ":", PATH_MAX); 4167c478bd9Sstevel@tonic-gate (void) strlcat(p_path, minor_nm, PATH_MAX); 4177c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: path %s\n", p_path); 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate for (i = 0; ; i++) { 4227c478bd9Sstevel@tonic-gate if ((driver_name_table[i].driver_name == NULL) || 4237c478bd9Sstevel@tonic-gate (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) { 4247c478bd9Sstevel@tonic-gate index = driver_name_table[i].index; 4257c478bd9Sstevel@tonic-gate break; 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate } 4287c478bd9Sstevel@tonic-gate switch (index) { 4297c478bd9Sstevel@tonic-gate case DRIVER_AGPPSEUDO: 4307c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4312449e17fSsherrym "agp_process: psdeudo driver name\n"); 4327c478bd9Sstevel@tonic-gate name = "agpgart"; 4337c478bd9Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "%s", name); 4347c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4357c478bd9Sstevel@tonic-gate "mklink %s -> %s\n", I_path, p_path); 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate free(I_path); 4407c478bd9Sstevel@tonic-gate free(p_path); 4417c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4427c478bd9Sstevel@tonic-gate case DRIVER_AGPTARGET: 4437c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4442449e17fSsherrym "agp_process: target driver name\n"); 4457c478bd9Sstevel@tonic-gate rules[0] = agptarget_rules[0]; 4467c478bd9Sstevel@tonic-gate name = "agptarget"; 4477c478bd9Sstevel@tonic-gate break; 4487c478bd9Sstevel@tonic-gate case DRIVER_CPUGART: 4497c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4502449e17fSsherrym "agp_process: cpugart driver name\n"); 4517c478bd9Sstevel@tonic-gate rules[0] = cpugart_rules[0]; 4527c478bd9Sstevel@tonic-gate name = "cpugart"; 4537c478bd9Sstevel@tonic-gate break; 454e57b9183Scg case DRIVER_AGPMASTER_DRM_I915: 455e57b9183Scg case DRIVER_AGPMASTER_DRM_RADEON: 45660405de4Skz case DRIVER_AGPMASTER_VGATEXT: 4577c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4582449e17fSsherrym "agp_process: agpmaster driver name\n"); 4597c478bd9Sstevel@tonic-gate rules[0] = agpmaster_rules[0]; 4607c478bd9Sstevel@tonic-gate name = "agpmaster"; 4617c478bd9Sstevel@tonic-gate break; 4627c478bd9Sstevel@tonic-gate case DRIVER_UNKNOWN: 4637c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4642449e17fSsherrym "agp_process: unknown driver name=%s\n", drv_nm); 4657c478bd9Sstevel@tonic-gate free(I_path); 4667c478bd9Sstevel@tonic-gate free(p_path); 4677c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { 4717c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: exit/coninue\n"); 4727c478bd9Sstevel@tonic-gate free(I_path); 4737c478bd9Sstevel@tonic-gate free(p_path); 4747c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf); 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n", 4812449e17fSsherrym p_path, buf); 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate free(buf); 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate free(p_path); 4907c478bd9Sstevel@tonic-gate free(I_path); 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4937c478bd9Sstevel@tonic-gate } 4947aec1d6eScindi 49560405de4Skz static int 49660405de4Skz drm_node(di_minor_t minor, di_node_t node) 49760405de4Skz { 49860405de4Skz char *minor_nm, *drv_nm; 49960405de4Skz char *devfspath; 50060405de4Skz char *I_path, *p_path, *buf; 50160405de4Skz char *name = "card"; 50260405de4Skz 50360405de4Skz devfsadm_enumerate_t drm_rules[1] = {"^dri$/^card([0-9]+)$", 1, 50460405de4Skz MATCH_ALL }; 50560405de4Skz 50660405de4Skz 50760405de4Skz minor_nm = di_minor_name(minor); 50860405de4Skz drv_nm = di_driver_name(node); 50960405de4Skz if ((minor_nm == NULL) || (drv_nm == NULL)) { 51060405de4Skz return (DEVFSADM_CONTINUE); 51160405de4Skz } 51260405de4Skz 51360405de4Skz devfsadm_print(debug_mid, "drm_node: minor=%s node=%s type=%s\n", 51460405de4Skz minor_nm, di_node_name(node), di_minor_nodetype(minor)); 51560405de4Skz 51660405de4Skz devfspath = di_devfs_path(node); 51760405de4Skz if (devfspath == NULL) { 51860405de4Skz devfsadm_print(debug_mid, "drm_node: devfspath is NULL\n"); 51960405de4Skz return (DEVFSADM_CONTINUE); 52060405de4Skz } 52160405de4Skz 52260405de4Skz I_path = (char *)malloc(PATH_MAX); 52360405de4Skz 52460405de4Skz if (I_path == NULL) { 52560405de4Skz di_devfs_path_free(devfspath); 52660405de4Skz devfsadm_print(debug_mid, "drm_node: malloc failed\n"); 52760405de4Skz return (DEVFSADM_CONTINUE); 52860405de4Skz } 52960405de4Skz 53060405de4Skz p_path = (char *)malloc(PATH_MAX); 53160405de4Skz 53260405de4Skz if (p_path == NULL) { 53360405de4Skz devfsadm_print(debug_mid, "drm_node: malloc failed\n"); 53460405de4Skz di_devfs_path_free(devfspath); 53560405de4Skz free(I_path); 53660405de4Skz return (DEVFSADM_CONTINUE); 53760405de4Skz } 53860405de4Skz 53960405de4Skz (void) strlcpy(p_path, devfspath, PATH_MAX); 54060405de4Skz (void) strlcat(p_path, ":", PATH_MAX); 54160405de4Skz (void) strlcat(p_path, minor_nm, PATH_MAX); 54260405de4Skz di_devfs_path_free(devfspath); 54360405de4Skz 54460405de4Skz devfsadm_print(debug_mid, "drm_node: p_path %s\n", p_path); 54560405de4Skz 54660405de4Skz if (devfsadm_enumerate_int(p_path, 0, &buf, drm_rules, 1)) { 54760405de4Skz free(p_path); 54860405de4Skz devfsadm_print(debug_mid, "drm_node: exit/coninue\n"); 54960405de4Skz return (DEVFSADM_CONTINUE); 55060405de4Skz } 55160405de4Skz (void) snprintf(I_path, PATH_MAX, "dri/%s%s", name, buf); 55260405de4Skz 55360405de4Skz devfsadm_print(debug_mid, "drm_node: p_path=%s buf=%s\n", 5542449e17fSsherrym p_path, buf); 55560405de4Skz 55660405de4Skz free(buf); 55760405de4Skz 55860405de4Skz devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 55960405de4Skz (void) devfsadm_mklink(I_path, node, minor, 0); 56060405de4Skz 56160405de4Skz free(p_path); 56260405de4Skz free(I_path); 56360405de4Skz 56460405de4Skz return (0); 56560405de4Skz } 56660405de4Skz 5677aec1d6eScindi /* 5687aec1d6eScindi * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd 5697aec1d6eScindi */ 5707aec1d6eScindi static int 5717aec1d6eScindi mc_node(di_minor_t minor, di_node_t node) 5727aec1d6eScindi { 5737aec1d6eScindi const char *minorname = di_minor_name(minor); 5747aec1d6eScindi const char *busaddr = di_bus_addr(node); 5757aec1d6eScindi char linkpath[PATH_MAX]; 5767aec1d6eScindi int unitaddr; 5777aec1d6eScindi char *c; 5787aec1d6eScindi 5797aec1d6eScindi if (minorname == NULL || busaddr == NULL) 5807aec1d6eScindi return (DEVFSADM_CONTINUE); 5817aec1d6eScindi 5827aec1d6eScindi errno = 0; 5837aec1d6eScindi unitaddr = strtol(busaddr, &c, 16); 5847aec1d6eScindi 58520c794b3Sgavinm if (errno != 0) 5867aec1d6eScindi return (DEVFSADM_CONTINUE); 5877aec1d6eScindi 58820c794b3Sgavinm if (unitaddr == 0) { 58920c794b3Sgavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc"); 59020c794b3Sgavinm } else if (unitaddr >= MC_AMD_DEV_OFFSET) { 59120c794b3Sgavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 59220c794b3Sgavinm unitaddr - MC_AMD_DEV_OFFSET); 59320c794b3Sgavinm } else { 594e3d60c9bSAdrian Frost (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 595e3d60c9bSAdrian Frost minor->dev_minor); 59620c794b3Sgavinm } 5977aec1d6eScindi (void) devfsadm_mklink(linkpath, node, minor, 0); 5987aec1d6eScindi return (DEVFSADM_CONTINUE); 5997aec1d6eScindi } 600ae115bc7Smrj 601ae115bc7Smrj /* 602ae115bc7Smrj * Creates \M0 devlink for xsvc node 603ae115bc7Smrj */ 604ae115bc7Smrj static int 605ae115bc7Smrj xsvc(di_minor_t minor, di_node_t node) 606ae115bc7Smrj { 607ae115bc7Smrj char *mn; 608ae115bc7Smrj 609ae115bc7Smrj if (strcmp(di_node_name(node), "xsvc") != 0) 610ae115bc7Smrj return (DEVFSADM_CONTINUE); 611ae115bc7Smrj 612ae115bc7Smrj mn = di_minor_name(minor); 613ae115bc7Smrj if (mn == NULL) 614ae115bc7Smrj return (DEVFSADM_CONTINUE); 615ae115bc7Smrj 616ae115bc7Smrj (void) devfsadm_mklink(mn, node, minor, 0); 617ae115bc7Smrj return (DEVFSADM_CONTINUE); 618ae115bc7Smrj } 6192449e17fSsherrym 6202df1fe9cSrandyf /* 6212df1fe9cSrandyf * Creates \M0 devlink for srn device 6222df1fe9cSrandyf */ 6232df1fe9cSrandyf static int 6242df1fe9cSrandyf srn(di_minor_t minor, di_node_t node) 6252df1fe9cSrandyf { 6262df1fe9cSrandyf char *mn; 6272df1fe9cSrandyf 6282df1fe9cSrandyf if (strcmp(di_node_name(node), "srn") != 0) 6292df1fe9cSrandyf return (DEVFSADM_CONTINUE); 6302df1fe9cSrandyf 6312df1fe9cSrandyf mn = di_minor_name(minor); 6322df1fe9cSrandyf if (mn == NULL) 6332df1fe9cSrandyf return (DEVFSADM_CONTINUE); 6342df1fe9cSrandyf 6352df1fe9cSrandyf (void) devfsadm_mklink(mn, node, minor, 0); 6362df1fe9cSrandyf return (DEVFSADM_CONTINUE); 6372df1fe9cSrandyf } 6382df1fe9cSrandyf 6392449e17fSsherrym /* 6402449e17fSsherrym * /dev/ucode -> /devices/pseudo/ucode@0:ucode 6412449e17fSsherrym */ 6422449e17fSsherrym static int 6432449e17fSsherrym ucode(di_minor_t minor, di_node_t node) 6442449e17fSsherrym { 6452449e17fSsherrym (void) devfsadm_mklink("ucode", node, minor, 0); 6462449e17fSsherrym return (DEVFSADM_CONTINUE); 6472449e17fSsherrym } 648617e2443SMark Logan 649617e2443SMark Logan static int 650617e2443SMark Logan heci(di_minor_t minor, di_node_t node) 651617e2443SMark Logan { 652617e2443SMark Logan if (strcmp(di_minor_name(minor), "AMT") == 0) { 653617e2443SMark Logan (void) devfsadm_mklink("heci", node, minor, 0); 654617e2443SMark Logan } 655617e2443SMark Logan return (DEVFSADM_CONTINUE); 656617e2443SMark Logan } 657