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