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);
477aec1d6eScindi static int mc_node(di_minor_t minor, di_node_t node);
48ae115bc7Smrj static int xsvc(di_minor_t minor, di_node_t node);
492df1fe9cSrandyf static int srn(di_minor_t minor, di_node_t node);
502449e17fSsherrym static int ucode(di_minor_t minor, di_node_t node);
51617e2443SMark Logan
527c478bd9Sstevel@tonic-gate
537c478bd9Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = {
547c478bd9Sstevel@tonic-gate { "vt00", "ddi_display", NULL,
557c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, vt00
567c478bd9Sstevel@tonic-gate },
577c478bd9Sstevel@tonic-gate { "mouse", "ddi_mouse", "mouse8042",
587c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse
597c478bd9Sstevel@tonic-gate },
60*989f2807SJerry Jelinek { "pseudo", "ddi_pseudo", "ipmi",
61*989f2807SJerry Jelinek TYPE_EXACT | DRV_EXACT, ILEVEL_0, ipmi,
627c478bd9Sstevel@tonic-gate },
6384ab085aSmws { "pseudo", "ddi_pseudo", "smbios",
6484ab085aSmws TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios,
6584ab085aSmws },
6694ee2d0fSJimmy Vetayases /* floppies share the same class, but not link regex, as hard disks */
677c478bd9Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL,
687c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette
697c478bd9Sstevel@tonic-gate },
707c478bd9Sstevel@tonic-gate { "parallel", "ddi_printer", NULL,
717c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, lp
727c478bd9Sstevel@tonic-gate },
737c478bd9Sstevel@tonic-gate { "serial", "ddi_serial:mb", NULL,
747c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial
757c478bd9Sstevel@tonic-gate },
767c478bd9Sstevel@tonic-gate { "serial", "ddi_serial:dialout,mb", NULL,
777c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, serial_dialout
787c478bd9Sstevel@tonic-gate },
79ae115bc7Smrj { "pseudo", "ddi_pseudo", NULL,
80ae115bc7Smrj TYPE_EXACT, ILEVEL_0, xsvc
81ae115bc7Smrj },
822df1fe9cSrandyf { "pseudo", "ddi_pseudo", NULL,
832df1fe9cSrandyf TYPE_EXACT, ILEVEL_0, srn
842df1fe9cSrandyf },
857aec1d6eScindi { "memory-controller", "ddi_mem_ctrl", NULL,
867aec1d6eScindi TYPE_EXACT, ILEVEL_0, mc_node
872449e17fSsherrym },
882449e17fSsherrym { "pseudo", "ddi_pseudo", "ucode",
892449e17fSsherrym TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode,
90617e2443SMark Logan },
917c478bd9Sstevel@tonic-gate };
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt);
947c478bd9Sstevel@tonic-gate
957c478bd9Sstevel@tonic-gate static devfsadm_remove_t misc_remove_cbt[] = {
967c478bd9Sstevel@tonic-gate { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS,
977c478bd9Sstevel@tonic-gate ILEVEL_0, devfsadm_rm_all
982449e17fSsherrym },
992449e17fSsherrym { "pseudo", "^ucode$", RM_ALWAYS | RM_PRE | RM_HOT,
1002449e17fSsherrym ILEVEL_0, devfsadm_rm_all
10194ee2d0fSJimmy Vetayases },
10294ee2d0fSJimmy Vetayases { "mouse", "^kdmouse$", RM_ALWAYS | RM_PRE,
10394ee2d0fSJimmy Vetayases ILEVEL_0, devfsadm_rm_all
10494ee2d0fSJimmy Vetayases },
10594ee2d0fSJimmy Vetayases { "disk", "^(diskette|rdiskette)([0-9]*)$",
10694ee2d0fSJimmy Vetayases RM_ALWAYS | RM_PRE, ILEVEL_1, devfsadm_rm_all
10794ee2d0fSJimmy Vetayases },
10894ee2d0fSJimmy Vetayases { "parallel", "^(lp|ecpp)([0-9]+)$", RM_ALWAYS | RM_PRE,
10994ee2d0fSJimmy Vetayases ILEVEL_1, devfsadm_rm_all
11094ee2d0fSJimmy Vetayases },
11194ee2d0fSJimmy Vetayases { "serial", "^(tty|ttyd)([0-9]+)$", RM_ALWAYS | RM_PRE,
11294ee2d0fSJimmy Vetayases ILEVEL_1, devfsadm_rm_all
11394ee2d0fSJimmy Vetayases },
11494ee2d0fSJimmy Vetayases { "serial", "^tty[a-z]$", RM_ALWAYS | RM_PRE,
11594ee2d0fSJimmy Vetayases ILEVEL_1, devfsadm_rm_all
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate };
1187c478bd9Sstevel@tonic-gate
1197c478bd9Sstevel@tonic-gate DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt);
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate /*
1227c478bd9Sstevel@tonic-gate * Handles minor node type "ddi_display", in addition to generic processing
1237c478bd9Sstevel@tonic-gate * done by display().
1247c478bd9Sstevel@tonic-gate *
1257c478bd9Sstevel@tonic-gate * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility.
1267c478bd9Sstevel@tonic-gate */
1277c478bd9Sstevel@tonic-gate /* ARGSUSED */
1287c478bd9Sstevel@tonic-gate int
vt00(di_minor_t minor,di_node_t node)1297c478bd9Sstevel@tonic-gate vt00(di_minor_t minor, di_node_t node)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate (void) devfsadm_secondary_link("vt00", "fb", 0);
1327c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c diskette
1377c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette
1387c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c diskette\A2
1397c478bd9Sstevel@tonic-gate * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2
1407c478bd9Sstevel@tonic-gate */
1417c478bd9Sstevel@tonic-gate static int
diskette(di_minor_t minor,di_node_t node)1427c478bd9Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node)
1437c478bd9Sstevel@tonic-gate {
14445916cd2Sjpk int flags = 0;
1457c478bd9Sstevel@tonic-gate char *a2;
1467c478bd9Sstevel@tonic-gate char link[PATH_MAX];
1477c478bd9Sstevel@tonic-gate char *addr = di_bus_addr(node);
1487c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor);
1497c478bd9Sstevel@tonic-gate
15045916cd2Sjpk if (system_labeled)
15145916cd2Sjpk flags = DA_ADD|DA_FLOPPY;
15245916cd2Sjpk
1537c478bd9Sstevel@tonic-gate if (strcmp(addr, "0,0") == 0) {
1547c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) {
15545916cd2Sjpk (void) devfsadm_mklink("diskette", node, minor, flags);
1567c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) {
15745916cd2Sjpk (void) devfsadm_mklink("rdiskette", node, minor, flags);
1587c478bd9Sstevel@tonic-gate }
1597c478bd9Sstevel@tonic-gate
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate
1627c478bd9Sstevel@tonic-gate if (addr[0] == '0') {
1637c478bd9Sstevel@tonic-gate if ((a2 = strchr(addr, ',')) != NULL) {
1647c478bd9Sstevel@tonic-gate a2++;
1657c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) {
1667c478bd9Sstevel@tonic-gate (void) strcpy(link, "diskette");
1677c478bd9Sstevel@tonic-gate (void) strcat(link, a2);
16845916cd2Sjpk (void) devfsadm_mklink(link, node, minor,
16945916cd2Sjpk flags);
1707c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) {
1717c478bd9Sstevel@tonic-gate (void) strcpy(link, "rdiskette");
1727c478bd9Sstevel@tonic-gate (void) strcat(link, a2);
17345916cd2Sjpk (void) devfsadm_mklink(link, node, minor,
17445916cd2Sjpk flags);
1757c478bd9Sstevel@tonic-gate }
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate
1827c478bd9Sstevel@tonic-gate /*
1837c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,3bc lp0
1847c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,378 lp1
1857c478bd9Sstevel@tonic-gate * type=ddi_printer;name=lp;addr=1,278 lp2
1867c478bd9Sstevel@tonic-gate */
1877c478bd9Sstevel@tonic-gate static int
lp(di_minor_t minor,di_node_t node)1887c478bd9Sstevel@tonic-gate lp(di_minor_t minor, di_node_t node)
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate char *addr = di_bus_addr(node);
1917c478bd9Sstevel@tonic-gate char *buf;
1927c478bd9Sstevel@tonic-gate char path[PATH_MAX + 1];
1937c478bd9Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate if (strcmp(addr, "1,3bc") == 0) {
1967c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp0", node, minor, 0);
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate } else if (strcmp(addr, "1,378") == 0) {
1997c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp1", node, minor, 0);
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate } else if (strcmp(addr, "1,278") == 0) {
2027c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lp2", node, minor, 0);
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) {
2067c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) {
2107c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s",
2147c478bd9Sstevel@tonic-gate buf, di_minor_name(minor));
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate di_devfs_path_free(buf);
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
2197c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2207c478bd9Sstevel@tonic-gate }
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf);
2237c478bd9Sstevel@tonic-gate free(buf);
2247c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
2257c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate /*
2297c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=a tty00
2307c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=b tty01
2317c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=c tty02
2327c478bd9Sstevel@tonic-gate * type=ddi_serial:mb;minor=d tty03
2337c478bd9Sstevel@tonic-gate */
2347c478bd9Sstevel@tonic-gate static int
serial(di_minor_t minor,di_node_t node)2357c478bd9Sstevel@tonic-gate serial(di_minor_t minor, di_node_t node)
2367c478bd9Sstevel@tonic-gate {
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor);
2397c478bd9Sstevel@tonic-gate char link[PATH_MAX];
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate (void) strcpy(link, "tty");
2427c478bd9Sstevel@tonic-gate (void) strcat(link, mn);
2437c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(link, node, minor, 0);
2447c478bd9Sstevel@tonic-gate
2457c478bd9Sstevel@tonic-gate if (strcmp(mn, "a") == 0) {
2467c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty00", node, minor, 0);
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "b") == 0) {
2497c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty01", node, minor, 0);
2507c478bd9Sstevel@tonic-gate
2517c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c") == 0) {
2527c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty02", node, minor, 0);
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "d") == 0) {
2557c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("tty03", node, minor, 0);
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2587c478bd9Sstevel@tonic-gate }
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate /*
2617c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=a,cu ttyd0
2627c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=b,cu ttyd1
2637c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=c,cu ttyd2
2647c478bd9Sstevel@tonic-gate * type=ddi_serial:dialout,mb;minor=d,cu ttyd3
2657c478bd9Sstevel@tonic-gate */
2667c478bd9Sstevel@tonic-gate static int
serial_dialout(di_minor_t minor,di_node_t node)2677c478bd9Sstevel@tonic-gate serial_dialout(di_minor_t minor, di_node_t node)
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor);
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate if (strcmp(mn, "a,cu") == 0) {
2727c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd0", node, minor, 0);
2737c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua0", node, minor, 0);
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "b,cu") == 0) {
2767c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd1", node, minor, 0);
2777c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua1", node, minor, 0);
2787c478bd9Sstevel@tonic-gate
2797c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,cu") == 0) {
2807c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd2", node, minor, 0);
2817c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua2", node, minor, 0);
2827c478bd9Sstevel@tonic-gate
2837c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "d,cu") == 0) {
2847c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ttyd3", node, minor, 0);
2857c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("cua3", node, minor, 0);
2867c478bd9Sstevel@tonic-gate }
2877c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate
2907c478bd9Sstevel@tonic-gate static int
kdmouse(di_minor_t minor,di_node_t node)2917c478bd9Sstevel@tonic-gate kdmouse(di_minor_t minor, di_node_t node)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("kdmouse", node, minor, 0);
2947c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate static int
ipmi(di_minor_t minor,di_node_t node)298*989f2807SJerry Jelinek ipmi(di_minor_t minor, di_node_t node)
2997c478bd9Sstevel@tonic-gate {
300*989f2807SJerry Jelinek /*
301*989f2807SJerry Jelinek * Follow convention from other systems, and include an instance#,
302*989f2807SJerry Jelinek * even though there will only be one.
303*989f2807SJerry Jelinek */
304*989f2807SJerry Jelinek (void) devfsadm_mklink("ipmi0", node, minor, 0);
3057c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
3067c478bd9Sstevel@tonic-gate }
30784ab085aSmws
30884ab085aSmws static int
smbios(di_minor_t minor,di_node_t node)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
3157aec1d6eScindi /*
3167aec1d6eScindi * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd
3177aec1d6eScindi */
3187aec1d6eScindi static int
mc_node(di_minor_t minor,di_node_t node)3197aec1d6eScindi mc_node(di_minor_t minor, di_node_t node)
3207aec1d6eScindi {
3217aec1d6eScindi const char *minorname = di_minor_name(minor);
3227aec1d6eScindi const char *busaddr = di_bus_addr(node);
3237aec1d6eScindi char linkpath[PATH_MAX];
3247aec1d6eScindi int unitaddr;
3257aec1d6eScindi char *c;
3267aec1d6eScindi
3277aec1d6eScindi if (minorname == NULL || busaddr == NULL)
3287aec1d6eScindi return (DEVFSADM_CONTINUE);
3297aec1d6eScindi
3307aec1d6eScindi errno = 0;
3317aec1d6eScindi unitaddr = strtol(busaddr, &c, 16);
3327aec1d6eScindi
33320c794b3Sgavinm if (errno != 0)
3347aec1d6eScindi return (DEVFSADM_CONTINUE);
3357aec1d6eScindi
33620c794b3Sgavinm if (unitaddr == 0) {
33720c794b3Sgavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc");
33820c794b3Sgavinm } else if (unitaddr >= MC_AMD_DEV_OFFSET) {
3397aec1d6eScindi (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u",
3407aec1d6eScindi unitaddr - MC_AMD_DEV_OFFSET);
34120c794b3Sgavinm } else {
342e3d60c9bSAdrian Frost (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u",
343e3d60c9bSAdrian Frost minor->dev_minor);
34420c794b3Sgavinm }
3457aec1d6eScindi (void) devfsadm_mklink(linkpath, node, minor, 0);
3467aec1d6eScindi return (DEVFSADM_CONTINUE);
3477aec1d6eScindi }
348ae115bc7Smrj
349ae115bc7Smrj /*
350ae115bc7Smrj * Creates \M0 devlink for xsvc node
351ae115bc7Smrj */
352ae115bc7Smrj static int
xsvc(di_minor_t minor,di_node_t node)353ae115bc7Smrj xsvc(di_minor_t minor, di_node_t node)
354ae115bc7Smrj {
355ae115bc7Smrj char *mn;
356ae115bc7Smrj
357ae115bc7Smrj if (strcmp(di_node_name(node), "xsvc") != 0)
358ae115bc7Smrj return (DEVFSADM_CONTINUE);
359ae115bc7Smrj
360ae115bc7Smrj mn = di_minor_name(minor);
361ae115bc7Smrj if (mn == NULL)
362ae115bc7Smrj return (DEVFSADM_CONTINUE);
363ae115bc7Smrj
364ae115bc7Smrj (void) devfsadm_mklink(mn, node, minor, 0);
365ae115bc7Smrj return (DEVFSADM_CONTINUE);
366ae115bc7Smrj }
3672449e17fSsherrym
3682449e17fSsherrym /*
3692df1fe9cSrandyf * Creates \M0 devlink for srn device
3702df1fe9cSrandyf */
3712df1fe9cSrandyf static int
srn(di_minor_t minor,di_node_t node)3722df1fe9cSrandyf srn(di_minor_t minor, di_node_t node)
3732df1fe9cSrandyf {
3742df1fe9cSrandyf char *mn;
3752df1fe9cSrandyf
3762df1fe9cSrandyf if (strcmp(di_node_name(node), "srn") != 0)
3772df1fe9cSrandyf return (DEVFSADM_CONTINUE);
3782df1fe9cSrandyf
3792df1fe9cSrandyf mn = di_minor_name(minor);
3802df1fe9cSrandyf if (mn == NULL)
3812df1fe9cSrandyf return (DEVFSADM_CONTINUE);
3822df1fe9cSrandyf
3832df1fe9cSrandyf (void) devfsadm_mklink(mn, node, minor, 0);
3842df1fe9cSrandyf return (DEVFSADM_CONTINUE);
3852df1fe9cSrandyf }
3862df1fe9cSrandyf
3872df1fe9cSrandyf /*
3882449e17fSsherrym * /dev/ucode -> /devices/pseudo/ucode@0:ucode
3892449e17fSsherrym */
3902449e17fSsherrym static int
ucode(di_minor_t minor,di_node_t node)3912449e17fSsherrym ucode(di_minor_t minor, di_node_t node)
3922449e17fSsherrym {
3932449e17fSsherrym (void) devfsadm_mklink("ucode", node, minor, 0);
3942449e17fSsherrym return (DEVFSADM_CONTINUE);
3952449e17fSsherrym }
396