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 1772 jl139090 * Common Development and Distribution License (the "License"). 6 1772 jl139090 * 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 8485 Peter * 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/zone.h> 33 0 stevel #include <sys/zcons.h> 34 0 stevel #include <sys/cpuid_drv.h> 35 0 stevel 36 0 stevel static int display(di_minor_t minor, di_node_t node); 37 0 stevel static int parallel(di_minor_t minor, di_node_t node); 38 0 stevel static int node_slash_minor(di_minor_t minor, di_node_t node); 39 0 stevel static int driver_minor(di_minor_t minor, di_node_t node); 40 0 stevel static int node_name(di_minor_t minor, di_node_t node); 41 0 stevel static int minor_name(di_minor_t minor, di_node_t node); 42 995 hx147065 static int wifi_minor_name(di_minor_t minor, di_node_t node); 43 0 stevel static int conskbd(di_minor_t minor, di_node_t node); 44 0 stevel static int consms(di_minor_t minor, di_node_t node); 45 0 stevel static int power_button(di_minor_t minor, di_node_t node); 46 0 stevel static int fc_port(di_minor_t minor, di_node_t node); 47 0 stevel static int printer_create(di_minor_t minor, di_node_t node); 48 0 stevel static int se_hdlc_create(di_minor_t minor, di_node_t node); 49 0 stevel static int ppm(di_minor_t minor, di_node_t node); 50 0 stevel static int gpio(di_minor_t minor, di_node_t node); 51 0 stevel static int av_create(di_minor_t minor, di_node_t node); 52 0 stevel static int tsalarm_create(di_minor_t minor, di_node_t node); 53 467 sc121708 static int ntwdt_create(di_minor_t minor, di_node_t node); 54 0 stevel static int zcons_create(di_minor_t minor, di_node_t node); 55 0 stevel static int cpuid(di_minor_t minor, di_node_t node); 56 0 stevel static int glvc(di_minor_t minor, di_node_t node); 57 0 stevel static int ses_callback(di_minor_t minor, di_node_t node); 58 1772 jl139090 static int kmdrv_create(di_minor_t minor, di_node_t node); 59 0 stevel 60 0 stevel static devfsadm_create_t misc_cbt[] = { 61 2621 llai1 { "pseudo", "ddi_pseudo", "(^sad$)", 62 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_0, node_slash_minor 63 0 stevel }, 64 0 stevel { "pseudo", "ddi_pseudo", "zsh", 65 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, driver_minor 66 0 stevel }, 67 0 stevel { "network", "ddi_network", NULL, 68 0 stevel TYPE_EXACT, ILEVEL_0, minor_name 69 995 hx147065 }, 70 995 hx147065 { "wifi", "ddi_network:wifi", NULL, 71 995 hx147065 TYPE_EXACT, ILEVEL_0, wifi_minor_name 72 0 stevel }, 73 0 stevel { "display", "ddi_display", NULL, 74 0 stevel TYPE_EXACT, ILEVEL_0, display 75 0 stevel }, 76 0 stevel { "parallel", "ddi_parallel", NULL, 77 0 stevel TYPE_EXACT, ILEVEL_0, parallel 78 0 stevel }, 79 0 stevel { "enclosure", DDI_NT_SCSI_ENCLOSURE, NULL, 80 0 stevel TYPE_EXACT, ILEVEL_0, ses_callback 81 0 stevel }, 82 0 stevel { "pseudo", "ddi_pseudo", "(^winlock$)|(^pm$)", 83 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_0, node_name 84 0 stevel }, 85 0 stevel { "pseudo", "ddi_pseudo", "conskbd", 86 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, conskbd 87 0 stevel }, 88 0 stevel { "pseudo", "ddi_pseudo", "consms", 89 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, consms 90 0 stevel }, 91 0 stevel { "pseudo", "ddi_pseudo", "rsm", 92 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name 93 0 stevel }, 94 0 stevel { "pseudo", "ddi_pseudo", 95 0 stevel "(^lockstat$)|(^SUNW,rtvc$)|(^vol$)|(^log$)|(^sy$)|" 96 8023 Phil "(^ksyms$)|(^clone$)|(^tl$)|(^tnf$)|(^kstat$)|(^mdesc$)|(^eeprom$)|" 97 8023 Phil "(^ptsl$)|(^mm$)|(^wc$)|(^dump$)|(^cn$)|(^svvslo$)|(^ptm$)|" 98 0 stevel "(^ptc$)|(^openeepr$)|(^poll$)|(^sysmsg$)|(^random$)|(^trapstat$)|" 99 0 stevel "(^cryptoadm$)|(^crypto$)|(^pool$)|(^poolctl$)|(^bl$)|(^kmdb$)|" 100 3253 mec "(^sysevent$)|(^kssl$)|(^physmem$)", 101 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name 102 0 stevel }, 103 0 stevel { "pseudo", "ddi_pseudo", 104 0 stevel "(^ip$)|(^tcp$)|(^udp$)|(^icmp$)|(^sctp$)|" 105 0 stevel "(^ip6$)|(^tcp6$)|(^udp6$)|(^icmp6$)|(^sctp6$)|" 106 0 stevel "(^rts$)|(^arp$)|(^ipsecah$)|(^ipsecesp$)|(^keysock$)|(^spdsock$)|" 107 11042 Erik "(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)", 108 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name 109 0 stevel }, 110 0 stevel { "pseudo", "ddi_pseudo", 111 2958 dr146992 "(^ipf$)|(^ipnat$)|(^ipstate$)|(^ipauth$)|" 112 0 stevel "(^ipsync$)|(^ipscan$)|(^iplookup$)", 113 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name, 114 7408 Sebastien }, 115 7408 Sebastien { "pseudo", "ddi_pseudo", "dld", 116 7408 Sebastien TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name 117 0 stevel }, 118 0 stevel { "pseudo", "ddi_pseudo", 119 9840 gdamore "(^kdmouse$)|(^rootprop$)", 120 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_0, node_name 121 0 stevel }, 122 0 stevel { "pseudo", "ddi_pseudo", "tod", 123 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, node_name 124 0 stevel }, 125 0 stevel { "pseudo", "ddi_pseudo", "envctrl(two)?", 126 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name, 127 0 stevel }, 128 0 stevel { "pseudo", "ddi_pseudo", "fcode", 129 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_0, minor_name, 130 0 stevel }, 131 0 stevel { "power_button", "ddi_power_button", NULL, 132 0 stevel TYPE_EXACT, ILEVEL_0, power_button, 133 0 stevel }, 134 0 stevel { "FC port", "ddi_ctl:devctl", "fp", 135 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, fc_port 136 0 stevel }, 137 0 stevel { "printer", "ddi_printer", NULL, 138 0 stevel TYPE_EXACT, ILEVEL_0, printer_create 139 0 stevel }, 140 0 stevel { "pseudo", "ddi_pseudo", "se", 141 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, se_hdlc_create 142 0 stevel }, 143 0 stevel { "ppm", "ddi_ppm", NULL, 144 0 stevel TYPE_EXACT, ILEVEL_0, ppm 145 0 stevel }, 146 0 stevel { "pseudo", "ddi_pseudo", "gpio_87317", 147 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, gpio 148 0 stevel }, 149 0 stevel { "pseudo", "ddi_pseudo", "sckmdrv", 150 1772 jl139090 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create, 151 1772 jl139090 }, 152 1772 jl139090 { "pseudo", "ddi_pseudo", "oplkmdrv", 153 1772 jl139090 TYPE_EXACT | DRV_RE, ILEVEL_0, kmdrv_create, 154 0 stevel }, 155 0 stevel { "av", "^ddi_av:(isoch|async)$", NULL, 156 0 stevel TYPE_RE, ILEVEL_0, av_create, 157 0 stevel }, 158 0 stevel { "pseudo", "ddi_pseudo", "tsalarm", 159 0 stevel TYPE_EXACT | DRV_RE, ILEVEL_0, tsalarm_create, 160 467 sc121708 }, 161 467 sc121708 { "pseudo", "ddi_pseudo", "ntwdt", 162 467 sc121708 TYPE_EXACT | DRV_RE, ILEVEL_0, ntwdt_create, 163 0 stevel }, 164 0 stevel { "pseudo", "ddi_pseudo", "daplt", 165 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name 166 0 stevel }, 167 0 stevel { "pseudo", "ddi_pseudo", "zcons", 168 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, zcons_create, 169 0 stevel }, 170 0 stevel { "pseudo", "ddi_pseudo", CPUID_DRIVER_NAME, 171 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, cpuid, 172 0 stevel }, 173 0 stevel { "pseudo", "ddi_pseudo", "glvc", 174 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, glvc, 175 1772 jl139090 }, 176 1772 jl139090 { "pseudo", "ddi_pseudo", "dm2s", 177 1772 jl139090 TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name, 178 6007 thurlow }, 179 6007 thurlow { "pseudo", "ddi_pseudo", "nsmb", 180 6330 jc25722 TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name, 181 6330 jc25722 }, 182 6330 jc25722 { "pseudo", "ddi_pseudo", "mem_cache", 183 6007 thurlow TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name, 184 0 stevel }, 185 7532 Sean { "pseudo", "ddi_pseudo", "fm", 186 7532 Sean TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name, 187 10346 wyllys }, 188 10346 wyllys { "pseudo", "ddi_pseudo", "tpm", 189 10346 wyllys TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name 190 10346 wyllys }, 191 0 stevel }; 192 0 stevel 193 0 stevel DEVFSADM_CREATE_INIT_V0(misc_cbt); 194 0 stevel 195 0 stevel static devfsadm_remove_t misc_remove_cbt[] = { 196 0 stevel { "pseudo", "^profile$", 197 0 stevel RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 198 0 stevel }, 199 0 stevel { "pseudo", "^rsm$", 200 0 stevel RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 201 0 stevel }, 202 0 stevel { "printer", "^printers/[0-9]+$", 203 0 stevel RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 204 0 stevel }, 205 0 stevel { "av", "^av/[0-9]+/(async|isoch)$", 206 0 stevel RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 207 0 stevel }, 208 0 stevel { "pseudo", "^daplt$", 209 0 stevel RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 210 0 stevel }, 211 0 stevel { "pseudo", "^zcons/" ZONENAME_REGEXP "/(" ZCONS_MASTER_NAME "|" 212 0 stevel ZCONS_SLAVE_NAME ")$", 213 0 stevel RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 214 0 stevel }, 215 5084 johnlev { "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT, 216 0 stevel ILEVEL_0, devfsadm_rm_all 217 0 stevel }, 218 0 stevel { "enclosure", "^es/ses[0-9]+$", RM_POST, 219 0 stevel ILEVEL_0, devfsadm_rm_all 220 4482 dr146992 }, 221 4482 dr146992 { "pseudo", "^pfil$", 222 4482 dr146992 RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 223 10346 wyllys }, 224 10346 wyllys { "pseudo", "^tpm$", 225 10346 wyllys RM_PRE | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all 226 10346 wyllys }, 227 0 stevel }; 228 0 stevel 229 0 stevel /* Rules for gpio devices */ 230 0 stevel static devfsadm_enumerate_t gpio_rules[1] = 231 0 stevel {"^gpio([0-9]+)$", 1, MATCH_ALL}; 232 0 stevel 233 0 stevel DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); 234 0 stevel 235 0 stevel /* 236 0 stevel * Handles minor node type "ddi_display". 237 0 stevel * 238 0 stevel * type=ddi_display fbs/\M0 fb\N0 239 0 stevel */ 240 0 stevel static int 241 0 stevel display(di_minor_t minor, di_node_t node) 242 0 stevel { 243 0 stevel char l_path[PATH_MAX + 1], contents[PATH_MAX + 1], *buf; 244 0 stevel devfsadm_enumerate_t rules[1] = {"^fb([0-9]+)$", 1, MATCH_ALL}; 245 0 stevel char *mn = di_minor_name(minor); 246 0 stevel 247 0 stevel /* create fbs/\M0 primary link */ 248 0 stevel (void) strcpy(l_path, "fbs/"); 249 0 stevel (void) strcat(l_path, mn); 250 0 stevel (void) devfsadm_mklink(l_path, node, minor, 0); 251 0 stevel 252 0 stevel /* create fb\N0 which links to fbs/\M0 */ 253 0 stevel if (devfsadm_enumerate_int(l_path, 0, &buf, rules, 1)) { 254 0 stevel return (DEVFSADM_CONTINUE); 255 0 stevel } 256 0 stevel (void) strcpy(contents, l_path); 257 0 stevel (void) strcpy(l_path, "fb"); 258 0 stevel (void) strcat(l_path, buf); 259 0 stevel free(buf); 260 0 stevel (void) devfsadm_secondary_link(l_path, contents, 0); 261 0 stevel return (DEVFSADM_CONTINUE); 262 0 stevel } 263 0 stevel 264 0 stevel /* 265 0 stevel * Handles minor node type "ddi_parallel". 266 0 stevel * type=ddi_parallel;name=mcpp mcpp\N0 267 0 stevel */ 268 0 stevel static int 269 0 stevel parallel(di_minor_t minor, di_node_t node) 270 0 stevel { 271 0 stevel char path[PATH_MAX + 1], *buf; 272 0 stevel devfsadm_enumerate_t rules[1] = {"mcpp([0-9]+)$", 1, MATCH_ALL}; 273 0 stevel 274 0 stevel 275 0 stevel if (strcmp(di_node_name(node), "mcpp") != 0) { 276 0 stevel return (DEVFSADM_CONTINUE); 277 0 stevel } 278 0 stevel 279 0 stevel if (NULL == (buf = di_devfs_path(node))) { 280 0 stevel return (DEVFSADM_CONTINUE); 281 0 stevel } 282 0 stevel 283 0 stevel (void) snprintf(path, sizeof (path), "%s:%s", 284 0 stevel buf, di_minor_name(minor)); 285 0 stevel 286 0 stevel di_devfs_path_free(buf); 287 0 stevel 288 0 stevel if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 289 0 stevel return (DEVFSADM_CONTINUE); 290 0 stevel } 291 0 stevel (void) snprintf(path, sizeof (path), "mcpp%s", buf); 292 0 stevel free(buf); 293 0 stevel 294 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 295 0 stevel return (DEVFSADM_CONTINUE); 296 0 stevel } 297 0 stevel 298 0 stevel static int 299 0 stevel ses_callback(di_minor_t minor, di_node_t node) 300 0 stevel { 301 0 stevel char l_path[PATH_MAX]; 302 0 stevel char *buf; 303 0 stevel char *devfspath; 304 0 stevel char p_path[PATH_MAX]; 305 0 stevel devfsadm_enumerate_t re[] = {"^es$/^ses([0-9]+)$", 1, MATCH_ALL}; 306 0 stevel 307 0 stevel /* find devices path -- need to free mem */ 308 0 stevel if (NULL == (devfspath = di_devfs_path(node))) { 309 0 stevel return (DEVFSADM_CONTINUE); 310 0 stevel } 311 0 stevel 312 0 stevel (void) snprintf(p_path, sizeof (p_path), "%s:%s", devfspath, 313 0 stevel di_minor_name(minor)); 314 0 stevel 315 0 stevel 316 0 stevel /* find next number to use; buf is an ascii number */ 317 0 stevel if (devfsadm_enumerate_int(p_path, 0, &buf, re, 1)) { 318 0 stevel /* free memory */ 319 0 stevel di_devfs_path_free(devfspath); 320 0 stevel return (DEVFSADM_CONTINUE); 321 0 stevel } 322 0 stevel 323 0 stevel (void) snprintf(l_path, sizeof (l_path), "es/ses%s", buf); 324 0 stevel 325 0 stevel (void) devfsadm_mklink(l_path, node, minor, 0); 326 0 stevel /* free memory */ 327 0 stevel free(buf); 328 0 stevel di_devfs_path_free(devfspath); 329 0 stevel return (DEVFSADM_CONTINUE); 330 0 stevel 331 0 stevel } 332 0 stevel 333 0 stevel static int 334 0 stevel node_slash_minor(di_minor_t minor, di_node_t node) 335 0 stevel { 336 0 stevel 337 0 stevel char path[PATH_MAX + 1]; 338 0 stevel 339 0 stevel (void) strcpy(path, di_node_name(node)); 340 0 stevel (void) strcat(path, "/"); 341 0 stevel (void) strcat(path, di_minor_name(minor)); 342 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 343 0 stevel return (DEVFSADM_CONTINUE); 344 0 stevel } 345 0 stevel 346 0 stevel static int 347 0 stevel driver_minor(di_minor_t minor, di_node_t node) 348 0 stevel { 349 0 stevel char path[PATH_MAX + 1]; 350 0 stevel 351 0 stevel (void) strcpy(path, di_driver_name(node)); 352 0 stevel (void) strcat(path, di_minor_name(minor)); 353 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 354 0 stevel return (DEVFSADM_CONTINUE); 355 0 stevel } 356 0 stevel 357 0 stevel /* 358 0 stevel * Handles links of the form: 359 0 stevel * type=ddi_pseudo;name=xyz \D 360 0 stevel */ 361 0 stevel static int 362 0 stevel node_name(di_minor_t minor, di_node_t node) 363 0 stevel { 364 0 stevel (void) devfsadm_mklink(di_node_name(node), node, minor, 0); 365 0 stevel return (DEVFSADM_CONTINUE); 366 0 stevel } 367 0 stevel 368 0 stevel /* 369 0 stevel * Handles links of the form: 370 0 stevel * type=ddi_pseudo;name=xyz \M0 371 0 stevel */ 372 0 stevel static int 373 0 stevel minor_name(di_minor_t minor, di_node_t node) 374 0 stevel { 375 0 stevel char *mn = di_minor_name(minor); 376 0 stevel 377 0 stevel (void) devfsadm_mklink(mn, node, minor, 0); 378 0 stevel if (strcmp(mn, "icmp") == 0) { 379 0 stevel (void) devfsadm_mklink("rawip", node, minor, 0); 380 0 stevel } 381 0 stevel if (strcmp(mn, "icmp6") == 0) { 382 0 stevel (void) devfsadm_mklink("rawip6", node, minor, 0); 383 0 stevel } 384 0 stevel if (strcmp(mn, "ipf") == 0) { 385 0 stevel (void) devfsadm_mklink("ipl", node, minor, 0); 386 0 stevel } 387 0 stevel return (DEVFSADM_CONTINUE); 388 0 stevel } 389 0 stevel 390 995 hx147065 /* 391 995 hx147065 * create links at /dev/wifi for wifi minor node 392 995 hx147065 */ 393 995 hx147065 static int 394 995 hx147065 wifi_minor_name(di_minor_t minor, di_node_t node) 395 995 hx147065 { 396 995 hx147065 char buf[256]; 397 995 hx147065 char *mn = di_minor_name(minor); 398 995 hx147065 399 995 hx147065 (void) snprintf(buf, sizeof (buf), "%s%s", "wifi/", mn); 400 995 hx147065 (void) devfsadm_mklink(buf, node, minor, 0); 401 995 hx147065 402 995 hx147065 return (DEVFSADM_CONTINUE); 403 995 hx147065 } 404 0 stevel 405 0 stevel static int 406 0 stevel conskbd(di_minor_t minor, di_node_t node) 407 0 stevel { 408 0 stevel (void) devfsadm_mklink("kbd", node, minor, 0); 409 0 stevel return (DEVFSADM_CONTINUE); 410 0 stevel } 411 0 stevel 412 0 stevel static int 413 0 stevel consms(di_minor_t minor, di_node_t node) 414 0 stevel { 415 0 stevel (void) devfsadm_mklink("mouse", node, minor, 0); 416 0 stevel return (DEVFSADM_CONTINUE); 417 0 stevel } 418 0 stevel 419 0 stevel static int 420 0 stevel power_button(di_minor_t minor, di_node_t node) 421 0 stevel { 422 0 stevel (void) devfsadm_mklink("power_button", node, minor, 0); 423 0 stevel return (DEVFSADM_CONTINUE); 424 0 stevel } 425 0 stevel 426 0 stevel static int 427 0 stevel fc_port(di_minor_t minor, di_node_t node) 428 0 stevel { 429 0 stevel devfsadm_enumerate_t rules[1] = {"fc/fp([0-9]+)$", 1, MATCH_ALL}; 430 0 stevel char *buf, path[PATH_MAX + 1]; 431 0 stevel char *ptr; 432 0 stevel 433 0 stevel if (NULL == (ptr = di_devfs_path(node))) { 434 0 stevel return (DEVFSADM_CONTINUE); 435 0 stevel } 436 0 stevel 437 0 stevel (void) strcpy(path, ptr); 438 0 stevel (void) strcat(path, ":"); 439 0 stevel (void) strcat(path, di_minor_name(minor)); 440 0 stevel 441 0 stevel di_devfs_path_free(ptr); 442 0 stevel 443 0 stevel if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) { 444 0 stevel return (DEVFSADM_CONTINUE); 445 0 stevel } 446 0 stevel 447 0 stevel (void) strcpy(path, "fc/fp"); 448 0 stevel (void) strcat(path, buf); 449 0 stevel free(buf); 450 0 stevel 451 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 452 0 stevel return (DEVFSADM_CONTINUE); 453 0 stevel } 454 0 stevel 455 0 stevel /* 456 0 stevel * Handles: 457 0 stevel * minor node type "ddi_printer". 458 0 stevel * rules of the form: type=ddi_printer;name=bpp \M0 459 0 stevel */ 460 0 stevel static int 461 0 stevel printer_create(di_minor_t minor, di_node_t node) 462 0 stevel { 463 0 stevel char *mn; 464 0 stevel char path[PATH_MAX + 1], *buf; 465 0 stevel devfsadm_enumerate_t rules[1] = {"^printers$/^([0-9]+)$", 1, MATCH_ALL}; 466 0 stevel 467 0 stevel mn = di_minor_name(minor); 468 0 stevel 469 0 stevel if (strcmp(di_driver_name(node), "bpp") == 0) { 470 0 stevel (void) devfsadm_mklink(mn, node, minor, 0); 471 0 stevel } 472 0 stevel 473 0 stevel if (NULL == (buf = di_devfs_path(node))) { 474 0 stevel return (DEVFSADM_CONTINUE); 475 0 stevel } 476 0 stevel 477 0 stevel (void) snprintf(path, sizeof (path), "%s:%s", buf, mn); 478 0 stevel di_devfs_path_free(buf); 479 0 stevel 480 0 stevel if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 481 0 stevel return (DEVFSADM_CONTINUE); 482 0 stevel } 483 0 stevel 484 0 stevel (void) snprintf(path, sizeof (path), "printers/%s", buf); 485 0 stevel free(buf); 486 0 stevel 487 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 488 0 stevel 489 0 stevel return (DEVFSADM_CONTINUE); 490 0 stevel } 491 0 stevel 492 0 stevel /* 493 0 stevel * Handles links of the form: 494 0 stevel * type=ddi_pseudo;name=se;minor2=hdlc se_hdlc\N0 495 0 stevel * type=ddi_pseudo;name=serial;minor2=hdlc se_hdlc\N0 496 0 stevel */ 497 0 stevel static int 498 0 stevel se_hdlc_create(di_minor_t minor, di_node_t node) 499 0 stevel { 500 0 stevel devfsadm_enumerate_t rules[1] = {"^se_hdlc([0-9]+)$", 1, MATCH_ALL}; 501 0 stevel char *buf, path[PATH_MAX + 1]; 502 0 stevel char *ptr; 503 0 stevel char *mn; 504 0 stevel 505 0 stevel mn = di_minor_name(minor); 506 0 stevel 507 0 stevel /* minor node should be of the form: "?,hdlc" */ 508 0 stevel if (strcmp(mn + 1, ",hdlc") != 0) { 509 0 stevel return (DEVFSADM_CONTINUE); 510 0 stevel } 511 0 stevel 512 0 stevel if (NULL == (ptr = di_devfs_path(node))) { 513 0 stevel return (DEVFSADM_CONTINUE); 514 0 stevel } 515 0 stevel 516 0 stevel (void) strcpy(path, ptr); 517 0 stevel (void) strcat(path, ":"); 518 0 stevel (void) strcat(path, mn); 519 0 stevel 520 0 stevel di_devfs_path_free(ptr); 521 0 stevel 522 0 stevel if (devfsadm_enumerate_int(path, 0, &buf, rules, 1) != 0) { 523 0 stevel return (DEVFSADM_CONTINUE); 524 0 stevel } 525 0 stevel 526 0 stevel (void) strcpy(path, "se_hdlc"); 527 0 stevel (void) strcat(path, buf); 528 0 stevel free(buf); 529 0 stevel 530 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 531 0 stevel 532 0 stevel return (DEVFSADM_CONTINUE); 533 0 stevel } 534 0 stevel 535 0 stevel static int 536 0 stevel gpio(di_minor_t minor, di_node_t node) 537 0 stevel { 538 0 stevel char l_path[PATH_MAX], p_path[PATH_MAX], *buf, *devfspath; 539 0 stevel char *minor_nm, *drvr_nm; 540 0 stevel 541 0 stevel 542 0 stevel minor_nm = di_minor_name(minor); 543 0 stevel drvr_nm = di_driver_name(node); 544 0 stevel if ((minor_nm == NULL) || (drvr_nm == NULL)) { 545 0 stevel return (DEVFSADM_CONTINUE); 546 0 stevel } 547 0 stevel 548 0 stevel devfspath = di_devfs_path(node); 549 0 stevel 550 0 stevel (void) strcpy(p_path, devfspath); 551 0 stevel (void) strcat(p_path, ":"); 552 0 stevel (void) strcat(p_path, minor_nm); 553 0 stevel di_devfs_path_free(devfspath); 554 0 stevel 555 0 stevel /* build the physical path from the components */ 556 0 stevel if (devfsadm_enumerate_int(p_path, 0, &buf, gpio_rules, 1)) { 557 0 stevel return (DEVFSADM_CONTINUE); 558 0 stevel } 559 0 stevel 560 0 stevel (void) snprintf(l_path, sizeof (l_path), "%s%s", "gpio", buf); 561 0 stevel 562 0 stevel free(buf); 563 0 stevel 564 0 stevel (void) devfsadm_mklink(l_path, node, minor, 0); 565 0 stevel 566 0 stevel return (DEVFSADM_CONTINUE); 567 0 stevel } 568 0 stevel 569 0 stevel /* 570 0 stevel * Creates /dev/ppm nodes for Platform Specific PM module 571 0 stevel */ 572 0 stevel static int 573 0 stevel ppm(di_minor_t minor, di_node_t node) 574 0 stevel { 575 0 stevel (void) devfsadm_mklink("ppm", node, minor, 0); 576 0 stevel return (DEVFSADM_CONTINUE); 577 0 stevel } 578 0 stevel 579 0 stevel /* 580 0 stevel * Handles: 581 0 stevel * /dev/av/[0-9]+/(async|isoch) 582 0 stevel */ 583 0 stevel static int 584 0 stevel av_create(di_minor_t minor, di_node_t node) 585 0 stevel { 586 0 stevel devfsadm_enumerate_t rules[1] = {"^av$/^([0-9]+)$", 1, MATCH_ADDR}; 587 0 stevel char *minor_str; 588 0 stevel char path[PATH_MAX + 1]; 589 0 stevel char *buf; 590 0 stevel 591 0 stevel if ((buf = di_devfs_path(node)) == NULL) { 592 0 stevel return (DEVFSADM_CONTINUE); 593 0 stevel } 594 0 stevel 595 0 stevel minor_str = di_minor_name(minor); 596 0 stevel (void) snprintf(path, sizeof (path), "%s:%s", buf, minor_str); 597 0 stevel di_devfs_path_free(buf); 598 0 stevel 599 0 stevel if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 600 0 stevel return (DEVFSADM_CONTINUE); 601 0 stevel } 602 0 stevel 603 0 stevel (void) snprintf(path, sizeof (path), "av/%s/%s", buf, minor_str); 604 0 stevel free(buf); 605 0 stevel 606 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 607 0 stevel 608 0 stevel return (DEVFSADM_CONTINUE); 609 0 stevel } 610 0 stevel 611 0 stevel /* 612 0 stevel * Creates /dev/lom and /dev/tsalarm:ctl for tsalarm node 613 0 stevel */ 614 0 stevel static int 615 0 stevel tsalarm_create(di_minor_t minor, di_node_t node) 616 0 stevel { 617 0 stevel char buf[PATH_MAX + 1]; 618 0 stevel char *mn = di_minor_name(minor); 619 0 stevel 620 0 stevel (void) snprintf(buf, sizeof (buf), "%s%s", di_node_name(node), ":ctl"); 621 0 stevel 622 0 stevel (void) devfsadm_mklink(mn, node, minor, 0); 623 0 stevel (void) devfsadm_mklink(buf, node, minor, 0); 624 0 stevel 625 0 stevel return (DEVFSADM_CONTINUE); 626 0 stevel } 627 0 stevel 628 467 sc121708 /* 629 467 sc121708 * Creates /dev/ntwdt for ntwdt node 630 467 sc121708 */ 631 467 sc121708 static int 632 467 sc121708 ntwdt_create(di_minor_t minor, di_node_t node) 633 467 sc121708 { 634 467 sc121708 (void) devfsadm_mklink("ntwdt", node, minor, 0); 635 467 sc121708 return (DEVFSADM_CONTINUE); 636 467 sc121708 } 637 467 sc121708 638 0 stevel static int 639 0 stevel zcons_create(di_minor_t minor, di_node_t node) 640 0 stevel { 641 0 stevel char *minor_str; 642 0 stevel char *zonename; 643 0 stevel char path[MAXPATHLEN]; 644 0 stevel 645 0 stevel minor_str = di_minor_name(minor); 646 0 stevel 647 0 stevel if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zonename", 648 0 stevel &zonename) == -1) { 649 0 stevel return (DEVFSADM_CONTINUE); 650 0 stevel } 651 0 stevel 652 0 stevel (void) snprintf(path, sizeof (path), "zcons/%s/%s", zonename, 653 0 stevel minor_str); 654 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 655 0 stevel 656 0 stevel return (DEVFSADM_CONTINUE); 657 0 stevel } 658 0 stevel 659 0 stevel /* 660 0 stevel * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self 661 0 stevel */ 662 0 stevel static int 663 0 stevel cpuid(di_minor_t minor, di_node_t node) 664 0 stevel { 665 0 stevel (void) devfsadm_mklink(CPUID_SELF_NAME, node, minor, 0); 666 0 stevel return (DEVFSADM_CONTINUE); 667 0 stevel } 668 0 stevel 669 0 stevel /* 670 0 stevel * For device 671 0 stevel * /dev/spfma -> /devices/virtual-devices/fma@5:glvc 672 0 stevel */ 673 0 stevel static int 674 0 stevel glvc(di_minor_t minor, di_node_t node) 675 0 stevel { 676 0 stevel char node_name[MAXNAMELEN + 1]; 677 0 stevel 678 0 stevel (void) strcpy(node_name, di_node_name(node)); 679 0 stevel 680 0 stevel if (strncmp(node_name, "fma", 3) == 0) { 681 0 stevel /* Only one fma channel */ 682 0 stevel (void) devfsadm_mklink("spfma", node, minor, 0); 683 0 stevel } 684 0 stevel return (DEVFSADM_CONTINUE); 685 0 stevel } 686 1772 jl139090 687 1772 jl139090 /* 688 1772 jl139090 * Handles links of the form: 689 1772 jl139090 * type=ddi_pseudo;name=sckmdrv kmdrv\M0 690 1772 jl139090 * type=ddi_pseudo;name=oplkmdrv kmdrv\M0 691 1772 jl139090 */ 692 1772 jl139090 static int 693 1772 jl139090 kmdrv_create(di_minor_t minor, di_node_t node) 694 1772 jl139090 { 695 1772 jl139090 696 1772 jl139090 (void) devfsadm_mklink("kmdrv", node, minor, 0); 697 1772 jl139090 return (DEVFSADM_CONTINUE); 698 1772 jl139090 } 699