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 9203 Mark * 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 <ctype.h> 33 5254 gavinm #include <sys/mc_amd.h> 34 1676 jpk #include <bsm/devalloc.h> 35 1676 jpk 36 1676 jpk extern int system_labeled; 37 0 stevel 38 0 stevel static int lp(di_minor_t minor, di_node_t node); 39 0 stevel static int serial_dialout(di_minor_t minor, di_node_t node); 40 0 stevel static int serial(di_minor_t minor, di_node_t node); 41 0 stevel static int diskette(di_minor_t minor, di_node_t node); 42 0 stevel static int vt00(di_minor_t minor, di_node_t node); 43 0 stevel static int kdmouse(di_minor_t minor, di_node_t node); 44 0 stevel static int bmc(di_minor_t minor, di_node_t node); 45 437 mws static int smbios(di_minor_t minor, di_node_t node); 46 0 stevel static int agp_process(di_minor_t minor, di_node_t node); 47 2820 kz151634 static int drm_node(di_minor_t minor, di_node_t node); 48 1414 cindi static int mc_node(di_minor_t minor, di_node_t node); 49 3446 mrj static int xsvc(di_minor_t minor, di_node_t node); 50 5295 randyf static int srn(di_minor_t minor, di_node_t node); 51 4581 sherrym static int ucode(di_minor_t minor, di_node_t node); 52 9203 Mark static int heci(di_minor_t minor, di_node_t node); 53 9203 Mark 54 0 stevel 55 0 stevel static devfsadm_create_t misc_cbt[] = { 56 0 stevel { "vt00", "ddi_display", NULL, 57 0 stevel TYPE_EXACT, ILEVEL_0, vt00 58 2820 kz151634 }, 59 2820 kz151634 { "drm", "ddi_display:drm", NULL, 60 2820 kz151634 TYPE_EXACT, ILEVEL_0, drm_node 61 0 stevel }, 62 0 stevel { "mouse", "ddi_mouse", "mouse8042", 63 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, kdmouse 64 0 stevel }, 65 0 stevel { "pseudo", "ddi_pseudo", "bmc", 66 0 stevel TYPE_EXACT | DRV_EXACT, ILEVEL_0, bmc, 67 437 mws }, 68 437 mws { "pseudo", "ddi_pseudo", "smbios", 69 437 mws TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios, 70 0 stevel }, 71 0 stevel { "disk", "ddi_block:diskette", NULL, 72 0 stevel TYPE_EXACT, ILEVEL_1, diskette 73 0 stevel }, 74 0 stevel { "parallel", "ddi_printer", NULL, 75 0 stevel TYPE_EXACT, ILEVEL_1, lp 76 0 stevel }, 77 0 stevel { "serial", "ddi_serial:mb", NULL, 78 0 stevel TYPE_EXACT, ILEVEL_1, serial 79 0 stevel }, 80 0 stevel { "serial", "ddi_serial:dialout,mb", NULL, 81 0 stevel TYPE_EXACT, ILEVEL_1, serial_dialout 82 0 stevel }, 83 1414 cindi { "agp", "ddi_agp:pseudo", NULL, 84 0 stevel TYPE_EXACT, ILEVEL_0, agp_process 85 0 stevel }, 86 1414 cindi { "agp", "ddi_agp:target", NULL, 87 0 stevel TYPE_EXACT, ILEVEL_0, agp_process 88 0 stevel }, 89 1414 cindi { "agp", "ddi_agp:cpugart", NULL, 90 0 stevel TYPE_EXACT, ILEVEL_0, agp_process 91 0 stevel }, 92 1414 cindi { "agp", "ddi_agp:master", NULL, 93 0 stevel TYPE_EXACT, ILEVEL_0, agp_process 94 3446 mrj }, 95 3446 mrj { "pseudo", "ddi_pseudo", NULL, 96 3446 mrj TYPE_EXACT, ILEVEL_0, xsvc 97 5295 randyf }, 98 5295 randyf { "pseudo", "ddi_pseudo", NULL, 99 5295 randyf TYPE_EXACT, ILEVEL_0, srn 100 1414 cindi }, 101 1414 cindi { "memory-controller", "ddi_mem_ctrl", NULL, 102 1414 cindi TYPE_EXACT, ILEVEL_0, mc_node 103 4581 sherrym }, 104 4581 sherrym { "pseudo", "ddi_pseudo", "ucode", 105 4581 sherrym TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode, 106 9203 Mark }, 107 9203 Mark { "pseudo", "ddi_pseudo", "heci", 108 9203 Mark TYPE_EXACT | DRV_EXACT, ILEVEL_0, heci, 109 0 stevel } 110 0 stevel }; 111 0 stevel 112 0 stevel DEVFSADM_CREATE_INIT_V0(misc_cbt); 113 0 stevel 114 2820 kz151634 static char *debug_mid = "misc_mid"; 115 0 stevel 116 0 stevel typedef enum { 117 0 stevel DRIVER_AGPPSEUDO = 0, 118 0 stevel DRIVER_AGPTARGET, 119 0 stevel DRIVER_CPUGART, 120 6393 cg149915 DRIVER_AGPMASTER_DRM_I915, 121 6393 cg149915 DRIVER_AGPMASTER_DRM_RADEON, 122 2820 kz151634 DRIVER_AGPMASTER_VGATEXT, 123 0 stevel DRIVER_UNKNOWN 124 0 stevel } driver_defs_t; 125 0 stevel 126 0 stevel typedef struct { 127 0 stevel char *driver_name; 128 0 stevel int index; 129 0 stevel } driver_name_table_entry_t; 130 0 stevel 131 0 stevel static driver_name_table_entry_t driver_name_table[] = { 132 0 stevel { "agpgart", DRIVER_AGPPSEUDO }, 133 0 stevel { "agptarget", DRIVER_AGPTARGET }, 134 0 stevel { "amd64_gart", DRIVER_CPUGART }, 135 2820 kz151634 /* AGP master device managed by drm driver */ 136 6393 cg149915 { "i915", DRIVER_AGPMASTER_DRM_I915 }, 137 6393 cg149915 { "radeon", DRIVER_AGPMASTER_DRM_RADEON }, 138 2820 kz151634 { "vgatext", DRIVER_AGPMASTER_VGATEXT }, 139 0 stevel { NULL, DRIVER_UNKNOWN } 140 0 stevel }; 141 0 stevel 142 0 stevel static devfsadm_enumerate_t agptarget_rules[1] = 143 0 stevel { "^agp$/^agptarget([0-9]+)$", 1, MATCH_ALL }; 144 0 stevel static devfsadm_enumerate_t cpugart_rules[1] = 145 0 stevel { "^agp$/^cpugart([0-9]+)$", 1, MATCH_ALL }; 146 0 stevel static devfsadm_enumerate_t agpmaster_rules[1] = 147 0 stevel { "^agp$/^agpmaster([0-9]+)$", 1, MATCH_ALL }; 148 0 stevel 149 0 stevel static devfsadm_remove_t misc_remove_cbt[] = { 150 0 stevel { "vt", "vt[0-9][0-9]", RM_PRE|RM_ALWAYS, 151 4581 sherrym ILEVEL_0, devfsadm_rm_all 152 4581 sherrym }, 153 4581 sherrym { "pseudo", "^ucode$", RM_ALWAYS | RM_PRE | RM_HOT, 154 0 stevel ILEVEL_0, devfsadm_rm_all 155 0 stevel } 156 0 stevel }; 157 0 stevel 158 0 stevel DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); 159 0 stevel 160 0 stevel /* 161 0 stevel * Handles minor node type "ddi_display", in addition to generic processing 162 0 stevel * done by display(). 163 0 stevel * 164 0 stevel * This creates a /dev/vt00 link to /dev/fb, for backwards compatibility. 165 0 stevel */ 166 0 stevel /* ARGSUSED */ 167 0 stevel int 168 0 stevel vt00(di_minor_t minor, di_node_t node) 169 0 stevel { 170 0 stevel (void) devfsadm_secondary_link("vt00", "fb", 0); 171 0 stevel return (DEVFSADM_CONTINUE); 172 0 stevel } 173 0 stevel 174 0 stevel /* 175 0 stevel * type=ddi_block:diskette;addr=0,0;minor=c diskette 176 0 stevel * type=ddi_block:diskette;addr=0,0;minor=c,raw rdiskette 177 0 stevel * type=ddi_block:diskette;addr1=0;minor=c diskette\A2 178 0 stevel * type=ddi_block:diskette;addr1=0;minor=c,raw rdiskette\A2 179 0 stevel */ 180 0 stevel static int 181 0 stevel diskette(di_minor_t minor, di_node_t node) 182 0 stevel { 183 1676 jpk int flags = 0; 184 0 stevel char *a2; 185 0 stevel char link[PATH_MAX]; 186 0 stevel char *addr = di_bus_addr(node); 187 0 stevel char *mn = di_minor_name(minor); 188 0 stevel 189 1676 jpk if (system_labeled) 190 1676 jpk flags = DA_ADD|DA_FLOPPY; 191 1676 jpk 192 0 stevel if (strcmp(addr, "0,0") == 0) { 193 0 stevel if (strcmp(mn, "c") == 0) { 194 1676 jpk (void) devfsadm_mklink("diskette", node, minor, flags); 195 0 stevel } else if (strcmp(mn, "c,raw") == 0) { 196 1676 jpk (void) devfsadm_mklink("rdiskette", node, minor, flags); 197 0 stevel } 198 0 stevel 199 0 stevel } 200 0 stevel 201 0 stevel if (addr[0] == '0') { 202 0 stevel if ((a2 = strchr(addr, ',')) != NULL) { 203 0 stevel a2++; 204 0 stevel if (strcmp(mn, "c") == 0) { 205 0 stevel (void) strcpy(link, "diskette"); 206 0 stevel (void) strcat(link, a2); 207 1676 jpk (void) devfsadm_mklink(link, node, minor, 208 1676 jpk flags); 209 0 stevel } else if (strcmp(mn, "c,raw") == 0) { 210 0 stevel (void) strcpy(link, "rdiskette"); 211 0 stevel (void) strcat(link, a2); 212 1676 jpk (void) devfsadm_mklink(link, node, minor, 213 1676 jpk flags); 214 0 stevel } 215 0 stevel } 216 0 stevel } 217 0 stevel 218 0 stevel return (DEVFSADM_CONTINUE); 219 0 stevel } 220 0 stevel 221 0 stevel /* 222 0 stevel * type=ddi_printer;name=lp;addr=1,3bc lp0 223 0 stevel * type=ddi_printer;name=lp;addr=1,378 lp1 224 0 stevel * type=ddi_printer;name=lp;addr=1,278 lp2 225 0 stevel */ 226 0 stevel static int 227 0 stevel lp(di_minor_t minor, di_node_t node) 228 0 stevel { 229 0 stevel char *addr = di_bus_addr(node); 230 0 stevel char *buf; 231 0 stevel char path[PATH_MAX + 1]; 232 0 stevel devfsadm_enumerate_t rules[1] = {"^ecpp([0-9]+)$", 1, MATCH_ALL}; 233 0 stevel 234 0 stevel if (strcmp(addr, "1,3bc") == 0) { 235 0 stevel (void) devfsadm_mklink("lp0", node, minor, 0); 236 0 stevel 237 0 stevel } else if (strcmp(addr, "1,378") == 0) { 238 0 stevel (void) devfsadm_mklink("lp1", node, minor, 0); 239 0 stevel 240 0 stevel } else if (strcmp(addr, "1,278") == 0) { 241 0 stevel (void) devfsadm_mklink("lp2", node, minor, 0); 242 0 stevel } 243 0 stevel 244 0 stevel if (strcmp(di_driver_name(node), "ecpp") != 0) { 245 0 stevel return (DEVFSADM_CONTINUE); 246 0 stevel } 247 0 stevel 248 0 stevel if ((buf = di_devfs_path(node)) == NULL) { 249 0 stevel return (DEVFSADM_CONTINUE); 250 0 stevel } 251 0 stevel 252 0 stevel (void) snprintf(path, sizeof (path), "%s:%s", 253 0 stevel buf, di_minor_name(minor)); 254 0 stevel 255 0 stevel di_devfs_path_free(buf); 256 0 stevel 257 0 stevel if (devfsadm_enumerate_int(path, 0, &buf, rules, 1)) { 258 0 stevel return (DEVFSADM_CONTINUE); 259 0 stevel } 260 0 stevel 261 0 stevel (void) snprintf(path, sizeof (path), "ecpp%s", buf); 262 0 stevel free(buf); 263 0 stevel (void) devfsadm_mklink(path, node, minor, 0); 264 0 stevel return (DEVFSADM_CONTINUE); 265 0 stevel } 266 0 stevel 267 0 stevel /* 268 0 stevel * type=ddi_serial:mb;minor=a tty00 269 0 stevel * type=ddi_serial:mb;minor=b tty01 270 0 stevel * type=ddi_serial:mb;minor=c tty02 271 0 stevel * type=ddi_serial:mb;minor=d tty03 272 0 stevel */ 273 0 stevel static int 274 0 stevel serial(di_minor_t minor, di_node_t node) 275 0 stevel { 276 0 stevel 277 0 stevel char *mn = di_minor_name(minor); 278 0 stevel char link[PATH_MAX]; 279 0 stevel 280 0 stevel (void) strcpy(link, "tty"); 281 0 stevel (void) strcat(link, mn); 282 0 stevel (void) devfsadm_mklink(link, node, minor, 0); 283 0 stevel 284 0 stevel if (strcmp(mn, "a") == 0) { 285 0 stevel (void) devfsadm_mklink("tty00", node, minor, 0); 286 0 stevel 287 0 stevel } else if (strcmp(mn, "b") == 0) { 288 0 stevel (void) devfsadm_mklink("tty01", node, minor, 0); 289 0 stevel 290 0 stevel } else if (strcmp(mn, "c") == 0) { 291 0 stevel (void) devfsadm_mklink("tty02", node, minor, 0); 292 0 stevel 293 0 stevel } else if (strcmp(mn, "d") == 0) { 294 0 stevel (void) devfsadm_mklink("tty03", node, minor, 0); 295 0 stevel } 296 0 stevel return (DEVFSADM_CONTINUE); 297 0 stevel } 298 0 stevel 299 0 stevel /* 300 0 stevel * type=ddi_serial:dialout,mb;minor=a,cu ttyd0 301 0 stevel * type=ddi_serial:dialout,mb;minor=b,cu ttyd1 302 0 stevel * type=ddi_serial:dialout,mb;minor=c,cu ttyd2 303 0 stevel * type=ddi_serial:dialout,mb;minor=d,cu ttyd3 304 0 stevel */ 305 0 stevel static int 306 0 stevel serial_dialout(di_minor_t minor, di_node_t node) 307 0 stevel { 308 0 stevel char *mn = di_minor_name(minor); 309 0 stevel 310 0 stevel if (strcmp(mn, "a,cu") == 0) { 311 0 stevel (void) devfsadm_mklink("ttyd0", node, minor, 0); 312 0 stevel (void) devfsadm_mklink("cua0", node, minor, 0); 313 0 stevel 314 0 stevel } else if (strcmp(mn, "b,cu") == 0) { 315 0 stevel (void) devfsadm_mklink("ttyd1", node, minor, 0); 316 0 stevel (void) devfsadm_mklink("cua1", node, minor, 0); 317 0 stevel 318 0 stevel } else if (strcmp(mn, "c,cu") == 0) { 319 0 stevel (void) devfsadm_mklink("ttyd2", node, minor, 0); 320 0 stevel (void) devfsadm_mklink("cua2", node, minor, 0); 321 0 stevel 322 0 stevel } else if (strcmp(mn, "d,cu") == 0) { 323 0 stevel (void) devfsadm_mklink("ttyd3", node, minor, 0); 324 0 stevel (void) devfsadm_mklink("cua3", node, minor, 0); 325 0 stevel } 326 0 stevel return (DEVFSADM_CONTINUE); 327 0 stevel } 328 0 stevel 329 0 stevel static int 330 0 stevel kdmouse(di_minor_t minor, di_node_t node) 331 0 stevel { 332 0 stevel (void) devfsadm_mklink("kdmouse", node, minor, 0); 333 0 stevel return (DEVFSADM_CONTINUE); 334 0 stevel } 335 0 stevel 336 0 stevel static int 337 0 stevel bmc(di_minor_t minor, di_node_t node) 338 0 stevel { 339 0 stevel (void) devfsadm_mklink("bmc", node, minor, 0); 340 0 stevel return (DEVFSADM_CONTINUE); 341 0 stevel } 342 437 mws 343 437 mws static int 344 437 mws smbios(di_minor_t minor, di_node_t node) 345 437 mws { 346 437 mws (void) devfsadm_mklink("smbios", node, minor, 0); 347 437 mws return (DEVFSADM_CONTINUE); 348 437 mws } 349 437 mws 350 0 stevel static int 351 0 stevel agp_process(di_minor_t minor, di_node_t node) 352 0 stevel { 353 0 stevel char *minor_nm, *drv_nm; 354 0 stevel char *devfspath; 355 0 stevel char *I_path, *p_path, *buf; 356 0 stevel char *name = (char *)NULL; 357 0 stevel int i, index; 358 0 stevel devfsadm_enumerate_t rules[1]; 359 0 stevel 360 0 stevel minor_nm = di_minor_name(minor); 361 0 stevel drv_nm = di_driver_name(node); 362 0 stevel 363 0 stevel if ((minor_nm == NULL) || (drv_nm == NULL)) { 364 0 stevel return (DEVFSADM_CONTINUE); 365 0 stevel } 366 0 stevel 367 0 stevel devfsadm_print(debug_mid, "agp_process: minor=%s node=%s\n", 368 4581 sherrym minor_nm, di_node_name(node)); 369 0 stevel 370 0 stevel devfspath = di_devfs_path(node); 371 0 stevel if (devfspath == NULL) { 372 0 stevel devfsadm_print(debug_mid, "agp_process: devfspath is NULL\n"); 373 0 stevel return (DEVFSADM_CONTINUE); 374 0 stevel } 375 0 stevel 376 0 stevel I_path = (char *)malloc(PATH_MAX); 377 0 stevel 378 0 stevel if (I_path == NULL) { 379 0 stevel di_devfs_path_free(devfspath); 380 0 stevel devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 381 0 stevel return (DEVFSADM_CONTINUE); 382 0 stevel } 383 0 stevel 384 0 stevel p_path = (char *)malloc(PATH_MAX); 385 0 stevel 386 0 stevel if (p_path == NULL) { 387 0 stevel devfsadm_print(debug_mid, "agp_process: malloc failed\n"); 388 0 stevel di_devfs_path_free(devfspath); 389 0 stevel free(I_path); 390 0 stevel return (DEVFSADM_CONTINUE); 391 0 stevel } 392 0 stevel 393 0 stevel (void) strlcpy(p_path, devfspath, PATH_MAX); 394 0 stevel (void) strlcat(p_path, ":", PATH_MAX); 395 0 stevel (void) strlcat(p_path, minor_nm, PATH_MAX); 396 0 stevel di_devfs_path_free(devfspath); 397 0 stevel 398 0 stevel devfsadm_print(debug_mid, "agp_process: path %s\n", p_path); 399 0 stevel 400 0 stevel for (i = 0; ; i++) { 401 0 stevel if ((driver_name_table[i].driver_name == NULL) || 402 0 stevel (strcmp(drv_nm, driver_name_table[i].driver_name) == 0)) { 403 0 stevel index = driver_name_table[i].index; 404 0 stevel break; 405 0 stevel } 406 0 stevel } 407 0 stevel switch (index) { 408 0 stevel case DRIVER_AGPPSEUDO: 409 0 stevel devfsadm_print(debug_mid, 410 4581 sherrym "agp_process: psdeudo driver name\n"); 411 0 stevel name = "agpgart"; 412 0 stevel (void) snprintf(I_path, PATH_MAX, "%s", name); 413 0 stevel devfsadm_print(debug_mid, 414 0 stevel "mklink %s -> %s\n", I_path, p_path); 415 0 stevel 416 0 stevel (void) devfsadm_mklink(I_path, node, minor, 0); 417 0 stevel 418 0 stevel free(I_path); 419 0 stevel free(p_path); 420 0 stevel return (DEVFSADM_CONTINUE); 421 0 stevel case DRIVER_AGPTARGET: 422 0 stevel devfsadm_print(debug_mid, 423 4581 sherrym "agp_process: target driver name\n"); 424 0 stevel rules[0] = agptarget_rules[0]; 425 0 stevel name = "agptarget"; 426 0 stevel break; 427 0 stevel case DRIVER_CPUGART: 428 0 stevel devfsadm_print(debug_mid, 429 4581 sherrym "agp_process: cpugart driver name\n"); 430 0 stevel rules[0] = cpugart_rules[0]; 431 0 stevel name = "cpugart"; 432 0 stevel break; 433 6393 cg149915 case DRIVER_AGPMASTER_DRM_I915: 434 6393 cg149915 case DRIVER_AGPMASTER_DRM_RADEON: 435 2820 kz151634 case DRIVER_AGPMASTER_VGATEXT: 436 0 stevel devfsadm_print(debug_mid, 437 4581 sherrym "agp_process: agpmaster driver name\n"); 438 0 stevel rules[0] = agpmaster_rules[0]; 439 0 stevel name = "agpmaster"; 440 0 stevel break; 441 0 stevel case DRIVER_UNKNOWN: 442 0 stevel devfsadm_print(debug_mid, 443 4581 sherrym "agp_process: unknown driver name=%s\n", drv_nm); 444 0 stevel free(I_path); 445 0 stevel free(p_path); 446 0 stevel return (DEVFSADM_CONTINUE); 447 0 stevel } 448 0 stevel 449 0 stevel if (devfsadm_enumerate_int(p_path, 0, &buf, rules, 1)) { 450 0 stevel devfsadm_print(debug_mid, "agp_process: exit/coninue\n"); 451 0 stevel free(I_path); 452 0 stevel free(p_path); 453 0 stevel return (DEVFSADM_CONTINUE); 454 0 stevel } 455 0 stevel 456 0 stevel 457 0 stevel (void) snprintf(I_path, PATH_MAX, "agp/%s%s", name, buf); 458 0 stevel 459 0 stevel devfsadm_print(debug_mid, "agp_process: p_path=%s buf=%s\n", 460 4581 sherrym p_path, buf); 461 0 stevel 462 0 stevel free(buf); 463 0 stevel 464 0 stevel devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 465 0 stevel 466 0 stevel (void) devfsadm_mklink(I_path, node, minor, 0); 467 0 stevel 468 0 stevel free(p_path); 469 0 stevel free(I_path); 470 0 stevel 471 0 stevel return (DEVFSADM_CONTINUE); 472 2820 kz151634 } 473 2820 kz151634 474 2820 kz151634 static int 475 2820 kz151634 drm_node(di_minor_t minor, di_node_t node) 476 2820 kz151634 { 477 2820 kz151634 char *minor_nm, *drv_nm; 478 2820 kz151634 char *devfspath; 479 2820 kz151634 char *I_path, *p_path, *buf; 480 2820 kz151634 char *name = "card"; 481 2820 kz151634 482 2820 kz151634 devfsadm_enumerate_t drm_rules[1] = {"^dri$/^card([0-9]+)$", 1, 483 2820 kz151634 MATCH_ALL }; 484 2820 kz151634 485 2820 kz151634 486 2820 kz151634 minor_nm = di_minor_name(minor); 487 2820 kz151634 drv_nm = di_driver_name(node); 488 2820 kz151634 if ((minor_nm == NULL) || (drv_nm == NULL)) { 489 2820 kz151634 return (DEVFSADM_CONTINUE); 490 2820 kz151634 } 491 2820 kz151634 492 2820 kz151634 devfsadm_print(debug_mid, "drm_node: minor=%s node=%s type=%s\n", 493 2820 kz151634 minor_nm, di_node_name(node), di_minor_nodetype(minor)); 494 2820 kz151634 495 2820 kz151634 devfspath = di_devfs_path(node); 496 2820 kz151634 if (devfspath == NULL) { 497 2820 kz151634 devfsadm_print(debug_mid, "drm_node: devfspath is NULL\n"); 498 2820 kz151634 return (DEVFSADM_CONTINUE); 499 2820 kz151634 } 500 2820 kz151634 501 2820 kz151634 I_path = (char *)malloc(PATH_MAX); 502 2820 kz151634 503 2820 kz151634 if (I_path == NULL) { 504 2820 kz151634 di_devfs_path_free(devfspath); 505 2820 kz151634 devfsadm_print(debug_mid, "drm_node: malloc failed\n"); 506 2820 kz151634 return (DEVFSADM_CONTINUE); 507 2820 kz151634 } 508 2820 kz151634 509 2820 kz151634 p_path = (char *)malloc(PATH_MAX); 510 2820 kz151634 511 2820 kz151634 if (p_path == NULL) { 512 2820 kz151634 devfsadm_print(debug_mid, "drm_node: malloc failed\n"); 513 2820 kz151634 di_devfs_path_free(devfspath); 514 2820 kz151634 free(I_path); 515 2820 kz151634 return (DEVFSADM_CONTINUE); 516 2820 kz151634 } 517 2820 kz151634 518 2820 kz151634 (void) strlcpy(p_path, devfspath, PATH_MAX); 519 2820 kz151634 (void) strlcat(p_path, ":", PATH_MAX); 520 2820 kz151634 (void) strlcat(p_path, minor_nm, PATH_MAX); 521 2820 kz151634 di_devfs_path_free(devfspath); 522 2820 kz151634 523 2820 kz151634 devfsadm_print(debug_mid, "drm_node: p_path %s\n", p_path); 524 2820 kz151634 525 2820 kz151634 if (devfsadm_enumerate_int(p_path, 0, &buf, drm_rules, 1)) { 526 2820 kz151634 free(p_path); 527 2820 kz151634 devfsadm_print(debug_mid, "drm_node: exit/coninue\n"); 528 2820 kz151634 return (DEVFSADM_CONTINUE); 529 2820 kz151634 } 530 2820 kz151634 (void) snprintf(I_path, PATH_MAX, "dri/%s%s", name, buf); 531 2820 kz151634 532 2820 kz151634 devfsadm_print(debug_mid, "drm_node: p_path=%s buf=%s\n", 533 4581 sherrym p_path, buf); 534 2820 kz151634 535 2820 kz151634 free(buf); 536 2820 kz151634 537 2820 kz151634 devfsadm_print(debug_mid, "mklink %s -> %s\n", I_path, p_path); 538 2820 kz151634 (void) devfsadm_mklink(I_path, node, minor, 0); 539 2820 kz151634 540 2820 kz151634 free(p_path); 541 2820 kz151634 free(I_path); 542 2820 kz151634 543 2820 kz151634 return (0); 544 0 stevel } 545 1414 cindi 546 1414 cindi /* 547 1414 cindi * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd 548 1414 cindi */ 549 1414 cindi static int 550 1414 cindi mc_node(di_minor_t minor, di_node_t node) 551 1414 cindi { 552 1414 cindi const char *minorname = di_minor_name(minor); 553 1414 cindi const char *busaddr = di_bus_addr(node); 554 1414 cindi char linkpath[PATH_MAX]; 555 1414 cindi int unitaddr; 556 1414 cindi char *c; 557 1414 cindi 558 1414 cindi if (minorname == NULL || busaddr == NULL) 559 1414 cindi return (DEVFSADM_CONTINUE); 560 1414 cindi 561 1414 cindi errno = 0; 562 1414 cindi unitaddr = strtol(busaddr, &c, 16); 563 1414 cindi 564 5254 gavinm if (errno != 0) 565 1414 cindi return (DEVFSADM_CONTINUE); 566 1414 cindi 567 5254 gavinm if (unitaddr == 0) { 568 5254 gavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc"); 569 5254 gavinm } else if (unitaddr >= MC_AMD_DEV_OFFSET) { 570 5254 gavinm (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 571 5254 gavinm unitaddr - MC_AMD_DEV_OFFSET); 572 5254 gavinm } else { 573 7349 Adrian (void) snprintf(linkpath, sizeof (linkpath), "mc/mc%u", 574 7349 Adrian minor->dev_minor); 575 5254 gavinm } 576 1414 cindi (void) devfsadm_mklink(linkpath, node, minor, 0); 577 1414 cindi return (DEVFSADM_CONTINUE); 578 1414 cindi } 579 3446 mrj 580 3446 mrj /* 581 3446 mrj * Creates \M0 devlink for xsvc node 582 3446 mrj */ 583 3446 mrj static int 584 3446 mrj xsvc(di_minor_t minor, di_node_t node) 585 3446 mrj { 586 3446 mrj char *mn; 587 3446 mrj 588 3446 mrj if (strcmp(di_node_name(node), "xsvc") != 0) 589 3446 mrj return (DEVFSADM_CONTINUE); 590 3446 mrj 591 3446 mrj mn = di_minor_name(minor); 592 3446 mrj if (mn == NULL) 593 3446 mrj return (DEVFSADM_CONTINUE); 594 3446 mrj 595 3446 mrj (void) devfsadm_mklink(mn, node, minor, 0); 596 3446 mrj return (DEVFSADM_CONTINUE); 597 3446 mrj } 598 4581 sherrym 599 4581 sherrym /* 600 5295 randyf * Creates \M0 devlink for srn device 601 5295 randyf */ 602 5295 randyf static int 603 5295 randyf srn(di_minor_t minor, di_node_t node) 604 5295 randyf { 605 5295 randyf char *mn; 606 5295 randyf 607 5295 randyf if (strcmp(di_node_name(node), "srn") != 0) 608 5295 randyf return (DEVFSADM_CONTINUE); 609 5295 randyf 610 5295 randyf mn = di_minor_name(minor); 611 5295 randyf if (mn == NULL) 612 5295 randyf return (DEVFSADM_CONTINUE); 613 5295 randyf 614 5295 randyf (void) devfsadm_mklink(mn, node, minor, 0); 615 5295 randyf return (DEVFSADM_CONTINUE); 616 5295 randyf } 617 5295 randyf 618 5295 randyf /* 619 4581 sherrym * /dev/ucode -> /devices/pseudo/ucode@0:ucode 620 4581 sherrym */ 621 4581 sherrym static int 622 4581 sherrym ucode(di_minor_t minor, di_node_t node) 623 4581 sherrym { 624 4581 sherrym (void) devfsadm_mklink("ucode", node, minor, 0); 625 4581 sherrym return (DEVFSADM_CONTINUE); 626 4581 sherrym } 627 9203 Mark 628 9203 Mark static int 629 9203 Mark heci(di_minor_t minor, di_node_t node) 630 9203 Mark { 631 9203 Mark if (strcmp(di_minor_name(minor), "AMT") == 0) { 632 9203 Mark (void) devfsadm_mklink("heci", node, minor, 0); 633 9203 Mark } 634 9203 Mark return (DEVFSADM_CONTINUE); 635 9203 Mark } 636