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
vt00(di_minor_t minor,di_node_t node)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
diskette(di_minor_t minor,di_node_t node)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
lp(di_minor_t minor,di_node_t node)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
serial(di_minor_t minor,di_node_t node)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
serial_dialout(di_minor_t minor,di_node_t node)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
kdmouse(di_minor_t minor,di_node_t node)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
bmc(di_minor_t minor,di_node_t node)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
smbios(di_minor_t minor,di_node_t node)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
agp_process(di_minor_t minor,di_node_t node)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
drm_node(di_minor_t minor,di_node_t node)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
mc_node(di_minor_t minor,di_node_t node)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
xsvc(di_minor_t minor,di_node_t node)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
srn(di_minor_t minor,di_node_t node)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
ucode(di_minor_t minor,di_node_t node)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
heci(di_minor_t minor,di_node_t node)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