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 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*1414Scindi * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <regex.h> 300Sstevel@tonic-gate #include <devfsadm.h> 310Sstevel@tonic-gate #include <stdio.h> 320Sstevel@tonic-gate #include <strings.h> 330Sstevel@tonic-gate #include <stdlib.h> 340Sstevel@tonic-gate #include <limits.h> 350Sstevel@tonic-gate #include <ctype.h> 36*1414Scindi #include <sys/mc.h> 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); 47*1414Scindi static int mc_node(di_minor_t minor, di_node_t node); 480Sstevel@tonic-gate 490Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = { 500Sstevel@tonic-gate { "vt00", "ddi_display", NULL, 510Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, vt00 520Sstevel@tonic-gate }, 530Sstevel@tonic-gate { "mouse", "ddi_mouse", "mouse8042", 540Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse 550Sstevel@tonic-gate }, 560Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "bmc", 570Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc, 580Sstevel@tonic-gate }, 59437Smws { "pseudo", "ddi_pseudo", "smbios", 60437Smws TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios, 61437Smws }, 620Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL, 630Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette 640Sstevel@tonic-gate }, 650Sstevel@tonic-gate { "parallel", "ddi_printer", NULL, 660Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, lp 670Sstevel@tonic-gate }, 680Sstevel@tonic-gate { "serial", "ddi_serial:mb", NULL, 690Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial 700Sstevel@tonic-gate }, 710Sstevel@tonic-gate { "serial", "ddi_serial:dialout,mb", NULL, 720Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial_dialout 730Sstevel@tonic-gate }, 74*1414Scindi { "agp", "ddi_agp:pseudo", NULL, 750Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 760Sstevel@tonic-gate }, 77*1414Scindi { "agp", "ddi_agp:target", NULL, 780Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 790Sstevel@tonic-gate }, 80*1414Scindi { "agp", "ddi_agp:cpugart", NULL, 810Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 820Sstevel@tonic-gate }, 83*1414Scindi { "agp", "ddi_agp:master", NULL, 840Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, agp_process 85*1414Scindi }, 86*1414Scindi { "memory-controller", "ddi_mem_ctrl", NULL, 87*1414Scindi TYPE_EXACT, ILEVEL_0, mc_node 880Sstevel@tonic-gate } 890Sstevel@tonic-gate }; 900Sstevel@tonic-gate 910Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt); 920Sstevel@tonic-gate 930Sstevel@tonic-gate static char *debug_mid = "agp_mid"; 940Sstevel@tonic-gate 950Sstevel@tonic-gate typedef enum { 960Sstevel@tonic-gate DRIVER_AGPPSEUDO = 0, 970Sstevel@tonic-gate DRIVER_AGPTARGET, 980Sstevel@tonic-gate DRIVER_CPUGART, 990Sstevel@tonic-gate DRIVER_AGPMASTER, 1000Sstevel@tonic-gate DRIVER_UNKNOWN 1010Sstevel@tonic-gate } driver_defs_t; 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate typedef struct { 1040Sstevel@tonic-gate char *driver_name; 1050Sstevel@tonic-gate int index; 1060Sstevel@tonic-gate } driver_name_table_entry_t; 1070Sstevel@tonic-gate 1080Sstevel@tonic-gate static driver_name_table_entry_t driver_name_table[] = { 1090Sstevel@tonic-gate { "agpgart", DRIVER_AGPPSEUDO }, 1100Sstevel@tonic-gate { "agptarget", DRIVER_AGPTARGET }, 1110Sstevel@tonic-gate { "amd64_gart", DRIVER_CPUGART }, 1120Sstevel@tonic-gate { "vgatext", DRIVER_AGPMASTER }, 1130Sstevel@tonic-gate { NULL, DRIVER_UNKNOWN } 1140Sstevel@tonic-gate }; 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate static devfsadm_enumerate_t agptarget_rules[1] = 1170Sstevel@tonic-gate { "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL }; 1180Sstevel@tonic-gate static devfsadm_enumerate_t cpugart_rules[1] = 1190Sstevel@tonic-gate { "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL }; 1200Sstevel@tonic-gate static devfsadm_enumerate_t agpmaster_rules[1] = 1210Sstevel@tonic-gate { "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL }; 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate static devfsadm_remove_t misc_remove_cbt[] = { 1240Sstevel@tonic-gate { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS, 1250Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all 1260Sstevel@tonic-gate } 1270Sstevel@tonic-gate }; 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate /* 1320Sstevel@tonic-gate * Handles minor node type "ddi_display", in addition to generic processing 1330Sstevel@tonic-gate * done by display(). 1340Sstevel@tonic-gate * 1350Sstevel@tonic-gate * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility. 1360Sstevel@tonic-gate */ 1370Sstevel@tonic-gate /* ARGSUSED */ 1380Sstevel@tonic-gate int 1390Sstevel@tonic-gate vt00(di_minor_t minor, di_node_t node) 1400Sstevel@tonic-gate { 1410Sstevel@tonic-gate (void) devfsadm_secondary_link("vt00", "fb", 0); 1420Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate /* 1460Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c diskette 1470Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette 1480Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c diskette\A2 1490Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2 1500Sstevel@tonic-gate */ 1510Sstevel@tonic-gate static int 1520Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node) 1530Sstevel@tonic-gate { 1540Sstevel@tonic-gate char *a2; 1550Sstevel@tonic-gate char link[PATH_MAX]; 1560Sstevel@tonic-gate char *addr = di_bus_addr(node); 1570Sstevel@tonic-gate char *mn = di_minor_name(minor); 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate if (strcmp(addr, "0,0") == 0) { 1600Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 1610Sstevel@tonic-gate (void) devfsadm_mklink("diskette", node, minor, 0); 1620Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 1630Sstevel@tonic-gate (void) devfsadm_mklink("rdiskette", node, minor, 0); 1640Sstevel@tonic-gate } 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate } 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate if (addr[0] == '0') { 1690Sstevel@tonic-gate if ((a2 = strchr(addr, ',')) != NULL) { 1700Sstevel@tonic-gate a2++; 1710Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 1720Sstevel@tonic-gate (void) strcpy(link, "diskette"); 1730Sstevel@tonic-gate (void) strcat(link, a2); 1740Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 1750Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 1760Sstevel@tonic-gate (void) strcpy(link, "rdiskette"); 1770Sstevel@tonic-gate (void) strcat(link, a2); 1780Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 1790Sstevel@tonic-gate } 1800Sstevel@tonic-gate } 1810Sstevel@tonic-gate } 1820Sstevel@tonic-gate 1830Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1840Sstevel@tonic-gate } 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate /* 1870Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,3bc lp0 1880Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,378 lp1 1890Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,278 lp2 1900Sstevel@tonic-gate */ 1910Sstevel@tonic-gate static int 1920Sstevel@tonic-gate lp(di_minor_t minor, di_node_t node) 1930Sstevel@tonic-gate { 1940Sstevel@tonic-gate char *addr = di_bus_addr(node); 1950Sstevel@tonic-gate char *buf; 1960Sstevel@tonic-gate char path[PATH_MAX + 1]; 1970Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate if (strcmp(addr, "1,3bc") == 0) { 2000Sstevel@tonic-gate (void) devfsadm_mklink("lp0", node, minor, 0); 2010Sstevel@tonic-gate 2020Sstevel@tonic-gate } else if (strcmp(addr, "1,378") == 0) { 2030Sstevel@tonic-gate (void) devfsadm_mklink("lp1", node, minor, 0); 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate } else if (strcmp(addr, "1,278") == 0) { 2060Sstevel@tonic-gate (void) devfsadm_mklink("lp2", node, minor, 0); 2070Sstevel@tonic-gate } 2080Sstevel@tonic-gate 2090Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) { 2100Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2110Sstevel@tonic-gate } 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) { 2140Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2150Sstevel@tonic-gate } 2160Sstevel@tonic-gate 2170Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", 2180Sstevel@tonic-gate buf, di_minor_name(minor)); 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate di_devfs_path_free(buf); 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 2230Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2240Sstevel@tonic-gate } 2250Sstevel@tonic-gate 2260Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf); 2270Sstevel@tonic-gate free(buf); 2280Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0); 2290Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2300Sstevel@tonic-gate } 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate /* 2330Sstevel@tonic-gate * type=ddi_serial:mb;minor=a tty00 2340Sstevel@tonic-gate * type=ddi_serial:mb;minor=b tty01 2350Sstevel@tonic-gate * type=ddi_serial:mb;minor=c tty02 2360Sstevel@tonic-gate * type=ddi_serial:mb;minor=d tty03 2370Sstevel@tonic-gate */ 2380Sstevel@tonic-gate static int 2390Sstevel@tonic-gate serial(di_minor_t minor, di_node_t node) 2400Sstevel@tonic-gate { 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate char *mn = di_minor_name(minor); 2430Sstevel@tonic-gate char link[PATH_MAX]; 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate (void) strcpy(link, "tty"); 2460Sstevel@tonic-gate (void) strcat(link, mn); 2470Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0); 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate if (strcmp(mn, "a") == 0) { 2500Sstevel@tonic-gate (void) devfsadm_mklink("tty00", node, minor, 0); 2510Sstevel@tonic-gate 2520Sstevel@tonic-gate } else if (strcmp(mn, "b") == 0) { 2530Sstevel@tonic-gate (void) devfsadm_mklink("tty01", node, minor, 0); 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate } else if (strcmp(mn, "c") == 0) { 2560Sstevel@tonic-gate (void) devfsadm_mklink("tty02", node, minor, 0); 2570Sstevel@tonic-gate 2580Sstevel@tonic-gate } else if (strcmp(mn, "d") == 0) { 2590Sstevel@tonic-gate (void) devfsadm_mklink("tty03", node, minor, 0); 2600Sstevel@tonic-gate } 2610Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate /* 2650Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=a,cu ttyd0 2660Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=b,cu ttyd1 2670Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=c,cu ttyd2 2680Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=d,cu ttyd3 2690Sstevel@tonic-gate */ 2700Sstevel@tonic-gate static int 2710Sstevel@tonic-gate serial_dialout(di_minor_t minor, di_node_t node) 2720Sstevel@tonic-gate { 2730Sstevel@tonic-gate char *mn = di_minor_name(minor); 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate if (strcmp(mn, "a,cu") == 0) { 2760Sstevel@tonic-gate (void) devfsadm_mklink("ttyd0", node, minor, 0); 2770Sstevel@tonic-gate (void) devfsadm_mklink("cua0", node, minor, 0); 2780Sstevel@tonic-gate 2790Sstevel@tonic-gate } else if (strcmp(mn, "b,cu") == 0) { 2800Sstevel@tonic-gate (void) devfsadm_mklink("ttyd1", node, minor, 0); 2810Sstevel@tonic-gate (void) devfsadm_mklink("cua1", node, minor, 0); 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate } else if (strcmp(mn, "c,cu") == 0) { 2840Sstevel@tonic-gate (void) devfsadm_mklink("ttyd2", node, minor, 0); 2850Sstevel@tonic-gate (void) devfsadm_mklink("cua2", node, minor, 0); 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate } else if (strcmp(mn, "d,cu") == 0) { 2880Sstevel@tonic-gate (void) devfsadm_mklink("ttyd3", node, minor, 0); 2890Sstevel@tonic-gate (void) devfsadm_mklink("cua3", node, minor, 0); 2900Sstevel@tonic-gate } 2910Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate static int 2950Sstevel@tonic-gate kdmouse(di_minor_t minor, di_node_t node) 2960Sstevel@tonic-gate { 2970Sstevel@tonic-gate (void) devfsadm_mklink("kdmouse", node, minor, 0); 2980Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2990Sstevel@tonic-gate } 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate static int 3020Sstevel@tonic-gate bmc(di_minor_t minor, di_node_t node) 3030Sstevel@tonic-gate { 3040Sstevel@tonic-gate (void) devfsadm_mklink("bmc", node, minor, 0); 3050Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3060Sstevel@tonic-gate } 307437Smws 308437Smws static int 309437Smws smbios(di_minor_t minor, di_node_t node) 310437Smws { 311437Smws (void) devfsadm_mklink("smbios", node, minor, 0); 312437Smws return (DEVFSADM_CONTINUE); 313437Smws } 314437Smws 3150Sstevel@tonic-gate static int 3160Sstevel@tonic-gate agp_process(di_minor_t minor, di_node_t node) 3170Sstevel@tonic-gate { 3180Sstevel@tonic-gate char *minor_nm, *drv_nm; 3190Sstevel@tonic-gate char *devfspath; 3200Sstevel@tonic-gate char *I_path, *p_path, *buf; 3210Sstevel@tonic-gate char *name = (char *)NULL; 3220Sstevel@tonic-gate int i, index; 3230Sstevel@tonic-gate devfsadm_enumerate_t rules[1]; 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate minor_nm = di_minor_name(minor); 3260Sstevel@tonic-gate drv_nm = di_driver_name(node); 3270Sstevel@tonic-gate 3280Sstevel@tonic-gate if ((minor_nm == NULL) || (drv_nm == NULL)) { 3290Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3300Sstevel@tonic-gate } 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n", 3330Sstevel@tonic-gate minor_nm, di_node_name(node)); 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate devfspath = di_devfs_path(node); 3360Sstevel@tonic-gate if (devfspath == NULL) { 3370Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n"); 3380Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate I_path = (char *)malloc(PATH_MAX); 3420Sstevel@tonic-gate 3430Sstevel@tonic-gate if (I_path == NULL) { 3440Sstevel@tonic-gate di_devfs_path_free(devfspath); 3450Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 3460Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3470Sstevel@tonic-gate } 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate p_path = (char *)malloc(PATH_MAX); 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate if (p_path == NULL) { 3520Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 3530Sstevel@tonic-gate di_devfs_path_free(devfspath); 3540Sstevel@tonic-gate free(I_path); 3550Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3560Sstevel@tonic-gate } 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate (void) strlcpy(p_path, devfspath, PATH_MAX); 3590Sstevel@tonic-gate (void) strlcat(p_path, ":", PATH_MAX); 3600Sstevel@tonic-gate (void) strlcat(p_path, minor_nm, PATH_MAX); 3610Sstevel@tonic-gate di_devfs_path_free(devfspath); 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: path %s\n", p_path); 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate for (i = 0; ; i++) { 3660Sstevel@tonic-gate if ((driver_name_table[i].driver_name == NULL) || 3670Sstevel@tonic-gate (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) { 3680Sstevel@tonic-gate index = driver_name_table[i].index; 3690Sstevel@tonic-gate break; 3700Sstevel@tonic-gate } 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate switch (index) { 3730Sstevel@tonic-gate case DRIVER_AGPPSEUDO: 3740Sstevel@tonic-gate devfsadm_print(debug_mid, 3750Sstevel@tonic-gate "agp_process: psdeudo driver name\n"); 3760Sstevel@tonic-gate name = "agpgart"; 3770Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "%s", name); 3780Sstevel@tonic-gate devfsadm_print(debug_mid, 3790Sstevel@tonic-gate "mklink %s -> %s\n", I_path, p_path); 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate free(I_path); 3840Sstevel@tonic-gate free(p_path); 3850Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 3860Sstevel@tonic-gate case DRIVER_AGPTARGET: 3870Sstevel@tonic-gate devfsadm_print(debug_mid, 3880Sstevel@tonic-gate "agp_process: target driver name\n"); 3890Sstevel@tonic-gate rules[0] = agptarget_rules[0]; 3900Sstevel@tonic-gate name = "agptarget"; 3910Sstevel@tonic-gate break; 3920Sstevel@tonic-gate case DRIVER_CPUGART: 3930Sstevel@tonic-gate devfsadm_print(debug_mid, 3940Sstevel@tonic-gate "agp_process: cpugart driver name\n"); 3950Sstevel@tonic-gate rules[0] = cpugart_rules[0]; 3960Sstevel@tonic-gate name = "cpugart"; 3970Sstevel@tonic-gate break; 3980Sstevel@tonic-gate case DRIVER_AGPMASTER: 3990Sstevel@tonic-gate devfsadm_print(debug_mid, 4000Sstevel@tonic-gate "agp_process: agpmaster driver name\n"); 4010Sstevel@tonic-gate rules[0] = agpmaster_rules[0]; 4020Sstevel@tonic-gate name = "agpmaster"; 4030Sstevel@tonic-gate break; 4040Sstevel@tonic-gate case DRIVER_UNKNOWN: 4050Sstevel@tonic-gate devfsadm_print(debug_mid, 4060Sstevel@tonic-gate "agp_process: unknown driver name=%s\n", drv_nm); 4070Sstevel@tonic-gate free(I_path); 4080Sstevel@tonic-gate free(p_path); 4090Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4100Sstevel@tonic-gate } 4110Sstevel@tonic-gate 4120Sstevel@tonic-gate if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { 4130Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: exit/coninue\n"); 4140Sstevel@tonic-gate free(I_path); 4150Sstevel@tonic-gate free(p_path); 4160Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4170Sstevel@tonic-gate } 4180Sstevel@tonic-gate 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate (void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf); 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n", 4230Sstevel@tonic-gate p_path, buf); 4240Sstevel@tonic-gate 4250Sstevel@tonic-gate free(buf); 4260Sstevel@tonic-gate 4270Sstevel@tonic-gate devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate (void) devfsadm_mklink(I_path, node, minor, 0); 4300Sstevel@tonic-gate 4310Sstevel@tonic-gate free(p_path); 4320Sstevel@tonic-gate free(I_path); 4330Sstevel@tonic-gate 4340Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 4350Sstevel@tonic-gate } 436*1414Scindi 437*1414Scindi /* 438*1414Scindi * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd 439*1414Scindi */ 440*1414Scindi static int 441*1414Scindi mc_node(di_minor_t minor, di_node_t node) 442*1414Scindi { 443*1414Scindi const char *minorname = di_minor_name(minor); 444*1414Scindi const char *busaddr = di_bus_addr(node); 445*1414Scindi char linkpath[PATH_MAX]; 446*1414Scindi int unitaddr; 447*1414Scindi char *c; 448*1414Scindi 449*1414Scindi if (minorname == NULL || busaddr == NULL) 450*1414Scindi return (DEVFSADM_CONTINUE); 451*1414Scindi 452*1414Scindi errno = 0; 453*1414Scindi unitaddr = strtol(busaddr, &c, 16); 454*1414Scindi 455*1414Scindi if (errno != 0 || unitaddr < MC_AMD_DEV_OFFSET) 456*1414Scindi return (DEVFSADM_CONTINUE); 457*1414Scindi 458*1414Scindi (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 459*1414Scindi unitaddr - MC_AMD_DEV_OFFSET); 460*1414Scindi (void) devfsadm_mklink(linkpath, node, minor, 0); 461*1414Scindi return (DEVFSADM_CONTINUE); 462*1414Scindi } 463