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*10702SDarren.Moffat@Sun.COM * Copyright 2009 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 <sys/mkdev.h>
331676Sjpk #include <bsm/devalloc.h>
341676Sjpk
351676Sjpk extern int system_labeled;
360Sstevel@tonic-gate
370Sstevel@tonic-gate
380Sstevel@tonic-gate static int ddi_other(di_minor_t minor, di_node_t node);
390Sstevel@tonic-gate static int diskette(di_minor_t minor, di_node_t node);
400Sstevel@tonic-gate static int ecpp_create(di_minor_t minor, di_node_t node);
410Sstevel@tonic-gate static int mc_node(di_minor_t minor, di_node_t node);
420Sstevel@tonic-gate static int starcat_sbbc_node(di_minor_t minor, di_node_t node);
430Sstevel@tonic-gate static int lom(di_minor_t minor, di_node_t node);
440Sstevel@tonic-gate static int ntwdt_create(di_minor_t minor, di_node_t node);
456516Sky115808 static int bmc(di_minor_t minor, di_node_t node);
460Sstevel@tonic-gate
470Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = {
480Sstevel@tonic-gate { "other", "ddi_other", NULL,
490Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, ddi_other
500Sstevel@tonic-gate },
510Sstevel@tonic-gate { "memory-controller", "ddi_mem_ctrl", NULL,
520Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, mc_node
530Sstevel@tonic-gate },
540Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "sbbc",
550Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_1, starcat_sbbc_node
560Sstevel@tonic-gate },
570Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL,
580Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette
590Sstevel@tonic-gate },
600Sstevel@tonic-gate { "printer", "ddi_printer", NULL,
610Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, ecpp_create
620Sstevel@tonic-gate },
630Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "lw8",
640Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, lom
650Sstevel@tonic-gate },
660Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "ntwdt",
670Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, ntwdt_create
680Sstevel@tonic-gate },
696516Sky115808 { "pseudo", "ddi_pseudo", "bmc",
706516Sky115808 TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc
716516Sky115808 }
720Sstevel@tonic-gate };
730Sstevel@tonic-gate
740Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt);
750Sstevel@tonic-gate
760Sstevel@tonic-gate
770Sstevel@tonic-gate /*
780Sstevel@tonic-gate * Handles minor node type "ddi_other"
790Sstevel@tonic-gate * type=ddi_other;name=SUNW,pmc pmc
800Sstevel@tonic-gate * type=ddi_other;name=SUNW,mic mic\M0
810Sstevel@tonic-gate */
820Sstevel@tonic-gate static int
ddi_other(di_minor_t minor,di_node_t node)830Sstevel@tonic-gate ddi_other(di_minor_t minor, di_node_t node)
840Sstevel@tonic-gate {
850Sstevel@tonic-gate char path[PATH_MAX + 1];
860Sstevel@tonic-gate char *nn = di_node_name(node);
870Sstevel@tonic-gate char *mn = di_minor_name(minor);
880Sstevel@tonic-gate
890Sstevel@tonic-gate if (strcmp(nn, "SUNW,pmc") == 0) {
900Sstevel@tonic-gate (void) devfsadm_mklink("pcm", node, minor, 0);
910Sstevel@tonic-gate } else if (strcmp(nn, "SUNW,mic") == 0) {
920Sstevel@tonic-gate (void) strcpy(path, "mic");
930Sstevel@tonic-gate (void) strcat(path, mn);
940Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
950Sstevel@tonic-gate }
960Sstevel@tonic-gate
970Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
980Sstevel@tonic-gate }
990Sstevel@tonic-gate
1000Sstevel@tonic-gate /*
1010Sstevel@tonic-gate * This function is called for diskette nodes
1020Sstevel@tonic-gate */
1030Sstevel@tonic-gate static int
diskette(di_minor_t minor,di_node_t node)1040Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node)
1050Sstevel@tonic-gate {
1061676Sjpk int flags = 0;
1071676Sjpk char *mn = di_minor_name(minor);
1081676Sjpk
1091676Sjpk if (system_labeled)
1101676Sjpk flags = DA_ADD|DA_FLOPPY;
1111676Sjpk
1120Sstevel@tonic-gate if (strcmp(mn, "c") == 0) {
1131676Sjpk (void) devfsadm_mklink("diskette", node, minor, flags);
1141676Sjpk (void) devfsadm_mklink("diskette0", node, minor, flags);
1150Sstevel@tonic-gate
1160Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) {
1171676Sjpk (void) devfsadm_mklink("rdiskette", node, minor, flags);
1181676Sjpk (void) devfsadm_mklink("rdiskette0", node, minor, flags);
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate /*
1250Sstevel@tonic-gate * Handles links of the form:
1260Sstevel@tonic-gate * type=ddi_printer;name=ecpp ecpp\N0
1270Sstevel@tonic-gate */
1280Sstevel@tonic-gate static int
ecpp_create(di_minor_t minor,di_node_t node)1290Sstevel@tonic-gate ecpp_create(di_minor_t minor, di_node_t node)
1300Sstevel@tonic-gate {
1310Sstevel@tonic-gate char *buf;
1320Sstevel@tonic-gate char path[PATH_MAX + 1];
1330Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL};
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) {
1360Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) {
1400Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s",
1440Sstevel@tonic-gate buf, di_minor_name(minor));
1450Sstevel@tonic-gate
1460Sstevel@tonic-gate di_devfs_path_free(buf);
1470Sstevel@tonic-gate
1480Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) {
1490Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf);
1530Sstevel@tonic-gate free(buf);
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0);
1560Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate
1590Sstevel@tonic-gate /* Rules for memory controller */
1600Sstevel@tonic-gate static devfsadm_enumerate_t mc_rules[1] =
1610Sstevel@tonic-gate {"^mc$/^mc([0-9]+)$", 1, MATCH_ALL};
1620Sstevel@tonic-gate
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate static int
mc_node(di_minor_t minor,di_node_t node)1650Sstevel@tonic-gate mc_node(di_minor_t minor, di_node_t node)
1660Sstevel@tonic-gate {
1670Sstevel@tonic-gate char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath;
1680Sstevel@tonic-gate char *minor_nm;
1690Sstevel@tonic-gate
1700Sstevel@tonic-gate minor_nm = di_minor_name(minor);
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate if (minor_nm == NULL) {
1730Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate devfspath = di_devfs_path(node);
1770Sstevel@tonic-gate
1780Sstevel@tonic-gate (void) strcpy(path, devfspath);
1790Sstevel@tonic-gate (void) strcat(path, ":");
1800Sstevel@tonic-gate (void) strcat(path, minor_nm);
1810Sstevel@tonic-gate di_devfs_path_free(devfspath);
1820Sstevel@tonic-gate
1830Sstevel@tonic-gate /* build the physical path from the components */
1840Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, mc_rules, 1)) {
1850Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1860Sstevel@tonic-gate }
1870Sstevel@tonic-gate
1880Sstevel@tonic-gate (void) strcpy(l_path, "mc/mc");
1890Sstevel@tonic-gate (void) strcat(l_path, buf);
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate free(buf);
1920Sstevel@tonic-gate
1930Sstevel@tonic-gate (void) devfsadm_mklink(l_path, node, minor, 0);
1940Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate /*
1990Sstevel@tonic-gate * Starcat sbbc node. We only really care about generating a /dev
2000Sstevel@tonic-gate * link for the lone sbbc on the SC (as opposed to the potentially
2010Sstevel@tonic-gate * numerous sbbcs on the domain), so only operate on instance 0.
2020Sstevel@tonic-gate */
2030Sstevel@tonic-gate static int
starcat_sbbc_node(di_minor_t minor,di_node_t node)2040Sstevel@tonic-gate starcat_sbbc_node(di_minor_t minor, di_node_t node)
2050Sstevel@tonic-gate {
2060Sstevel@tonic-gate char *mn;
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate if (di_instance(node) == 0) {
2090Sstevel@tonic-gate mn = di_minor_name(minor);
2100Sstevel@tonic-gate (void) devfsadm_mklink(mn, node, minor, 0);
2110Sstevel@tonic-gate }
2120Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate
2160Sstevel@tonic-gate /*
2170Sstevel@tonic-gate * Creates /dev/lom nodes for Platform Specific lom driver
2180Sstevel@tonic-gate */
2190Sstevel@tonic-gate static int
lom(di_minor_t minor,di_node_t node)2200Sstevel@tonic-gate lom(di_minor_t minor, di_node_t node)
2210Sstevel@tonic-gate {
2220Sstevel@tonic-gate (void) devfsadm_mklink("lom", node, minor, 0);
2230Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate
2260Sstevel@tonic-gate /*
2270Sstevel@tonic-gate * Creates /dev/ntwdt nodes for Platform Specific ntwdt driver
2280Sstevel@tonic-gate */
2290Sstevel@tonic-gate static int
ntwdt_create(di_minor_t minor,di_node_t node)2300Sstevel@tonic-gate ntwdt_create(di_minor_t minor, di_node_t node)
2310Sstevel@tonic-gate {
2320Sstevel@tonic-gate (void) devfsadm_mklink("ntwdt", node, minor, 0);
2330Sstevel@tonic-gate return (DEVFSADM_CONTINUE);
2340Sstevel@tonic-gate }
2356516Sky115808
2366516Sky115808 /*
2376516Sky115808 * Creates /dev/bmc node.
2386516Sky115808 */
2396516Sky115808 static int
bmc(di_minor_t minor,di_node_t node)2406516Sky115808 bmc(di_minor_t minor, di_node_t node)
2416516Sky115808 {
2426516Sky115808 (void) devfsadm_mklink("bmc", node, minor, 0);
2436516Sky115808 return (DEVFSADM_CONTINUE);
2446516Sky115808 }
245