1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <regex.h> 27 #include <devfsadm.h> 28 #include <stdio.h> 29 #include <strings.h> 30 #include <stdlib.h> 31 #include <limits.h> 32 #include <sys/mkdev.h> 33 #include <bsm/devalloc.h> 34 35 extern int system_labeled; 36 37 38 static int ddi_other(di_minor_t minor, di_node_t node); 39 static int diskette(di_minor_t minor, di_node_t node); 40 static int ecpp_create(di_minor_t minor, di_node_t node); 41 static int mc_node(di_minor_t minor, di_node_t node); 42 static int starcat_sbbc_node(di_minor_t minor, di_node_t node); 43 static int lom(di_minor_t minor, di_node_t node); 44 static int ntwdt_create(di_minor_t minor, di_node_t node); 45 static int bmc(di_minor_t minor, di_node_t node); 46 47 static devfsadm_create_t misc_cbt[] = { 48 { "other", "ddi_other", NULL, 49 TYPE_EXACT, ILEVEL_0, ddi_other 50 }, 51 { "memory-controller", "ddi_mem_ctrl", NULL, 52 TYPE_EXACT, ILEVEL_0, mc_node 53 }, 54 { "pseudo", "ddi_pseudo", "sbbc", 55 TYPE_EXACT | DRV_EXACT, ILEVEL_1, starcat_sbbc_node 56 }, 57 { "disk", "ddi_block:diskette", NULL, 58 TYPE_EXACT, ILEVEL_1, diskette 59 }, 60 { "printer", "ddi_printer", NULL, 61 TYPE_EXACT, ILEVEL_1, ecpp_create 62 }, 63 { "pseudo", "ddi_pseudo", "lw8", 64 TYPE_EXACT | DRV_EXACT, ILEVEL_0, lom 65 }, 66 { "pseudo", "ddi_pseudo", "ntwdt", 67 TYPE_EXACT | DRV_EXACT, ILEVEL_0, ntwdt_create 68 }, 69 { "pseudo", "ddi_pseudo", "bmc", 70 TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc 71 } 72 }; 73 74 DEVFSADM_CREATE_INIT_V0(misc_cbt); 75 76 77 /* 78 * Handles minor node type "ddi_other" 79 * type=ddi_other;name=SUNW,pmc pmc 80 * type=ddi_other;name=SUNW,mic mic\M0 81 */ 82 static int 83 ddi_other(di_minor_t minor, di_node_t node) 84 { 85 char path[PATH_MAX + 1]; 86 char *nn = di_node_name(node); 87 char *mn = di_minor_name(minor); 88 89 if (strcmp(nn, "SUNW,pmc") == 0) { 90 (void) devfsadm_mklink("pcm", node, minor, 0); 91 } else if (strcmp(nn, "SUNW,mic") == 0) { 92 (void) strcpy(path, "mic"); 93 (void) strcat(path, mn); 94 (void) devfsadm_mklink(path, node, minor, 0); 95 } 96 97 return (DEVFSADM_CONTINUE); 98 } 99 100 /* 101 * This function is called for diskette nodes 102 */ 103 static int 104 diskette(di_minor_t minor, di_node_t node) 105 { 106 int flags = 0; 107 char *mn = di_minor_name(minor); 108 109 if (system_labeled) 110 flags = DA_ADD|DA_FLOPPY; 111 112 if (strcmp(mn, "c") == 0) { 113 (void) devfsadm_mklink("diskette", node, minor, flags); 114 (void) devfsadm_mklink("diskette0", node, minor, flags); 115 116 } else if (strcmp(mn, "c,raw") == 0) { 117 (void) devfsadm_mklink("rdiskette", node, minor, flags); 118 (void) devfsadm_mklink("rdiskette0", node, minor, flags); 119 120 } 121 return (DEVFSADM_CONTINUE); 122 } 123 124 /* 125 * Handles links of the form: 126 * type=ddi_printer;name=ecpp ecpp\N0 127 */ 128 static int 129 ecpp_create(di_minor_t minor, di_node_t node) 130 { 131 char *buf; 132 char path[PATH_MAX + 1]; 133 devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 134 135 if (strcmp(di_driver_name(node), "ecpp") != 0) { 136 return (DEVFSADM_CONTINUE); 137 } 138 139 if ((buf = di_devfs_path(node)) == NULL) { 140 return (DEVFSADM_CONTINUE); 141 } 142 143 (void) snprintf(path, sizeof (path), "%s:%s", 144 buf, di_minor_name(minor)); 145 146 di_devfs_path_free(buf); 147 148 if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 149 return (DEVFSADM_CONTINUE); 150 } 151 152 (void) snprintf(path, sizeof (path), "ecpp%s", buf); 153 free(buf); 154 155 (void) devfsadm_mklink(path, node, minor, 0); 156 return (DEVFSADM_CONTINUE); 157 } 158 159 /* Rules for memory controller */ 160 static devfsadm_enumerate_t mc_rules[1] = 161 {"^mc$/^mc([0-9]+)$", 1, MATCH_ALL}; 162 163 164 static int 165 mc_node(di_minor_t minor, di_node_t node) 166 { 167 char path[PATH_MAX], l_path[PATH_MAX], *buf, *devfspath; 168 char *minor_nm; 169 170 minor_nm = di_minor_name(minor); 171 172 if (minor_nm == NULL) { 173 return (DEVFSADM_CONTINUE); 174 } 175 176 devfspath = di_devfs_path(node); 177 178 (void) strcpy(path, devfspath); 179 (void) strcat(path, ":"); 180 (void) strcat(path, minor_nm); 181 di_devfs_path_free(devfspath); 182 183 /* build the physical path from the components */ 184 if (devfsadm_enumerate_int(path, 0, &buf, mc_rules, 1)) { 185 return (DEVFSADM_CONTINUE); 186 } 187 188 (void) strcpy(l_path, "mc/mc"); 189 (void) strcat(l_path, buf); 190 191 free(buf); 192 193 (void) devfsadm_mklink(l_path, node, minor, 0); 194 return (DEVFSADM_CONTINUE); 195 } 196 197 198 /* 199 * Starcat sbbc node. We only really care about generating a /dev 200 * link for the lone sbbc on the SC (as opposed to the potentially 201 * numerous sbbcs on the domain), so only operate on instance 0. 202 */ 203 static int 204 starcat_sbbc_node(di_minor_t minor, di_node_t node) 205 { 206 char *mn; 207 208 if (di_instance(node) == 0) { 209 mn = di_minor_name(minor); 210 (void) devfsadm_mklink(mn, node, minor, 0); 211 } 212 return (DEVFSADM_CONTINUE); 213 214 } 215 216 /* 217 * Creates /dev/lom nodes for Platform Specific lom driver 218 */ 219 static int 220 lom(di_minor_t minor, di_node_t node) 221 { 222 (void) devfsadm_mklink("lom", node, minor, 0); 223 return (DEVFSADM_CONTINUE); 224 } 225 226 /* 227 * Creates /dev/ntwdt nodes for Platform Specific ntwdt driver 228 */ 229 static int 230 ntwdt_create(di_minor_t minor, di_node_t node) 231 { 232 (void) devfsadm_mklink("ntwdt", node, minor, 0); 233 return (DEVFSADM_CONTINUE); 234 } 235 236 /* 237 * Creates /dev/bmc node. 238 */ 239 static int 240 bmc(di_minor_t minor, di_node_t node) 241 { 242 (void) devfsadm_mklink("bmc", node, minor, 0); 243 return (DEVFSADM_CONTINUE); 244 } 245