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 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*7aec1d6eScindi * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <regex.h> 307c478bd9Sstevel@tonic-gate #include <devfsadm.h> 317c478bd9Sstevel@tonic-gate #include <stdio.h> 327c478bd9Sstevel@tonic-gate #include <strings.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <limits.h> 357c478bd9Sstevel@tonic-gate #include <ctype.h> 36*7aec1d6eScindi #include <sys/mc.h> 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate static int lp(di_minor_t minor, di_node_t node); 397c478bd9Sstevel@tonic-gate static int serial_dialout(di_minor_t minor, di_node_t node); 407c478bd9Sstevel@tonic-gate static int serial(di_minor_t minor, di_node_t node); 417c478bd9Sstevel@tonic-gate static int diskette(di_minor_t minor, di_node_t node); 427c478bd9Sstevel@tonic-gate static int vt00(di_minor_t minor, di_node_t node); 437c478bd9Sstevel@tonic-gate static int kdmouse(di_minor_t minor, di_node_t node); 447c478bd9Sstevel@tonic-gate static int bmc(di_minor_t minor, di_node_t node); 4584ab085aSmws static int smbios(di_minor_t minor, di_node_t node); 467c478bd9Sstevel@tonic-gate static int agp_process(di_minor_t minor, di_node_t node); 47*7aec1d6eScindi static int mc_node(di_minor_t minor, di_node_t node); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = { 507c478bd9Sstevel@tonic-gate { "vt00", "ddi_display", NULL, 517c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, vt00 527c478bd9Sstevel@tonic-gate }, 537c478bd9Sstevel@tonic-gate { "mouse", "ddi_mouse", "mouse8042", 547c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse 557c478bd9Sstevel@tonic-gate }, 567c478bd9Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "bmc", 577c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc, 587c478bd9Sstevel@tonic-gate }, 5984ab085aSmws { "pseudo", "ddi_pseudo", "smbios", 6084ab085aSmws TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios, 6184ab085aSmws }, 627c478bd9Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL, 637c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette 647c478bd9Sstevel@tonic-gate }, 657c478bd9Sstevel@tonic-gate { "parallel", "ddi_printer", NULL, 667c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, lp 677c478bd9Sstevel@tonic-gate }, 687c478bd9Sstevel@tonic-gate { "serial", "ddi_serial:mb", NULL, 697c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial 707c478bd9Sstevel@tonic-gate }, 717c478bd9Sstevel@tonic-gate { "serial", "ddi_serial:dialout,mb", NULL, 727c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial_dialout 737c478bd9Sstevel@tonic-gate }, 74*7aec1d6eScindi { "agp", "ddi_agp:pseudo", NULL, 757c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 767c478bd9Sstevel@tonic-gate }, 77*7aec1d6eScindi { "agp", "ddi_agp:target", NULL, 787c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 797c478bd9Sstevel@tonic-gate }, 80*7aec1d6eScindi { "agp", "ddi_agp:cpugart", NULL, 817c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 827c478bd9Sstevel@tonic-gate }, 83*7aec1d6eScindi { "agp", "ddi_agp:master", NULL, 847c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 85*7aec1d6eScindi }, 86*7aec1d6eScindi { "memory-controller", "ddi_mem_ctrl", NULL, 87*7aec1d6eScindi TYPE_EXACT, ILEVEL_0, mc_node 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate }; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt); 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate static char *debug_mid = "agp_mid"; 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate typedef enum { 967c478bd9Sstevel@tonic-gate DRIVER_AGPPSEUDO = 0, 977c478bd9Sstevel@tonic-gate DRIVER_AGPTARGET, 987c478bd9Sstevel@tonic-gate DRIVER_CPUGART, 997c478bd9Sstevel@tonic-gate DRIVER_AGPMASTER, 1007c478bd9Sstevel@tonic-gate DRIVER_UNKNOWN 1017c478bd9Sstevel@tonic-gate } driver_defs_t; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate typedef struct { 1047c478bd9Sstevel@tonic-gate char *driver_name; 1057c478bd9Sstevel@tonic-gate int index; 1067c478bd9Sstevel@tonic-gate } driver_name_table_entry_t; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate static driver_name_table_entry_t driver_name_table[] = { 1097c478bd9Sstevel@tonic-gate { "agpgart", DRIVER_AGPPSEUDO }, 1107c478bd9Sstevel@tonic-gate { "agptarget", DRIVER_AGPTARGET }, 1117c478bd9Sstevel@tonic-gate { "amd64_gart", DRIVER_CPUGART }, 1127c478bd9Sstevel@tonic-gate { "vgatext", DRIVER_AGPMASTER }, 1137c478bd9Sstevel@tonic-gate { NULL, DRIVER_UNKNOWN } 1147c478bd9Sstevel@tonic-gate }; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t agptarget_rules[1] = 1177c478bd9Sstevel@tonic-gate { "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL }; 1187c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t cpugart_rules[1] = 1197c478bd9Sstevel@tonic-gate { "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL }; 1207c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t agpmaster_rules[1] = 1217c478bd9Sstevel@tonic-gate { "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL }; 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate static devfsadm_remove_t misc_remove_cbt[] = { 1247c478bd9Sstevel@tonic-gate { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS, 1257c478bd9Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate }; 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate /* 1327c478bd9Sstevel@tonic-gate * Handles minor node type "ddi_display", in addition to generic processing 1337c478bd9Sstevel@tonic-gate * done by display(). 1347c478bd9Sstevel@tonic-gate * 1357c478bd9Sstevel@tonic-gate * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate /* ARGSUSED */ 1387c478bd9Sstevel@tonic-gate int 1397c478bd9Sstevel@tonic-gate vt00(di_minor_t minor, di_node_t node) 1407c478bd9Sstevel@tonic-gate { 1417c478bd9Sstevel@tonic-gate (void) devfsadm_secondary_link("vt00", "fb", 0); 1427c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c diskette 1477c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette 1487c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c diskette\A2 1497c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2 1507c478bd9Sstevel@tonic-gate */ 1517c478bd9Sstevel@tonic-gate static int 1527c478bd9Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node) 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate char *a2; 1557c478bd9Sstevel@tonic-gate char link[PATH_MAX]; 1567c478bd9Sstevel@tonic-gate char *addr = di_bus_addr(node); 1577c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate if (strcmp(addr, "0,0") == 0) { 1607c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 1617c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("diskette", node, minor, 0); 1627c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 1637c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("rdiskette", node, minor, 0); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate } 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate if (addr[0] == '0') { 1697c478bd9Sstevel@tonic-gate if ((a2 = strchr(addr, ',')) != NULL) { 1707c478bd9Sstevel@tonic-gate a2++; 1717c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 1727c478bd9Sstevel@tonic-gate (void) strcpy(link, "diskette"); 1737c478bd9Sstevel@tonic-gate (void) strcat(link, a2); 1747c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 1757c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 1767c478bd9Sstevel@tonic-gate (void) strcpy(link, "rdiskette"); 1777c478bd9Sstevel@tonic-gate (void) strcat(link, a2); 1787c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate /* 1877c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,3bc lp0 1887c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,378 lp1 1897c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,278 lp2 1907c478bd9Sstevel@tonic-gate */ 1917c478bd9Sstevel@tonic-gate static int 1927c478bd9Sstevel@tonic-gate lp(di_minor_t minor, di_node_t node) 1937c478bd9Sstevel@tonic-gate { 1947c478bd9Sstevel@tonic-gate char *addr = di_bus_addr(node); 1957c478bd9Sstevel@tonic-gate char *buf; 1967c478bd9Sstevel@tonic-gate char path[PATH_MAX + 1]; 1977c478bd9Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate if (strcmp(addr, "1,3bc") == 0) { 2007c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp0", node, minor, 0); 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate } else if (strcmp(addr, "1,378") == 0) { 2037c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp1", node, minor, 0); 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate } else if (strcmp(addr, "1,278") == 0) { 2067c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp2", node, minor, 0); 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) { 2107c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) { 2147c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate 2177c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", 2187c478bd9Sstevel@tonic-gate buf, di_minor_name(minor)); 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate di_devfs_path_free(buf); 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 2237c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf); 2277c478bd9Sstevel@tonic-gate free(buf); 2287c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0); 2297c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate /* 2337c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=a tty00 2347c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=b tty01 2357c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=c tty02 2367c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=d tty03 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate static int 2397c478bd9Sstevel@tonic-gate serial(di_minor_t minor, di_node_t node) 2407c478bd9Sstevel@tonic-gate { 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 2437c478bd9Sstevel@tonic-gate char link[PATH_MAX]; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate (void) strcpy(link, "tty"); 2467c478bd9Sstevel@tonic-gate (void) strcat(link, mn); 2477c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate if (strcmp(mn, "a") == 0) { 2507c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty00", node, minor, 0); 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "b") == 0) { 2537c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty01", node, minor, 0); 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c") == 0) { 2567c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty02", node, minor, 0); 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "d") == 0) { 2597c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty03", node, minor, 0); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=a,cu ttyd0 2667c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=b,cu ttyd1 2677c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=c,cu ttyd2 2687c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=d,cu ttyd3 2697c478bd9Sstevel@tonic-gate */ 2707c478bd9Sstevel@tonic-gate static int 2717c478bd9Sstevel@tonic-gate serial_dialout(di_minor_t minor, di_node_t node) 2727c478bd9Sstevel@tonic-gate { 2737c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 2747c478bd9Sstevel@tonic-gate 2757c478bd9Sstevel@tonic-gate if (strcmp(mn, "a,cu") == 0) { 2767c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd0", node, minor, 0); 2777c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua0", node, minor, 0); 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "b,cu") == 0) { 2807c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd1", node, minor, 0); 2817c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua1", node, minor, 0); 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,cu") == 0) { 2847c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd2", node, minor, 0); 2857c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua2", node, minor, 0); 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "d,cu") == 0) { 2887c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd3", node, minor, 0); 2897c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua3", node, minor, 0); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate static int 2957c478bd9Sstevel@tonic-gate kdmouse(di_minor_t minor, di_node_t node) 2967c478bd9Sstevel@tonic-gate { 2977c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("kdmouse", node, minor, 0); 2987c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2997c478bd9Sstevel@tonic-gate } 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate static int 3027c478bd9Sstevel@tonic-gate bmc(di_minor_t minor, di_node_t node) 3037c478bd9Sstevel@tonic-gate { 3047c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("bmc", node, minor, 0); 3057c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3067c478bd9Sstevel@tonic-gate } 30784ab085aSmws 30884ab085aSmws static int 30984ab085aSmws smbios(di_minor_t minor, di_node_t node) 31084ab085aSmws { 31184ab085aSmws (void) devfsadm_mklink("smbios", node, minor, 0); 31284ab085aSmws return (DEVFSADM_CONTINUE); 31384ab085aSmws } 31484ab085aSmws 3157c478bd9Sstevel@tonic-gate static int 3167c478bd9Sstevel@tonic-gate agp_process(di_minor_t minor, di_node_t node) 3177c478bd9Sstevel@tonic-gate { 3187c478bd9Sstevel@tonic-gate char *minor_nm, *drv_nm; 3197c478bd9Sstevel@tonic-gate char *devfspath; 3207c478bd9Sstevel@tonic-gate char *I_path, *p_path, *buf; 3217c478bd9Sstevel@tonic-gate char *name = (char *)NULL; 3227c478bd9Sstevel@tonic-gate int i, index; 3237c478bd9Sstevel@tonic-gate devfsadm_enumerate_t rules[1]; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate minor_nm = di_minor_name(minor); 3267c478bd9Sstevel@tonic-gate drv_nm = di_driver_name(node); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if ((minor_nm == NULL) || (drv_nm == NULL)) { 3297c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n", 3337c478bd9Sstevel@tonic-gate minor_nm, di_node_name(node)); 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate devfspath = di_devfs_path(node); 3367c478bd9Sstevel@tonic-gate if (devfspath == NULL) { 3377c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n"); 3387c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate I_path = (char *)malloc(PATH_MAX); 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate if (I_path == NULL) { 3447c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 3457c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 3467c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate p_path = (char *)malloc(PATH_MAX); 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate if (p_path == NULL) { 3527c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 3537c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 3547c478bd9Sstevel@tonic-gate free(I_path); 3557c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate (void) strlcpy(p_path, devfspath, PATH_MAX); 3597c478bd9Sstevel@tonic-gate (void) strlcat(p_path, ":", PATH_MAX); 3607c478bd9Sstevel@tonic-gate (void) strlcat(p_path, minor_nm, PATH_MAX); 3617c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: path %s\n", p_path); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate for (i = 0; ; i++) { 3667c478bd9Sstevel@tonic-gate if ((driver_name_table[i].driver_name == NULL) || 3677c478bd9Sstevel@tonic-gate (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) { 3687c478bd9Sstevel@tonic-gate index = driver_name_table[i].index; 3697c478bd9Sstevel@tonic-gate break; 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate } 3727c478bd9Sstevel@tonic-gate switch (index) { 3737c478bd9Sstevel@tonic-gate case DRIVER_AGPPSEUDO: 3747c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 3757c478bd9Sstevel@tonic-gate "agp_process: psdeudo driver name\n"); 3767c478bd9Sstevel@tonic-gate name = "agpgart"; 3777c478bd9Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "%s", name); 3787c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 3797c478bd9Sstevel@tonic-gate "mklink %s -> %s\n", I_path, p_path); 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate free(I_path); 3847c478bd9Sstevel@tonic-gate free(p_path); 3857c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3867c478bd9Sstevel@tonic-gate case DRIVER_AGPTARGET: 3877c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 3887c478bd9Sstevel@tonic-gate "agp_process: target driver name\n"); 3897c478bd9Sstevel@tonic-gate rules[0] = agptarget_rules[0]; 3907c478bd9Sstevel@tonic-gate name = "agptarget"; 3917c478bd9Sstevel@tonic-gate break; 3927c478bd9Sstevel@tonic-gate case DRIVER_CPUGART: 3937c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 3947c478bd9Sstevel@tonic-gate "agp_process: cpugart driver name\n"); 3957c478bd9Sstevel@tonic-gate rules[0] = cpugart_rules[0]; 3967c478bd9Sstevel@tonic-gate name = "cpugart"; 3977c478bd9Sstevel@tonic-gate break; 3987c478bd9Sstevel@tonic-gate case DRIVER_AGPMASTER: 3997c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4007c478bd9Sstevel@tonic-gate "agp_process: agpmaster driver name\n"); 4017c478bd9Sstevel@tonic-gate rules[0] = agpmaster_rules[0]; 4027c478bd9Sstevel@tonic-gate name = "agpmaster"; 4037c478bd9Sstevel@tonic-gate break; 4047c478bd9Sstevel@tonic-gate case DRIVER_UNKNOWN: 4057c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, 4067c478bd9Sstevel@tonic-gate "agp_process: unknown driver name=%s\n", drv_nm); 4077c478bd9Sstevel@tonic-gate free(I_path); 4087c478bd9Sstevel@tonic-gate free(p_path); 4097c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4107c478bd9Sstevel@tonic-gate } 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { 4137c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: exit/coninue\n"); 4147c478bd9Sstevel@tonic-gate free(I_path); 4157c478bd9Sstevel@tonic-gate free(p_path); 4167c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf); 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n", 4237c478bd9Sstevel@tonic-gate p_path, buf); 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate free(buf); 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate free(p_path); 4327c478bd9Sstevel@tonic-gate free(I_path); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4357c478bd9Sstevel@tonic-gate } 436*7aec1d6eScindi 437*7aec1d6eScindi /* 438*7aec1d6eScindi * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd 439*7aec1d6eScindi */ 440*7aec1d6eScindi static int 441*7aec1d6eScindi mc_node(di_minor_t minor, di_node_t node) 442*7aec1d6eScindi { 443*7aec1d6eScindi const char *minorname = di_minor_name(minor); 444*7aec1d6eScindi const char *busaddr = di_bus_addr(node); 445*7aec1d6eScindi char linkpath[PATH_MAX]; 446*7aec1d6eScindi int unitaddr; 447*7aec1d6eScindi char *c; 448*7aec1d6eScindi 449*7aec1d6eScindi if (minorname == NULL || busaddr == NULL) 450*7aec1d6eScindi return (DEVFSADM_CONTINUE); 451*7aec1d6eScindi 452*7aec1d6eScindi errno = 0; 453*7aec1d6eScindi unitaddr = strtol(busaddr, &c, 16); 454*7aec1d6eScindi 455*7aec1d6eScindi if (errno != 0 || unitaddr < MC_AMD_DEV_OFFSET) 456*7aec1d6eScindi return (DEVFSADM_CONTINUE); 457*7aec1d6eScindi 458*7aec1d6eScindi (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 459*7aec1d6eScindi unitaddr - MC_AMD_DEV_OFFSET); 460*7aec1d6eScindi (void) devfsadm_mklink(linkpath, node, minor, 0); 461*7aec1d6eScindi return (DEVFSADM_CONTINUE); 462*7aec1d6eScindi } 463