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 /* 22*38603a20SDarren J Moffat * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <regex.h> 277c478bd9Sstevel@tonic-gate #include <devfsadm.h> 287c478bd9Sstevel@tonic-gate #include <stdio.h> 297c478bd9Sstevel@tonic-gate #include <strings.h> 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <limits.h> 327c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 3345916cd2Sjpk #include <bsm/devalloc.h> 3445916cd2Sjpk 3545916cd2Sjpk extern int system_labeled; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate static int ddi_other(di_minor_t minor, di_node_t node); 397c478bd9Sstevel@tonic-gate static int diskette(di_minor_t minor, di_node_t node); 407c478bd9Sstevel@tonic-gate static int ecpp_create(di_minor_t minor, di_node_t node); 417c478bd9Sstevel@tonic-gate static int mc_node(di_minor_t minor, di_node_t node); 427c478bd9Sstevel@tonic-gate static int starcat_sbbc_node(di_minor_t minor, di_node_t node); 437c478bd9Sstevel@tonic-gate static int lom(di_minor_t minor, di_node_t node); 447c478bd9Sstevel@tonic-gate static int ntwdt_create(di_minor_t minor, di_node_t node); 451a6ee848Sky115808 static int bmc(di_minor_t minor, di_node_t node); 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate static devfsadm_create_t misc_cbt[] = { 487c478bd9Sstevel@tonic-gate { "other", "ddi_other", NULL, 497c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, ddi_other 507c478bd9Sstevel@tonic-gate }, 517c478bd9Sstevel@tonic-gate { "memory-controller", "ddi_mem_ctrl", NULL, 527c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_0, mc_node 537c478bd9Sstevel@tonic-gate }, 547c478bd9Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "sbbc", 557c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_1, starcat_sbbc_node 567c478bd9Sstevel@tonic-gate }, 577c478bd9Sstevel@tonic-gate { "disk", "ddi_block:diskette", NULL, 587c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, diskette 597c478bd9Sstevel@tonic-gate }, 607c478bd9Sstevel@tonic-gate { "printer", "ddi_printer", NULL, 617c478bd9Sstevel@tonic-gate TYPE_EXACT, ILEVEL_1, ecpp_create 627c478bd9Sstevel@tonic-gate }, 637c478bd9Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "lw8", 647c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, lom 657c478bd9Sstevel@tonic-gate }, 667c478bd9Sstevel@tonic-gate { "pseudo", "ddi_pseudo", "ntwdt", 677c478bd9Sstevel@tonic-gate TYPE_EXACT | DRV_EXACT, ILEVEL_0, ntwdt_create 687c478bd9Sstevel@tonic-gate }, 691a6ee848Sky115808 { "pseudo", "ddi_pseudo", "bmc", 701a6ee848Sky115808 TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc 711a6ee848Sky115808 } 727c478bd9Sstevel@tonic-gate }; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate DEVFSADM_CREATE_INIT_V0(misc_cbt); 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * Handles minor node type "ddi_other" 797c478bd9Sstevel@tonic-gate * type=ddi_other;name=SUNW,pmc pmc 807c478bd9Sstevel@tonic-gate * type=ddi_other;name=SUNW,mic mic\M0 817c478bd9Sstevel@tonic-gate */ 827c478bd9Sstevel@tonic-gate static int 837c478bd9Sstevel@tonic-gate ddi_other(di_minor_t minor, di_node_t node) 847c478bd9Sstevel@tonic-gate { 857c478bd9Sstevel@tonic-gate char path[PATH_MAX + 1]; 867c478bd9Sstevel@tonic-gate char *nn = di_node_name(node); 877c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate if (strcmp(nn, "SUNW,pmc") == 0) { 907c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("pcm", node, minor, 0); 917c478bd9Sstevel@tonic-gate } else if (strcmp(nn, "SUNW,mic") == 0) { 927c478bd9Sstevel@tonic-gate (void) strcpy(path, "mic"); 937c478bd9Sstevel@tonic-gate (void) strcat(path, mn); 947c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* 1017c478bd9Sstevel@tonic-gate * This function is called for diskette nodes 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate static int 1047c478bd9Sstevel@tonic-gate diskette(di_minor_t minor, di_node_t node) 1057c478bd9Sstevel@tonic-gate { 10645916cd2Sjpk int flags = 0; 1077c478bd9Sstevel@tonic-gate char *mn = di_minor_name(minor); 10845916cd2Sjpk 10945916cd2Sjpk if (system_labeled) 11045916cd2Sjpk flags = DA_ADD|DA_FLOPPY; 11145916cd2Sjpk 1127c478bd9Sstevel@tonic-gate if (strcmp(mn, "c") == 0) { 11345916cd2Sjpk (void) devfsadm_mklink("diskette", node, minor, flags); 11445916cd2Sjpk (void) devfsadm_mklink("diskette0", node, minor, flags); 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate } else if (strcmp(mn, "c,raw") == 0) { 11745916cd2Sjpk (void) devfsadm_mklink("rdiskette", node, minor, flags); 11845916cd2Sjpk (void) devfsadm_mklink("rdiskette0", node, minor, flags); 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* 1257c478bd9Sstevel@tonic-gate * Handles links of the form: 1267c478bd9Sstevel@tonic-gate * type=ddi_printer;name=ecpp ecpp\N0 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate static int 1297c478bd9Sstevel@tonic-gate ecpp_create(di_minor_t minor, di_node_t node) 1307c478bd9Sstevel@tonic-gate { 1317c478bd9Sstevel@tonic-gate char *buf; 1327c478bd9Sstevel@tonic-gate char path[PATH_MAX + 1]; 1337c478bd9Sstevel@tonic-gate devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate if (strcmp(di_driver_name(node), "ecpp") != 0) { 1367c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate if ((buf = di_devfs_path(node)) == NULL) { 1407c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "%s:%s", 1447c478bd9Sstevel@tonic-gate buf, di_minor_name(minor)); 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate di_devfs_path_free(buf); 1477c478bd9Sstevel@tonic-gate 1487c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 1497c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate (void) snprintf(path, sizeof (path), "ecpp%s", buf); 1537c478bd9Sstevel@tonic-gate free(buf); 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(path, node, minor, 0); 1567c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate /* Rules for memory controller */ 1607c478bd9Sstevel@tonic-gate static devfsadm_enumerate_t mc_rules[1] = 1617c478bd9Sstevel@tonic-gate {"^mc$/^mc([0-9]+)$", 1, MATCH_ALL}; 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate static int 1657c478bd9Sstevel@tonic-gate mc_node(di_minor_t minor, di_node_t node) 1667c478bd9Sstevel@tonic-gate { 1677c478bd9Sstevel@tonic-gate char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath; 1687c478bd9Sstevel@tonic-gate char *minor_nm; 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate minor_nm = di_minor_name(minor); 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate if (minor_nm == NULL) { 1737c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate 1767c478bd9Sstevel@tonic-gate devfspath = di_devfs_path(node); 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate (void) strcpy(path, devfspath); 1797c478bd9Sstevel@tonic-gate (void) strcat(path, ":"); 1807c478bd9Sstevel@tonic-gate (void) strcat(path, minor_nm); 1817c478bd9Sstevel@tonic-gate di_devfs_path_free(devfspath); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* build the physical path from the components */ 1847c478bd9Sstevel@tonic-gate if (devfsadm_enumerate_int(path, 0, &buf, mc_rules, 1)) { 1857c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate (void) strcpy(l_path, "mc/mc"); 1897c478bd9Sstevel@tonic-gate (void) strcat(l_path, buf); 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate free(buf); 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(l_path, node, minor, 0); 1947c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate /* 1997c478bd9Sstevel@tonic-gate * Starcat sbbc node. We only really care about generating a /dev 2007c478bd9Sstevel@tonic-gate * link for the lone sbbc on the SC (as opposed to the potentially 2017c478bd9Sstevel@tonic-gate * numerous sbbcs on the domain), so only operate on instance 0. 2027c478bd9Sstevel@tonic-gate */ 2037c478bd9Sstevel@tonic-gate static int 2047c478bd9Sstevel@tonic-gate starcat_sbbc_node(di_minor_t minor, di_node_t node) 2057c478bd9Sstevel@tonic-gate { 2067c478bd9Sstevel@tonic-gate char *mn; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate if (di_instance(node) == 0) { 2097c478bd9Sstevel@tonic-gate mn = di_minor_name(minor); 2107c478bd9Sstevel@tonic-gate (void) devfsadm_mklink(mn, node, minor, 0); 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate /* 2177c478bd9Sstevel@tonic-gate * Creates /dev/lom nodes for Platform Specific lom driver 2187c478bd9Sstevel@tonic-gate */ 2197c478bd9Sstevel@tonic-gate static int 2207c478bd9Sstevel@tonic-gate lom(di_minor_t minor, di_node_t node) 2217c478bd9Sstevel@tonic-gate { 2227c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("lom", node, minor, 0); 2237c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate /* 2277c478bd9Sstevel@tonic-gate * Creates /dev/ntwdt nodes for Platform Specific ntwdt driver 2287c478bd9Sstevel@tonic-gate */ 2297c478bd9Sstevel@tonic-gate static int 2307c478bd9Sstevel@tonic-gate ntwdt_create(di_minor_t minor, di_node_t node) 2317c478bd9Sstevel@tonic-gate { 2327c478bd9Sstevel@tonic-gate (void) devfsadm_mklink("ntwdt", node, minor, 0); 2337c478bd9Sstevel@tonic-gate return (DEVFSADM_CONTINUE); 2347c478bd9Sstevel@tonic-gate } 2351a6ee848Sky115808 2361a6ee848Sky115808 /* 2371a6ee848Sky115808 * Creates /dev/bmc node. 2381a6ee848Sky115808 */ 2391a6ee848Sky115808 static int 2401a6ee848Sky115808 bmc(di_minor_t minor, di_node_t node) 2411a6ee848Sky115808 { 2421a6ee848Sky115808 (void) devfsadm_mklink("bmc", node, minor, 0); 2431a6ee848Sky115808 return (DEVFSADM_CONTINUE); 2441a6ee848Sky115808 } 245