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 (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 24 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. 25 * Copyright (c) 2013, Joyent, Inc. All rights reserved. 26 * Copyright (c) 2016 by Delphix. All rights reserved. 27 * Copyright 2020 Joshua M. Clulow <josh@sysmgr.org> 28 */ 29 30 #include <sys/note.h> 31 #include <sys/t_lock.h> 32 #include <sys/cmn_err.h> 33 #include <sys/instance.h> 34 #include <sys/conf.h> 35 #include <sys/stat.h> 36 #include <sys/ddi.h> 37 #include <sys/hwconf.h> 38 #include <sys/sunddi.h> 39 #include <sys/sunndi.h> 40 #include <sys/ddi_impldefs.h> 41 #include <sys/ndi_impldefs.h> 42 #include <sys/modctl.h> 43 #include <sys/contract/device_impl.h> 44 #include <sys/dacf.h> 45 #include <sys/promif.h> 46 #include <sys/pci.h> 47 #include <sys/cpuvar.h> 48 #include <sys/pathname.h> 49 #include <sys/taskq.h> 50 #include <sys/sysevent.h> 51 #include <sys/sunmdi.h> 52 #include <sys/stream.h> 53 #include <sys/strsubr.h> 54 #include <sys/fs/snode.h> 55 #include <sys/fs/dv_node.h> 56 #include <sys/reboot.h> 57 #include <sys/sysmacros.h> 58 #include <sys/systm.h> 59 #include <sys/fs/sdev_impl.h> 60 #include <sys/sunldi.h> 61 #include <sys/sunldi_impl.h> 62 #include <sys/bootprops.h> 63 #include <sys/varargs.h> 64 #include <sys/modhash.h> 65 #include <sys/instance.h> 66 #include <sys/sysevent/eventdefs.h> 67 68 #if defined(__amd64) && !defined(__xpv) 69 #include <sys/iommulib.h> 70 #endif 71 72 #ifdef DEBUG 73 int ddidebug = DDI_AUDIT; 74 #else 75 int ddidebug = 0; 76 #endif 77 78 #define MT_CONFIG_OP 0 79 #define MT_UNCONFIG_OP 1 80 81 /* Multi-threaded configuration */ 82 struct mt_config_handle { 83 kmutex_t mtc_lock; 84 kcondvar_t mtc_cv; 85 int mtc_thr_count; 86 dev_info_t *mtc_pdip; /* parent dip for mt_config_children */ 87 dev_info_t **mtc_fdip; /* "a" dip where unconfigure failed */ 88 major_t mtc_parmajor; /* parent major for mt_config_driver */ 89 major_t mtc_major; 90 int mtc_flags; 91 int mtc_op; /* config or unconfig */ 92 int mtc_error; /* operation error */ 93 struct brevq_node **mtc_brevqp; /* outstanding branch events queue */ 94 #ifdef DEBUG 95 int total_time; 96 timestruc_t start_time; 97 #endif /* DEBUG */ 98 }; 99 100 struct devi_nodeid { 101 pnode_t nodeid; 102 dev_info_t *dip; 103 struct devi_nodeid *next; 104 }; 105 106 struct devi_nodeid_list { 107 kmutex_t dno_lock; /* Protects other fields */ 108 struct devi_nodeid *dno_head; /* list of devi nodeid elements */ 109 struct devi_nodeid *dno_free; /* Free list */ 110 uint_t dno_list_length; /* number of dips in list */ 111 }; 112 113 /* used to keep track of branch remove events to be generated */ 114 struct brevq_node { 115 char *brn_deviname; 116 struct brevq_node *brn_sibling; 117 struct brevq_node *brn_child; 118 }; 119 120 static struct devi_nodeid_list devi_nodeid_list; 121 static struct devi_nodeid_list *devimap = &devi_nodeid_list; 122 123 /* 124 * Well known nodes which are attached first at boot time. 125 */ 126 dev_info_t *top_devinfo; /* root of device tree */ 127 dev_info_t *options_dip; 128 dev_info_t *pseudo_dip; 129 dev_info_t *clone_dip; 130 dev_info_t *scsi_vhci_dip; /* MPXIO dip */ 131 major_t clone_major; 132 133 /* 134 * A non-global zone's /dev is derived from the device tree. 135 * This generation number serves to indicate when a zone's 136 * /dev may need to be updated. 137 */ 138 volatile ulong_t devtree_gen; /* generation number */ 139 140 /* block all future dev_info state changes */ 141 hrtime_t volatile devinfo_freeze = 0; 142 143 /* number of dev_info attaches/detaches currently in progress */ 144 static ulong_t devinfo_attach_detach = 0; 145 146 extern int sys_shutdown; 147 extern kmutex_t global_vhci_lock; 148 149 /* bitset of DS_SYSAVAIL & DS_RECONFIG - no races, no lock */ 150 static int devname_state = 0; 151 152 /* 153 * The devinfo snapshot cache and related variables. 154 * The only field in the di_cache structure that needs initialization 155 * is the mutex (cache_lock). However, since this is an adaptive mutex 156 * (MUTEX_DEFAULT) - it is automatically initialized by being allocated 157 * in zeroed memory (static storage class). Therefore no explicit 158 * initialization of the di_cache structure is needed. 159 */ 160 struct di_cache di_cache = {1}; 161 int di_cache_debug = 0; 162 163 /* For ddvis, which needs pseudo children under PCI */ 164 int pci_allow_pseudo_children = 0; 165 166 /* Allow path-oriented alias driver binding on driver.conf enumerated nodes */ 167 int driver_conf_allow_path_alias = 1; 168 169 /* 170 * The following switch is for service people, in case a 171 * 3rd party driver depends on identify(9e) being called. 172 */ 173 int identify_9e = 0; 174 175 /* 176 * Add flag so behaviour of preventing attach for retired persistant nodes 177 * can be disabled. 178 */ 179 int retire_prevents_attach = 1; 180 181 int mtc_off; /* turn off mt config */ 182 183 int quiesce_debug = 0; 184 185 boolean_t ddi_aliases_present = B_FALSE; 186 ddi_alias_t ddi_aliases; 187 uint_t tsd_ddi_redirect; 188 189 #define DDI_ALIAS_HASH_SIZE (2700) 190 191 static kmem_cache_t *ddi_node_cache; /* devinfo node cache */ 192 static devinfo_log_header_t *devinfo_audit_log; /* devinfo log */ 193 static int devinfo_log_size; /* size in pages */ 194 195 boolean_t ddi_err_panic = B_FALSE; 196 197 static int lookup_compatible(dev_info_t *, uint_t); 198 static char *encode_composite_string(char **, uint_t, size_t *, uint_t); 199 static void link_to_driver_list(dev_info_t *); 200 static void unlink_from_driver_list(dev_info_t *); 201 static void add_to_dn_list(struct devnames *, dev_info_t *); 202 static void remove_from_dn_list(struct devnames *, dev_info_t *); 203 static dev_info_t *find_duplicate_child(); 204 static void add_global_props(dev_info_t *); 205 static void remove_global_props(dev_info_t *); 206 static int uninit_node(dev_info_t *); 207 static void da_log_init(void); 208 static void da_log_enter(dev_info_t *); 209 static int walk_devs(dev_info_t *, int (*f)(dev_info_t *, void *), void *, int); 210 static int reset_nexus_flags(dev_info_t *, void *); 211 static void ddi_optimize_dtree(dev_info_t *); 212 static int is_leaf_node(dev_info_t *); 213 static struct mt_config_handle *mt_config_init(dev_info_t *, dev_info_t **, 214 int, major_t, int, struct brevq_node **); 215 static void mt_config_children(struct mt_config_handle *); 216 static void mt_config_driver(struct mt_config_handle *); 217 static int mt_config_fini(struct mt_config_handle *); 218 static int devi_unconfig_common(dev_info_t *, dev_info_t **, int, major_t, 219 struct brevq_node **); 220 static int 221 ndi_devi_config_obp_args(dev_info_t *parent, char *devnm, 222 dev_info_t **childp, int flags); 223 static void i_link_vhci_node(dev_info_t *); 224 static void ndi_devi_exit_and_wait(dev_info_t *dip, 225 int circular, clock_t end_time); 226 static int ndi_devi_unbind_driver(dev_info_t *dip); 227 228 static int i_ddi_check_retire(dev_info_t *dip); 229 230 static void quiesce_one_device(dev_info_t *, void *); 231 232 dev_info_t *ddi_alias_redirect(char *alias); 233 char *ddi_curr_redirect(char *currpath); 234 235 236 /* 237 * dev_info cache and node management 238 */ 239 240 /* initialize dev_info node cache */ 241 void 242 i_ddi_node_cache_init() 243 { 244 ASSERT(ddi_node_cache == NULL); 245 ddi_node_cache = kmem_cache_create("dev_info_node_cache", 246 sizeof (struct dev_info), 0, NULL, NULL, NULL, NULL, NULL, 0); 247 248 if (ddidebug & DDI_AUDIT) 249 da_log_init(); 250 } 251 252 253 /* 254 * Allocating a dev_info node, callable from interrupt context with KM_NOSLEEP 255 * The allocated node has a reference count of 0. 256 */ 257 dev_info_t * 258 i_ddi_alloc_node(dev_info_t *pdip, const char *node_name, pnode_t nodeid, 259 int instance, ddi_prop_t *sys_prop, int flag) 260 { 261 struct dev_info *devi; 262 struct devi_nodeid *elem; 263 static char failed[] = "i_ddi_alloc_node: out of memory"; 264 265 ASSERT(node_name != NULL); 266 267 if ((devi = kmem_cache_alloc(ddi_node_cache, flag)) == NULL) { 268 cmn_err(CE_NOTE, failed); 269 return (NULL); 270 } 271 272 bzero(devi, sizeof (struct dev_info)); 273 274 if (devinfo_audit_log) { 275 devi->devi_audit = kmem_zalloc(sizeof (devinfo_audit_t), flag); 276 if (devi->devi_audit == NULL) 277 goto fail; 278 } 279 280 if ((devi->devi_node_name = i_ddi_strdup(node_name, flag)) == NULL) 281 goto fail; 282 283 /* default binding name is node name */ 284 devi->devi_binding_name = devi->devi_node_name; 285 devi->devi_major = DDI_MAJOR_T_NONE; /* unbound by default */ 286 287 /* 288 * Make a copy of system property 289 */ 290 if (sys_prop && 291 (devi->devi_sys_prop_ptr = i_ddi_prop_list_dup(sys_prop, flag)) 292 == NULL) 293 goto fail; 294 295 /* 296 * Assign devi_nodeid, devi_node_class, devi_node_attributes 297 * according to the following algorithm: 298 * 299 * nodeid arg node class node attributes 300 * 301 * DEVI_PSEUDO_NODEID DDI_NC_PSEUDO A 302 * DEVI_SID_NODEID DDI_NC_PSEUDO A,P 303 * DEVI_SID_HIDDEN_NODEID DDI_NC_PSEUDO A,P,H 304 * DEVI_SID_HP_NODEID DDI_NC_PSEUDO A,P,h 305 * DEVI_SID_HP_HIDDEN_NODEID DDI_NC_PSEUDO A,P,H,h 306 * other DDI_NC_PROM P 307 * 308 * Where A = DDI_AUTO_ASSIGNED_NODEID (auto-assign a nodeid) 309 * and P = DDI_PERSISTENT 310 * and H = DDI_HIDDEN_NODE 311 * and h = DDI_HOTPLUG_NODE 312 * 313 * auto-assigned nodeids are also auto-freed. 314 */ 315 devi->devi_node_attributes = 0; 316 elem = NULL; 317 switch (nodeid) { 318 case DEVI_SID_HIDDEN_NODEID: 319 devi->devi_node_attributes |= DDI_HIDDEN_NODE; 320 goto sid; 321 322 case DEVI_SID_HP_NODEID: 323 devi->devi_node_attributes |= DDI_HOTPLUG_NODE; 324 goto sid; 325 326 case DEVI_SID_HP_HIDDEN_NODEID: 327 devi->devi_node_attributes |= DDI_HIDDEN_NODE; 328 devi->devi_node_attributes |= DDI_HOTPLUG_NODE; 329 goto sid; 330 331 case DEVI_SID_NODEID: 332 sid: devi->devi_node_attributes |= DDI_PERSISTENT; 333 if ((elem = kmem_zalloc(sizeof (*elem), flag)) == NULL) 334 goto fail; 335 /*FALLTHROUGH*/ 336 337 case DEVI_PSEUDO_NODEID: 338 devi->devi_node_attributes |= DDI_AUTO_ASSIGNED_NODEID; 339 devi->devi_node_class = DDI_NC_PSEUDO; 340 if (impl_ddi_alloc_nodeid(&devi->devi_nodeid)) { 341 panic("i_ddi_alloc_node: out of nodeids"); 342 /*NOTREACHED*/ 343 } 344 break; 345 346 default: 347 if ((elem = kmem_zalloc(sizeof (*elem), flag)) == NULL) 348 goto fail; 349 350 /* 351 * the nodetype is 'prom', try to 'take' the nodeid now. 352 * This requires memory allocation, so check for failure. 353 */ 354 if (impl_ddi_take_nodeid(nodeid, flag) != 0) { 355 kmem_free(elem, sizeof (*elem)); 356 goto fail; 357 } 358 359 devi->devi_nodeid = nodeid; 360 devi->devi_node_class = DDI_NC_PROM; 361 devi->devi_node_attributes = DDI_PERSISTENT; 362 break; 363 } 364 365 if (ndi_dev_is_persistent_node((dev_info_t *)devi)) { 366 mutex_enter(&devimap->dno_lock); 367 elem->next = devimap->dno_free; 368 devimap->dno_free = elem; 369 mutex_exit(&devimap->dno_lock); 370 } 371 372 /* 373 * Instance is normally initialized to -1. In a few special 374 * cases, the caller may specify an instance (e.g. CPU nodes). 375 */ 376 devi->devi_instance = instance; 377 378 /* 379 * set parent and bus_ctl parent 380 */ 381 devi->devi_parent = DEVI(pdip); 382 devi->devi_bus_ctl = DEVI(pdip); 383 384 NDI_CONFIG_DEBUG((CE_CONT, 385 "i_ddi_alloc_node: name=%s id=%d\n", node_name, devi->devi_nodeid)); 386 387 cv_init(&(devi->devi_cv), NULL, CV_DEFAULT, NULL); 388 mutex_init(&(devi->devi_lock), NULL, MUTEX_DEFAULT, NULL); 389 mutex_init(&(devi->devi_pm_lock), NULL, MUTEX_DEFAULT, NULL); 390 mutex_init(&(devi->devi_pm_busy_lock), NULL, MUTEX_DEFAULT, NULL); 391 392 RIO_TRACE((CE_NOTE, "i_ddi_alloc_node: Initing contract fields: " 393 "dip=%p, name=%s", (void *)devi, node_name)); 394 395 mutex_init(&(devi->devi_ct_lock), NULL, MUTEX_DEFAULT, NULL); 396 cv_init(&(devi->devi_ct_cv), NULL, CV_DEFAULT, NULL); 397 devi->devi_ct_count = -1; /* counter not in use if -1 */ 398 list_create(&(devi->devi_ct), sizeof (cont_device_t), 399 offsetof(cont_device_t, cond_next)); 400 401 i_ddi_set_node_state((dev_info_t *)devi, DS_PROTO); 402 da_log_enter((dev_info_t *)devi); 403 return ((dev_info_t *)devi); 404 405 fail: 406 if (devi->devi_sys_prop_ptr) 407 i_ddi_prop_list_delete(devi->devi_sys_prop_ptr); 408 if (devi->devi_node_name) 409 kmem_free(devi->devi_node_name, strlen(node_name) + 1); 410 if (devi->devi_audit) 411 kmem_free(devi->devi_audit, sizeof (devinfo_audit_t)); 412 kmem_cache_free(ddi_node_cache, devi); 413 cmn_err(CE_NOTE, failed); 414 return (NULL); 415 } 416 417 /* 418 * free a dev_info structure. 419 * NB. Not callable from interrupt since impl_ddi_free_nodeid may block. 420 */ 421 void 422 i_ddi_free_node(dev_info_t *dip) 423 { 424 struct dev_info *devi = DEVI(dip); 425 struct devi_nodeid *elem; 426 427 ASSERT(devi->devi_ref == 0); 428 ASSERT(devi->devi_addr == NULL); 429 ASSERT(devi->devi_node_state == DS_PROTO); 430 ASSERT(devi->devi_child == NULL); 431 ASSERT(devi->devi_hp_hdlp == NULL); 432 433 /* free devi_addr_buf allocated by ddi_set_name_addr() */ 434 if (devi->devi_addr_buf) 435 kmem_free(devi->devi_addr_buf, 2 * MAXNAMELEN); 436 437 if (i_ndi_dev_is_auto_assigned_node(dip)) 438 impl_ddi_free_nodeid(DEVI(dip)->devi_nodeid); 439 440 if (ndi_dev_is_persistent_node(dip)) { 441 mutex_enter(&devimap->dno_lock); 442 ASSERT(devimap->dno_free); 443 elem = devimap->dno_free; 444 devimap->dno_free = elem->next; 445 mutex_exit(&devimap->dno_lock); 446 kmem_free(elem, sizeof (*elem)); 447 } 448 449 if (DEVI(dip)->devi_compat_names) 450 kmem_free(DEVI(dip)->devi_compat_names, 451 DEVI(dip)->devi_compat_length); 452 if (DEVI(dip)->devi_rebinding_name) 453 kmem_free(DEVI(dip)->devi_rebinding_name, 454 strlen(DEVI(dip)->devi_rebinding_name) + 1); 455 456 ddi_prop_remove_all(dip); /* remove driver properties */ 457 if (devi->devi_sys_prop_ptr) 458 i_ddi_prop_list_delete(devi->devi_sys_prop_ptr); 459 if (devi->devi_hw_prop_ptr) 460 i_ddi_prop_list_delete(devi->devi_hw_prop_ptr); 461 462 if (DEVI(dip)->devi_devid_str) 463 ddi_devid_str_free(DEVI(dip)->devi_devid_str); 464 465 i_ddi_set_node_state(dip, DS_INVAL); 466 da_log_enter(dip); 467 if (devi->devi_audit) { 468 kmem_free(devi->devi_audit, sizeof (devinfo_audit_t)); 469 } 470 if (devi->devi_device_class) 471 kmem_free(devi->devi_device_class, 472 strlen(devi->devi_device_class) + 1); 473 cv_destroy(&(devi->devi_cv)); 474 mutex_destroy(&(devi->devi_lock)); 475 mutex_destroy(&(devi->devi_pm_lock)); 476 mutex_destroy(&(devi->devi_pm_busy_lock)); 477 478 RIO_TRACE((CE_NOTE, "i_ddi_free_node: destroying contract fields: " 479 "dip=%p", (void *)dip)); 480 contract_device_remove_dip(dip); 481 ASSERT(devi->devi_ct_count == -1); 482 ASSERT(list_is_empty(&(devi->devi_ct))); 483 cv_destroy(&(devi->devi_ct_cv)); 484 list_destroy(&(devi->devi_ct)); 485 /* free this last since contract_device_remove_dip() uses it */ 486 mutex_destroy(&(devi->devi_ct_lock)); 487 RIO_TRACE((CE_NOTE, "i_ddi_free_node: destroyed all contract fields: " 488 "dip=%p, name=%s", (void *)dip, devi->devi_node_name)); 489 490 kmem_free(devi->devi_node_name, strlen(devi->devi_node_name) + 1); 491 492 /* free event data */ 493 if (devi->devi_ev_path) 494 kmem_free(devi->devi_ev_path, MAXPATHLEN); 495 496 kmem_cache_free(ddi_node_cache, devi); 497 } 498 499 500 /* 501 * Node state transitions 502 */ 503 504 /* 505 * Change the node name 506 */ 507 int 508 ndi_devi_set_nodename(dev_info_t *dip, char *name, int flags) 509 { 510 _NOTE(ARGUNUSED(flags)) 511 char *nname, *oname; 512 513 ASSERT(dip && name); 514 515 oname = DEVI(dip)->devi_node_name; 516 if (strcmp(oname, name) == 0) 517 return (DDI_SUCCESS); 518 519 /* 520 * pcicfg_fix_ethernet requires a name change after node 521 * is linked into the tree. When pcicfg is fixed, we 522 * should only allow name change in DS_PROTO state. 523 */ 524 if (i_ddi_node_state(dip) >= DS_BOUND) { 525 /* 526 * Don't allow name change once node is bound 527 */ 528 cmn_err(CE_NOTE, 529 "ndi_devi_set_nodename: node already bound dip = %p," 530 " %s -> %s", (void *)dip, ddi_node_name(dip), name); 531 return (NDI_FAILURE); 532 } 533 534 nname = i_ddi_strdup(name, KM_SLEEP); 535 DEVI(dip)->devi_node_name = nname; 536 i_ddi_set_binding_name(dip, nname); 537 kmem_free(oname, strlen(oname) + 1); 538 539 da_log_enter(dip); 540 return (NDI_SUCCESS); 541 } 542 543 void 544 i_ddi_add_devimap(dev_info_t *dip) 545 { 546 struct devi_nodeid *elem; 547 548 ASSERT(dip); 549 550 if (!ndi_dev_is_persistent_node(dip)) 551 return; 552 553 ASSERT(ddi_get_parent(dip) == NULL || (DEVI_VHCI_NODE(dip)) || 554 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 555 556 mutex_enter(&devimap->dno_lock); 557 558 ASSERT(devimap->dno_free); 559 560 elem = devimap->dno_free; 561 devimap->dno_free = elem->next; 562 563 elem->nodeid = ddi_get_nodeid(dip); 564 elem->dip = dip; 565 elem->next = devimap->dno_head; 566 devimap->dno_head = elem; 567 568 devimap->dno_list_length++; 569 570 mutex_exit(&devimap->dno_lock); 571 } 572 573 static int 574 i_ddi_remove_devimap(dev_info_t *dip) 575 { 576 struct devi_nodeid *prev, *elem; 577 static const char *fcn = "i_ddi_remove_devimap"; 578 579 ASSERT(dip); 580 581 if (!ndi_dev_is_persistent_node(dip)) 582 return (DDI_SUCCESS); 583 584 mutex_enter(&devimap->dno_lock); 585 586 /* 587 * The following check is done with dno_lock held 588 * to prevent race between dip removal and 589 * e_ddi_prom_node_to_dip() 590 */ 591 if (e_ddi_devi_holdcnt(dip)) { 592 mutex_exit(&devimap->dno_lock); 593 return (DDI_FAILURE); 594 } 595 596 ASSERT(devimap->dno_head); 597 ASSERT(devimap->dno_list_length > 0); 598 599 prev = NULL; 600 for (elem = devimap->dno_head; elem; elem = elem->next) { 601 if (elem->dip == dip) { 602 ASSERT(elem->nodeid == ddi_get_nodeid(dip)); 603 break; 604 } 605 prev = elem; 606 } 607 608 if (elem && prev) 609 prev->next = elem->next; 610 else if (elem) 611 devimap->dno_head = elem->next; 612 else 613 panic("%s: devinfo node(%p) not found", 614 fcn, (void *)dip); 615 616 devimap->dno_list_length--; 617 618 elem->nodeid = 0; 619 elem->dip = NULL; 620 621 elem->next = devimap->dno_free; 622 devimap->dno_free = elem; 623 624 mutex_exit(&devimap->dno_lock); 625 626 return (DDI_SUCCESS); 627 } 628 629 /* 630 * Link this node into the devinfo tree and add to orphan list 631 * Not callable from interrupt context 632 */ 633 static void 634 link_node(dev_info_t *dip) 635 { 636 struct dev_info *devi = DEVI(dip); 637 struct dev_info *parent = devi->devi_parent; 638 dev_info_t **dipp; 639 640 ASSERT(parent); /* never called for root node */ 641 642 NDI_CONFIG_DEBUG((CE_CONT, "link_node: parent = %s child = %s\n", 643 parent->devi_node_name, devi->devi_node_name)); 644 645 /* 646 * Hold the global_vhci_lock before linking any direct 647 * children of rootnex driver. This special lock protects 648 * linking and unlinking for rootnext direct children. 649 */ 650 if ((dev_info_t *)parent == ddi_root_node()) 651 mutex_enter(&global_vhci_lock); 652 653 /* 654 * attach the node to end of the list unless the node is already there 655 */ 656 dipp = (dev_info_t **)(&DEVI(parent)->devi_child); 657 while (*dipp && (*dipp != dip)) { 658 dipp = (dev_info_t **)(&DEVI(*dipp)->devi_sibling); 659 } 660 ASSERT(*dipp == NULL); /* node is not linked */ 661 662 /* 663 * Now that we are in the tree, update the devi-nodeid map. 664 */ 665 i_ddi_add_devimap(dip); 666 667 /* 668 * This is a temporary workaround for Bug 4618861. 669 * We keep the scsi_vhci nexus node on the left side of the devinfo 670 * tree (under the root nexus driver), so that virtual nodes under 671 * scsi_vhci will be SUSPENDed first and RESUMEd last. This ensures 672 * that the pHCI nodes are active during times when their clients 673 * may be depending on them. This workaround embodies the knowledge 674 * that system PM and CPR both traverse the tree left-to-right during 675 * SUSPEND and right-to-left during RESUME. 676 * Extending the workaround to IB Nexus/VHCI 677 * driver also. 678 */ 679 if (strcmp(devi->devi_binding_name, "scsi_vhci") == 0) { 680 /* Add scsi_vhci to beginning of list */ 681 ASSERT((dev_info_t *)parent == top_devinfo); 682 /* scsi_vhci under rootnex */ 683 devi->devi_sibling = parent->devi_child; 684 parent->devi_child = devi; 685 } else if (strcmp(devi->devi_binding_name, "ib") == 0) { 686 i_link_vhci_node(dip); 687 } else { 688 /* Add to end of list */ 689 *dipp = dip; 690 DEVI(dip)->devi_sibling = NULL; 691 } 692 693 /* 694 * Release the global_vhci_lock before linking any direct 695 * children of rootnex driver. 696 */ 697 if ((dev_info_t *)parent == ddi_root_node()) 698 mutex_exit(&global_vhci_lock); 699 700 /* persistent nodes go on orphan list */ 701 if (ndi_dev_is_persistent_node(dip)) 702 add_to_dn_list(&orphanlist, dip); 703 } 704 705 /* 706 * Unlink this node from the devinfo tree 707 */ 708 static int 709 unlink_node(dev_info_t *dip) 710 { 711 struct dev_info *devi = DEVI(dip); 712 struct dev_info *parent = devi->devi_parent; 713 dev_info_t **dipp; 714 ddi_hp_cn_handle_t *hdlp; 715 716 ASSERT(parent != NULL); 717 ASSERT(devi->devi_node_state == DS_LINKED); 718 719 NDI_CONFIG_DEBUG((CE_CONT, "unlink_node: name = %s\n", 720 ddi_node_name(dip))); 721 722 /* check references */ 723 if (devi->devi_ref || i_ddi_remove_devimap(dip) != DDI_SUCCESS) 724 return (DDI_FAILURE); 725 726 /* 727 * Hold the global_vhci_lock before linking any direct 728 * children of rootnex driver. 729 */ 730 if ((dev_info_t *)parent == ddi_root_node()) 731 mutex_enter(&global_vhci_lock); 732 733 dipp = (dev_info_t **)(&DEVI(parent)->devi_child); 734 while (*dipp && (*dipp != dip)) { 735 dipp = (dev_info_t **)(&DEVI(*dipp)->devi_sibling); 736 } 737 if (*dipp) { 738 *dipp = (dev_info_t *)(devi->devi_sibling); 739 devi->devi_sibling = NULL; 740 } else { 741 NDI_CONFIG_DEBUG((CE_NOTE, "unlink_node: %s not linked", 742 devi->devi_node_name)); 743 } 744 745 /* 746 * Release the global_vhci_lock before linking any direct 747 * children of rootnex driver. 748 */ 749 if ((dev_info_t *)parent == ddi_root_node()) 750 mutex_exit(&global_vhci_lock); 751 752 /* Remove node from orphan list */ 753 if (ndi_dev_is_persistent_node(dip)) { 754 remove_from_dn_list(&orphanlist, dip); 755 } 756 757 /* Update parent's hotplug handle list */ 758 for (hdlp = DEVI(parent)->devi_hp_hdlp; hdlp; hdlp = hdlp->next) { 759 if (hdlp->cn_info.cn_child == dip) 760 hdlp->cn_info.cn_child = NULL; 761 } 762 return (DDI_SUCCESS); 763 } 764 765 /* 766 * Bind this devinfo node to a driver. If compat is NON-NULL, try that first. 767 * Else, use the node-name. 768 * 769 * NOTE: IEEE1275 specifies that nodename should be tried before compatible. 770 * Solaris implementation binds nodename after compatible. 771 * 772 * If we find a binding, 773 * - set the binding name to the string, 774 * - set major number to driver major 775 * 776 * If we don't find a binding, 777 * - return failure 778 */ 779 static int 780 bind_node(dev_info_t *dip) 781 { 782 char *p = NULL; 783 major_t major = DDI_MAJOR_T_NONE; 784 struct dev_info *devi = DEVI(dip); 785 dev_info_t *parent = ddi_get_parent(dip); 786 787 ASSERT(devi->devi_node_state == DS_LINKED); 788 789 NDI_CONFIG_DEBUG((CE_CONT, "bind_node: 0x%p(name = %s)\n", 790 (void *)dip, ddi_node_name(dip))); 791 792 mutex_enter(&DEVI(dip)->devi_lock); 793 if (DEVI(dip)->devi_flags & DEVI_NO_BIND) { 794 mutex_exit(&DEVI(dip)->devi_lock); 795 return (DDI_FAILURE); 796 } 797 mutex_exit(&DEVI(dip)->devi_lock); 798 799 /* find the driver with most specific binding using compatible */ 800 major = ddi_compatible_driver_major(dip, &p); 801 if (major == DDI_MAJOR_T_NONE) 802 return (DDI_FAILURE); 803 804 devi->devi_major = major; 805 if (p != NULL) { 806 i_ddi_set_binding_name(dip, p); 807 NDI_CONFIG_DEBUG((CE_CONT, "bind_node: %s bound to %s\n", 808 devi->devi_node_name, p)); 809 } 810 811 /* Link node to per-driver list */ 812 link_to_driver_list(dip); 813 814 /* 815 * reset parent flag so that nexus will merge .conf props 816 */ 817 if (ndi_dev_is_persistent_node(dip)) { 818 mutex_enter(&DEVI(parent)->devi_lock); 819 DEVI(parent)->devi_flags &= 820 ~(DEVI_ATTACHED_CHILDREN|DEVI_MADE_CHILDREN); 821 mutex_exit(&DEVI(parent)->devi_lock); 822 } 823 return (DDI_SUCCESS); 824 } 825 826 /* 827 * Unbind this devinfo node 828 * Called before the node is destroyed or driver is removed from system 829 */ 830 static int 831 unbind_node(dev_info_t *dip) 832 { 833 ASSERT(DEVI(dip)->devi_node_state == DS_BOUND); 834 ASSERT(DEVI(dip)->devi_major != DDI_MAJOR_T_NONE); 835 836 /* check references */ 837 if (DEVI(dip)->devi_ref) 838 return (DDI_FAILURE); 839 840 NDI_CONFIG_DEBUG((CE_CONT, "unbind_node: 0x%p(name = %s)\n", 841 (void *)dip, ddi_node_name(dip))); 842 843 unlink_from_driver_list(dip); 844 845 DEVI(dip)->devi_major = DDI_MAJOR_T_NONE; 846 DEVI(dip)->devi_binding_name = DEVI(dip)->devi_node_name; 847 return (DDI_SUCCESS); 848 } 849 850 /* 851 * Initialize a node: calls the parent nexus' bus_ctl ops to do the operation. 852 * Must hold parent and per-driver list while calling this function. 853 * A successful init_node() returns with an active ndi_hold_devi() hold on 854 * the parent. 855 */ 856 static int 857 init_node(dev_info_t *dip) 858 { 859 int error; 860 dev_info_t *pdip = ddi_get_parent(dip); 861 int (*f)(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, void *, void *); 862 char *path; 863 major_t major; 864 ddi_devid_t devid = NULL; 865 866 ASSERT(i_ddi_node_state(dip) == DS_BOUND); 867 868 /* should be DS_READY except for pcmcia ... */ 869 ASSERT(i_ddi_node_state(pdip) >= DS_PROBED); 870 871 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 872 (void) ddi_pathname(dip, path); 873 NDI_CONFIG_DEBUG((CE_CONT, "init_node: entry: path %s 0x%p\n", 874 path, (void *)dip)); 875 876 /* 877 * The parent must have a bus_ctl operation. 878 */ 879 if ((DEVI(pdip)->devi_ops->devo_bus_ops == NULL) || 880 (f = DEVI(pdip)->devi_ops->devo_bus_ops->bus_ctl) == NULL) { 881 error = DDI_FAILURE; 882 goto out; 883 } 884 885 add_global_props(dip); 886 887 /* 888 * Invoke the parent's bus_ctl operation with the DDI_CTLOPS_INITCHILD 889 * command to transform the child to canonical form 1. If there 890 * is an error, ddi_remove_child should be called, to clean up. 891 */ 892 error = (*f)(pdip, pdip, DDI_CTLOPS_INITCHILD, dip, NULL); 893 if (error != DDI_SUCCESS) { 894 NDI_CONFIG_DEBUG((CE_CONT, "init_node: %s 0x%p failed\n", 895 path, (void *)dip)); 896 remove_global_props(dip); 897 898 /* 899 * If a nexus INITCHILD implementation calls ddi_devid_regster() 900 * prior to setting devi_addr, the devid is not recorded in 901 * the devid cache (i.e. DEVI_CACHED_DEVID is not set). 902 * With mpxio, while the vhci client path may be missing 903 * from the cache, phci pathinfo paths may have already be 904 * added to the cache, against the client dip, by use of 905 * e_devid_cache_pathinfo(). Because of this, when INITCHILD 906 * of the client fails, we need to purge the client dip from 907 * the cache even if DEVI_CACHED_DEVID is not set - if only 908 * devi_devid_str is set. 909 */ 910 mutex_enter(&DEVI(dip)->devi_lock); 911 if ((DEVI(dip)->devi_flags & DEVI_CACHED_DEVID) || 912 DEVI(dip)->devi_devid_str) { 913 DEVI(dip)->devi_flags &= ~DEVI_CACHED_DEVID; 914 mutex_exit(&DEVI(dip)->devi_lock); 915 ddi_devid_unregister(dip); 916 } else 917 mutex_exit(&DEVI(dip)->devi_lock); 918 919 /* in case nexus driver didn't clear this field */ 920 ddi_set_name_addr(dip, NULL); 921 error = DDI_FAILURE; 922 goto out; 923 } 924 925 ndi_hold_devi(pdip); /* initial hold of parent */ 926 927 /* recompute path after initchild for @addr information */ 928 (void) ddi_pathname(dip, path); 929 930 /* Check for duplicate nodes */ 931 if (find_duplicate_child(pdip, dip) != NULL) { 932 /* 933 * uninit_node() the duplicate - a successful uninit_node() 934 * will release inital hold of parent using ndi_rele_devi(). 935 */ 936 if ((error = uninit_node(dip)) != DDI_SUCCESS) { 937 ndi_rele_devi(pdip); /* release initial hold */ 938 cmn_err(CE_WARN, "init_node: uninit of duplicate " 939 "node %s failed", path); 940 } 941 NDI_CONFIG_DEBUG((CE_CONT, "init_node: duplicate uninit " 942 "%s 0x%p%s\n", path, (void *)dip, 943 (error == DDI_SUCCESS) ? "" : " failed")); 944 error = DDI_FAILURE; 945 goto out; 946 } 947 948 /* 949 * If a devid was registered for a DS_BOUND node then the devid_cache 950 * may not have captured the path. Detect this situation and ensure that 951 * the path enters the cache now that devi_addr is established. 952 */ 953 if (!(DEVI(dip)->devi_flags & DEVI_CACHED_DEVID) && 954 (ddi_devid_get(dip, &devid) == DDI_SUCCESS)) { 955 if (e_devid_cache_register(dip, devid) == DDI_SUCCESS) { 956 mutex_enter(&DEVI(dip)->devi_lock); 957 DEVI(dip)->devi_flags |= DEVI_CACHED_DEVID; 958 mutex_exit(&DEVI(dip)->devi_lock); 959 } 960 961 ddi_devid_free(devid); 962 } 963 964 /* 965 * Check to see if we have a path-oriented driver alias that overrides 966 * the current driver binding. If so, we need to rebind. This check 967 * needs to be delayed until after a successful DDI_CTLOPS_INITCHILD, 968 * so the unit-address is established on the last component of the path. 969 * 970 * NOTE: Allowing a path-oriented alias to change the driver binding 971 * of a driver.conf node results in non-intuitive property behavior. 972 * We provide a tunable (driver_conf_allow_path_alias) to control 973 * this behavior. See uninit_node() for more details. 974 * 975 * NOTE: If you are adding a path-oriented alias for the boot device, 976 * and there is mismatch between OBP and the kernel in regard to 977 * generic name use, like "disk" .vs. "ssd", then you will need 978 * to add a path-oriented alias for both paths. 979 */ 980 major = ddi_name_to_major(path); 981 if (driver_active(major) && (major != DEVI(dip)->devi_major) && 982 (ndi_dev_is_persistent_node(dip) || driver_conf_allow_path_alias)) { 983 984 /* Mark node for rebind processing. */ 985 mutex_enter(&DEVI(dip)->devi_lock); 986 DEVI(dip)->devi_flags |= DEVI_REBIND; 987 mutex_exit(&DEVI(dip)->devi_lock); 988 989 /* 990 * Add an extra hold on the parent to prevent it from ever 991 * having a zero devi_ref during the child rebind process. 992 * This is necessary to ensure that the parent will never 993 * detach(9E) during the rebind. 994 */ 995 ndi_hold_devi(pdip); /* extra hold of parent */ 996 997 /* 998 * uninit_node() current binding - a successful uninit_node() 999 * will release extra hold of parent using ndi_rele_devi(). 1000 */ 1001 if ((error = uninit_node(dip)) != DDI_SUCCESS) { 1002 ndi_rele_devi(pdip); /* release extra hold */ 1003 ndi_rele_devi(pdip); /* release initial hold */ 1004 cmn_err(CE_WARN, "init_node: uninit for rebind " 1005 "of node %s failed", path); 1006 goto out; 1007 } 1008 1009 /* Unbind: demote the node back to DS_LINKED. */ 1010 if ((error = ndi_devi_unbind_driver(dip)) != DDI_SUCCESS) { 1011 ndi_rele_devi(pdip); /* release initial hold */ 1012 cmn_err(CE_WARN, "init_node: unbind for rebind " 1013 "of node %s failed", path); 1014 goto out; 1015 } 1016 1017 /* establish rebinding name */ 1018 if (DEVI(dip)->devi_rebinding_name == NULL) 1019 DEVI(dip)->devi_rebinding_name = 1020 i_ddi_strdup(path, KM_SLEEP); 1021 1022 /* 1023 * Now that we are demoted and marked for rebind, repromote. 1024 * We need to do this in steps, instead of just calling 1025 * ddi_initchild, so that we can redo the merge operation 1026 * after we are rebound to the path-bound driver. 1027 * 1028 * Start by rebinding node to the path-bound driver. 1029 */ 1030 if ((error = ndi_devi_bind_driver(dip, 0)) != DDI_SUCCESS) { 1031 ndi_rele_devi(pdip); /* release initial hold */ 1032 cmn_err(CE_WARN, "init_node: rebind " 1033 "of node %s failed", path); 1034 goto out; 1035 } 1036 1037 /* 1038 * If the node is not a driver.conf node then merge 1039 * driver.conf properties from new path-bound driver.conf. 1040 */ 1041 if (ndi_dev_is_persistent_node(dip)) 1042 (void) i_ndi_make_spec_children(pdip, 0); 1043 1044 /* 1045 * Now that we have taken care of merge, repromote back 1046 * to DS_INITIALIZED. 1047 */ 1048 error = ddi_initchild(pdip, dip); 1049 NDI_CONFIG_DEBUG((CE_CONT, "init_node: rebind " 1050 "%s 0x%p\n", path, (void *)dip)); 1051 1052 /* 1053 * Release our initial hold. If ddi_initchild() was 1054 * successful then it will return with the active hold. 1055 */ 1056 ndi_rele_devi(pdip); 1057 goto out; 1058 } 1059 1060 /* 1061 * Apply multi-parent/deep-nexus optimization to the new node 1062 */ 1063 DEVI(dip)->devi_instance = e_ddi_assign_instance(dip); 1064 ddi_optimize_dtree(dip); 1065 error = DDI_SUCCESS; /* return with active hold */ 1066 1067 out: if (error != DDI_SUCCESS) { 1068 /* On failure ensure that DEVI_REBIND is cleared */ 1069 mutex_enter(&DEVI(dip)->devi_lock); 1070 DEVI(dip)->devi_flags &= ~DEVI_REBIND; 1071 mutex_exit(&DEVI(dip)->devi_lock); 1072 } 1073 kmem_free(path, MAXPATHLEN); 1074 return (error); 1075 } 1076 1077 /* 1078 * Uninitialize node 1079 * The per-driver list must be held busy during the call. 1080 * A successful uninit_node() releases the init_node() hold on 1081 * the parent by calling ndi_rele_devi(). 1082 */ 1083 static int 1084 uninit_node(dev_info_t *dip) 1085 { 1086 int node_state_entry; 1087 dev_info_t *pdip; 1088 struct dev_ops *ops; 1089 int (*f)(); 1090 int error; 1091 char *addr; 1092 1093 /* 1094 * Don't check for references here or else a ref-counted 1095 * dip cannot be downgraded by the framework. 1096 */ 1097 node_state_entry = i_ddi_node_state(dip); 1098 ASSERT((node_state_entry == DS_BOUND) || 1099 (node_state_entry == DS_INITIALIZED)); 1100 pdip = ddi_get_parent(dip); 1101 ASSERT(pdip); 1102 1103 NDI_CONFIG_DEBUG((CE_CONT, "uninit_node: 0x%p(%s%d)\n", 1104 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1105 1106 if (((ops = ddi_get_driver(pdip)) == NULL) || 1107 (ops->devo_bus_ops == NULL) || 1108 ((f = ops->devo_bus_ops->bus_ctl) == NULL)) { 1109 return (DDI_FAILURE); 1110 } 1111 1112 /* 1113 * save the @addr prior to DDI_CTLOPS_UNINITCHILD for use in 1114 * freeing the instance if it succeeds. 1115 */ 1116 if (node_state_entry == DS_INITIALIZED) { 1117 addr = ddi_get_name_addr(dip); 1118 if (addr) 1119 addr = i_ddi_strdup(addr, KM_SLEEP); 1120 } else { 1121 addr = NULL; 1122 } 1123 1124 error = (*f)(pdip, pdip, DDI_CTLOPS_UNINITCHILD, dip, (void *)NULL); 1125 if (error == DDI_SUCCESS) { 1126 /* ensure that devids are unregistered */ 1127 mutex_enter(&DEVI(dip)->devi_lock); 1128 if ((DEVI(dip)->devi_flags & DEVI_CACHED_DEVID)) { 1129 DEVI(dip)->devi_flags &= ~DEVI_CACHED_DEVID; 1130 mutex_exit(&DEVI(dip)->devi_lock); 1131 ddi_devid_unregister(dip); 1132 } else 1133 mutex_exit(&DEVI(dip)->devi_lock); 1134 1135 /* if uninitchild forgot to set devi_addr to NULL do it now */ 1136 ddi_set_name_addr(dip, NULL); 1137 1138 /* 1139 * Free instance number. This is a no-op if instance has 1140 * been kept by probe_node(). Avoid free when we are called 1141 * from init_node (DS_BOUND) because the instance has not yet 1142 * been assigned. 1143 */ 1144 if (node_state_entry == DS_INITIALIZED) { 1145 e_ddi_free_instance(dip, addr); 1146 DEVI(dip)->devi_instance = -1; 1147 } 1148 1149 /* release the init_node hold */ 1150 ndi_rele_devi(pdip); 1151 1152 remove_global_props(dip); 1153 1154 /* 1155 * NOTE: The decision on whether to allow a path-oriented 1156 * rebind of a driver.conf enumerated node is made by 1157 * init_node() based on driver_conf_allow_path_alias. The 1158 * rebind code below prevents deletion of system properties 1159 * on driver.conf nodes. 1160 * 1161 * When driver_conf_allow_path_alias is set, property behavior 1162 * on rebound driver.conf file is non-intuitive. For a 1163 * driver.conf node, the unit-address properties come from 1164 * the driver.conf file as system properties. Removing system 1165 * properties from a driver.conf node makes the node 1166 * useless (we get node without unit-address properties) - so 1167 * we leave system properties in place. The result is a node 1168 * where system properties come from the node being rebound, 1169 * and global properties come from the driver.conf file 1170 * of the driver we are rebinding to. If we could determine 1171 * that the path-oriented alias driver.conf file defined a 1172 * node at the same unit address, it would be best to use 1173 * that node and avoid the non-intuitive property behavior. 1174 * Unfortunately, the current "merge" code does not support 1175 * this, so we live with the non-intuitive property behavior. 1176 */ 1177 if (!((ndi_dev_is_persistent_node(dip) == 0) && 1178 (DEVI(dip)->devi_flags & DEVI_REBIND))) 1179 e_ddi_prop_remove_all(dip); 1180 } else { 1181 NDI_CONFIG_DEBUG((CE_CONT, "uninit_node failed: 0x%p(%s%d)\n", 1182 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1183 } 1184 1185 if (addr) 1186 kmem_free(addr, strlen(addr) + 1); 1187 return (error); 1188 } 1189 1190 /* 1191 * Invoke driver's probe entry point to probe for existence of hardware. 1192 * Keep instance permanent for successful probe and leaf nodes. 1193 * 1194 * Per-driver list must be held busy while calling this function. 1195 */ 1196 static int 1197 probe_node(dev_info_t *dip) 1198 { 1199 int rv; 1200 1201 ASSERT(i_ddi_node_state(dip) == DS_INITIALIZED); 1202 1203 NDI_CONFIG_DEBUG((CE_CONT, "probe_node: 0x%p(%s%d)\n", 1204 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1205 1206 /* temporarily hold the driver while we probe */ 1207 DEVI(dip)->devi_ops = ndi_hold_driver(dip); 1208 if (DEVI(dip)->devi_ops == NULL) { 1209 NDI_CONFIG_DEBUG((CE_CONT, 1210 "probe_node: 0x%p(%s%d) cannot load driver\n", 1211 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1212 return (DDI_FAILURE); 1213 } 1214 1215 if (identify_9e != 0) 1216 (void) devi_identify(dip); 1217 1218 rv = devi_probe(dip); 1219 1220 /* release the driver now that probe is complete */ 1221 ndi_rele_driver(dip); 1222 DEVI(dip)->devi_ops = NULL; 1223 1224 switch (rv) { 1225 case DDI_PROBE_SUCCESS: /* found */ 1226 case DDI_PROBE_DONTCARE: /* ddi_dev_is_sid */ 1227 e_ddi_keep_instance(dip); /* persist instance */ 1228 rv = DDI_SUCCESS; 1229 break; 1230 1231 case DDI_PROBE_PARTIAL: /* maybe later */ 1232 case DDI_PROBE_FAILURE: /* not found */ 1233 NDI_CONFIG_DEBUG((CE_CONT, 1234 "probe_node: 0x%p(%s%d) no hardware found%s\n", 1235 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip), 1236 (rv == DDI_PROBE_PARTIAL) ? " yet" : "")); 1237 rv = DDI_FAILURE; 1238 break; 1239 1240 default: 1241 #ifdef DEBUG 1242 cmn_err(CE_WARN, "probe_node: %s%d: illegal probe(9E) value", 1243 ddi_driver_name(dip), ddi_get_instance(dip)); 1244 #endif /* DEBUG */ 1245 rv = DDI_FAILURE; 1246 break; 1247 } 1248 return (rv); 1249 } 1250 1251 /* 1252 * Unprobe a node. Simply reset the node state. 1253 * Per-driver list must be held busy while calling this function. 1254 */ 1255 static int 1256 unprobe_node(dev_info_t *dip) 1257 { 1258 ASSERT(i_ddi_node_state(dip) == DS_PROBED); 1259 1260 /* 1261 * Don't check for references here or else a ref-counted 1262 * dip cannot be downgraded by the framework. 1263 */ 1264 1265 NDI_CONFIG_DEBUG((CE_CONT, "unprobe_node: 0x%p(name = %s)\n", 1266 (void *)dip, ddi_node_name(dip))); 1267 return (DDI_SUCCESS); 1268 } 1269 1270 /* 1271 * Attach devinfo node. 1272 * Per-driver list must be held busy. 1273 */ 1274 static int 1275 attach_node(dev_info_t *dip) 1276 { 1277 int rv; 1278 1279 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); 1280 ASSERT(i_ddi_node_state(dip) == DS_PROBED); 1281 1282 NDI_CONFIG_DEBUG((CE_CONT, "attach_node: 0x%p(%s%d)\n", 1283 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1284 1285 /* 1286 * Tell mpxio framework that a node is about to online. 1287 */ 1288 if ((rv = mdi_devi_online(dip, 0)) != NDI_SUCCESS) { 1289 return (DDI_FAILURE); 1290 } 1291 1292 /* no recursive attachment */ 1293 ASSERT(DEVI(dip)->devi_ops == NULL); 1294 1295 /* 1296 * Hold driver the node is bound to. 1297 */ 1298 DEVI(dip)->devi_ops = ndi_hold_driver(dip); 1299 if (DEVI(dip)->devi_ops == NULL) { 1300 /* 1301 * We were able to load driver for probing, so we should 1302 * not get here unless something really bad happened. 1303 */ 1304 cmn_err(CE_WARN, "attach_node: no driver for major %d", 1305 DEVI(dip)->devi_major); 1306 return (DDI_FAILURE); 1307 } 1308 1309 if (NEXUS_DRV(DEVI(dip)->devi_ops)) 1310 DEVI(dip)->devi_taskq = ddi_taskq_create(dip, 1311 "nexus_enum_tq", 1, 1312 TASKQ_DEFAULTPRI, 0); 1313 1314 mutex_enter(&(DEVI(dip)->devi_lock)); 1315 DEVI_SET_ATTACHING(dip); 1316 DEVI_SET_NEED_RESET(dip); 1317 mutex_exit(&(DEVI(dip)->devi_lock)); 1318 1319 rv = devi_attach(dip, DDI_ATTACH); 1320 1321 mutex_enter(&(DEVI(dip)->devi_lock)); 1322 DEVI_CLR_ATTACHING(dip); 1323 1324 if (rv != DDI_SUCCESS) { 1325 DEVI_CLR_NEED_RESET(dip); 1326 mutex_exit(&DEVI(dip)->devi_lock); 1327 1328 /* 1329 * Cleanup dacf reservations 1330 */ 1331 mutex_enter(&dacf_lock); 1332 dacf_clr_rsrvs(dip, DACF_OPID_POSTATTACH); 1333 dacf_clr_rsrvs(dip, DACF_OPID_PREDETACH); 1334 mutex_exit(&dacf_lock); 1335 if (DEVI(dip)->devi_taskq) 1336 ddi_taskq_destroy(DEVI(dip)->devi_taskq); 1337 ddi_remove_minor_node(dip, NULL); 1338 1339 /* release the driver if attach failed */ 1340 ndi_rele_driver(dip); 1341 DEVI(dip)->devi_ops = NULL; 1342 NDI_CONFIG_DEBUG((CE_CONT, "attach_node: 0x%p(%s%d) failed\n", 1343 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1344 return (DDI_FAILURE); 1345 } else 1346 mutex_exit(&DEVI(dip)->devi_lock); 1347 1348 /* successful attach, return with driver held */ 1349 1350 return (DDI_SUCCESS); 1351 } 1352 1353 /* 1354 * Detach devinfo node. 1355 * Per-driver list must be held busy. 1356 */ 1357 static int 1358 detach_node(dev_info_t *dip, uint_t flag) 1359 { 1360 struct devnames *dnp; 1361 int rv; 1362 1363 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); 1364 ASSERT(i_ddi_node_state(dip) == DS_ATTACHED); 1365 1366 /* check references */ 1367 if (DEVI(dip)->devi_ref) 1368 return (DDI_FAILURE); 1369 1370 NDI_CONFIG_DEBUG((CE_CONT, "detach_node: 0x%p(%s%d)\n", 1371 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1372 1373 /* 1374 * NOTE: If we are processing a pHCI node then the calling code 1375 * must detect this and ndi_devi_enter() in (vHCI, parent(pHCI)) 1376 * order unless pHCI and vHCI are siblings. Code paths leading 1377 * here that must ensure this ordering include: 1378 * unconfig_immediate_children(), devi_unconfig_one(), 1379 * ndi_devi_unconfig_one(), ndi_devi_offline(). 1380 */ 1381 ASSERT(!MDI_PHCI(dip) || 1382 (ddi_get_parent(mdi_devi_get_vdip(dip)) == ddi_get_parent(dip)) || 1383 DEVI_BUSY_OWNED(mdi_devi_get_vdip(dip))); 1384 1385 /* Offline the device node with the mpxio framework. */ 1386 if (mdi_devi_offline(dip, flag) != NDI_SUCCESS) { 1387 return (DDI_FAILURE); 1388 } 1389 1390 /* drain the taskq */ 1391 if (DEVI(dip)->devi_taskq) 1392 ddi_taskq_wait(DEVI(dip)->devi_taskq); 1393 1394 rv = devi_detach(dip, DDI_DETACH); 1395 1396 if (rv != DDI_SUCCESS) { 1397 NDI_CONFIG_DEBUG((CE_CONT, 1398 "detach_node: 0x%p(%s%d) failed\n", 1399 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip))); 1400 return (DDI_FAILURE); 1401 } 1402 1403 mutex_enter(&(DEVI(dip)->devi_lock)); 1404 DEVI_CLR_NEED_RESET(dip); 1405 mutex_exit(&(DEVI(dip)->devi_lock)); 1406 1407 #if defined(__amd64) && !defined(__xpv) 1408 /* 1409 * Close any iommulib mediated linkage to an IOMMU 1410 */ 1411 if (IOMMU_USED(dip)) 1412 iommulib_nex_close(dip); 1413 #endif 1414 1415 /* destroy the taskq */ 1416 if (DEVI(dip)->devi_taskq) { 1417 ddi_taskq_destroy(DEVI(dip)->devi_taskq); 1418 DEVI(dip)->devi_taskq = NULL; 1419 } 1420 1421 /* Cleanup dacf reservations */ 1422 mutex_enter(&dacf_lock); 1423 dacf_clr_rsrvs(dip, DACF_OPID_POSTATTACH); 1424 dacf_clr_rsrvs(dip, DACF_OPID_PREDETACH); 1425 mutex_exit(&dacf_lock); 1426 1427 /* remove any additional flavors that were added */ 1428 if (DEVI(dip)->devi_flavorv_n > 1 && DEVI(dip)->devi_flavorv != NULL) { 1429 kmem_free(DEVI(dip)->devi_flavorv, 1430 (DEVI(dip)->devi_flavorv_n - 1) * sizeof (void *)); 1431 DEVI(dip)->devi_flavorv = NULL; 1432 } 1433 1434 /* Remove properties and minor nodes in case driver forgots */ 1435 ddi_remove_minor_node(dip, NULL); 1436 ddi_prop_remove_all(dip); 1437 1438 /* a detached node can't have attached or .conf children */ 1439 mutex_enter(&DEVI(dip)->devi_lock); 1440 DEVI(dip)->devi_flags &= ~(DEVI_MADE_CHILDREN|DEVI_ATTACHED_CHILDREN); 1441 mutex_exit(&DEVI(dip)->devi_lock); 1442 1443 /* 1444 * If the instance has successfully detached in detach_driver() context, 1445 * clear DN_DRIVER_HELD for correct ddi_hold_installed_driver() 1446 * behavior. Consumers like qassociate() depend on this (via clnopen()). 1447 */ 1448 if (flag & NDI_DETACH_DRIVER) { 1449 dnp = &(devnamesp[DEVI(dip)->devi_major]); 1450 LOCK_DEV_OPS(&dnp->dn_lock); 1451 dnp->dn_flags &= ~DN_DRIVER_HELD; 1452 UNLOCK_DEV_OPS(&dnp->dn_lock); 1453 } 1454 1455 /* successful detach, release the driver */ 1456 ndi_rele_driver(dip); 1457 DEVI(dip)->devi_ops = NULL; 1458 return (DDI_SUCCESS); 1459 } 1460 1461 /* 1462 * Run dacf post_attach routines 1463 */ 1464 static int 1465 postattach_node(dev_info_t *dip) 1466 { 1467 int rval; 1468 1469 /* 1470 * For hotplug busses like USB, it's possible that devices 1471 * are removed but dip is still around. We don't want to 1472 * run dacf routines as part of detach failure recovery. 1473 * 1474 * Pretend success until we figure out how to prevent 1475 * access to such devinfo nodes. 1476 */ 1477 if (DEVI_IS_DEVICE_REMOVED(dip)) 1478 return (DDI_SUCCESS); 1479 1480 /* 1481 * if dacf_postattach failed, report it to the framework 1482 * so that it can be retried later at the open time. 1483 */ 1484 mutex_enter(&dacf_lock); 1485 rval = dacfc_postattach(dip); 1486 mutex_exit(&dacf_lock); 1487 1488 /* 1489 * Plumbing during postattach may fail because of the 1490 * underlying device is not ready. This will fail ndi_devi_config() 1491 * in dv_filldir(). 1492 */ 1493 if (rval != DACF_SUCCESS) { 1494 NDI_CONFIG_DEBUG((CE_CONT, "postattach_node: %s%d (%p) " 1495 "postattach failed\n", ddi_driver_name(dip), 1496 ddi_get_instance(dip), (void *)dip)); 1497 return (DDI_FAILURE); 1498 } 1499 1500 return (DDI_SUCCESS); 1501 } 1502 1503 /* 1504 * Run dacf pre-detach routines 1505 */ 1506 static int 1507 predetach_node(dev_info_t *dip, uint_t flag) 1508 { 1509 int ret; 1510 1511 /* 1512 * Don't auto-detach if DDI_FORCEATTACH or DDI_NO_AUTODETACH 1513 * properties are set. 1514 */ 1515 if (flag & NDI_AUTODETACH) { 1516 struct devnames *dnp; 1517 int pflag = DDI_PROP_NOTPROM | DDI_PROP_DONTPASS; 1518 1519 if ((ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1520 pflag, DDI_FORCEATTACH, 0) == 1) || 1521 (ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1522 pflag, DDI_NO_AUTODETACH, 0) == 1)) 1523 return (DDI_FAILURE); 1524 1525 /* check for driver global version of DDI_NO_AUTODETACH */ 1526 dnp = &devnamesp[DEVI(dip)->devi_major]; 1527 LOCK_DEV_OPS(&dnp->dn_lock); 1528 if (dnp->dn_flags & DN_NO_AUTODETACH) { 1529 UNLOCK_DEV_OPS(&dnp->dn_lock); 1530 return (DDI_FAILURE); 1531 } 1532 UNLOCK_DEV_OPS(&dnp->dn_lock); 1533 } 1534 1535 mutex_enter(&dacf_lock); 1536 ret = dacfc_predetach(dip); 1537 mutex_exit(&dacf_lock); 1538 1539 return (ret); 1540 } 1541 1542 /* 1543 * Wrapper for making multiple state transitions 1544 */ 1545 1546 /* 1547 * i_ndi_config_node: upgrade dev_info node into a specified state. 1548 * It is a bit tricky because the locking protocol changes before and 1549 * after a node is bound to a driver. All locks are held external to 1550 * this function. 1551 */ 1552 int 1553 i_ndi_config_node(dev_info_t *dip, ddi_node_state_t state, uint_t flag) 1554 { 1555 _NOTE(ARGUNUSED(flag)) 1556 int rv = DDI_SUCCESS; 1557 1558 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); 1559 1560 while ((i_ddi_node_state(dip) < state) && (rv == DDI_SUCCESS)) { 1561 1562 /* don't allow any more changes to the device tree */ 1563 if (devinfo_freeze) { 1564 rv = DDI_FAILURE; 1565 break; 1566 } 1567 1568 switch (i_ddi_node_state(dip)) { 1569 case DS_PROTO: 1570 /* 1571 * only caller can reference this node, no external 1572 * locking needed. 1573 */ 1574 link_node(dip); 1575 translate_devid((dev_info_t *)dip); 1576 i_ddi_set_node_state(dip, DS_LINKED); 1577 break; 1578 case DS_LINKED: 1579 /* 1580 * Three code path may attempt to bind a node: 1581 * - boot code 1582 * - add_drv 1583 * - hotplug thread 1584 * Boot code is single threaded, add_drv synchronize 1585 * on a userland lock, and hotplug synchronize on 1586 * hotplug_lk. There could be a race between add_drv 1587 * and hotplug thread. We'll live with this until the 1588 * conversion to top-down loading. 1589 */ 1590 if ((rv = bind_node(dip)) == DDI_SUCCESS) 1591 i_ddi_set_node_state(dip, DS_BOUND); 1592 1593 break; 1594 case DS_BOUND: 1595 /* 1596 * The following transitions synchronizes on the 1597 * per-driver busy changing flag, since we already 1598 * have a driver. 1599 */ 1600 if ((rv = init_node(dip)) == DDI_SUCCESS) 1601 i_ddi_set_node_state(dip, DS_INITIALIZED); 1602 break; 1603 case DS_INITIALIZED: 1604 if ((rv = probe_node(dip)) == DDI_SUCCESS) 1605 i_ddi_set_node_state(dip, DS_PROBED); 1606 break; 1607 case DS_PROBED: 1608 /* 1609 * If node is retired and persistent, then prevent 1610 * attach. We can't do this for non-persistent nodes 1611 * as we would lose evidence that the node existed. 1612 */ 1613 if (i_ddi_check_retire(dip) == 1 && 1614 ndi_dev_is_persistent_node(dip) && 1615 retire_prevents_attach == 1) { 1616 rv = DDI_FAILURE; 1617 break; 1618 } 1619 atomic_inc_ulong(&devinfo_attach_detach); 1620 if ((rv = attach_node(dip)) == DDI_SUCCESS) 1621 i_ddi_set_node_state(dip, DS_ATTACHED); 1622 atomic_dec_ulong(&devinfo_attach_detach); 1623 break; 1624 case DS_ATTACHED: 1625 if ((rv = postattach_node(dip)) == DDI_SUCCESS) 1626 i_ddi_set_node_state(dip, DS_READY); 1627 break; 1628 case DS_READY: 1629 break; 1630 default: 1631 /* should never reach here */ 1632 ASSERT("unknown devinfo state"); 1633 } 1634 } 1635 1636 if (ddidebug & DDI_AUDIT) 1637 da_log_enter(dip); 1638 return (rv); 1639 } 1640 1641 /* 1642 * i_ndi_unconfig_node: downgrade dev_info node into a specified state. 1643 */ 1644 int 1645 i_ndi_unconfig_node(dev_info_t *dip, ddi_node_state_t state, uint_t flag) 1646 { 1647 int rv = DDI_SUCCESS; 1648 1649 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); 1650 1651 while ((i_ddi_node_state(dip) > state) && (rv == DDI_SUCCESS)) { 1652 1653 /* don't allow any more changes to the device tree */ 1654 if (devinfo_freeze) { 1655 rv = DDI_FAILURE; 1656 break; 1657 } 1658 1659 switch (i_ddi_node_state(dip)) { 1660 case DS_PROTO: 1661 break; 1662 case DS_LINKED: 1663 /* 1664 * Persistent nodes are only removed by hotplug code 1665 * .conf nodes synchronizes on per-driver list. 1666 */ 1667 if ((rv = unlink_node(dip)) == DDI_SUCCESS) 1668 i_ddi_set_node_state(dip, DS_PROTO); 1669 break; 1670 case DS_BOUND: 1671 /* 1672 * The following transitions synchronizes on the 1673 * per-driver busy changing flag, since we already 1674 * have a driver. 1675 */ 1676 if ((rv = unbind_node(dip)) == DDI_SUCCESS) 1677 i_ddi_set_node_state(dip, DS_LINKED); 1678 break; 1679 case DS_INITIALIZED: 1680 if ((rv = uninit_node(dip)) == DDI_SUCCESS) 1681 i_ddi_set_node_state(dip, DS_BOUND); 1682 break; 1683 case DS_PROBED: 1684 if ((rv = unprobe_node(dip)) == DDI_SUCCESS) 1685 i_ddi_set_node_state(dip, DS_INITIALIZED); 1686 break; 1687 case DS_ATTACHED: 1688 atomic_inc_ulong(&devinfo_attach_detach); 1689 1690 mutex_enter(&(DEVI(dip)->devi_lock)); 1691 DEVI_SET_DETACHING(dip); 1692 mutex_exit(&(DEVI(dip)->devi_lock)); 1693 1694 membar_enter(); /* ensure visibility for hold_devi */ 1695 1696 if ((rv = detach_node(dip, flag)) == DDI_SUCCESS) 1697 i_ddi_set_node_state(dip, DS_PROBED); 1698 1699 mutex_enter(&(DEVI(dip)->devi_lock)); 1700 DEVI_CLR_DETACHING(dip); 1701 mutex_exit(&(DEVI(dip)->devi_lock)); 1702 1703 atomic_dec_ulong(&devinfo_attach_detach); 1704 break; 1705 case DS_READY: 1706 if ((rv = predetach_node(dip, flag)) == DDI_SUCCESS) 1707 i_ddi_set_node_state(dip, DS_ATTACHED); 1708 break; 1709 default: 1710 ASSERT("unknown devinfo state"); 1711 } 1712 } 1713 da_log_enter(dip); 1714 return (rv); 1715 } 1716 1717 /* 1718 * ddi_initchild: transform node to DS_INITIALIZED state 1719 */ 1720 int 1721 ddi_initchild(dev_info_t *parent, dev_info_t *proto) 1722 { 1723 int ret, circ; 1724 1725 ndi_devi_enter(parent, &circ); 1726 ret = i_ndi_config_node(proto, DS_INITIALIZED, 0); 1727 ndi_devi_exit(parent, circ); 1728 1729 return (ret); 1730 } 1731 1732 /* 1733 * ddi_uninitchild: transform node down to DS_BOUND state 1734 */ 1735 int 1736 ddi_uninitchild(dev_info_t *dip) 1737 { 1738 int ret, circ; 1739 dev_info_t *parent = ddi_get_parent(dip); 1740 ASSERT(parent); 1741 1742 ndi_devi_enter(parent, &circ); 1743 ret = i_ndi_unconfig_node(dip, DS_BOUND, 0); 1744 ndi_devi_exit(parent, circ); 1745 1746 return (ret); 1747 } 1748 1749 /* 1750 * i_ddi_attachchild: transform node to DS_READY/i_ddi_devi_attached() state 1751 */ 1752 static int 1753 i_ddi_attachchild(dev_info_t *dip) 1754 { 1755 dev_info_t *parent = ddi_get_parent(dip); 1756 int ret; 1757 1758 ASSERT(parent && DEVI_BUSY_OWNED(parent)); 1759 1760 if ((i_ddi_node_state(dip) < DS_BOUND) || DEVI_IS_DEVICE_OFFLINE(dip)) 1761 return (DDI_FAILURE); 1762 1763 ret = i_ndi_config_node(dip, DS_READY, 0); 1764 if (ret == NDI_SUCCESS) { 1765 ret = DDI_SUCCESS; 1766 } else { 1767 /* 1768 * Take it down to DS_INITIALIZED so pm_pre_probe is run 1769 * on the next attach 1770 */ 1771 (void) i_ndi_unconfig_node(dip, DS_INITIALIZED, 0); 1772 ret = DDI_FAILURE; 1773 } 1774 1775 return (ret); 1776 } 1777 1778 /* 1779 * i_ddi_detachchild: transform node down to DS_PROBED state 1780 * If it fails, put it back to DS_READY state. 1781 * NOTE: A node that fails detach may be at DS_ATTACHED instead 1782 * of DS_READY for a small amount of time - this is the source of 1783 * transient DS_READY->DS_ATTACHED->DS_READY state changes. 1784 */ 1785 static int 1786 i_ddi_detachchild(dev_info_t *dip, uint_t flags) 1787 { 1788 dev_info_t *parent = ddi_get_parent(dip); 1789 int ret; 1790 1791 ASSERT(parent && DEVI_BUSY_OWNED(parent)); 1792 1793 ret = i_ndi_unconfig_node(dip, DS_PROBED, flags); 1794 if (ret != DDI_SUCCESS) 1795 (void) i_ndi_config_node(dip, DS_READY, 0); 1796 else 1797 /* allow pm_pre_probe to reestablish pm state */ 1798 (void) i_ndi_unconfig_node(dip, DS_INITIALIZED, 0); 1799 return (ret); 1800 } 1801 1802 /* 1803 * Add a child and bind to driver 1804 */ 1805 dev_info_t * 1806 ddi_add_child(dev_info_t *pdip, char *name, uint_t nodeid, uint_t unit) 1807 { 1808 int circ; 1809 dev_info_t *dip; 1810 1811 /* allocate a new node */ 1812 dip = i_ddi_alloc_node(pdip, name, nodeid, (int)unit, NULL, KM_SLEEP); 1813 1814 ndi_devi_enter(pdip, &circ); 1815 (void) i_ndi_config_node(dip, DS_BOUND, 0); 1816 ndi_devi_exit(pdip, circ); 1817 return (dip); 1818 } 1819 1820 /* 1821 * ddi_remove_child: remove the dip. The parent must be attached and held 1822 */ 1823 int 1824 ddi_remove_child(dev_info_t *dip, int dummy) 1825 { 1826 _NOTE(ARGUNUSED(dummy)) 1827 int circ, ret; 1828 dev_info_t *parent = ddi_get_parent(dip); 1829 ASSERT(parent); 1830 1831 ndi_devi_enter(parent, &circ); 1832 1833 /* 1834 * If we still have children, for example SID nodes marked 1835 * as persistent but not attached, attempt to remove them. 1836 */ 1837 if (DEVI(dip)->devi_child) { 1838 ret = ndi_devi_unconfig(dip, NDI_DEVI_REMOVE); 1839 if (ret != NDI_SUCCESS) { 1840 ndi_devi_exit(parent, circ); 1841 return (DDI_FAILURE); 1842 } 1843 ASSERT(DEVI(dip)->devi_child == NULL); 1844 } 1845 1846 ret = i_ndi_unconfig_node(dip, DS_PROTO, 0); 1847 ndi_devi_exit(parent, circ); 1848 1849 if (ret != DDI_SUCCESS) 1850 return (ret); 1851 1852 ASSERT(i_ddi_node_state(dip) == DS_PROTO); 1853 i_ddi_free_node(dip); 1854 return (DDI_SUCCESS); 1855 } 1856 1857 /* 1858 * NDI wrappers for ref counting, node allocation, and transitions 1859 */ 1860 1861 /* 1862 * Hold/release the devinfo node itself. 1863 * Caller is assumed to prevent the devi from detaching during this call 1864 */ 1865 void 1866 ndi_hold_devi(dev_info_t *dip) 1867 { 1868 mutex_enter(&DEVI(dip)->devi_lock); 1869 ASSERT(DEVI(dip)->devi_ref >= 0); 1870 DEVI(dip)->devi_ref++; 1871 membar_enter(); /* make sure stores are flushed */ 1872 mutex_exit(&DEVI(dip)->devi_lock); 1873 } 1874 1875 void 1876 ndi_rele_devi(dev_info_t *dip) 1877 { 1878 ASSERT(DEVI(dip)->devi_ref > 0); 1879 1880 mutex_enter(&DEVI(dip)->devi_lock); 1881 DEVI(dip)->devi_ref--; 1882 membar_enter(); /* make sure stores are flushed */ 1883 mutex_exit(&DEVI(dip)->devi_lock); 1884 } 1885 1886 int 1887 e_ddi_devi_holdcnt(dev_info_t *dip) 1888 { 1889 return (DEVI(dip)->devi_ref); 1890 } 1891 1892 /* 1893 * Hold/release the driver the devinfo node is bound to. 1894 */ 1895 struct dev_ops * 1896 ndi_hold_driver(dev_info_t *dip) 1897 { 1898 if (i_ddi_node_state(dip) < DS_BOUND) 1899 return (NULL); 1900 1901 ASSERT(DEVI(dip)->devi_major != -1); 1902 return (mod_hold_dev_by_major(DEVI(dip)->devi_major)); 1903 } 1904 1905 void 1906 ndi_rele_driver(dev_info_t *dip) 1907 { 1908 ASSERT(i_ddi_node_state(dip) >= DS_BOUND); 1909 mod_rele_dev_by_major(DEVI(dip)->devi_major); 1910 } 1911 1912 /* 1913 * Single thread entry into devinfo node for modifying its children (devinfo, 1914 * pathinfo, and minor). To verify in ASSERTS use DEVI_BUSY_OWNED macro. 1915 */ 1916 void 1917 ndi_devi_enter(dev_info_t *dip, int *circular) 1918 { 1919 struct dev_info *devi = DEVI(dip); 1920 ASSERT(dip != NULL); 1921 1922 /* for vHCI, enforce (vHCI, pHCI) ndi_deve_enter() order */ 1923 ASSERT(!MDI_VHCI(dip) || (mdi_devi_pdip_entered(dip) == 0) || 1924 DEVI_BUSY_OWNED(dip)); 1925 1926 mutex_enter(&devi->devi_lock); 1927 if (devi->devi_busy_thread == curthread) { 1928 devi->devi_circular++; 1929 } else { 1930 while (DEVI_BUSY_CHANGING(devi) && !panicstr) 1931 cv_wait(&(devi->devi_cv), &(devi->devi_lock)); 1932 if (panicstr) { 1933 mutex_exit(&devi->devi_lock); 1934 return; 1935 } 1936 devi->devi_flags |= DEVI_BUSY; 1937 devi->devi_busy_thread = curthread; 1938 } 1939 *circular = devi->devi_circular; 1940 mutex_exit(&devi->devi_lock); 1941 } 1942 1943 /* 1944 * Release ndi_devi_enter or successful ndi_devi_tryenter. 1945 */ 1946 void 1947 ndi_devi_exit(dev_info_t *dip, int circular) 1948 { 1949 struct dev_info *devi = DEVI(dip); 1950 struct dev_info *vdevi; 1951 ASSERT(dip != NULL); 1952 1953 if (panicstr) 1954 return; 1955 1956 mutex_enter(&(devi->devi_lock)); 1957 if (circular != 0) { 1958 devi->devi_circular--; 1959 } else { 1960 devi->devi_flags &= ~DEVI_BUSY; 1961 ASSERT(devi->devi_busy_thread == curthread); 1962 devi->devi_busy_thread = NULL; 1963 cv_broadcast(&(devi->devi_cv)); 1964 } 1965 mutex_exit(&(devi->devi_lock)); 1966 1967 /* 1968 * For pHCI exit we issue a broadcast to vHCI for ndi_devi_config_one() 1969 * doing cv_wait on vHCI. 1970 */ 1971 if (MDI_PHCI(dip)) { 1972 vdevi = DEVI(mdi_devi_get_vdip(dip)); 1973 if (vdevi) { 1974 mutex_enter(&(vdevi->devi_lock)); 1975 if (vdevi->devi_flags & DEVI_PHCI_SIGNALS_VHCI) { 1976 vdevi->devi_flags &= ~DEVI_PHCI_SIGNALS_VHCI; 1977 cv_broadcast(&(vdevi->devi_cv)); 1978 } 1979 mutex_exit(&(vdevi->devi_lock)); 1980 } 1981 } 1982 } 1983 1984 /* 1985 * Release ndi_devi_enter and wait for possibility of new children, avoiding 1986 * possibility of missing broadcast before getting to cv_timedwait(). 1987 */ 1988 static void 1989 ndi_devi_exit_and_wait(dev_info_t *dip, int circular, clock_t end_time) 1990 { 1991 struct dev_info *devi = DEVI(dip); 1992 ASSERT(dip != NULL); 1993 1994 if (panicstr) 1995 return; 1996 1997 /* 1998 * We are called to wait for of a new child, and new child can 1999 * only be added if circular is zero. 2000 */ 2001 ASSERT(circular == 0); 2002 2003 /* like ndi_devi_exit with circular of zero */ 2004 mutex_enter(&(devi->devi_lock)); 2005 devi->devi_flags &= ~DEVI_BUSY; 2006 ASSERT(devi->devi_busy_thread == curthread); 2007 devi->devi_busy_thread = NULL; 2008 cv_broadcast(&(devi->devi_cv)); 2009 2010 /* now wait for new children while still holding devi_lock */ 2011 (void) cv_timedwait(&devi->devi_cv, &(devi->devi_lock), end_time); 2012 mutex_exit(&(devi->devi_lock)); 2013 } 2014 2015 /* 2016 * Attempt to single thread entry into devinfo node for modifying its children. 2017 */ 2018 int 2019 ndi_devi_tryenter(dev_info_t *dip, int *circular) 2020 { 2021 int rval = 1; /* assume we enter */ 2022 struct dev_info *devi = DEVI(dip); 2023 ASSERT(dip != NULL); 2024 2025 mutex_enter(&devi->devi_lock); 2026 if (devi->devi_busy_thread == (void *)curthread) { 2027 devi->devi_circular++; 2028 } else { 2029 if (!DEVI_BUSY_CHANGING(devi)) { 2030 devi->devi_flags |= DEVI_BUSY; 2031 devi->devi_busy_thread = (void *)curthread; 2032 } else { 2033 rval = 0; /* devi is busy */ 2034 } 2035 } 2036 *circular = devi->devi_circular; 2037 mutex_exit(&devi->devi_lock); 2038 return (rval); 2039 } 2040 2041 /* 2042 * Allocate and initialize a new dev_info structure. 2043 * 2044 * This routine may be called at interrupt time by a nexus in 2045 * response to a hotplug event, therefore memory allocations are 2046 * not allowed to sleep. 2047 */ 2048 int 2049 ndi_devi_alloc(dev_info_t *parent, const char *node_name, pnode_t nodeid, 2050 dev_info_t **ret_dip) 2051 { 2052 ASSERT(node_name != NULL); 2053 ASSERT(ret_dip != NULL); 2054 2055 *ret_dip = i_ddi_alloc_node(parent, node_name, nodeid, -1, NULL, 2056 KM_NOSLEEP); 2057 if (*ret_dip == NULL) { 2058 return (NDI_NOMEM); 2059 } 2060 2061 return (NDI_SUCCESS); 2062 } 2063 2064 /* 2065 * Allocate and initialize a new dev_info structure 2066 * This routine may sleep and should not be called at interrupt time 2067 */ 2068 void 2069 ndi_devi_alloc_sleep(dev_info_t *parent, const char *node_name, pnode_t nodeid, 2070 dev_info_t **ret_dip) 2071 { 2072 ASSERT(node_name != NULL); 2073 ASSERT(ret_dip != NULL); 2074 2075 *ret_dip = i_ddi_alloc_node(parent, node_name, nodeid, -1, NULL, 2076 KM_SLEEP); 2077 ASSERT(*ret_dip); 2078 } 2079 2080 /* 2081 * Remove an initialized (but not yet attached) dev_info 2082 * node from it's parent. 2083 */ 2084 int 2085 ndi_devi_free(dev_info_t *dip) 2086 { 2087 ASSERT(dip != NULL); 2088 2089 if (i_ddi_node_state(dip) >= DS_INITIALIZED) 2090 return (DDI_FAILURE); 2091 2092 NDI_CONFIG_DEBUG((CE_CONT, "ndi_devi_free: %s%d (%p)\n", 2093 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip)); 2094 2095 (void) ddi_remove_child(dip, 0); 2096 2097 return (NDI_SUCCESS); 2098 } 2099 2100 /* 2101 * ndi_devi_bind_driver() binds a driver to a given device. If it fails 2102 * to bind the driver, it returns an appropriate error back. Some drivers 2103 * may want to know if the actually failed to bind. 2104 */ 2105 int 2106 ndi_devi_bind_driver(dev_info_t *dip, uint_t flags) 2107 { 2108 int ret = NDI_FAILURE; 2109 int circ; 2110 dev_info_t *pdip = ddi_get_parent(dip); 2111 ASSERT(pdip); 2112 2113 NDI_CONFIG_DEBUG((CE_CONT, 2114 "ndi_devi_bind_driver: %s%d (%p) flags: %x\n", 2115 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags)); 2116 2117 ndi_devi_enter(pdip, &circ); 2118 if (i_ndi_config_node(dip, DS_BOUND, flags) == DDI_SUCCESS) 2119 ret = NDI_SUCCESS; 2120 ndi_devi_exit(pdip, circ); 2121 2122 return (ret); 2123 } 2124 2125 /* 2126 * ndi_devi_unbind_driver: unbind the dip 2127 */ 2128 static int 2129 ndi_devi_unbind_driver(dev_info_t *dip) 2130 { 2131 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); 2132 2133 return (i_ndi_unconfig_node(dip, DS_LINKED, 0)); 2134 } 2135 2136 /* 2137 * Misc. help routines called by framework only 2138 */ 2139 2140 /* 2141 * Get the state of node 2142 */ 2143 ddi_node_state_t 2144 i_ddi_node_state(dev_info_t *dip) 2145 { 2146 return (DEVI(dip)->devi_node_state); 2147 } 2148 2149 /* 2150 * Set the state of node 2151 */ 2152 void 2153 i_ddi_set_node_state(dev_info_t *dip, ddi_node_state_t state) 2154 { 2155 DEVI(dip)->devi_node_state = state; 2156 membar_enter(); /* make sure stores are flushed */ 2157 } 2158 2159 /* 2160 * Determine if node is attached. The implementation accommodates transient 2161 * DS_READY->DS_ATTACHED->DS_READY state changes. Outside this file, this 2162 * function should be instead of i_ddi_node_state() DS_ATTACHED/DS_READY 2163 * state checks. 2164 */ 2165 int 2166 i_ddi_devi_attached(dev_info_t *dip) 2167 { 2168 return (DEVI(dip)->devi_node_state >= DS_ATTACHED); 2169 } 2170 2171 /* 2172 * Common function for finding a node in a sibling list given name and addr. 2173 * 2174 * By default, name is matched with devi_node_name. The following 2175 * alternative match strategies are supported: 2176 * 2177 * FIND_NODE_BY_NODENAME: Match on node name - typical use. 2178 * 2179 * FIND_NODE_BY_DRIVER: A match on driver name bound to node is conducted. 2180 * This support is used for support of OBP generic names and 2181 * for the conversion from driver names to generic names. When 2182 * more consistency in the generic name environment is achieved 2183 * (and not needed for upgrade) this support can be removed. 2184 * 2185 * FIND_NODE_BY_ADDR: Match on just the addr. 2186 * This support is only used/needed during boot to match 2187 * a node bound via a path-based driver alias. 2188 * 2189 * If a child is not named (dev_addr == NULL), there are three 2190 * possible actions: 2191 * 2192 * (1) skip it 2193 * (2) FIND_ADDR_BY_INIT: bring child to DS_INITIALIZED state 2194 * (3) FIND_ADDR_BY_CALLBACK: use a caller-supplied callback function 2195 */ 2196 #define FIND_NODE_BY_NODENAME 0x01 2197 #define FIND_NODE_BY_DRIVER 0x02 2198 #define FIND_NODE_BY_ADDR 0x04 2199 #define FIND_ADDR_BY_INIT 0x10 2200 #define FIND_ADDR_BY_CALLBACK 0x20 2201 2202 static dev_info_t * 2203 find_sibling(dev_info_t *head, char *cname, char *caddr, uint_t flag, 2204 int (*callback)(dev_info_t *, char *, int)) 2205 { 2206 dev_info_t *dip; 2207 char *addr, *buf; 2208 major_t major; 2209 uint_t by; 2210 2211 /* only one way to find a node */ 2212 by = flag & 2213 (FIND_NODE_BY_DRIVER | FIND_NODE_BY_NODENAME | FIND_NODE_BY_ADDR); 2214 ASSERT(by && BIT_ONLYONESET(by)); 2215 2216 /* only one way to name a node */ 2217 ASSERT(((flag & FIND_ADDR_BY_INIT) == 0) || 2218 ((flag & FIND_ADDR_BY_CALLBACK) == 0)); 2219 2220 if (by == FIND_NODE_BY_DRIVER) { 2221 major = ddi_name_to_major(cname); 2222 if (major == DDI_MAJOR_T_NONE) 2223 return (NULL); 2224 } 2225 2226 buf = NULL; 2227 /* preallocate buffer of naming node by callback */ 2228 if (flag & FIND_ADDR_BY_CALLBACK) 2229 buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 2230 2231 /* 2232 * Walk the child list to find a match 2233 */ 2234 if (head == NULL) 2235 return (NULL); 2236 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(head))); 2237 for (dip = head; dip; dip = ddi_get_next_sibling(dip)) { 2238 if (by == FIND_NODE_BY_NODENAME) { 2239 /* match node name */ 2240 if (strcmp(cname, DEVI(dip)->devi_node_name) != 0) 2241 continue; 2242 } else if (by == FIND_NODE_BY_DRIVER) { 2243 /* match driver major */ 2244 if (DEVI(dip)->devi_major != major) 2245 continue; 2246 } 2247 2248 if ((addr = DEVI(dip)->devi_addr) == NULL) { 2249 /* name the child based on the flag */ 2250 if (flag & FIND_ADDR_BY_INIT) { 2251 if (ddi_initchild(ddi_get_parent(dip), dip) 2252 != DDI_SUCCESS) 2253 continue; 2254 addr = DEVI(dip)->devi_addr; 2255 } else if (flag & FIND_ADDR_BY_CALLBACK) { 2256 if ((callback == NULL) || (callback( 2257 dip, buf, MAXNAMELEN) != DDI_SUCCESS)) 2258 continue; 2259 addr = buf; 2260 } else { 2261 continue; /* skip */ 2262 } 2263 } 2264 2265 /* match addr */ 2266 ASSERT(addr != NULL); 2267 if (strcmp(caddr, addr) == 0) 2268 break; /* node found */ 2269 2270 } 2271 if (flag & FIND_ADDR_BY_CALLBACK) 2272 kmem_free(buf, MAXNAMELEN); 2273 return (dip); 2274 } 2275 2276 /* 2277 * Find child of pdip with name: cname@caddr 2278 * Called by init_node() to look for duplicate nodes 2279 */ 2280 static dev_info_t * 2281 find_duplicate_child(dev_info_t *pdip, dev_info_t *dip) 2282 { 2283 dev_info_t *dup; 2284 char *cname = DEVI(dip)->devi_node_name; 2285 char *caddr = DEVI(dip)->devi_addr; 2286 2287 /* search nodes before dip */ 2288 dup = find_sibling(ddi_get_child(pdip), cname, caddr, 2289 FIND_NODE_BY_NODENAME, NULL); 2290 if (dup != dip) 2291 return (dup); 2292 2293 /* 2294 * search nodes after dip; normally this is not needed, 2295 */ 2296 return (find_sibling(ddi_get_next_sibling(dip), cname, caddr, 2297 FIND_NODE_BY_NODENAME, NULL)); 2298 } 2299 2300 /* 2301 * Find a child of a given name and address, using a callback to name 2302 * unnamed children. cname is the binding name. 2303 */ 2304 dev_info_t * 2305 ndi_devi_findchild_by_callback(dev_info_t *pdip, char *dname, char *ua, 2306 int (*make_ua)(dev_info_t *, char *, int)) 2307 { 2308 int by = FIND_ADDR_BY_CALLBACK; 2309 2310 ASSERT(DEVI_BUSY_OWNED(pdip)); 2311 by |= dname ? FIND_NODE_BY_DRIVER : FIND_NODE_BY_ADDR; 2312 return (find_sibling(ddi_get_child(pdip), dname, ua, by, make_ua)); 2313 } 2314 2315 /* 2316 * Find a child of a given name and address, invoking initchild to name 2317 * unnamed children. cname is the node name. 2318 */ 2319 static dev_info_t * 2320 find_child_by_name(dev_info_t *pdip, char *cname, char *caddr) 2321 { 2322 dev_info_t *dip; 2323 2324 /* attempt search without changing state of preceding siblings */ 2325 dip = find_sibling(ddi_get_child(pdip), cname, caddr, 2326 FIND_NODE_BY_NODENAME, NULL); 2327 if (dip) 2328 return (dip); 2329 2330 return (find_sibling(ddi_get_child(pdip), cname, caddr, 2331 FIND_NODE_BY_NODENAME|FIND_ADDR_BY_INIT, NULL)); 2332 } 2333 2334 /* 2335 * Find a child of a given name and address, invoking initchild to name 2336 * unnamed children. cname is the node name. 2337 */ 2338 static dev_info_t * 2339 find_child_by_driver(dev_info_t *pdip, char *cname, char *caddr) 2340 { 2341 dev_info_t *dip; 2342 2343 /* attempt search without changing state of preceding siblings */ 2344 dip = find_sibling(ddi_get_child(pdip), cname, caddr, 2345 FIND_NODE_BY_DRIVER, NULL); 2346 if (dip) 2347 return (dip); 2348 2349 return (find_sibling(ddi_get_child(pdip), cname, caddr, 2350 FIND_NODE_BY_DRIVER|FIND_ADDR_BY_INIT, NULL)); 2351 } 2352 2353 /* 2354 * Find a child of a given address, invoking initchild to name 2355 * unnamed children. cname is the node name. 2356 * 2357 * NOTE: This function is only used during boot. One would hope that 2358 * unique sibling unit-addresses on hardware branches of the tree would 2359 * be a requirement to avoid two drivers trying to control the same 2360 * piece of hardware. Unfortunately there are some cases where this 2361 * situation exists (/ssm@0,0/pci@1c,700000 /ssm@0,0/sghsc@1c,700000). 2362 * Until unit-address uniqueness of siblings is guaranteed, use of this 2363 * interface for purposes other than boot should be avoided. 2364 */ 2365 static dev_info_t * 2366 find_child_by_addr(dev_info_t *pdip, char *caddr) 2367 { 2368 dev_info_t *dip; 2369 2370 /* return NULL if called without a unit-address */ 2371 if ((caddr == NULL) || (*caddr == '\0')) 2372 return (NULL); 2373 2374 /* attempt search without changing state of preceding siblings */ 2375 dip = find_sibling(ddi_get_child(pdip), NULL, caddr, 2376 FIND_NODE_BY_ADDR, NULL); 2377 if (dip) 2378 return (dip); 2379 2380 return (find_sibling(ddi_get_child(pdip), NULL, caddr, 2381 FIND_NODE_BY_ADDR|FIND_ADDR_BY_INIT, NULL)); 2382 } 2383 2384 /* 2385 * Deleting a property list. Take care, since some property structures 2386 * may not be fully built. 2387 */ 2388 void 2389 i_ddi_prop_list_delete(ddi_prop_t *prop) 2390 { 2391 while (prop) { 2392 ddi_prop_t *next = prop->prop_next; 2393 if (prop->prop_name) 2394 kmem_free(prop->prop_name, strlen(prop->prop_name) + 1); 2395 if ((prop->prop_len != 0) && prop->prop_val) 2396 kmem_free(prop->prop_val, prop->prop_len); 2397 kmem_free(prop, sizeof (struct ddi_prop)); 2398 prop = next; 2399 } 2400 } 2401 2402 /* 2403 * Duplicate property list 2404 */ 2405 ddi_prop_t * 2406 i_ddi_prop_list_dup(ddi_prop_t *prop, uint_t flag) 2407 { 2408 ddi_prop_t *result, *prev, *copy; 2409 2410 if (prop == NULL) 2411 return (NULL); 2412 2413 result = prev = NULL; 2414 for (; prop != NULL; prop = prop->prop_next) { 2415 ASSERT(prop->prop_name != NULL); 2416 copy = kmem_zalloc(sizeof (struct ddi_prop), flag); 2417 if (copy == NULL) 2418 goto fail; 2419 2420 copy->prop_dev = prop->prop_dev; 2421 copy->prop_flags = prop->prop_flags; 2422 copy->prop_name = i_ddi_strdup(prop->prop_name, flag); 2423 if (copy->prop_name == NULL) 2424 goto fail; 2425 2426 if ((copy->prop_len = prop->prop_len) != 0) { 2427 copy->prop_val = kmem_zalloc(prop->prop_len, flag); 2428 if (copy->prop_val == NULL) 2429 goto fail; 2430 2431 bcopy(prop->prop_val, copy->prop_val, prop->prop_len); 2432 } 2433 2434 if (prev == NULL) 2435 result = prev = copy; 2436 else 2437 prev->prop_next = copy; 2438 prev = copy; 2439 } 2440 return (result); 2441 2442 fail: 2443 i_ddi_prop_list_delete(result); 2444 return (NULL); 2445 } 2446 2447 /* 2448 * Create a reference property list, currently used only for 2449 * driver global properties. Created with ref count of 1. 2450 */ 2451 ddi_prop_list_t * 2452 i_ddi_prop_list_create(ddi_prop_t *props) 2453 { 2454 ddi_prop_list_t *list = kmem_alloc(sizeof (*list), KM_SLEEP); 2455 list->prop_list = props; 2456 list->prop_ref = 1; 2457 return (list); 2458 } 2459 2460 /* 2461 * Increment/decrement reference count. The reference is 2462 * protected by dn_lock. The only interfaces modifying 2463 * dn_global_prop_ptr is in impl_make[free]_parlist(). 2464 */ 2465 void 2466 i_ddi_prop_list_hold(ddi_prop_list_t *prop_list, struct devnames *dnp) 2467 { 2468 ASSERT(prop_list->prop_ref >= 0); 2469 ASSERT(mutex_owned(&dnp->dn_lock)); 2470 prop_list->prop_ref++; 2471 } 2472 2473 void 2474 i_ddi_prop_list_rele(ddi_prop_list_t *prop_list, struct devnames *dnp) 2475 { 2476 ASSERT(prop_list->prop_ref > 0); 2477 ASSERT(mutex_owned(&dnp->dn_lock)); 2478 prop_list->prop_ref--; 2479 2480 if (prop_list->prop_ref == 0) { 2481 i_ddi_prop_list_delete(prop_list->prop_list); 2482 kmem_free(prop_list, sizeof (*prop_list)); 2483 } 2484 } 2485 2486 /* 2487 * Free table of classes by drivers 2488 */ 2489 void 2490 i_ddi_free_exported_classes(char **classes, int n) 2491 { 2492 if ((n == 0) || (classes == NULL)) 2493 return; 2494 2495 kmem_free(classes, n * sizeof (char *)); 2496 } 2497 2498 /* 2499 * Get all classes exported by dip 2500 */ 2501 int 2502 i_ddi_get_exported_classes(dev_info_t *dip, char ***classes) 2503 { 2504 extern void lock_hw_class_list(); 2505 extern void unlock_hw_class_list(); 2506 extern int get_class(const char *, char **); 2507 2508 static char *rootclass = "root"; 2509 int n = 0, nclass = 0; 2510 char **buf; 2511 2512 ASSERT(i_ddi_node_state(dip) >= DS_BOUND); 2513 2514 if (dip == ddi_root_node()) /* rootnode exports class "root" */ 2515 nclass = 1; 2516 lock_hw_class_list(); 2517 nclass += get_class(ddi_driver_name(dip), NULL); 2518 if (nclass == 0) { 2519 unlock_hw_class_list(); 2520 return (0); /* no class exported */ 2521 } 2522 2523 *classes = buf = kmem_alloc(nclass * sizeof (char *), KM_SLEEP); 2524 if (dip == ddi_root_node()) { 2525 *buf++ = rootclass; 2526 n = 1; 2527 } 2528 n += get_class(ddi_driver_name(dip), buf); 2529 unlock_hw_class_list(); 2530 2531 ASSERT(n == nclass); /* make sure buf wasn't overrun */ 2532 return (nclass); 2533 } 2534 2535 /* 2536 * Helper functions, returns NULL if no memory. 2537 */ 2538 char * 2539 i_ddi_strdup(const char *str, uint_t flag) 2540 { 2541 char *copy; 2542 2543 if (str == NULL) 2544 return (NULL); 2545 2546 copy = kmem_alloc(strlen(str) + 1, flag); 2547 if (copy == NULL) 2548 return (NULL); 2549 2550 (void) strcpy(copy, str); 2551 return (copy); 2552 } 2553 2554 /* 2555 * Load driver.conf file for major. Load all if major == -1. 2556 * 2557 * This is called 2558 * - early in boot after devnames array is initialized 2559 * - from vfs code when certain file systems are mounted 2560 * - from add_drv when a new driver is added 2561 */ 2562 int 2563 i_ddi_load_drvconf(major_t major) 2564 { 2565 extern int modrootloaded; 2566 2567 major_t low, high, m; 2568 2569 if (major == DDI_MAJOR_T_NONE) { 2570 low = 0; 2571 high = devcnt - 1; 2572 } else { 2573 if (major >= devcnt) 2574 return (EINVAL); 2575 low = high = major; 2576 } 2577 2578 for (m = low; m <= high; m++) { 2579 struct devnames *dnp = &devnamesp[m]; 2580 LOCK_DEV_OPS(&dnp->dn_lock); 2581 dnp->dn_flags &= ~(DN_DRIVER_HELD|DN_DRIVER_INACTIVE); 2582 (void) impl_make_parlist(m); 2583 UNLOCK_DEV_OPS(&dnp->dn_lock); 2584 } 2585 2586 if (modrootloaded) { 2587 ddi_walk_devs(ddi_root_node(), reset_nexus_flags, 2588 (void *)(uintptr_t)major); 2589 } 2590 2591 /* build dn_list from old entries in path_to_inst */ 2592 e_ddi_unorphan_instance_nos(); 2593 return (0); 2594 } 2595 2596 /* 2597 * Unload a specific driver.conf. 2598 * Don't support unload all because it doesn't make any sense 2599 */ 2600 int 2601 i_ddi_unload_drvconf(major_t major) 2602 { 2603 int error; 2604 struct devnames *dnp; 2605 2606 if (major >= devcnt) 2607 return (EINVAL); 2608 2609 /* 2610 * Take the per-driver lock while unloading driver.conf 2611 */ 2612 dnp = &devnamesp[major]; 2613 LOCK_DEV_OPS(&dnp->dn_lock); 2614 error = impl_free_parlist(major); 2615 UNLOCK_DEV_OPS(&dnp->dn_lock); 2616 return (error); 2617 } 2618 2619 /* 2620 * Merge a .conf node. This is called by nexus drivers to augment 2621 * hw node with properties specified in driver.conf file. This function 2622 * takes a callback routine to name nexus children. 2623 * The parent node must be held busy. 2624 * 2625 * It returns DDI_SUCCESS if the node is merged and DDI_FAILURE otherwise. 2626 */ 2627 int 2628 ndi_merge_node(dev_info_t *dip, int (*make_ua)(dev_info_t *, char *, int)) 2629 { 2630 dev_info_t *hwdip; 2631 2632 ASSERT(ndi_dev_is_persistent_node(dip) == 0); 2633 ASSERT(ddi_get_name_addr(dip) != NULL); 2634 2635 hwdip = ndi_devi_findchild_by_callback(ddi_get_parent(dip), 2636 ddi_binding_name(dip), ddi_get_name_addr(dip), make_ua); 2637 2638 /* 2639 * Look for the hardware node that is the target of the merge; 2640 * return failure if not found. 2641 */ 2642 if ((hwdip == NULL) || (hwdip == dip)) { 2643 char *buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 2644 NDI_CONFIG_DEBUG((CE_WARN, "No HW node to merge conf node %s", 2645 ddi_deviname(dip, buf))); 2646 kmem_free(buf, MAXNAMELEN); 2647 return (DDI_FAILURE); 2648 } 2649 2650 /* 2651 * Make sure the hardware node is uninitialized and has no property. 2652 * This may not be the case if new .conf files are load after some 2653 * hardware nodes have already been initialized and attached. 2654 * 2655 * N.B. We return success here because the node was *intended* 2656 * to be a merge node because there is a hw node with the name. 2657 */ 2658 mutex_enter(&DEVI(hwdip)->devi_lock); 2659 if (ndi_dev_is_persistent_node(hwdip) == 0) { 2660 char *buf; 2661 mutex_exit(&DEVI(hwdip)->devi_lock); 2662 2663 buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 2664 NDI_CONFIG_DEBUG((CE_NOTE, "Duplicate .conf node %s", 2665 ddi_deviname(dip, buf))); 2666 kmem_free(buf, MAXNAMELEN); 2667 return (DDI_SUCCESS); 2668 } 2669 2670 /* 2671 * If it is possible that the hardware has already been touched 2672 * then don't merge. 2673 */ 2674 if (i_ddi_node_state(hwdip) >= DS_INITIALIZED || 2675 (DEVI(hwdip)->devi_sys_prop_ptr != NULL) || 2676 (DEVI(hwdip)->devi_drv_prop_ptr != NULL)) { 2677 char *buf; 2678 mutex_exit(&DEVI(hwdip)->devi_lock); 2679 2680 buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 2681 NDI_CONFIG_DEBUG((CE_NOTE, 2682 "!Cannot merge .conf node %s with hw node %p " 2683 "-- not in proper state", 2684 ddi_deviname(dip, buf), (void *)hwdip)); 2685 kmem_free(buf, MAXNAMELEN); 2686 return (DDI_SUCCESS); 2687 } 2688 2689 mutex_enter(&DEVI(dip)->devi_lock); 2690 DEVI(hwdip)->devi_sys_prop_ptr = DEVI(dip)->devi_sys_prop_ptr; 2691 DEVI(hwdip)->devi_drv_prop_ptr = DEVI(dip)->devi_drv_prop_ptr; 2692 DEVI(dip)->devi_sys_prop_ptr = NULL; 2693 DEVI(dip)->devi_drv_prop_ptr = NULL; 2694 mutex_exit(&DEVI(dip)->devi_lock); 2695 mutex_exit(&DEVI(hwdip)->devi_lock); 2696 2697 return (DDI_SUCCESS); 2698 } 2699 2700 /* 2701 * Merge a "wildcard" .conf node. This is called by nexus drivers to 2702 * augment a set of hw node with properties specified in driver.conf file. 2703 * The parent node must be held busy. 2704 * 2705 * There is no failure mode, since the nexus may or may not have child 2706 * node bound the driver specified by the wildcard node. 2707 */ 2708 void 2709 ndi_merge_wildcard_node(dev_info_t *dip) 2710 { 2711 dev_info_t *hwdip; 2712 dev_info_t *pdip = ddi_get_parent(dip); 2713 major_t major = ddi_driver_major(dip); 2714 2715 /* never attempt to merge a hw node */ 2716 ASSERT(ndi_dev_is_persistent_node(dip) == 0); 2717 /* must be bound to a driver major number */ 2718 ASSERT(major != DDI_MAJOR_T_NONE); 2719 2720 /* 2721 * Walk the child list to find all nodes bound to major 2722 * and copy properties. 2723 */ 2724 mutex_enter(&DEVI(dip)->devi_lock); 2725 ASSERT(DEVI_BUSY_OWNED(pdip)); 2726 for (hwdip = ddi_get_child(pdip); hwdip; 2727 hwdip = ddi_get_next_sibling(hwdip)) { 2728 /* 2729 * Skip nodes not bound to same driver 2730 */ 2731 if (ddi_driver_major(hwdip) != major) 2732 continue; 2733 2734 /* 2735 * Skip .conf nodes 2736 */ 2737 if (ndi_dev_is_persistent_node(hwdip) == 0) 2738 continue; 2739 2740 /* 2741 * Make sure the node is uninitialized and has no property. 2742 */ 2743 mutex_enter(&DEVI(hwdip)->devi_lock); 2744 if (i_ddi_node_state(hwdip) >= DS_INITIALIZED || 2745 (DEVI(hwdip)->devi_sys_prop_ptr != NULL) || 2746 (DEVI(hwdip)->devi_drv_prop_ptr != NULL)) { 2747 mutex_exit(&DEVI(hwdip)->devi_lock); 2748 NDI_CONFIG_DEBUG((CE_NOTE, "HW node %p state not " 2749 "suitable for merging wildcard conf node %s", 2750 (void *)hwdip, ddi_node_name(dip))); 2751 continue; 2752 } 2753 2754 DEVI(hwdip)->devi_sys_prop_ptr = 2755 i_ddi_prop_list_dup(DEVI(dip)->devi_sys_prop_ptr, KM_SLEEP); 2756 DEVI(hwdip)->devi_drv_prop_ptr = 2757 i_ddi_prop_list_dup(DEVI(dip)->devi_drv_prop_ptr, KM_SLEEP); 2758 mutex_exit(&DEVI(hwdip)->devi_lock); 2759 } 2760 mutex_exit(&DEVI(dip)->devi_lock); 2761 } 2762 2763 /* 2764 * Return the major number based on the compatible property. This interface 2765 * may be used in situations where we are trying to detect if a better driver 2766 * now exists for a device, so it must use the 'compatible' property. If 2767 * a non-NULL formp is specified and the binding was based on compatible then 2768 * return the pointer to the form used in *formp. 2769 */ 2770 major_t 2771 ddi_compatible_driver_major(dev_info_t *dip, char **formp) 2772 { 2773 struct dev_info *devi = DEVI(dip); 2774 void *compat; 2775 size_t len; 2776 char *p = NULL; 2777 major_t major = DDI_MAJOR_T_NONE; 2778 2779 if (formp) 2780 *formp = NULL; 2781 2782 if (ddi_prop_exists(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 2783 "ddi-assigned")) { 2784 major = ddi_name_to_major("nulldriver"); 2785 return (major); 2786 } 2787 2788 /* 2789 * Highest precedence binding is a path-oriented alias. Since this 2790 * requires a 'path', this type of binding occurs via more obtuse 2791 * 'rebind'. The need for a path-oriented alias 'rebind' is detected 2792 * after a successful DDI_CTLOPS_INITCHILD to another driver: this is 2793 * is the first point at which the unit-address (or instance) of the 2794 * last component of the path is available (even though the path is 2795 * bound to the wrong driver at this point). 2796 */ 2797 if (devi->devi_flags & DEVI_REBIND) { 2798 p = devi->devi_rebinding_name; 2799 major = ddi_name_to_major(p); 2800 if (driver_active(major)) { 2801 if (formp) 2802 *formp = p; 2803 return (major); 2804 } 2805 2806 /* 2807 * If for some reason devi_rebinding_name no longer resolves 2808 * to a proper driver then clear DEVI_REBIND. 2809 */ 2810 mutex_enter(&devi->devi_lock); 2811 devi->devi_flags &= ~DEVI_REBIND; 2812 mutex_exit(&devi->devi_lock); 2813 } 2814 2815 /* look up compatible property */ 2816 (void) lookup_compatible(dip, KM_SLEEP); 2817 compat = (void *)(devi->devi_compat_names); 2818 len = devi->devi_compat_length; 2819 2820 /* find the highest precedence compatible form with a driver binding */ 2821 while ((p = prom_decode_composite_string(compat, len, p)) != NULL) { 2822 major = ddi_name_to_major(p); 2823 if (driver_active(major)) { 2824 if (formp) 2825 *formp = p; 2826 return (major); 2827 } 2828 } 2829 2830 /* 2831 * none of the compatible forms have a driver binding, see if 2832 * the node name has a driver binding. 2833 */ 2834 major = ddi_name_to_major(ddi_node_name(dip)); 2835 if (driver_active(major)) 2836 return (major); 2837 2838 /* no driver */ 2839 return (DDI_MAJOR_T_NONE); 2840 } 2841 2842 /* 2843 * Static help functions 2844 */ 2845 2846 /* 2847 * lookup the "compatible" property and cache it's contents in the 2848 * device node. 2849 */ 2850 static int 2851 lookup_compatible(dev_info_t *dip, uint_t flag) 2852 { 2853 int rv; 2854 int prop_flags; 2855 uint_t ncompatstrs; 2856 char **compatstrpp; 2857 char *di_compat_strp; 2858 size_t di_compat_strlen; 2859 2860 if (DEVI(dip)->devi_compat_names) { 2861 return (DDI_SUCCESS); 2862 } 2863 2864 prop_flags = DDI_PROP_TYPE_STRING | DDI_PROP_DONTPASS; 2865 2866 if (flag & KM_NOSLEEP) { 2867 prop_flags |= DDI_PROP_DONTSLEEP; 2868 } 2869 2870 if (ndi_dev_is_prom_node(dip) == 0) { 2871 prop_flags |= DDI_PROP_NOTPROM; 2872 } 2873 2874 rv = ddi_prop_lookup_common(DDI_DEV_T_ANY, dip, prop_flags, 2875 "compatible", &compatstrpp, &ncompatstrs, 2876 ddi_prop_fm_decode_strings); 2877 2878 if (rv == DDI_PROP_NOT_FOUND) { 2879 return (DDI_SUCCESS); 2880 } 2881 2882 if (rv != DDI_PROP_SUCCESS) { 2883 return (DDI_FAILURE); 2884 } 2885 2886 /* 2887 * encode the compatible property data in the dev_info node 2888 */ 2889 rv = DDI_SUCCESS; 2890 if (ncompatstrs != 0) { 2891 di_compat_strp = encode_composite_string(compatstrpp, 2892 ncompatstrs, &di_compat_strlen, flag); 2893 if (di_compat_strp != NULL) { 2894 DEVI(dip)->devi_compat_names = di_compat_strp; 2895 DEVI(dip)->devi_compat_length = di_compat_strlen; 2896 } else { 2897 rv = DDI_FAILURE; 2898 } 2899 } 2900 ddi_prop_free(compatstrpp); 2901 return (rv); 2902 } 2903 2904 /* 2905 * Create a composite string from a list of strings. 2906 * 2907 * A composite string consists of a single buffer containing one 2908 * or more NULL terminated strings. 2909 */ 2910 static char * 2911 encode_composite_string(char **strings, uint_t nstrings, size_t *retsz, 2912 uint_t flag) 2913 { 2914 uint_t index; 2915 char **strpp; 2916 uint_t slen; 2917 size_t cbuf_sz = 0; 2918 char *cbuf_p; 2919 char *cbuf_ip; 2920 2921 if (strings == NULL || nstrings == 0 || retsz == NULL) { 2922 return (NULL); 2923 } 2924 2925 for (index = 0, strpp = strings; index < nstrings; index++) 2926 cbuf_sz += strlen(*(strpp++)) + 1; 2927 2928 if ((cbuf_p = kmem_alloc(cbuf_sz, flag)) == NULL) { 2929 cmn_err(CE_NOTE, 2930 "?failed to allocate device node compatstr"); 2931 return (NULL); 2932 } 2933 2934 cbuf_ip = cbuf_p; 2935 for (index = 0, strpp = strings; index < nstrings; index++) { 2936 slen = strlen(*strpp); 2937 bcopy(*(strpp++), cbuf_ip, slen); 2938 cbuf_ip += slen; 2939 *(cbuf_ip++) = '\0'; 2940 } 2941 2942 *retsz = cbuf_sz; 2943 return (cbuf_p); 2944 } 2945 2946 static void 2947 link_to_driver_list(dev_info_t *dip) 2948 { 2949 major_t major = DEVI(dip)->devi_major; 2950 struct devnames *dnp; 2951 2952 ASSERT(major != DDI_MAJOR_T_NONE); 2953 2954 /* 2955 * Remove from orphan list 2956 */ 2957 if (ndi_dev_is_persistent_node(dip)) { 2958 dnp = &orphanlist; 2959 remove_from_dn_list(dnp, dip); 2960 } 2961 2962 /* 2963 * Add to per driver list 2964 */ 2965 dnp = &devnamesp[major]; 2966 add_to_dn_list(dnp, dip); 2967 } 2968 2969 static void 2970 unlink_from_driver_list(dev_info_t *dip) 2971 { 2972 major_t major = DEVI(dip)->devi_major; 2973 struct devnames *dnp; 2974 2975 ASSERT(major != DDI_MAJOR_T_NONE); 2976 2977 /* 2978 * Remove from per-driver list 2979 */ 2980 dnp = &devnamesp[major]; 2981 remove_from_dn_list(dnp, dip); 2982 2983 /* 2984 * Add to orphan list 2985 */ 2986 if (ndi_dev_is_persistent_node(dip)) { 2987 dnp = &orphanlist; 2988 add_to_dn_list(dnp, dip); 2989 } 2990 } 2991 2992 /* 2993 * scan the per-driver list looking for dev_info "dip" 2994 */ 2995 static dev_info_t * 2996 in_dn_list(struct devnames *dnp, dev_info_t *dip) 2997 { 2998 struct dev_info *idevi; 2999 3000 if ((idevi = DEVI(dnp->dn_head)) == NULL) 3001 return (NULL); 3002 3003 while (idevi) { 3004 if (idevi == DEVI(dip)) 3005 return (dip); 3006 idevi = idevi->devi_next; 3007 } 3008 return (NULL); 3009 } 3010 3011 /* 3012 * insert devinfo node 'dip' into the per-driver instance list 3013 * headed by 'dnp' 3014 * 3015 * Nodes on the per-driver list are ordered: HW - SID - PSEUDO. The order is 3016 * required for merging of .conf file data to work properly. 3017 */ 3018 static void 3019 add_to_ordered_dn_list(struct devnames *dnp, dev_info_t *dip) 3020 { 3021 dev_info_t **dipp; 3022 3023 ASSERT(mutex_owned(&(dnp->dn_lock))); 3024 3025 dipp = &dnp->dn_head; 3026 if (ndi_dev_is_prom_node(dip)) { 3027 /* 3028 * Find the first non-prom node or end of list 3029 */ 3030 while (*dipp && (ndi_dev_is_prom_node(*dipp) != 0)) { 3031 dipp = (dev_info_t **)&DEVI(*dipp)->devi_next; 3032 } 3033 } else if (ndi_dev_is_persistent_node(dip)) { 3034 /* 3035 * Find the first non-persistent node 3036 */ 3037 while (*dipp && (ndi_dev_is_persistent_node(*dipp) != 0)) { 3038 dipp = (dev_info_t **)&DEVI(*dipp)->devi_next; 3039 } 3040 } else { 3041 /* 3042 * Find the end of the list 3043 */ 3044 while (*dipp) { 3045 dipp = (dev_info_t **)&DEVI(*dipp)->devi_next; 3046 } 3047 } 3048 3049 DEVI(dip)->devi_next = DEVI(*dipp); 3050 *dipp = dip; 3051 } 3052 3053 /* 3054 * add a list of device nodes to the device node list in the 3055 * devnames structure 3056 */ 3057 static void 3058 add_to_dn_list(struct devnames *dnp, dev_info_t *dip) 3059 { 3060 /* 3061 * Look to see if node already exists 3062 */ 3063 LOCK_DEV_OPS(&(dnp->dn_lock)); 3064 if (in_dn_list(dnp, dip)) { 3065 cmn_err(CE_NOTE, "add_to_dn_list: node %s already in list", 3066 DEVI(dip)->devi_node_name); 3067 } else { 3068 add_to_ordered_dn_list(dnp, dip); 3069 } 3070 UNLOCK_DEV_OPS(&(dnp->dn_lock)); 3071 } 3072 3073 static void 3074 remove_from_dn_list(struct devnames *dnp, dev_info_t *dip) 3075 { 3076 dev_info_t **plist; 3077 3078 LOCK_DEV_OPS(&(dnp->dn_lock)); 3079 3080 plist = (dev_info_t **)&dnp->dn_head; 3081 while (*plist && (*plist != dip)) { 3082 plist = (dev_info_t **)&DEVI(*plist)->devi_next; 3083 } 3084 3085 if (*plist != NULL) { 3086 ASSERT(*plist == dip); 3087 *plist = (dev_info_t *)(DEVI(dip)->devi_next); 3088 DEVI(dip)->devi_next = NULL; 3089 } else { 3090 NDI_CONFIG_DEBUG((CE_NOTE, 3091 "remove_from_dn_list: node %s not found in list", 3092 DEVI(dip)->devi_node_name)); 3093 } 3094 3095 UNLOCK_DEV_OPS(&(dnp->dn_lock)); 3096 } 3097 3098 /* 3099 * Add and remove reference driver global property list 3100 */ 3101 static void 3102 add_global_props(dev_info_t *dip) 3103 { 3104 struct devnames *dnp; 3105 ddi_prop_list_t *plist; 3106 3107 ASSERT(DEVI(dip)->devi_global_prop_list == NULL); 3108 ASSERT(DEVI(dip)->devi_major != DDI_MAJOR_T_NONE); 3109 3110 dnp = &devnamesp[DEVI(dip)->devi_major]; 3111 LOCK_DEV_OPS(&dnp->dn_lock); 3112 plist = dnp->dn_global_prop_ptr; 3113 if (plist == NULL) { 3114 UNLOCK_DEV_OPS(&dnp->dn_lock); 3115 return; 3116 } 3117 i_ddi_prop_list_hold(plist, dnp); 3118 UNLOCK_DEV_OPS(&dnp->dn_lock); 3119 3120 mutex_enter(&DEVI(dip)->devi_lock); 3121 DEVI(dip)->devi_global_prop_list = plist; 3122 mutex_exit(&DEVI(dip)->devi_lock); 3123 } 3124 3125 static void 3126 remove_global_props(dev_info_t *dip) 3127 { 3128 ddi_prop_list_t *proplist; 3129 3130 mutex_enter(&DEVI(dip)->devi_lock); 3131 proplist = DEVI(dip)->devi_global_prop_list; 3132 DEVI(dip)->devi_global_prop_list = NULL; 3133 mutex_exit(&DEVI(dip)->devi_lock); 3134 3135 if (proplist) { 3136 major_t major; 3137 struct devnames *dnp; 3138 3139 major = ddi_driver_major(dip); 3140 ASSERT(major != DDI_MAJOR_T_NONE); 3141 dnp = &devnamesp[major]; 3142 LOCK_DEV_OPS(&dnp->dn_lock); 3143 i_ddi_prop_list_rele(proplist, dnp); 3144 UNLOCK_DEV_OPS(&dnp->dn_lock); 3145 } 3146 } 3147 3148 #ifdef DEBUG 3149 /* 3150 * Set this variable to '0' to disable the optimization, 3151 * and to 2 to print debug message. 3152 */ 3153 static int optimize_dtree = 1; 3154 3155 static void 3156 debug_dtree(dev_info_t *devi, struct dev_info *adevi, char *service) 3157 { 3158 char *adeviname, *buf; 3159 3160 /* 3161 * Don't print unless optimize dtree is set to 2+ 3162 */ 3163 if (optimize_dtree <= 1) 3164 return; 3165 3166 buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); 3167 adeviname = ddi_deviname((dev_info_t *)adevi, buf); 3168 if (*adeviname == '\0') 3169 adeviname = "root"; 3170 3171 cmn_err(CE_CONT, "%s %s -> %s\n", 3172 ddi_deviname(devi, buf), service, adeviname); 3173 3174 kmem_free(buf, MAXNAMELEN); 3175 } 3176 #else /* DEBUG */ 3177 #define debug_dtree(a1, a2, a3) /* nothing */ 3178 #endif /* DEBUG */ 3179 3180 static void 3181 ddi_optimize_dtree(dev_info_t *devi) 3182 { 3183 struct dev_info *pdevi; 3184 struct bus_ops *b; 3185 3186 pdevi = DEVI(devi)->devi_parent; 3187 ASSERT(pdevi); 3188 3189 /* 3190 * Set the unoptimized values 3191 */ 3192 DEVI(devi)->devi_bus_map_fault = pdevi; 3193 DEVI(devi)->devi_bus_dma_allochdl = pdevi; 3194 DEVI(devi)->devi_bus_dma_freehdl = pdevi; 3195 DEVI(devi)->devi_bus_dma_bindhdl = pdevi; 3196 DEVI(devi)->devi_bus_dma_bindfunc = 3197 pdevi->devi_ops->devo_bus_ops->bus_dma_bindhdl; 3198 DEVI(devi)->devi_bus_dma_unbindhdl = pdevi; 3199 DEVI(devi)->devi_bus_dma_unbindfunc = 3200 pdevi->devi_ops->devo_bus_ops->bus_dma_unbindhdl; 3201 DEVI(devi)->devi_bus_dma_flush = pdevi; 3202 DEVI(devi)->devi_bus_dma_win = pdevi; 3203 DEVI(devi)->devi_bus_dma_ctl = pdevi; 3204 DEVI(devi)->devi_bus_ctl = pdevi; 3205 3206 #ifdef DEBUG 3207 if (optimize_dtree == 0) 3208 return; 3209 #endif /* DEBUG */ 3210 3211 b = pdevi->devi_ops->devo_bus_ops; 3212 3213 if (i_ddi_map_fault == b->bus_map_fault) { 3214 DEVI(devi)->devi_bus_map_fault = pdevi->devi_bus_map_fault; 3215 debug_dtree(devi, DEVI(devi)->devi_bus_map_fault, 3216 "bus_map_fault"); 3217 } 3218 3219 if (ddi_dma_allochdl == b->bus_dma_allochdl) { 3220 DEVI(devi)->devi_bus_dma_allochdl = 3221 pdevi->devi_bus_dma_allochdl; 3222 debug_dtree(devi, DEVI(devi)->devi_bus_dma_allochdl, 3223 "bus_dma_allochdl"); 3224 } 3225 3226 if (ddi_dma_freehdl == b->bus_dma_freehdl) { 3227 DEVI(devi)->devi_bus_dma_freehdl = pdevi->devi_bus_dma_freehdl; 3228 debug_dtree(devi, DEVI(devi)->devi_bus_dma_freehdl, 3229 "bus_dma_freehdl"); 3230 } 3231 3232 if (ddi_dma_bindhdl == b->bus_dma_bindhdl) { 3233 DEVI(devi)->devi_bus_dma_bindhdl = pdevi->devi_bus_dma_bindhdl; 3234 DEVI(devi)->devi_bus_dma_bindfunc = 3235 pdevi->devi_bus_dma_bindhdl->devi_ops-> 3236 devo_bus_ops->bus_dma_bindhdl; 3237 debug_dtree(devi, DEVI(devi)->devi_bus_dma_bindhdl, 3238 "bus_dma_bindhdl"); 3239 } 3240 3241 if (ddi_dma_unbindhdl == b->bus_dma_unbindhdl) { 3242 DEVI(devi)->devi_bus_dma_unbindhdl = 3243 pdevi->devi_bus_dma_unbindhdl; 3244 DEVI(devi)->devi_bus_dma_unbindfunc = 3245 pdevi->devi_bus_dma_unbindhdl->devi_ops-> 3246 devo_bus_ops->bus_dma_unbindhdl; 3247 debug_dtree(devi, DEVI(devi)->devi_bus_dma_unbindhdl, 3248 "bus_dma_unbindhdl"); 3249 } 3250 3251 if (ddi_dma_flush == b->bus_dma_flush) { 3252 DEVI(devi)->devi_bus_dma_flush = pdevi->devi_bus_dma_flush; 3253 debug_dtree(devi, DEVI(devi)->devi_bus_dma_flush, 3254 "bus_dma_flush"); 3255 } 3256 3257 if (ddi_dma_win == b->bus_dma_win) { 3258 DEVI(devi)->devi_bus_dma_win = pdevi->devi_bus_dma_win; 3259 debug_dtree(devi, DEVI(devi)->devi_bus_dma_win, 3260 "bus_dma_win"); 3261 } 3262 3263 if (ddi_dma_mctl == b->bus_dma_ctl) { 3264 DEVI(devi)->devi_bus_dma_ctl = pdevi->devi_bus_dma_ctl; 3265 debug_dtree(devi, DEVI(devi)->devi_bus_dma_ctl, "bus_dma_ctl"); 3266 } 3267 3268 if (ddi_ctlops == b->bus_ctl) { 3269 DEVI(devi)->devi_bus_ctl = pdevi->devi_bus_ctl; 3270 debug_dtree(devi, DEVI(devi)->devi_bus_ctl, "bus_ctl"); 3271 } 3272 } 3273 3274 #define MIN_DEVINFO_LOG_SIZE max_ncpus 3275 #define MAX_DEVINFO_LOG_SIZE max_ncpus * 10 3276 3277 static void 3278 da_log_init() 3279 { 3280 devinfo_log_header_t *dh; 3281 int logsize = devinfo_log_size; 3282 3283 if (logsize == 0) 3284 logsize = MIN_DEVINFO_LOG_SIZE; 3285 else if (logsize > MAX_DEVINFO_LOG_SIZE) 3286 logsize = MAX_DEVINFO_LOG_SIZE; 3287 3288 dh = kmem_alloc(logsize * PAGESIZE, KM_SLEEP); 3289 mutex_init(&dh->dh_lock, NULL, MUTEX_DEFAULT, NULL); 3290 dh->dh_max = ((logsize * PAGESIZE) - sizeof (*dh)) / 3291 sizeof (devinfo_audit_t) + 1; 3292 dh->dh_curr = -1; 3293 dh->dh_hits = 0; 3294 3295 devinfo_audit_log = dh; 3296 } 3297 3298 /* 3299 * Log the stack trace in per-devinfo audit structure and also enter 3300 * it into a system wide log for recording the time history. 3301 */ 3302 static void 3303 da_log_enter(dev_info_t *dip) 3304 { 3305 devinfo_audit_t *da_log, *da = DEVI(dip)->devi_audit; 3306 devinfo_log_header_t *dh = devinfo_audit_log; 3307 3308 if (devinfo_audit_log == NULL) 3309 return; 3310 3311 ASSERT(da != NULL); 3312 3313 da->da_devinfo = dip; 3314 da->da_timestamp = gethrtime(); 3315 da->da_thread = curthread; 3316 da->da_node_state = DEVI(dip)->devi_node_state; 3317 da->da_device_state = DEVI(dip)->devi_state; 3318 da->da_depth = getpcstack(da->da_stack, DDI_STACK_DEPTH); 3319 3320 /* 3321 * Copy into common log and note the location for tracing history 3322 */ 3323 mutex_enter(&dh->dh_lock); 3324 dh->dh_hits++; 3325 dh->dh_curr++; 3326 if (dh->dh_curr >= dh->dh_max) 3327 dh->dh_curr -= dh->dh_max; 3328 da_log = &dh->dh_entry[dh->dh_curr]; 3329 mutex_exit(&dh->dh_lock); 3330 3331 bcopy(da, da_log, sizeof (devinfo_audit_t)); 3332 da->da_lastlog = da_log; 3333 } 3334 3335 static void 3336 attach_drivers() 3337 { 3338 int i; 3339 for (i = 0; i < devcnt; i++) { 3340 struct devnames *dnp = &devnamesp[i]; 3341 if ((dnp->dn_flags & DN_FORCE_ATTACH) && 3342 (ddi_hold_installed_driver((major_t)i) != NULL)) 3343 ddi_rele_driver((major_t)i); 3344 } 3345 } 3346 3347 /* 3348 * Launch a thread to force attach drivers. This avoids penalty on boot time. 3349 */ 3350 void 3351 i_ddi_forceattach_drivers() 3352 { 3353 3354 /* 3355 * Attach IB VHCI driver before the force-attach thread attaches the 3356 * IB HCA driver. IB HCA driver will fail if IB Nexus has not yet 3357 * been attached. 3358 */ 3359 (void) ddi_hold_installed_driver(ddi_name_to_major("ib")); 3360 3361 (void) thread_create(NULL, 0, (void (*)())attach_drivers, NULL, 0, &p0, 3362 TS_RUN, minclsyspri); 3363 } 3364 3365 /* 3366 * This is a private DDI interface for optimizing boot performance. 3367 * I/O subsystem initialization is considered complete when devfsadm 3368 * is executed. 3369 * 3370 * NOTE: The start of syseventd happens to be a convenient indicator 3371 * of the completion of I/O initialization during boot. 3372 * The implementation should be replaced by something more robust. 3373 */ 3374 int 3375 i_ddi_io_initialized() 3376 { 3377 extern int sysevent_daemon_init; 3378 return (sysevent_daemon_init); 3379 } 3380 3381 /* 3382 * May be used to determine system boot state 3383 * "Available" means the system is for the most part up 3384 * and initialized, with all system services either up or 3385 * capable of being started. This state is set by devfsadm 3386 * during the boot process. The /dev filesystem infers 3387 * from this when implicit reconfig can be performed, 3388 * ie, devfsadm can be invoked. Please avoid making 3389 * further use of this unless it's really necessary. 3390 */ 3391 int 3392 i_ddi_sysavail() 3393 { 3394 return (devname_state & DS_SYSAVAIL); 3395 } 3396 3397 /* 3398 * May be used to determine if boot is a reconfigure boot. 3399 */ 3400 int 3401 i_ddi_reconfig() 3402 { 3403 return (devname_state & DS_RECONFIG); 3404 } 3405 3406 /* 3407 * Note system services are up, inform /dev. 3408 */ 3409 void 3410 i_ddi_set_sysavail() 3411 { 3412 if ((devname_state & DS_SYSAVAIL) == 0) { 3413 devname_state |= DS_SYSAVAIL; 3414 sdev_devstate_change(); 3415 } 3416 } 3417 3418 /* 3419 * Note reconfiguration boot, inform /dev. 3420 */ 3421 void 3422 i_ddi_set_reconfig() 3423 { 3424 if ((devname_state & DS_RECONFIG) == 0) { 3425 devname_state |= DS_RECONFIG; 3426 sdev_devstate_change(); 3427 } 3428 } 3429 3430 3431 /* 3432 * device tree walking 3433 */ 3434 3435 struct walk_elem { 3436 struct walk_elem *next; 3437 dev_info_t *dip; 3438 }; 3439 3440 static void 3441 free_list(struct walk_elem *list) 3442 { 3443 while (list) { 3444 struct walk_elem *next = list->next; 3445 kmem_free(list, sizeof (*list)); 3446 list = next; 3447 } 3448 } 3449 3450 static void 3451 append_node(struct walk_elem **list, dev_info_t *dip) 3452 { 3453 struct walk_elem *tail; 3454 struct walk_elem *elem = kmem_alloc(sizeof (*elem), KM_SLEEP); 3455 3456 elem->next = NULL; 3457 elem->dip = dip; 3458 3459 if (*list == NULL) { 3460 *list = elem; 3461 return; 3462 } 3463 3464 tail = *list; 3465 while (tail->next) 3466 tail = tail->next; 3467 3468 tail->next = elem; 3469 } 3470 3471 /* 3472 * The implementation of ddi_walk_devs(). 3473 */ 3474 static int 3475 walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg, 3476 int do_locking) 3477 { 3478 struct walk_elem *head = NULL; 3479 3480 /* 3481 * Do it in two passes. First pass invoke callback on each 3482 * dip on the sibling list. Second pass invoke callback on 3483 * children of each dip. 3484 */ 3485 while (dip) { 3486 switch ((*f)(dip, arg)) { 3487 case DDI_WALK_TERMINATE: 3488 free_list(head); 3489 return (DDI_WALK_TERMINATE); 3490 3491 case DDI_WALK_PRUNESIB: 3492 /* ignore sibling by setting dip to NULL */ 3493 append_node(&head, dip); 3494 dip = NULL; 3495 break; 3496 3497 case DDI_WALK_PRUNECHILD: 3498 /* don't worry about children */ 3499 dip = ddi_get_next_sibling(dip); 3500 break; 3501 3502 case DDI_WALK_CONTINUE: 3503 default: 3504 append_node(&head, dip); 3505 dip = ddi_get_next_sibling(dip); 3506 break; 3507 } 3508 3509 } 3510 3511 /* second pass */ 3512 while (head) { 3513 int circ; 3514 struct walk_elem *next = head->next; 3515 3516 if (do_locking) 3517 ndi_devi_enter(head->dip, &circ); 3518 if (walk_devs(ddi_get_child(head->dip), f, arg, do_locking) == 3519 DDI_WALK_TERMINATE) { 3520 if (do_locking) 3521 ndi_devi_exit(head->dip, circ); 3522 free_list(head); 3523 return (DDI_WALK_TERMINATE); 3524 } 3525 if (do_locking) 3526 ndi_devi_exit(head->dip, circ); 3527 kmem_free(head, sizeof (*head)); 3528 head = next; 3529 } 3530 3531 return (DDI_WALK_CONTINUE); 3532 } 3533 3534 /* 3535 * This general-purpose routine traverses the tree of dev_info nodes, 3536 * starting from the given node, and calls the given function for each 3537 * node that it finds with the current node and the pointer arg (which 3538 * can point to a structure of information that the function 3539 * needs) as arguments. 3540 * 3541 * It does the walk a layer at a time, not depth-first. The given function 3542 * must return one of the following values: 3543 * DDI_WALK_CONTINUE 3544 * DDI_WALK_PRUNESIB 3545 * DDI_WALK_PRUNECHILD 3546 * DDI_WALK_TERMINATE 3547 * 3548 * N.B. Since we walk the sibling list, the caller must ensure that 3549 * the parent of dip is held against changes, unless the parent 3550 * is rootnode. ndi_devi_enter() on the parent is sufficient. 3551 * 3552 * To avoid deadlock situations, caller must not attempt to 3553 * configure/unconfigure/remove device node in (*f)(), nor should 3554 * it attempt to recurse on other nodes in the system. Any 3555 * ndi_devi_enter() done by (*f)() must occur 'at-or-below' the 3556 * node entered prior to ddi_walk_devs(). Furthermore, if (*f)() 3557 * does any multi-threading (in framework *or* in driver) then the 3558 * ndi_devi_enter() calls done by dependent threads must be 3559 * 'strictly-below'. 3560 * 3561 * This is not callable from device autoconfiguration routines. 3562 * They include, but not limited to, _init(9e), _fini(9e), probe(9e), 3563 * attach(9e), and detach(9e). 3564 */ 3565 void 3566 ddi_walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg) 3567 { 3568 3569 ASSERT(dip == NULL || ddi_get_parent(dip) == NULL || 3570 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 3571 3572 (void) walk_devs(dip, f, arg, 1); 3573 } 3574 3575 /* 3576 * This is a general-purpose routine traverses the per-driver list 3577 * and calls the given function for each node. must return one of 3578 * the following values: 3579 * DDI_WALK_CONTINUE 3580 * DDI_WALK_TERMINATE 3581 * 3582 * N.B. The same restrictions from ddi_walk_devs() apply. 3583 */ 3584 void 3585 e_ddi_walk_driver(char *drv, int (*f)(dev_info_t *, void *), void *arg) 3586 { 3587 major_t major; 3588 struct devnames *dnp; 3589 dev_info_t *dip; 3590 3591 major = ddi_name_to_major(drv); 3592 if (major == DDI_MAJOR_T_NONE) 3593 return; 3594 3595 dnp = &devnamesp[major]; 3596 LOCK_DEV_OPS(&dnp->dn_lock); 3597 dip = dnp->dn_head; 3598 while (dip) { 3599 ndi_hold_devi(dip); 3600 UNLOCK_DEV_OPS(&dnp->dn_lock); 3601 if ((*f)(dip, arg) == DDI_WALK_TERMINATE) { 3602 ndi_rele_devi(dip); 3603 return; 3604 } 3605 LOCK_DEV_OPS(&dnp->dn_lock); 3606 ndi_rele_devi(dip); 3607 dip = ddi_get_next(dip); 3608 } 3609 UNLOCK_DEV_OPS(&dnp->dn_lock); 3610 } 3611 3612 struct preroot_walk_block_devices_arg { 3613 int (*prwb_func)(const char *, void *); 3614 void *prwb_arg; 3615 }; 3616 3617 static int 3618 preroot_walk_block_devices_walker(dev_info_t *dip, void *arg) 3619 { 3620 struct preroot_walk_block_devices_arg *prwb = arg; 3621 3622 if (i_ddi_devi_class(dip) == NULL || 3623 strcmp(i_ddi_devi_class(dip), ESC_DISK) != 0) { 3624 /* 3625 * We do not think that this is a disk. 3626 */ 3627 return (DDI_WALK_CONTINUE); 3628 } 3629 3630 for (struct ddi_minor_data *md = DEVI(dip)->devi_minor; md != NULL; 3631 md = md->next) { 3632 if (md->ddm_spec_type != S_IFBLK) { 3633 /* 3634 * We don't want the raw version of any block device. 3635 */ 3636 continue; 3637 } 3638 3639 /* 3640 * The node type taxonomy is hierarchical, with each level 3641 * separated by colons. Nodes of interest are either of the 3642 * BLOCK type, or are prefixed with that type. 3643 */ 3644 if (strcmp(md->ddm_node_type, DDI_NT_BLOCK) != 0 && 3645 strncmp(md->ddm_node_type, DDI_NT_BLOCK ":", 3646 strlen(DDI_NT_BLOCK ":")) != 0) { 3647 /* 3648 * This minor node does not represent a block device. 3649 */ 3650 continue; 3651 } 3652 3653 char buf[MAXPATHLEN]; 3654 int r; 3655 if ((r = prwb->prwb_func(ddi_pathname_minor(md, buf), 3656 prwb->prwb_arg)) == PREROOT_WALK_BLOCK_DEVICES_CANCEL) { 3657 /* 3658 * The consumer does not need any more minor nodes. 3659 */ 3660 return (DDI_WALK_TERMINATE); 3661 } 3662 VERIFY3S(r, ==, PREROOT_WALK_BLOCK_DEVICES_NEXT); 3663 } 3664 3665 return (DDI_WALK_CONTINUE); 3666 } 3667 3668 /* 3669 * Private routine for ZFS when it needs to attach and scan all of the block 3670 * device minors in the system while looking for vdev labels. 3671 * 3672 * The callback function accepts a physical device path and the context 3673 * argument (arg) passed to this function; it should return 3674 * PREROOT_WALK_BLOCK_DEVICES_NEXT when more devices are required and 3675 * PREROOT_WALK_BLOCK_DEVICES_CANCEL to stop the walk. 3676 */ 3677 void 3678 preroot_walk_block_devices(int (*callback)(const char *, void *), void *arg) 3679 { 3680 /* 3681 * First, force everything which can attach to do so. The device class 3682 * is not derived until at least one minor mode is created, so we 3683 * cannot walk the device tree looking for a device class of ESC_DISK 3684 * until everything is attached. 3685 */ 3686 (void) ndi_devi_config(ddi_root_node(), NDI_CONFIG | NDI_DEVI_PERSIST | 3687 NDI_NO_EVENT | NDI_DRV_CONF_REPROBE); 3688 3689 struct preroot_walk_block_devices_arg prwb; 3690 prwb.prwb_func = callback; 3691 prwb.prwb_arg = arg; 3692 3693 ddi_walk_devs(ddi_root_node(), preroot_walk_block_devices_walker, 3694 &prwb); 3695 } 3696 3697 /* 3698 * argument to i_find_devi, a devinfo node search callback function. 3699 */ 3700 struct match_info { 3701 dev_info_t *dip; /* result */ 3702 char *nodename; /* if non-null, nodename must match */ 3703 int instance; /* if != -1, instance must match */ 3704 int attached; /* if != 0, i_ddi_devi_attached() */ 3705 }; 3706 3707 static int 3708 i_find_devi(dev_info_t *dip, void *arg) 3709 { 3710 struct match_info *info = (struct match_info *)arg; 3711 3712 if (((info->nodename == NULL) || 3713 (strcmp(ddi_node_name(dip), info->nodename) == 0)) && 3714 ((info->instance == -1) || 3715 (ddi_get_instance(dip) == info->instance)) && 3716 ((info->attached == 0) || i_ddi_devi_attached(dip))) { 3717 info->dip = dip; 3718 ndi_hold_devi(dip); 3719 return (DDI_WALK_TERMINATE); 3720 } 3721 3722 return (DDI_WALK_CONTINUE); 3723 } 3724 3725 /* 3726 * Find dip with a known node name and instance and return with it held 3727 */ 3728 dev_info_t * 3729 ddi_find_devinfo(char *nodename, int instance, int attached) 3730 { 3731 struct match_info info; 3732 3733 info.nodename = nodename; 3734 info.instance = instance; 3735 info.attached = attached; 3736 info.dip = NULL; 3737 3738 ddi_walk_devs(ddi_root_node(), i_find_devi, &info); 3739 return (info.dip); 3740 } 3741 3742 extern ib_boot_prop_t *iscsiboot_prop; 3743 static void 3744 i_ddi_parse_iscsi_name(char *name, char **nodename, char **addrname, 3745 char **minorname) 3746 { 3747 char *cp, *colon; 3748 static char nulladdrname[] = ""; 3749 3750 /* default values */ 3751 if (nodename) 3752 *nodename = name; 3753 if (addrname) 3754 *addrname = nulladdrname; 3755 if (minorname) 3756 *minorname = NULL; 3757 3758 cp = colon = name; 3759 while (*cp != '\0') { 3760 if (addrname && *cp == '@') { 3761 *addrname = cp + 1; 3762 *cp = '\0'; 3763 } else if (minorname && *cp == ':') { 3764 *minorname = cp + 1; 3765 colon = cp; 3766 } 3767 ++cp; 3768 } 3769 if (colon != name) { 3770 *colon = '\0'; 3771 } 3772 } 3773 3774 /* 3775 * Parse for name, addr, and minor names. Some args may be NULL. 3776 */ 3777 void 3778 i_ddi_parse_name(char *name, char **nodename, char **addrname, char **minorname) 3779 { 3780 char *cp; 3781 static char nulladdrname[] = ""; 3782 3783 /* default values */ 3784 if (nodename) 3785 *nodename = name; 3786 if (addrname) 3787 *addrname = nulladdrname; 3788 if (minorname) 3789 *minorname = NULL; 3790 3791 cp = name; 3792 while (*cp != '\0') { 3793 if (addrname && *cp == '@') { 3794 *addrname = cp + 1; 3795 *cp = '\0'; 3796 } else if (minorname && *cp == ':') { 3797 *minorname = cp + 1; 3798 *cp = '\0'; 3799 } 3800 ++cp; 3801 } 3802 } 3803 3804 static char * 3805 child_path_to_driver(dev_info_t *parent, char *child_name, char *unit_address) 3806 { 3807 char *p, *drvname = NULL; 3808 major_t maj; 3809 3810 /* 3811 * Construct the pathname and ask the implementation 3812 * if it can do a driver = f(pathname) for us, if not 3813 * we'll just default to using the node-name that 3814 * was given to us. We want to do this first to 3815 * allow the platform to use 'generic' names for 3816 * legacy device drivers. 3817 */ 3818 p = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 3819 (void) ddi_pathname(parent, p); 3820 (void) strcat(p, "/"); 3821 (void) strcat(p, child_name); 3822 if (unit_address && *unit_address) { 3823 (void) strcat(p, "@"); 3824 (void) strcat(p, unit_address); 3825 } 3826 3827 /* 3828 * Get the binding. If there is none, return the child_name 3829 * and let the caller deal with it. 3830 */ 3831 maj = path_to_major(p); 3832 3833 kmem_free(p, MAXPATHLEN); 3834 3835 if (maj != DDI_MAJOR_T_NONE) 3836 drvname = ddi_major_to_name(maj); 3837 if (drvname == NULL) 3838 drvname = child_name; 3839 3840 return (drvname); 3841 } 3842 3843 3844 #define PCI_EX_CLASS "pciexclass" 3845 #define PCI_EX "pciex" 3846 #define PCI_CLASS "pciclass" 3847 #define PCI "pci" 3848 3849 int 3850 ddi_is_pci_dip(dev_info_t *dip) 3851 { 3852 char *prop = NULL; 3853 3854 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 3855 "compatible", &prop) == DDI_PROP_SUCCESS) { 3856 ASSERT(prop); 3857 if (strncmp(prop, PCI_EX_CLASS, sizeof (PCI_EX_CLASS) - 1) 3858 == 0 || 3859 strncmp(prop, PCI_EX, sizeof (PCI_EX)- 1) 3860 == 0 || 3861 strncmp(prop, PCI_CLASS, sizeof (PCI_CLASS) - 1) 3862 == 0 || 3863 strncmp(prop, PCI, sizeof (PCI) - 1) 3864 == 0) { 3865 ddi_prop_free(prop); 3866 return (1); 3867 } 3868 } 3869 3870 if (prop != NULL) { 3871 ddi_prop_free(prop); 3872 } 3873 3874 return (0); 3875 } 3876 3877 /* 3878 * Given the pathname of a device, fill in the dev_info_t value and/or the 3879 * dev_t value and/or the spectype, depending on which parameters are non-NULL. 3880 * If there is an error, this function returns -1. 3881 * 3882 * NOTE: If this function returns the dev_info_t structure, then it 3883 * does so with a hold on the devi. Caller should ensure that they get 3884 * decremented via ddi_release_devi() or ndi_rele_devi(); 3885 * 3886 * This function can be invoked in the boot case for a pathname without 3887 * device argument (:xxxx), traditionally treated as a minor name. 3888 * In this case, we do the following 3889 * (1) search the minor node of type DDM_DEFAULT. 3890 * (2) if no DDM_DEFAULT minor exists, then the first non-alias minor is chosen. 3891 * (3) if neither exists, a dev_t is faked with minor number = instance. 3892 * As of S9 FCS, no instance of #1 exists. #2 is used by several platforms 3893 * to default the boot partition to :a possibly by other OBP definitions. 3894 * #3 is used for booting off network interfaces, most SPARC network 3895 * drivers support Style-2 only, so only DDM_ALIAS minor exists. 3896 * 3897 * It is possible for OBP to present device args at the end of the path as 3898 * well as in the middle. For example, with IB the following strings are 3899 * valid boot paths. 3900 * a /pci@8,700000/ib@1,2:port=1,pkey=ff,dhcp,... 3901 * b /pci@8,700000/ib@1,1:port=1/ioc@xxxxxx,yyyyyyy:dhcp 3902 * Case (a), we first look for minor node "port=1,pkey...". 3903 * Failing that, we will pass "port=1,pkey..." to the bus_config 3904 * entry point of ib (HCA) driver. 3905 * Case (b), configure ib@1,1 as usual. Then invoke ib's bus_config 3906 * with argument "ioc@xxxxxxx,yyyyyyy:port=1". After configuring 3907 * the ioc, look for minor node dhcp. If not found, pass ":dhcp" 3908 * to ioc's bus_config entry point. 3909 */ 3910 int 3911 resolve_pathname(char *pathname, dev_info_t **dipp, dev_t *devtp, 3912 int *spectypep) 3913 { 3914 int error; 3915 dev_info_t *parent, *child; 3916 struct pathname pn; 3917 char *component, *config_name; 3918 char *minorname = NULL; 3919 char *prev_minor = NULL; 3920 dev_t devt = NODEV; 3921 int spectype; 3922 struct ddi_minor_data *dmn; 3923 int circ; 3924 3925 if (*pathname != '/') 3926 return (EINVAL); 3927 parent = ddi_root_node(); /* Begin at the top of the tree */ 3928 3929 if (error = pn_get(pathname, UIO_SYSSPACE, &pn)) 3930 return (error); 3931 pn_skipslash(&pn); 3932 3933 ASSERT(i_ddi_devi_attached(parent)); 3934 ndi_hold_devi(parent); 3935 3936 component = kmem_alloc(MAXNAMELEN, KM_SLEEP); 3937 config_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); 3938 3939 while (pn_pathleft(&pn)) { 3940 /* remember prev minor (:xxx) in the middle of path */ 3941 if (minorname) 3942 prev_minor = i_ddi_strdup(minorname, KM_SLEEP); 3943 3944 /* Get component and chop off minorname */ 3945 (void) pn_getcomponent(&pn, component); 3946 if ((iscsiboot_prop != NULL) && 3947 (strcmp((DEVI(parent)->devi_node_name), "iscsi") == 0)) { 3948 i_ddi_parse_iscsi_name(component, NULL, NULL, 3949 &minorname); 3950 } else { 3951 i_ddi_parse_name(component, NULL, NULL, &minorname); 3952 } 3953 if (prev_minor == NULL) { 3954 (void) snprintf(config_name, MAXNAMELEN, "%s", 3955 component); 3956 } else { 3957 (void) snprintf(config_name, MAXNAMELEN, "%s:%s", 3958 component, prev_minor); 3959 kmem_free(prev_minor, strlen(prev_minor) + 1); 3960 prev_minor = NULL; 3961 } 3962 3963 /* 3964 * Find and configure the child 3965 */ 3966 if (ndi_devi_config_one(parent, config_name, &child, 3967 NDI_PROMNAME | NDI_NO_EVENT) != NDI_SUCCESS) { 3968 ndi_rele_devi(parent); 3969 pn_free(&pn); 3970 kmem_free(component, MAXNAMELEN); 3971 kmem_free(config_name, MAXNAMELEN); 3972 return (-1); 3973 } 3974 3975 ASSERT(i_ddi_devi_attached(child)); 3976 ndi_rele_devi(parent); 3977 parent = child; 3978 pn_skipslash(&pn); 3979 } 3980 3981 /* 3982 * First look for a minor node matching minorname. 3983 * Failing that, try to pass minorname to bus_config(). 3984 */ 3985 if (minorname && i_ddi_minorname_to_devtspectype(parent, 3986 minorname, &devt, &spectype) == DDI_FAILURE) { 3987 (void) snprintf(config_name, MAXNAMELEN, "%s", minorname); 3988 if (ndi_devi_config_obp_args(parent, 3989 config_name, &child, 0) != NDI_SUCCESS) { 3990 ndi_rele_devi(parent); 3991 pn_free(&pn); 3992 kmem_free(component, MAXNAMELEN); 3993 kmem_free(config_name, MAXNAMELEN); 3994 NDI_CONFIG_DEBUG((CE_NOTE, 3995 "%s: minor node not found\n", pathname)); 3996 return (-1); 3997 } 3998 minorname = NULL; /* look for default minor */ 3999 ASSERT(i_ddi_devi_attached(child)); 4000 ndi_rele_devi(parent); 4001 parent = child; 4002 } 4003 4004 if (devtp || spectypep) { 4005 if (minorname == NULL) { 4006 /* 4007 * Search for a default entry with an active 4008 * ndi_devi_enter to protect the devi_minor list. 4009 */ 4010 ndi_devi_enter(parent, &circ); 4011 for (dmn = DEVI(parent)->devi_minor; dmn; 4012 dmn = dmn->next) { 4013 if (dmn->type == DDM_DEFAULT) { 4014 devt = dmn->ddm_dev; 4015 spectype = dmn->ddm_spec_type; 4016 break; 4017 } 4018 } 4019 4020 if (devt == NODEV) { 4021 /* 4022 * No default minor node, try the first one; 4023 * else, assume 1-1 instance-minor mapping 4024 */ 4025 dmn = DEVI(parent)->devi_minor; 4026 if (dmn && ((dmn->type == DDM_MINOR) || 4027 (dmn->type == DDM_INTERNAL_PATH))) { 4028 devt = dmn->ddm_dev; 4029 spectype = dmn->ddm_spec_type; 4030 } else { 4031 devt = makedevice( 4032 DEVI(parent)->devi_major, 4033 ddi_get_instance(parent)); 4034 spectype = S_IFCHR; 4035 } 4036 } 4037 ndi_devi_exit(parent, circ); 4038 } 4039 if (devtp) 4040 *devtp = devt; 4041 if (spectypep) 4042 *spectypep = spectype; 4043 } 4044 4045 pn_free(&pn); 4046 kmem_free(component, MAXNAMELEN); 4047 kmem_free(config_name, MAXNAMELEN); 4048 4049 /* 4050 * If there is no error, return the appropriate parameters 4051 */ 4052 if (dipp != NULL) 4053 *dipp = parent; 4054 else { 4055 /* 4056 * We should really keep the ref count to keep the node from 4057 * detaching but ddi_pathname_to_dev_t() specifies a NULL dipp, 4058 * so we have no way of passing back the held dip. Not holding 4059 * the dip allows detaches to occur - which can cause problems 4060 * for subsystems which call ddi_pathname_to_dev_t (console). 4061 * 4062 * Instead of holding the dip, we place a ddi-no-autodetach 4063 * property on the node to prevent auto detaching. 4064 * 4065 * The right fix is to remove ddi_pathname_to_dev_t and replace 4066 * it, and all references, with a call that specifies a dipp. 4067 * In addition, the callers of this new interfaces would then 4068 * need to call ndi_rele_devi when the reference is complete. 4069 * 4070 */ 4071 (void) ddi_prop_update_int(DDI_DEV_T_NONE, parent, 4072 DDI_NO_AUTODETACH, 1); 4073 ndi_rele_devi(parent); 4074 } 4075 4076 return (0); 4077 } 4078 4079 /* 4080 * Given the pathname of a device, return the dev_t of the corresponding 4081 * device. Returns NODEV on failure. 4082 * 4083 * Note that this call sets the DDI_NO_AUTODETACH property on the devinfo node. 4084 */ 4085 dev_t 4086 ddi_pathname_to_dev_t(char *pathname) 4087 { 4088 dev_t devt; 4089 int error; 4090 4091 error = resolve_pathname(pathname, NULL, &devt, NULL); 4092 4093 return (error ? NODEV : devt); 4094 } 4095 4096 /* 4097 * Translate a prom pathname to kernel devfs pathname. 4098 * Caller is assumed to allocate devfspath memory of 4099 * size at least MAXPATHLEN 4100 * 4101 * The prom pathname may not include minor name, but 4102 * devfs pathname has a minor name portion. 4103 */ 4104 int 4105 i_ddi_prompath_to_devfspath(char *prompath, char *devfspath) 4106 { 4107 dev_t devt = (dev_t)NODEV; 4108 dev_info_t *dip = NULL; 4109 char *minor_name = NULL; 4110 int spectype; 4111 int error; 4112 int circ; 4113 4114 error = resolve_pathname(prompath, &dip, &devt, &spectype); 4115 if (error) 4116 return (DDI_FAILURE); 4117 ASSERT(dip && devt != NODEV); 4118 4119 /* 4120 * Get in-kernel devfs pathname 4121 */ 4122 (void) ddi_pathname(dip, devfspath); 4123 4124 ndi_devi_enter(dip, &circ); 4125 minor_name = i_ddi_devtspectype_to_minorname(dip, devt, spectype); 4126 if (minor_name) { 4127 (void) strcat(devfspath, ":"); 4128 (void) strcat(devfspath, minor_name); 4129 } else { 4130 /* 4131 * If minor_name is NULL, we have an alias minor node. 4132 * So manufacture a path to the corresponding clone minor. 4133 */ 4134 (void) snprintf(devfspath, MAXPATHLEN, "%s:%s", 4135 CLONE_PATH, ddi_driver_name(dip)); 4136 } 4137 ndi_devi_exit(dip, circ); 4138 4139 /* release hold from resolve_pathname() */ 4140 ndi_rele_devi(dip); 4141 return (0); 4142 } 4143 4144 /* 4145 * This function is intended to identify drivers that must quiesce for fast 4146 * reboot to succeed. It does not claim to have more knowledge about the device 4147 * than its driver. If a driver has implemented quiesce(), it will be invoked; 4148 * if a so identified driver does not manage any device that needs to be 4149 * quiesced, it must explicitly set its devo_quiesce dev_op to 4150 * ddi_quiesce_not_needed. 4151 */ 4152 static int skip_pseudo = 1; /* Skip pseudo devices */ 4153 static int skip_non_hw = 1; /* Skip devices with no hardware property */ 4154 static int 4155 should_implement_quiesce(dev_info_t *dip) 4156 { 4157 struct dev_info *devi = DEVI(dip); 4158 dev_info_t *pdip; 4159 4160 /* 4161 * If dip is pseudo and skip_pseudo is set, driver doesn't have to 4162 * implement quiesce(). 4163 */ 4164 if (skip_pseudo && 4165 strncmp(ddi_binding_name(dip), "pseudo", sizeof ("pseudo")) == 0) 4166 return (0); 4167 4168 /* 4169 * If parent dip is pseudo and skip_pseudo is set, driver doesn't have 4170 * to implement quiesce(). 4171 */ 4172 if (skip_pseudo && (pdip = ddi_get_parent(dip)) != NULL && 4173 strncmp(ddi_binding_name(pdip), "pseudo", sizeof ("pseudo")) == 0) 4174 return (0); 4175 4176 /* 4177 * If not attached, driver doesn't have to implement quiesce(). 4178 */ 4179 if (!i_ddi_devi_attached(dip)) 4180 return (0); 4181 4182 /* 4183 * If dip has no hardware property and skip_non_hw is set, 4184 * driver doesn't have to implement quiesce(). 4185 */ 4186 if (skip_non_hw && devi->devi_hw_prop_ptr == NULL) 4187 return (0); 4188 4189 return (1); 4190 } 4191 4192 static int 4193 driver_has_quiesce(struct dev_ops *ops) 4194 { 4195 if ((ops->devo_rev >= 4) && (ops->devo_quiesce != nodev) && 4196 (ops->devo_quiesce != NULL) && (ops->devo_quiesce != nulldev) && 4197 (ops->devo_quiesce != ddi_quiesce_not_supported)) 4198 return (1); 4199 else 4200 return (0); 4201 } 4202 4203 /* 4204 * Check to see if a driver has implemented the quiesce() DDI function. 4205 */ 4206 int 4207 check_driver_quiesce(dev_info_t *dip, void *arg) 4208 { 4209 struct dev_ops *ops; 4210 4211 if (!should_implement_quiesce(dip)) 4212 return (DDI_WALK_CONTINUE); 4213 4214 if ((ops = ddi_get_driver(dip)) == NULL) 4215 return (DDI_WALK_CONTINUE); 4216 4217 if (driver_has_quiesce(ops)) { 4218 if ((quiesce_debug & 0x2) == 0x2) { 4219 if (ops->devo_quiesce == ddi_quiesce_not_needed) 4220 cmn_err(CE_CONT, "%s does not need to be " 4221 "quiesced", ddi_driver_name(dip)); 4222 else 4223 cmn_err(CE_CONT, "%s has quiesce routine", 4224 ddi_driver_name(dip)); 4225 } 4226 } else { 4227 if (arg != NULL) 4228 *((int *)arg) = -1; 4229 cmn_err(CE_WARN, "%s has no quiesce()", ddi_driver_name(dip)); 4230 } 4231 4232 return (DDI_WALK_CONTINUE); 4233 } 4234 4235 /* 4236 * Quiesce device. 4237 */ 4238 static void 4239 quiesce_one_device(dev_info_t *dip, void *arg) 4240 { 4241 struct dev_ops *ops; 4242 int should_quiesce = 0; 4243 4244 /* 4245 * If the device is not attached it doesn't need to be quiesced. 4246 */ 4247 if (!i_ddi_devi_attached(dip)) 4248 return; 4249 4250 if ((ops = ddi_get_driver(dip)) == NULL) 4251 return; 4252 4253 should_quiesce = should_implement_quiesce(dip); 4254 4255 /* 4256 * If there's an implementation of quiesce(), always call it even if 4257 * some of the drivers don't have quiesce() or quiesce() have failed 4258 * so we can do force fast reboot. The implementation of quiesce() 4259 * should not negatively affect a regular reboot. 4260 */ 4261 if (driver_has_quiesce(ops)) { 4262 int rc = DDI_SUCCESS; 4263 4264 if (ops->devo_quiesce == ddi_quiesce_not_needed) 4265 return; 4266 4267 rc = devi_quiesce(dip); 4268 4269 if (rc != DDI_SUCCESS && should_quiesce) { 4270 #ifdef DEBUG 4271 cmn_err(CE_WARN, "quiesce() failed for %s%d", 4272 ddi_driver_name(dip), ddi_get_instance(dip)); 4273 #endif /* DEBUG */ 4274 if (arg != NULL) 4275 *((int *)arg) = -1; 4276 } 4277 } else if (should_quiesce && arg != NULL) { 4278 *((int *)arg) = -1; 4279 } 4280 } 4281 4282 /* 4283 * Traverse the dev info tree in a breadth-first manner so that we quiesce 4284 * children first. All subtrees under the parent of dip will be quiesced. 4285 */ 4286 void 4287 quiesce_devices(dev_info_t *dip, void *arg) 4288 { 4289 /* 4290 * if we're reached here, the device tree better not be changing. 4291 * so either devinfo_freeze better be set or we better be panicing. 4292 */ 4293 ASSERT(devinfo_freeze || panicstr); 4294 4295 for (; dip != NULL; dip = ddi_get_next_sibling(dip)) { 4296 quiesce_devices(ddi_get_child(dip), arg); 4297 4298 quiesce_one_device(dip, arg); 4299 } 4300 } 4301 4302 /* 4303 * Reset all the pure leaf drivers on the system at halt time 4304 */ 4305 static int 4306 reset_leaf_device(dev_info_t *dip, void *arg) 4307 { 4308 _NOTE(ARGUNUSED(arg)) 4309 struct dev_ops *ops; 4310 4311 /* if the device doesn't need to be reset then there's nothing to do */ 4312 if (!DEVI_NEED_RESET(dip)) 4313 return (DDI_WALK_CONTINUE); 4314 4315 /* 4316 * if the device isn't a char/block device or doesn't have a 4317 * reset entry point then there's nothing to do. 4318 */ 4319 ops = ddi_get_driver(dip); 4320 if ((ops == NULL) || (ops->devo_cb_ops == NULL) || 4321 (ops->devo_reset == nodev) || (ops->devo_reset == nulldev) || 4322 (ops->devo_reset == NULL)) 4323 return (DDI_WALK_CONTINUE); 4324 4325 if (DEVI_IS_ATTACHING(dip) || DEVI_IS_DETACHING(dip)) { 4326 static char path[MAXPATHLEN]; 4327 4328 /* 4329 * bad news, this device has blocked in it's attach or 4330 * detach routine, which means it not safe to call it's 4331 * devo_reset() entry point. 4332 */ 4333 cmn_err(CE_WARN, "unable to reset device: %s", 4334 ddi_pathname(dip, path)); 4335 return (DDI_WALK_CONTINUE); 4336 } 4337 4338 NDI_CONFIG_DEBUG((CE_NOTE, "resetting %s%d\n", 4339 ddi_driver_name(dip), ddi_get_instance(dip))); 4340 4341 (void) devi_reset(dip, DDI_RESET_FORCE); 4342 return (DDI_WALK_CONTINUE); 4343 } 4344 4345 void 4346 reset_leaves(void) 4347 { 4348 /* 4349 * if we're reached here, the device tree better not be changing. 4350 * so either devinfo_freeze better be set or we better be panicing. 4351 */ 4352 ASSERT(devinfo_freeze || panicstr); 4353 4354 (void) walk_devs(top_devinfo, reset_leaf_device, NULL, 0); 4355 } 4356 4357 4358 /* 4359 * devtree_freeze() must be called before quiesce_devices() and reset_leaves() 4360 * during a normal system shutdown. It attempts to ensure that there are no 4361 * outstanding attach or detach operations in progress when quiesce_devices() or 4362 * reset_leaves()is invoked. It must be called before the system becomes 4363 * single-threaded because device attach and detach are multi-threaded 4364 * operations. (note that during system shutdown the system doesn't actually 4365 * become single-thread since other threads still exist, but the shutdown thread 4366 * will disable preemption for itself, raise it's pil, and stop all the other 4367 * cpus in the system there by effectively making the system single-threaded.) 4368 */ 4369 void 4370 devtree_freeze(void) 4371 { 4372 int delayed = 0; 4373 4374 /* if we're panicing then the device tree isn't going to be changing */ 4375 if (panicstr) 4376 return; 4377 4378 /* stop all dev_info state changes in the device tree */ 4379 devinfo_freeze = gethrtime(); 4380 4381 /* 4382 * if we're not panicing and there are on-going attach or detach 4383 * operations, wait for up to 3 seconds for them to finish. This 4384 * is a randomly chosen interval but this should be ok because: 4385 * - 3 seconds is very small relative to the deadman timer. 4386 * - normal attach and detach operations should be very quick. 4387 * - attach and detach operations are fairly rare. 4388 */ 4389 while (!panicstr && atomic_add_long_nv(&devinfo_attach_detach, 0) && 4390 (delayed < 3)) { 4391 delayed += 1; 4392 4393 /* do a sleeping wait for one second */ 4394 ASSERT(!servicing_interrupt()); 4395 delay(drv_usectohz(MICROSEC)); 4396 } 4397 } 4398 4399 static int 4400 bind_dip(dev_info_t *dip, void *arg) 4401 { 4402 _NOTE(ARGUNUSED(arg)) 4403 char *path; 4404 major_t major, pmajor; 4405 4406 /* 4407 * If the node is currently bound to the wrong driver, try to unbind 4408 * so that we can rebind to the correct driver. 4409 */ 4410 if (i_ddi_node_state(dip) >= DS_BOUND) { 4411 major = ddi_compatible_driver_major(dip, NULL); 4412 if ((DEVI(dip)->devi_major == major) && 4413 (i_ddi_node_state(dip) >= DS_INITIALIZED)) { 4414 /* 4415 * Check for a path-oriented driver alias that 4416 * takes precedence over current driver binding. 4417 */ 4418 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 4419 (void) ddi_pathname(dip, path); 4420 pmajor = ddi_name_to_major(path); 4421 if (driver_active(pmajor)) 4422 major = pmajor; 4423 kmem_free(path, MAXPATHLEN); 4424 } 4425 4426 /* attempt unbind if current driver is incorrect */ 4427 if (driver_active(major) && 4428 (major != DEVI(dip)->devi_major)) 4429 (void) ndi_devi_unbind_driver(dip); 4430 } 4431 4432 /* If unbound, try to bind to a driver */ 4433 if (i_ddi_node_state(dip) < DS_BOUND) 4434 (void) ndi_devi_bind_driver(dip, 0); 4435 4436 return (DDI_WALK_CONTINUE); 4437 } 4438 4439 void 4440 i_ddi_bind_devs(void) 4441 { 4442 /* flush devfs so that ndi_devi_unbind_driver will work when possible */ 4443 (void) devfs_clean(top_devinfo, NULL, 0); 4444 4445 ddi_walk_devs(top_devinfo, bind_dip, (void *)NULL); 4446 } 4447 4448 /* callback data for unbind_children_by_alias() */ 4449 typedef struct unbind_data { 4450 major_t drv_major; 4451 char *drv_alias; 4452 int ndevs_bound; 4453 int unbind_errors; 4454 } unbind_data_t; 4455 4456 /* 4457 * A utility function provided for testing and support convenience 4458 * Called for each device during an upgrade_drv -d bound to the alias 4459 * that cannot be unbound due to device in use. 4460 */ 4461 static void 4462 unbind_alias_dev_in_use(dev_info_t *dip, char *alias) 4463 { 4464 if (moddebug & MODDEBUG_BINDING) { 4465 cmn_err(CE_CONT, "%s%d: state %d: bound to %s\n", 4466 ddi_driver_name(dip), ddi_get_instance(dip), 4467 i_ddi_node_state(dip), alias); 4468 } 4469 } 4470 4471 /* 4472 * walkdevs callback for unbind devices bound to specific driver 4473 * and alias. Invoked within the context of update_drv -d <alias>. 4474 */ 4475 static int 4476 unbind_children_by_alias(dev_info_t *dip, void *arg) 4477 { 4478 int circ; 4479 dev_info_t *cdip; 4480 dev_info_t *next; 4481 unbind_data_t *ub = (unbind_data_t *)(uintptr_t)arg; 4482 int rv; 4483 4484 /* 4485 * We are called from update_drv to try to unbind a specific 4486 * set of aliases for a driver. Unbind what persistent nodes 4487 * we can, and return the number of nodes which cannot be unbound. 4488 * If not all nodes can be unbound, update_drv leaves the 4489 * state of the driver binding files unchanged, except in 4490 * the case of -f. 4491 */ 4492 ndi_devi_enter(dip, &circ); 4493 for (cdip = ddi_get_child(dip); cdip; cdip = next) { 4494 next = ddi_get_next_sibling(cdip); 4495 if ((ddi_driver_major(cdip) != ub->drv_major) || 4496 (strcmp(DEVI(cdip)->devi_node_name, ub->drv_alias) != 0)) 4497 continue; 4498 if (i_ddi_node_state(cdip) >= DS_BOUND) { 4499 rv = ndi_devi_unbind_driver(cdip); 4500 if (rv != DDI_SUCCESS || 4501 (i_ddi_node_state(cdip) >= DS_BOUND)) { 4502 unbind_alias_dev_in_use(cdip, ub->drv_alias); 4503 ub->ndevs_bound++; 4504 continue; 4505 } 4506 if (ndi_dev_is_persistent_node(cdip) == 0) 4507 (void) ddi_remove_child(cdip, 0); 4508 } 4509 } 4510 ndi_devi_exit(dip, circ); 4511 4512 return (DDI_WALK_CONTINUE); 4513 } 4514 4515 /* 4516 * Unbind devices by driver & alias 4517 * Context: update_drv [-f] -d -i <alias> <driver> 4518 */ 4519 int 4520 i_ddi_unbind_devs_by_alias(major_t major, char *alias) 4521 { 4522 unbind_data_t *ub; 4523 int rv; 4524 4525 ub = kmem_zalloc(sizeof (*ub), KM_SLEEP); 4526 ub->drv_major = major; 4527 ub->drv_alias = alias; 4528 ub->ndevs_bound = 0; 4529 ub->unbind_errors = 0; 4530 4531 /* flush devfs so that ndi_devi_unbind_driver will work when possible */ 4532 (void) devfs_clean(top_devinfo, NULL, 0); 4533 ddi_walk_devs(top_devinfo, unbind_children_by_alias, 4534 (void *)(uintptr_t)ub); 4535 4536 /* return the number of devices remaining bound to the alias */ 4537 rv = ub->ndevs_bound + ub->unbind_errors; 4538 kmem_free(ub, sizeof (*ub)); 4539 return (rv); 4540 } 4541 4542 /* 4543 * walkdevs callback for unbind devices by driver 4544 */ 4545 static int 4546 unbind_children_by_driver(dev_info_t *dip, void *arg) 4547 { 4548 int circ; 4549 dev_info_t *cdip; 4550 dev_info_t *next; 4551 major_t major = (major_t)(uintptr_t)arg; 4552 int rv; 4553 4554 /* 4555 * We are called either from rem_drv or update_drv when reloading 4556 * a driver.conf file. In either case, we unbind persistent nodes 4557 * and destroy .conf nodes. In the case of rem_drv, this will be 4558 * the final state. In the case of update_drv, i_ddi_bind_devs() 4559 * may be invoked later to re-enumerate (new) driver.conf rebind 4560 * persistent nodes. 4561 */ 4562 ndi_devi_enter(dip, &circ); 4563 for (cdip = ddi_get_child(dip); cdip; cdip = next) { 4564 next = ddi_get_next_sibling(cdip); 4565 if (ddi_driver_major(cdip) != major) 4566 continue; 4567 if (i_ddi_node_state(cdip) >= DS_BOUND) { 4568 rv = ndi_devi_unbind_driver(cdip); 4569 if (rv == DDI_FAILURE || 4570 (i_ddi_node_state(cdip) >= DS_BOUND)) 4571 continue; 4572 if (ndi_dev_is_persistent_node(cdip) == 0) 4573 (void) ddi_remove_child(cdip, 0); 4574 } 4575 } 4576 ndi_devi_exit(dip, circ); 4577 4578 return (DDI_WALK_CONTINUE); 4579 } 4580 4581 /* 4582 * Unbind devices by driver 4583 * Context: rem_drv or unload driver.conf 4584 */ 4585 void 4586 i_ddi_unbind_devs(major_t major) 4587 { 4588 /* flush devfs so that ndi_devi_unbind_driver will work when possible */ 4589 (void) devfs_clean(top_devinfo, NULL, 0); 4590 ddi_walk_devs(top_devinfo, unbind_children_by_driver, 4591 (void *)(uintptr_t)major); 4592 } 4593 4594 /* 4595 * I/O Hotplug control 4596 */ 4597 4598 /* 4599 * create and attach a dev_info node from a .conf file spec 4600 */ 4601 static void 4602 init_spec_child(dev_info_t *pdip, struct hwc_spec *specp, uint_t flags) 4603 { 4604 _NOTE(ARGUNUSED(flags)) 4605 dev_info_t *dip; 4606 char *node_name; 4607 4608 if (((node_name = specp->hwc_devi_name) == NULL) || 4609 (ddi_name_to_major(node_name) == DDI_MAJOR_T_NONE)) { 4610 char *tmp = node_name; 4611 if (tmp == NULL) 4612 tmp = "<none>"; 4613 cmn_err(CE_CONT, 4614 "init_spec_child: parent=%s, bad spec (%s)\n", 4615 ddi_node_name(pdip), tmp); 4616 return; 4617 } 4618 4619 dip = i_ddi_alloc_node(pdip, node_name, (pnode_t)DEVI_PSEUDO_NODEID, 4620 -1, specp->hwc_devi_sys_prop_ptr, KM_SLEEP); 4621 4622 if (dip == NULL) 4623 return; 4624 4625 if (ddi_initchild(pdip, dip) != DDI_SUCCESS) 4626 (void) ddi_remove_child(dip, 0); 4627 } 4628 4629 /* 4630 * Lookup hwc specs from hash tables and make children from the spec 4631 * Because some .conf children are "merge" nodes, we also initialize 4632 * .conf children to merge properties onto hardware nodes. 4633 * 4634 * The pdip must be held busy. 4635 */ 4636 int 4637 i_ndi_make_spec_children(dev_info_t *pdip, uint_t flags) 4638 { 4639 extern struct hwc_spec *hwc_get_child_spec(dev_info_t *, major_t); 4640 int circ; 4641 struct hwc_spec *list, *spec; 4642 4643 ndi_devi_enter(pdip, &circ); 4644 if (DEVI(pdip)->devi_flags & DEVI_MADE_CHILDREN) { 4645 ndi_devi_exit(pdip, circ); 4646 return (DDI_SUCCESS); 4647 } 4648 4649 list = hwc_get_child_spec(pdip, DDI_MAJOR_T_NONE); 4650 for (spec = list; spec != NULL; spec = spec->hwc_next) { 4651 init_spec_child(pdip, spec, flags); 4652 } 4653 hwc_free_spec_list(list); 4654 4655 mutex_enter(&DEVI(pdip)->devi_lock); 4656 DEVI(pdip)->devi_flags |= DEVI_MADE_CHILDREN; 4657 mutex_exit(&DEVI(pdip)->devi_lock); 4658 ndi_devi_exit(pdip, circ); 4659 return (DDI_SUCCESS); 4660 } 4661 4662 /* 4663 * Run initchild on all child nodes such that instance assignment 4664 * for multiport network cards are contiguous. 4665 * 4666 * The pdip must be held busy. 4667 */ 4668 static void 4669 i_ndi_init_hw_children(dev_info_t *pdip, uint_t flags) 4670 { 4671 dev_info_t *dip; 4672 4673 ASSERT(DEVI(pdip)->devi_flags & DEVI_MADE_CHILDREN); 4674 4675 /* contiguous instance assignment */ 4676 e_ddi_enter_instance(); 4677 dip = ddi_get_child(pdip); 4678 while (dip) { 4679 if (ndi_dev_is_persistent_node(dip)) 4680 (void) i_ndi_config_node(dip, DS_INITIALIZED, flags); 4681 dip = ddi_get_next_sibling(dip); 4682 } 4683 e_ddi_exit_instance(); 4684 } 4685 4686 /* 4687 * report device status 4688 */ 4689 static void 4690 i_ndi_devi_report_status_change(dev_info_t *dip, char *path) 4691 { 4692 char *status; 4693 4694 if (!DEVI_NEED_REPORT(dip) || 4695 (i_ddi_node_state(dip) < DS_INITIALIZED) || 4696 ndi_dev_is_hidden_node(dip)) { 4697 return; 4698 } 4699 4700 /* Invalidate the devinfo snapshot cache */ 4701 i_ddi_di_cache_invalidate(); 4702 4703 if (DEVI_IS_DEVICE_REMOVED(dip)) { 4704 status = "removed"; 4705 } else if (DEVI_IS_DEVICE_OFFLINE(dip)) { 4706 status = "offline"; 4707 } else if (DEVI_IS_DEVICE_DOWN(dip)) { 4708 status = "down"; 4709 } else if (DEVI_IS_BUS_QUIESCED(dip)) { 4710 status = "quiesced"; 4711 } else if (DEVI_IS_BUS_DOWN(dip)) { 4712 status = "down"; 4713 } else if (i_ddi_devi_attached(dip)) { 4714 status = "online"; 4715 } else { 4716 status = "unknown"; 4717 } 4718 4719 if (path == NULL) { 4720 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 4721 cmn_err(CE_CONT, "?%s (%s%d) %s\n", 4722 ddi_pathname(dip, path), ddi_driver_name(dip), 4723 ddi_get_instance(dip), status); 4724 kmem_free(path, MAXPATHLEN); 4725 } else { 4726 cmn_err(CE_CONT, "?%s (%s%d) %s\n", 4727 path, ddi_driver_name(dip), 4728 ddi_get_instance(dip), status); 4729 } 4730 4731 mutex_enter(&(DEVI(dip)->devi_lock)); 4732 DEVI_REPORT_DONE(dip); 4733 mutex_exit(&(DEVI(dip)->devi_lock)); 4734 } 4735 4736 /* 4737 * log a notification that a dev_info node has been configured. 4738 */ 4739 static int 4740 i_log_devfs_add_devinfo(dev_info_t *dip, uint_t flags) 4741 { 4742 int se_err; 4743 char *pathname; 4744 sysevent_t *ev; 4745 sysevent_id_t eid; 4746 sysevent_value_t se_val; 4747 sysevent_attr_list_t *ev_attr_list = NULL; 4748 char *class_name; 4749 int no_transport = 0; 4750 4751 ASSERT(dip && ddi_get_parent(dip) && 4752 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 4753 4754 /* do not generate ESC_DEVFS_DEVI_ADD event during boot */ 4755 if (!i_ddi_io_initialized()) 4756 return (DDI_SUCCESS); 4757 4758 /* Invalidate the devinfo snapshot cache */ 4759 i_ddi_di_cache_invalidate(); 4760 4761 ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_DEVI_ADD, EP_DDI, SE_SLEEP); 4762 4763 pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP); 4764 4765 (void) ddi_pathname(dip, pathname); 4766 ASSERT(strlen(pathname)); 4767 4768 se_val.value_type = SE_DATA_TYPE_STRING; 4769 se_val.value.sv_string = pathname; 4770 if (sysevent_add_attr(&ev_attr_list, DEVFS_PATHNAME, 4771 &se_val, SE_SLEEP) != 0) { 4772 goto fail; 4773 } 4774 4775 /* add the device class attribute */ 4776 if ((class_name = i_ddi_devi_class(dip)) != NULL) { 4777 se_val.value_type = SE_DATA_TYPE_STRING; 4778 se_val.value.sv_string = class_name; 4779 4780 if (sysevent_add_attr(&ev_attr_list, 4781 DEVFS_DEVI_CLASS, &se_val, SE_SLEEP) != 0) { 4782 sysevent_free_attr(ev_attr_list); 4783 goto fail; 4784 } 4785 } 4786 4787 /* 4788 * must log a branch event too unless NDI_BRANCH_EVENT_OP is set, 4789 * in which case the branch event will be logged by the caller 4790 * after the entire branch has been configured. 4791 */ 4792 if ((flags & NDI_BRANCH_EVENT_OP) == 0) { 4793 /* 4794 * Instead of logging a separate branch event just add 4795 * DEVFS_BRANCH_EVENT attribute. It indicates devfsadmd to 4796 * generate a EC_DEV_BRANCH event. 4797 */ 4798 se_val.value_type = SE_DATA_TYPE_INT32; 4799 se_val.value.sv_int32 = 1; 4800 if (sysevent_add_attr(&ev_attr_list, 4801 DEVFS_BRANCH_EVENT, &se_val, SE_SLEEP) != 0) { 4802 sysevent_free_attr(ev_attr_list); 4803 goto fail; 4804 } 4805 } 4806 4807 if (sysevent_attach_attributes(ev, ev_attr_list) != 0) { 4808 sysevent_free_attr(ev_attr_list); 4809 goto fail; 4810 } 4811 4812 if ((se_err = log_sysevent(ev, SE_SLEEP, &eid)) != 0) { 4813 if (se_err == SE_NO_TRANSPORT) 4814 no_transport = 1; 4815 goto fail; 4816 } 4817 4818 sysevent_free(ev); 4819 kmem_free(pathname, MAXPATHLEN); 4820 4821 return (DDI_SUCCESS); 4822 4823 fail: 4824 cmn_err(CE_WARN, "failed to log ESC_DEVFS_DEVI_ADD event for %s%s", 4825 pathname, (no_transport) ? " (syseventd not responding)" : ""); 4826 4827 cmn_err(CE_WARN, "/dev may not be current for driver %s. " 4828 "Run devfsadm -i %s", 4829 ddi_driver_name(dip), ddi_driver_name(dip)); 4830 4831 sysevent_free(ev); 4832 kmem_free(pathname, MAXPATHLEN); 4833 return (DDI_SUCCESS); 4834 } 4835 4836 /* 4837 * log a notification that a dev_info node has been unconfigured. 4838 */ 4839 static int 4840 i_log_devfs_remove_devinfo(char *pathname, char *class_name, char *driver_name, 4841 int instance, uint_t flags) 4842 { 4843 sysevent_t *ev; 4844 sysevent_id_t eid; 4845 sysevent_value_t se_val; 4846 sysevent_attr_list_t *ev_attr_list = NULL; 4847 int se_err; 4848 int no_transport = 0; 4849 4850 if (!i_ddi_io_initialized()) 4851 return (DDI_SUCCESS); 4852 4853 /* Invalidate the devinfo snapshot cache */ 4854 i_ddi_di_cache_invalidate(); 4855 4856 ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_DEVI_REMOVE, EP_DDI, SE_SLEEP); 4857 4858 se_val.value_type = SE_DATA_TYPE_STRING; 4859 se_val.value.sv_string = pathname; 4860 if (sysevent_add_attr(&ev_attr_list, DEVFS_PATHNAME, 4861 &se_val, SE_SLEEP) != 0) { 4862 goto fail; 4863 } 4864 4865 if (class_name) { 4866 /* add the device class, driver name and instance attributes */ 4867 4868 se_val.value_type = SE_DATA_TYPE_STRING; 4869 se_val.value.sv_string = class_name; 4870 if (sysevent_add_attr(&ev_attr_list, 4871 DEVFS_DEVI_CLASS, &se_val, SE_SLEEP) != 0) { 4872 sysevent_free_attr(ev_attr_list); 4873 goto fail; 4874 } 4875 4876 se_val.value_type = SE_DATA_TYPE_STRING; 4877 se_val.value.sv_string = driver_name; 4878 if (sysevent_add_attr(&ev_attr_list, 4879 DEVFS_DRIVER_NAME, &se_val, SE_SLEEP) != 0) { 4880 sysevent_free_attr(ev_attr_list); 4881 goto fail; 4882 } 4883 4884 se_val.value_type = SE_DATA_TYPE_INT32; 4885 se_val.value.sv_int32 = instance; 4886 if (sysevent_add_attr(&ev_attr_list, 4887 DEVFS_INSTANCE, &se_val, SE_SLEEP) != 0) { 4888 sysevent_free_attr(ev_attr_list); 4889 goto fail; 4890 } 4891 } 4892 4893 /* 4894 * must log a branch event too unless NDI_BRANCH_EVENT_OP is set, 4895 * in which case the branch event will be logged by the caller 4896 * after the entire branch has been unconfigured. 4897 */ 4898 if ((flags & NDI_BRANCH_EVENT_OP) == 0) { 4899 /* 4900 * Instead of logging a separate branch event just add 4901 * DEVFS_BRANCH_EVENT attribute. It indicates devfsadmd to 4902 * generate a EC_DEV_BRANCH event. 4903 */ 4904 se_val.value_type = SE_DATA_TYPE_INT32; 4905 se_val.value.sv_int32 = 1; 4906 if (sysevent_add_attr(&ev_attr_list, 4907 DEVFS_BRANCH_EVENT, &se_val, SE_SLEEP) != 0) { 4908 sysevent_free_attr(ev_attr_list); 4909 goto fail; 4910 } 4911 } 4912 4913 if (sysevent_attach_attributes(ev, ev_attr_list) != 0) { 4914 sysevent_free_attr(ev_attr_list); 4915 goto fail; 4916 } 4917 4918 if ((se_err = log_sysevent(ev, SE_SLEEP, &eid)) != 0) { 4919 if (se_err == SE_NO_TRANSPORT) 4920 no_transport = 1; 4921 goto fail; 4922 } 4923 4924 sysevent_free(ev); 4925 return (DDI_SUCCESS); 4926 4927 fail: 4928 sysevent_free(ev); 4929 cmn_err(CE_WARN, "failed to log ESC_DEVFS_DEVI_REMOVE event for %s%s", 4930 pathname, (no_transport) ? " (syseventd not responding)" : ""); 4931 return (DDI_SUCCESS); 4932 } 4933 4934 static void 4935 i_ddi_log_devfs_device_remove(dev_info_t *dip) 4936 { 4937 char *path; 4938 4939 ASSERT(dip && ddi_get_parent(dip) && 4940 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 4941 ASSERT(DEVI_IS_DEVICE_REMOVED(dip)); 4942 4943 ASSERT(i_ddi_node_state(dip) >= DS_INITIALIZED); 4944 if (i_ddi_node_state(dip) < DS_INITIALIZED) 4945 return; 4946 4947 /* Inform LDI_EV_DEVICE_REMOVE callbacks. */ 4948 ldi_invoke_finalize(dip, DDI_DEV_T_ANY, 0, LDI_EV_DEVICE_REMOVE, 4949 LDI_EV_SUCCESS, NULL); 4950 4951 /* Generate EC_DEVFS_DEVI_REMOVE sysevent. */ 4952 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 4953 (void) i_log_devfs_remove_devinfo(ddi_pathname(dip, path), 4954 i_ddi_devi_class(dip), (char *)ddi_driver_name(dip), 4955 ddi_get_instance(dip), 0); 4956 kmem_free(path, MAXPATHLEN); 4957 } 4958 4959 static void 4960 i_ddi_log_devfs_device_insert(dev_info_t *dip) 4961 { 4962 ASSERT(dip && ddi_get_parent(dip) && 4963 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 4964 ASSERT(!DEVI_IS_DEVICE_REMOVED(dip)); 4965 4966 (void) i_log_devfs_add_devinfo(dip, 0); 4967 } 4968 4969 4970 /* 4971 * log an event that a dev_info branch has been configured or unconfigured. 4972 */ 4973 static int 4974 i_log_devfs_branch(char *node_path, char *subclass) 4975 { 4976 int se_err; 4977 sysevent_t *ev; 4978 sysevent_id_t eid; 4979 sysevent_value_t se_val; 4980 sysevent_attr_list_t *ev_attr_list = NULL; 4981 int no_transport = 0; 4982 4983 /* do not generate the event during boot */ 4984 if (!i_ddi_io_initialized()) 4985 return (DDI_SUCCESS); 4986 4987 /* Invalidate the devinfo snapshot cache */ 4988 i_ddi_di_cache_invalidate(); 4989 4990 ev = sysevent_alloc(EC_DEVFS, subclass, EP_DDI, SE_SLEEP); 4991 4992 se_val.value_type = SE_DATA_TYPE_STRING; 4993 se_val.value.sv_string = node_path; 4994 4995 if (sysevent_add_attr(&ev_attr_list, DEVFS_PATHNAME, 4996 &se_val, SE_SLEEP) != 0) { 4997 goto fail; 4998 } 4999 5000 if (sysevent_attach_attributes(ev, ev_attr_list) != 0) { 5001 sysevent_free_attr(ev_attr_list); 5002 goto fail; 5003 } 5004 5005 if ((se_err = log_sysevent(ev, SE_SLEEP, &eid)) != 0) { 5006 if (se_err == SE_NO_TRANSPORT) 5007 no_transport = 1; 5008 goto fail; 5009 } 5010 5011 sysevent_free(ev); 5012 return (DDI_SUCCESS); 5013 5014 fail: 5015 cmn_err(CE_WARN, "failed to log %s branch event for %s%s", 5016 subclass, node_path, 5017 (no_transport) ? " (syseventd not responding)" : ""); 5018 5019 sysevent_free(ev); 5020 return (DDI_FAILURE); 5021 } 5022 5023 /* 5024 * log an event that a dev_info tree branch has been configured. 5025 */ 5026 static int 5027 i_log_devfs_branch_add(dev_info_t *dip) 5028 { 5029 char *node_path; 5030 int rv; 5031 5032 node_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 5033 (void) ddi_pathname(dip, node_path); 5034 rv = i_log_devfs_branch(node_path, ESC_DEVFS_BRANCH_ADD); 5035 kmem_free(node_path, MAXPATHLEN); 5036 5037 return (rv); 5038 } 5039 5040 /* 5041 * log an event that a dev_info tree branch has been unconfigured. 5042 */ 5043 static int 5044 i_log_devfs_branch_remove(char *node_path) 5045 { 5046 return (i_log_devfs_branch(node_path, ESC_DEVFS_BRANCH_REMOVE)); 5047 } 5048 5049 /* 5050 * enqueue the dip's deviname on the branch event queue. 5051 */ 5052 static struct brevq_node * 5053 brevq_enqueue(struct brevq_node **brevqp, dev_info_t *dip, 5054 struct brevq_node *child) 5055 { 5056 struct brevq_node *brn; 5057 char *deviname; 5058 5059 deviname = kmem_alloc(MAXNAMELEN, KM_SLEEP); 5060 (void) ddi_deviname(dip, deviname); 5061 5062 brn = kmem_zalloc(sizeof (*brn), KM_SLEEP); 5063 brn->brn_deviname = i_ddi_strdup(deviname, KM_SLEEP); 5064 kmem_free(deviname, MAXNAMELEN); 5065 brn->brn_child = child; 5066 brn->brn_sibling = *brevqp; 5067 *brevqp = brn; 5068 5069 return (brn); 5070 } 5071 5072 /* 5073 * free the memory allocated for the elements on the branch event queue. 5074 */ 5075 static void 5076 free_brevq(struct brevq_node *brevq) 5077 { 5078 struct brevq_node *brn, *next_brn; 5079 5080 for (brn = brevq; brn != NULL; brn = next_brn) { 5081 next_brn = brn->brn_sibling; 5082 ASSERT(brn->brn_child == NULL); 5083 kmem_free(brn->brn_deviname, strlen(brn->brn_deviname) + 1); 5084 kmem_free(brn, sizeof (*brn)); 5085 } 5086 } 5087 5088 /* 5089 * log the events queued up on the branch event queue and free the 5090 * associated memory. 5091 * 5092 * node_path must have been allocated with at least MAXPATHLEN bytes. 5093 */ 5094 static void 5095 log_and_free_brevq(char *node_path, struct brevq_node *brevq) 5096 { 5097 struct brevq_node *brn; 5098 char *p; 5099 5100 p = node_path + strlen(node_path); 5101 for (brn = brevq; brn != NULL; brn = brn->brn_sibling) { 5102 (void) strcpy(p, brn->brn_deviname); 5103 (void) i_log_devfs_branch_remove(node_path); 5104 } 5105 *p = '\0'; 5106 5107 free_brevq(brevq); 5108 } 5109 5110 /* 5111 * log the events queued up on the branch event queue and free the 5112 * associated memory. Same as the previous function but operates on dip. 5113 */ 5114 static void 5115 log_and_free_brevq_dip(dev_info_t *dip, struct brevq_node *brevq) 5116 { 5117 char *path; 5118 5119 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 5120 (void) ddi_pathname(dip, path); 5121 log_and_free_brevq(path, brevq); 5122 kmem_free(path, MAXPATHLEN); 5123 } 5124 5125 /* 5126 * log the outstanding branch remove events for the grand children of the dip 5127 * and free the associated memory. 5128 */ 5129 static void 5130 log_and_free_br_events_on_grand_children(dev_info_t *dip, 5131 struct brevq_node *brevq) 5132 { 5133 struct brevq_node *brn; 5134 char *path; 5135 char *p; 5136 5137 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 5138 (void) ddi_pathname(dip, path); 5139 p = path + strlen(path); 5140 for (brn = brevq; brn != NULL; brn = brn->brn_sibling) { 5141 if (brn->brn_child) { 5142 (void) strcpy(p, brn->brn_deviname); 5143 /* now path contains the node path to the dip's child */ 5144 log_and_free_brevq(path, brn->brn_child); 5145 brn->brn_child = NULL; 5146 } 5147 } 5148 kmem_free(path, MAXPATHLEN); 5149 } 5150 5151 /* 5152 * log and cleanup branch remove events for the grand children of the dip. 5153 */ 5154 static void 5155 cleanup_br_events_on_grand_children(dev_info_t *dip, struct brevq_node **brevqp) 5156 { 5157 dev_info_t *child; 5158 struct brevq_node *brevq, *brn, *prev_brn, *next_brn; 5159 char *path; 5160 int circ; 5161 5162 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 5163 prev_brn = NULL; 5164 brevq = *brevqp; 5165 5166 ndi_devi_enter(dip, &circ); 5167 for (brn = brevq; brn != NULL; brn = next_brn) { 5168 next_brn = brn->brn_sibling; 5169 for (child = ddi_get_child(dip); child != NULL; 5170 child = ddi_get_next_sibling(child)) { 5171 if (i_ddi_node_state(child) >= DS_INITIALIZED) { 5172 (void) ddi_deviname(child, path); 5173 if (strcmp(path, brn->brn_deviname) == 0) 5174 break; 5175 } 5176 } 5177 5178 if (child != NULL && !(DEVI_EVREMOVE(child))) { 5179 /* 5180 * Event state is not REMOVE. So branch remove event 5181 * is not going be generated on brn->brn_child. 5182 * If any branch remove events were queued up on 5183 * brn->brn_child log them and remove the brn 5184 * from the queue. 5185 */ 5186 if (brn->brn_child) { 5187 (void) ddi_pathname(dip, path); 5188 (void) strcat(path, brn->brn_deviname); 5189 log_and_free_brevq(path, brn->brn_child); 5190 } 5191 5192 if (prev_brn) 5193 prev_brn->brn_sibling = next_brn; 5194 else 5195 *brevqp = next_brn; 5196 5197 kmem_free(brn->brn_deviname, 5198 strlen(brn->brn_deviname) + 1); 5199 kmem_free(brn, sizeof (*brn)); 5200 } else { 5201 /* 5202 * Free up the outstanding branch remove events 5203 * queued on brn->brn_child since brn->brn_child 5204 * itself is eligible for branch remove event. 5205 */ 5206 if (brn->brn_child) { 5207 free_brevq(brn->brn_child); 5208 brn->brn_child = NULL; 5209 } 5210 prev_brn = brn; 5211 } 5212 } 5213 5214 ndi_devi_exit(dip, circ); 5215 kmem_free(path, MAXPATHLEN); 5216 } 5217 5218 static int 5219 need_remove_event(dev_info_t *dip, int flags) 5220 { 5221 if ((flags & (NDI_NO_EVENT | NDI_AUTODETACH)) == 0 && 5222 (flags & (NDI_DEVI_OFFLINE | NDI_UNCONFIG | NDI_DEVI_REMOVE)) && 5223 !(DEVI_EVREMOVE(dip))) 5224 return (1); 5225 else 5226 return (0); 5227 } 5228 5229 /* 5230 * Unconfigure children/descendants of the dip. 5231 * 5232 * If the operation involves a branch event NDI_BRANCH_EVENT_OP is set 5233 * through out the unconfiguration. On successful return *brevqp is set to 5234 * a queue of dip's child devinames for which branch remove events need 5235 * to be generated. 5236 */ 5237 static int 5238 devi_unconfig_branch(dev_info_t *dip, dev_info_t **dipp, int flags, 5239 struct brevq_node **brevqp) 5240 { 5241 int rval; 5242 5243 *brevqp = NULL; 5244 5245 if ((!(flags & NDI_BRANCH_EVENT_OP)) && need_remove_event(dip, flags)) 5246 flags |= NDI_BRANCH_EVENT_OP; 5247 5248 if (flags & NDI_BRANCH_EVENT_OP) { 5249 rval = devi_unconfig_common(dip, dipp, flags, DDI_MAJOR_T_NONE, 5250 brevqp); 5251 5252 if (rval != NDI_SUCCESS && (*brevqp)) { 5253 log_and_free_brevq_dip(dip, *brevqp); 5254 *brevqp = NULL; 5255 } 5256 } else 5257 rval = devi_unconfig_common(dip, dipp, flags, DDI_MAJOR_T_NONE, 5258 NULL); 5259 5260 return (rval); 5261 } 5262 5263 /* 5264 * If the dip is already bound to a driver transition to DS_INITIALIZED 5265 * in order to generate an event in the case where the node was left in 5266 * DS_BOUND state since boot (never got attached) and the node is now 5267 * being offlined. 5268 */ 5269 static void 5270 init_bound_node_ev(dev_info_t *pdip, dev_info_t *dip, int flags) 5271 { 5272 if (need_remove_event(dip, flags) && 5273 i_ddi_node_state(dip) == DS_BOUND && 5274 i_ddi_devi_attached(pdip) && !DEVI_IS_DEVICE_OFFLINE(dip)) 5275 (void) ddi_initchild(pdip, dip); 5276 } 5277 5278 /* 5279 * attach a node/branch with parent already held busy 5280 */ 5281 static int 5282 devi_attach_node(dev_info_t *dip, uint_t flags) 5283 { 5284 dev_info_t *pdip = ddi_get_parent(dip); 5285 5286 ASSERT(pdip && DEVI_BUSY_OWNED(pdip)); 5287 5288 mutex_enter(&(DEVI(dip)->devi_lock)); 5289 if (flags & NDI_DEVI_ONLINE) { 5290 if (!i_ddi_devi_attached(dip)) 5291 DEVI_SET_REPORT(dip); 5292 DEVI_SET_DEVICE_ONLINE(dip); 5293 } 5294 if (DEVI_IS_DEVICE_OFFLINE(dip)) { 5295 mutex_exit(&(DEVI(dip)->devi_lock)); 5296 return (NDI_FAILURE); 5297 } 5298 mutex_exit(&(DEVI(dip)->devi_lock)); 5299 5300 if (i_ddi_attachchild(dip) != DDI_SUCCESS) { 5301 mutex_enter(&(DEVI(dip)->devi_lock)); 5302 DEVI_SET_EVUNINIT(dip); 5303 mutex_exit(&(DEVI(dip)->devi_lock)); 5304 5305 if (ndi_dev_is_persistent_node(dip)) 5306 (void) ddi_uninitchild(dip); 5307 else { 5308 /* 5309 * Delete .conf nodes and nodes that are not 5310 * well formed. 5311 */ 5312 (void) ddi_remove_child(dip, 0); 5313 } 5314 return (NDI_FAILURE); 5315 } 5316 5317 i_ndi_devi_report_status_change(dip, NULL); 5318 5319 /* 5320 * log an event, but not during devfs lookups in which case 5321 * NDI_NO_EVENT is set. 5322 */ 5323 if ((flags & NDI_NO_EVENT) == 0 && !(DEVI_EVADD(dip))) { 5324 (void) i_log_devfs_add_devinfo(dip, flags); 5325 5326 mutex_enter(&(DEVI(dip)->devi_lock)); 5327 DEVI_SET_EVADD(dip); 5328 mutex_exit(&(DEVI(dip)->devi_lock)); 5329 } else if (!(flags & NDI_NO_EVENT_STATE_CHNG)) { 5330 mutex_enter(&(DEVI(dip)->devi_lock)); 5331 DEVI_SET_EVADD(dip); 5332 mutex_exit(&(DEVI(dip)->devi_lock)); 5333 } 5334 5335 return (NDI_SUCCESS); 5336 } 5337 5338 /* internal function to config immediate children */ 5339 static int 5340 config_immediate_children(dev_info_t *pdip, uint_t flags, major_t major) 5341 { 5342 dev_info_t *child, *next; 5343 int circ; 5344 5345 ASSERT(i_ddi_devi_attached(pdip)); 5346 5347 if (!NEXUS_DRV(ddi_get_driver(pdip))) 5348 return (NDI_SUCCESS); 5349 5350 NDI_CONFIG_DEBUG((CE_CONT, 5351 "config_immediate_children: %s%d (%p), flags=%x\n", 5352 ddi_driver_name(pdip), ddi_get_instance(pdip), 5353 (void *)pdip, flags)); 5354 5355 ndi_devi_enter(pdip, &circ); 5356 5357 if (flags & NDI_CONFIG_REPROBE) { 5358 mutex_enter(&DEVI(pdip)->devi_lock); 5359 DEVI(pdip)->devi_flags &= ~DEVI_MADE_CHILDREN; 5360 mutex_exit(&DEVI(pdip)->devi_lock); 5361 } 5362 (void) i_ndi_make_spec_children(pdip, flags); 5363 i_ndi_init_hw_children(pdip, flags); 5364 5365 child = ddi_get_child(pdip); 5366 while (child) { 5367 /* NOTE: devi_attach_node() may remove the dip */ 5368 next = ddi_get_next_sibling(child); 5369 5370 /* 5371 * Configure all nexus nodes or leaf nodes with 5372 * matching driver major 5373 */ 5374 if ((major == DDI_MAJOR_T_NONE) || 5375 (major == ddi_driver_major(child)) || 5376 ((flags & NDI_CONFIG) && (is_leaf_node(child) == 0))) 5377 (void) devi_attach_node(child, flags); 5378 child = next; 5379 } 5380 5381 ndi_devi_exit(pdip, circ); 5382 5383 return (NDI_SUCCESS); 5384 } 5385 5386 /* internal function to config grand children */ 5387 static int 5388 config_grand_children(dev_info_t *pdip, uint_t flags, major_t major) 5389 { 5390 struct mt_config_handle *hdl; 5391 5392 /* multi-threaded configuration of child nexus */ 5393 hdl = mt_config_init(pdip, NULL, flags, major, MT_CONFIG_OP, NULL); 5394 mt_config_children(hdl); 5395 5396 return (mt_config_fini(hdl)); /* wait for threads to exit */ 5397 } 5398 5399 /* 5400 * Common function for device tree configuration, 5401 * either BUS_CONFIG_ALL or BUS_CONFIG_DRIVER. 5402 * The NDI_CONFIG flag causes recursive configuration of 5403 * grandchildren, devfs usage should not recurse. 5404 */ 5405 static int 5406 devi_config_common(dev_info_t *dip, int flags, major_t major) 5407 { 5408 int error; 5409 int (*f)(); 5410 5411 if (!i_ddi_devi_attached(dip)) 5412 return (NDI_FAILURE); 5413 5414 if (pm_pre_config(dip, NULL) != DDI_SUCCESS) 5415 return (NDI_FAILURE); 5416 5417 if ((DEVI(dip)->devi_ops->devo_bus_ops == NULL) || 5418 (DEVI(dip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) || 5419 (f = DEVI(dip)->devi_ops->devo_bus_ops->bus_config) == NULL) { 5420 error = config_immediate_children(dip, flags, major); 5421 } else { 5422 /* call bus_config entry point */ 5423 ddi_bus_config_op_t bus_op = (major == DDI_MAJOR_T_NONE) ? 5424 BUS_CONFIG_ALL : BUS_CONFIG_DRIVER; 5425 error = (*f)(dip, 5426 flags, bus_op, (void *)(uintptr_t)major, NULL, 0); 5427 } 5428 5429 if (error) { 5430 pm_post_config(dip, NULL); 5431 return (error); 5432 } 5433 5434 /* 5435 * Some callers, notably SCSI, need to mark the devfs cache 5436 * to be rebuilt together with the config operation. 5437 */ 5438 if (flags & NDI_DEVFS_CLEAN) 5439 (void) devfs_clean(dip, NULL, 0); 5440 5441 if (flags & NDI_CONFIG) 5442 (void) config_grand_children(dip, flags, major); 5443 5444 pm_post_config(dip, NULL); 5445 5446 return (NDI_SUCCESS); 5447 } 5448 5449 /* 5450 * Framework entry point for BUS_CONFIG_ALL 5451 */ 5452 int 5453 ndi_devi_config(dev_info_t *dip, int flags) 5454 { 5455 NDI_CONFIG_DEBUG((CE_CONT, 5456 "ndi_devi_config: par = %s%d (%p), flags = 0x%x\n", 5457 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags)); 5458 5459 return (devi_config_common(dip, flags, DDI_MAJOR_T_NONE)); 5460 } 5461 5462 /* 5463 * Framework entry point for BUS_CONFIG_DRIVER, bound to major 5464 */ 5465 int 5466 ndi_devi_config_driver(dev_info_t *dip, int flags, major_t major) 5467 { 5468 /* don't abuse this function */ 5469 ASSERT(major != DDI_MAJOR_T_NONE); 5470 5471 NDI_CONFIG_DEBUG((CE_CONT, 5472 "ndi_devi_config_driver: par = %s%d (%p), flags = 0x%x\n", 5473 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags)); 5474 5475 return (devi_config_common(dip, flags, major)); 5476 } 5477 5478 /* 5479 * Called by nexus drivers to configure its children. 5480 */ 5481 static int 5482 devi_config_one(dev_info_t *pdip, char *devnm, dev_info_t **cdipp, 5483 uint_t flags, clock_t timeout) 5484 { 5485 dev_info_t *vdip = NULL; 5486 char *drivername = NULL; 5487 int find_by_addr = 0; 5488 char *name, *addr; 5489 int v_circ, p_circ; 5490 clock_t end_time; /* 60 sec */ 5491 int probed; 5492 dev_info_t *cdip; 5493 mdi_pathinfo_t *cpip; 5494 5495 *cdipp = NULL; 5496 5497 if (!NEXUS_DRV(ddi_get_driver(pdip))) 5498 return (NDI_FAILURE); 5499 5500 /* split name into "name@addr" parts */ 5501 i_ddi_parse_name(devnm, &name, &addr, NULL); 5502 5503 /* 5504 * If the nexus is a pHCI and we are not processing a pHCI from 5505 * mdi bus_config code then we need to know the vHCI. 5506 */ 5507 if (MDI_PHCI(pdip)) 5508 vdip = mdi_devi_get_vdip(pdip); 5509 5510 /* 5511 * We may have a genericname on a system that creates drivername 5512 * nodes (from .conf files). Find the drivername by nodeid. If we 5513 * can't find a node with devnm as the node name then we search by 5514 * drivername. This allows an implementation to supply a genericly 5515 * named boot path (disk) and locate drivename nodes (sd). The 5516 * NDI_PROMNAME flag does not apply to /devices/pseudo paths. 5517 */ 5518 if ((flags & NDI_PROMNAME) && (pdip != pseudo_dip)) { 5519 drivername = child_path_to_driver(pdip, name, addr); 5520 find_by_addr = 1; 5521 } 5522 5523 /* 5524 * Determine end_time: This routine should *not* be called with a 5525 * constant non-zero timeout argument, the caller should be adjusting 5526 * the timeout argument relative to when it *started* its asynchronous 5527 * enumeration. 5528 */ 5529 if (timeout > 0) 5530 end_time = ddi_get_lbolt() + timeout; 5531 5532 for (;;) { 5533 /* 5534 * For pHCI, enter (vHCI, pHCI) and search for pathinfo/client 5535 * child - break out of for(;;) loop if child found. 5536 * NOTE: Lock order for ndi_devi_enter is (vHCI, pHCI). 5537 */ 5538 if (vdip) { 5539 /* use mdi_devi_enter ordering */ 5540 ndi_devi_enter(vdip, &v_circ); 5541 ndi_devi_enter(pdip, &p_circ); 5542 cpip = mdi_pi_find(pdip, NULL, addr); 5543 cdip = mdi_pi_get_client(cpip); 5544 if (cdip) 5545 break; 5546 } else 5547 ndi_devi_enter(pdip, &p_circ); 5548 5549 /* 5550 * When not a vHCI or not all pHCI devices are required to 5551 * enumerated under the vHCI (NDI_MDI_FALLBACK) search for 5552 * devinfo child. 5553 */ 5554 if ((vdip == NULL) || (flags & NDI_MDI_FALLBACK)) { 5555 /* determine if .conf nodes already built */ 5556 probed = (DEVI(pdip)->devi_flags & DEVI_MADE_CHILDREN); 5557 5558 /* 5559 * Search for child by name, if not found then search 5560 * for a node bound to the drivername driver with the 5561 * specified "@addr". Break out of for(;;) loop if 5562 * child found. To support path-oriented aliases 5563 * binding on boot-device, we do a search_by_addr too. 5564 */ 5565 again: (void) i_ndi_make_spec_children(pdip, flags); 5566 cdip = find_child_by_name(pdip, name, addr); 5567 if ((cdip == NULL) && drivername) 5568 cdip = find_child_by_driver(pdip, 5569 drivername, addr); 5570 if ((cdip == NULL) && find_by_addr) 5571 cdip = find_child_by_addr(pdip, addr); 5572 if (cdip) 5573 break; 5574 5575 /* 5576 * determine if we should reenumerate .conf nodes 5577 * and look for child again. 5578 */ 5579 if (probed && 5580 i_ddi_io_initialized() && 5581 (flags & NDI_CONFIG_REPROBE) && 5582 ((timeout <= 0) || (ddi_get_lbolt() >= end_time))) { 5583 probed = 0; 5584 mutex_enter(&DEVI(pdip)->devi_lock); 5585 DEVI(pdip)->devi_flags &= ~DEVI_MADE_CHILDREN; 5586 mutex_exit(&DEVI(pdip)->devi_lock); 5587 goto again; 5588 } 5589 } 5590 5591 /* break out of for(;;) if time expired */ 5592 if ((timeout <= 0) || (ddi_get_lbolt() >= end_time)) 5593 break; 5594 5595 /* 5596 * Child not found, exit and wait for asynchronous enumeration 5597 * to add child (or timeout). The addition of a new child (vhci 5598 * or phci) requires the asynchronous enumeration thread to 5599 * ndi_devi_enter/ndi_devi_exit. This exit will signal devi_cv 5600 * and cause us to return from ndi_devi_exit_and_wait, after 5601 * which we loop and search for the requested child again. 5602 */ 5603 NDI_DEBUG(flags, (CE_CONT, 5604 "%s%d: waiting for child %s@%s, timeout %ld", 5605 ddi_driver_name(pdip), ddi_get_instance(pdip), 5606 name, addr, timeout)); 5607 if (vdip) { 5608 /* 5609 * Mark vHCI for pHCI ndi_devi_exit broadcast. 5610 */ 5611 mutex_enter(&DEVI(vdip)->devi_lock); 5612 DEVI(vdip)->devi_flags |= 5613 DEVI_PHCI_SIGNALS_VHCI; 5614 mutex_exit(&DEVI(vdip)->devi_lock); 5615 ndi_devi_exit(pdip, p_circ); 5616 5617 /* 5618 * NB: There is a small race window from above 5619 * ndi_devi_exit() of pdip to cv_wait() in 5620 * ndi_devi_exit_and_wait() which can result in 5621 * not immediately finding a new pHCI child 5622 * of a pHCI that uses NDI_MDI_FAILBACK. 5623 */ 5624 ndi_devi_exit_and_wait(vdip, v_circ, end_time); 5625 } else { 5626 ndi_devi_exit_and_wait(pdip, p_circ, end_time); 5627 } 5628 } 5629 5630 /* done with paddr, fixup i_ddi_parse_name '@'->'\0' change */ 5631 if (addr && *addr != '\0') 5632 *(addr - 1) = '@'; 5633 5634 /* attach and hold the child, returning pointer to child */ 5635 if (cdip && (devi_attach_node(cdip, flags) == NDI_SUCCESS)) { 5636 ndi_hold_devi(cdip); 5637 *cdipp = cdip; 5638 } 5639 5640 ndi_devi_exit(pdip, p_circ); 5641 if (vdip) 5642 ndi_devi_exit(vdip, v_circ); 5643 return (*cdipp ? NDI_SUCCESS : NDI_FAILURE); 5644 } 5645 5646 /* 5647 * Enumerate and attach a child specified by name 'devnm'. 5648 * Called by devfs lookup and DR to perform a BUS_CONFIG_ONE. 5649 * Note: devfs does not make use of NDI_CONFIG to configure 5650 * an entire branch. 5651 */ 5652 int 5653 ndi_devi_config_one(dev_info_t *pdip, char *devnm, dev_info_t **dipp, int flags) 5654 { 5655 int error; 5656 int (*f)(); 5657 char *nmdup; 5658 int duplen; 5659 int branch_event = 0; 5660 5661 ASSERT(pdip); 5662 ASSERT(devnm); 5663 ASSERT(dipp); 5664 ASSERT(i_ddi_devi_attached(pdip)); 5665 5666 NDI_CONFIG_DEBUG((CE_CONT, 5667 "ndi_devi_config_one: par = %s%d (%p), child = %s\n", 5668 ddi_driver_name(pdip), ddi_get_instance(pdip), 5669 (void *)pdip, devnm)); 5670 5671 *dipp = NULL; 5672 5673 if (pm_pre_config(pdip, devnm) != DDI_SUCCESS) { 5674 cmn_err(CE_WARN, "preconfig failed: %s", devnm); 5675 return (NDI_FAILURE); 5676 } 5677 5678 if ((flags & (NDI_NO_EVENT | NDI_BRANCH_EVENT_OP)) == 0 && 5679 (flags & NDI_CONFIG)) { 5680 flags |= NDI_BRANCH_EVENT_OP; 5681 branch_event = 1; 5682 } 5683 5684 nmdup = strdup(devnm); 5685 duplen = strlen(devnm) + 1; 5686 5687 if ((DEVI(pdip)->devi_ops->devo_bus_ops == NULL) || 5688 (DEVI(pdip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) || 5689 (f = DEVI(pdip)->devi_ops->devo_bus_ops->bus_config) == NULL) { 5690 error = devi_config_one(pdip, devnm, dipp, flags, 0); 5691 } else { 5692 /* call bus_config entry point */ 5693 error = (*f)(pdip, flags, BUS_CONFIG_ONE, (void *)devnm, dipp); 5694 } 5695 5696 if (error) { 5697 *dipp = NULL; 5698 } 5699 5700 /* 5701 * if we fail to lookup and this could be an alias, lookup currdip 5702 * To prevent recursive lookups into the same hash table, only 5703 * do the currdip lookups once the hash table init is complete. 5704 * Use tsd so that redirection doesn't recurse 5705 */ 5706 if (error) { 5707 char *alias = kmem_alloc(MAXPATHLEN, KM_NOSLEEP); 5708 if (alias == NULL) { 5709 ddi_err(DER_PANIC, pdip, "alias alloc failed: %s", 5710 nmdup); 5711 } 5712 (void) ddi_pathname(pdip, alias); 5713 (void) strlcat(alias, "/", MAXPATHLEN); 5714 (void) strlcat(alias, nmdup, MAXPATHLEN); 5715 5716 *dipp = ddi_alias_redirect(alias); 5717 error = (*dipp ? NDI_SUCCESS : NDI_FAILURE); 5718 5719 kmem_free(alias, MAXPATHLEN); 5720 } 5721 kmem_free(nmdup, duplen); 5722 5723 if (error || !(flags & NDI_CONFIG)) { 5724 pm_post_config(pdip, devnm); 5725 return (error); 5726 } 5727 5728 /* 5729 * DR usage (i.e. call with NDI_CONFIG) recursively configures 5730 * grandchildren, performing a BUS_CONFIG_ALL from the node attached 5731 * by the BUS_CONFIG_ONE. 5732 */ 5733 ASSERT(*dipp); 5734 error = devi_config_common(*dipp, flags, DDI_MAJOR_T_NONE); 5735 5736 pm_post_config(pdip, devnm); 5737 5738 if (branch_event) 5739 (void) i_log_devfs_branch_add(*dipp); 5740 5741 return (error); 5742 } 5743 5744 /* 5745 * Enumerate and attach a child specified by name 'devnm'. 5746 * Called during configure the OBP options. This configures 5747 * only one node. 5748 */ 5749 static int 5750 ndi_devi_config_obp_args(dev_info_t *parent, char *devnm, 5751 dev_info_t **childp, int flags) 5752 { 5753 int error; 5754 int (*f)(); 5755 5756 ASSERT(childp); 5757 ASSERT(i_ddi_devi_attached(parent)); 5758 5759 NDI_CONFIG_DEBUG((CE_CONT, "ndi_devi_config_obp_args: " 5760 "par = %s%d (%p), child = %s\n", ddi_driver_name(parent), 5761 ddi_get_instance(parent), (void *)parent, devnm)); 5762 5763 if ((DEVI(parent)->devi_ops->devo_bus_ops == NULL) || 5764 (DEVI(parent)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) || 5765 (f = DEVI(parent)->devi_ops->devo_bus_ops->bus_config) == NULL) { 5766 error = NDI_FAILURE; 5767 } else { 5768 /* call bus_config entry point */ 5769 error = (*f)(parent, flags, 5770 BUS_CONFIG_OBP_ARGS, (void *)devnm, childp); 5771 } 5772 return (error); 5773 } 5774 5775 /* 5776 * Pay attention, the following is a bit tricky: 5777 * There are three possible cases when constraints are applied 5778 * 5779 * - A constraint is applied and the offline is disallowed. 5780 * Simply return failure and block the offline 5781 * 5782 * - A constraint is applied and the offline is allowed. 5783 * Mark the dip as having passed the constraint and allow 5784 * offline to proceed. 5785 * 5786 * - A constraint is not applied. Allow the offline to proceed for now. 5787 * 5788 * In the latter two cases we allow the offline to proceed. If the 5789 * offline succeeds (no users) everything is fine. It is ok for an unused 5790 * device to be offlined even if no constraints were imposed on the offline. 5791 * If the offline fails because there are users, we look at the constraint 5792 * flag on the dip. If the constraint flag is set (implying that it passed 5793 * a constraint) we allow the dip to be retired. If not, we don't allow 5794 * the retire. This ensures that we don't allow unconstrained retire. 5795 */ 5796 int 5797 e_ddi_offline_notify(dev_info_t *dip) 5798 { 5799 int retval; 5800 int constraint; 5801 int failure; 5802 5803 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): entered: dip=%p", 5804 (void *) dip)); 5805 5806 constraint = 0; 5807 failure = 0; 5808 5809 /* 5810 * Start with userland constraints first - applied via device contracts 5811 */ 5812 retval = contract_device_offline(dip, DDI_DEV_T_ANY, 0); 5813 switch (retval) { 5814 case CT_NACK: 5815 RIO_DEBUG((CE_NOTE, "Received NACK for dip=%p", (void *)dip)); 5816 failure = 1; 5817 goto out; 5818 case CT_ACK: 5819 constraint = 1; 5820 RIO_DEBUG((CE_NOTE, "Received ACK for dip=%p", (void *)dip)); 5821 break; 5822 case CT_NONE: 5823 /* no contracts */ 5824 RIO_DEBUG((CE_NOTE, "No contracts on dip=%p", (void *)dip)); 5825 break; 5826 default: 5827 ASSERT(retval == CT_NONE); 5828 } 5829 5830 /* 5831 * Next, use LDI to impose kernel constraints 5832 */ 5833 retval = ldi_invoke_notify(dip, DDI_DEV_T_ANY, 0, LDI_EV_OFFLINE, NULL); 5834 switch (retval) { 5835 case LDI_EV_FAILURE: 5836 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_FAILURE); 5837 RIO_DEBUG((CE_NOTE, "LDI callback failed on dip=%p", 5838 (void *)dip)); 5839 failure = 1; 5840 goto out; 5841 case LDI_EV_SUCCESS: 5842 constraint = 1; 5843 RIO_DEBUG((CE_NOTE, "LDI callback success on dip=%p", 5844 (void *)dip)); 5845 break; 5846 case LDI_EV_NONE: 5847 /* no matching LDI callbacks */ 5848 RIO_DEBUG((CE_NOTE, "No LDI callbacks for dip=%p", 5849 (void *)dip)); 5850 break; 5851 default: 5852 ASSERT(retval == LDI_EV_NONE); 5853 } 5854 5855 out: 5856 mutex_enter(&(DEVI(dip)->devi_lock)); 5857 if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && failure) { 5858 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): setting " 5859 "BLOCKED flag. dip=%p", (void *)dip)); 5860 DEVI(dip)->devi_flags |= DEVI_R_BLOCKED; 5861 if (DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT) { 5862 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): " 5863 "blocked. clearing RCM CONSTRAINT flag. dip=%p", 5864 (void *)dip)); 5865 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT; 5866 } 5867 } else if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && constraint) { 5868 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): setting " 5869 "CONSTRAINT flag. dip=%p", (void *)dip)); 5870 DEVI(dip)->devi_flags |= DEVI_R_CONSTRAINT; 5871 } else if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && 5872 ((DEVI(dip)->devi_ops != NULL && 5873 DEVI(dip)->devi_ops->devo_bus_ops != NULL) || 5874 DEVI(dip)->devi_ref == 0)) { 5875 /* also allow retire if nexus or if device is not in use */ 5876 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): device not in " 5877 "use. Setting CONSTRAINT flag. dip=%p", (void *)dip)); 5878 DEVI(dip)->devi_flags |= DEVI_R_CONSTRAINT; 5879 } else { 5880 /* 5881 * Note: We cannot ASSERT here that DEVI_R_CONSTRAINT is 5882 * not set, since other sources (such as RCM) may have 5883 * set the flag. 5884 */ 5885 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): not setting " 5886 "constraint flag. dip=%p", (void *)dip)); 5887 } 5888 mutex_exit(&(DEVI(dip)->devi_lock)); 5889 5890 5891 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): exit: dip=%p", 5892 (void *) dip)); 5893 5894 return (failure ? DDI_FAILURE : DDI_SUCCESS); 5895 } 5896 5897 void 5898 e_ddi_offline_finalize(dev_info_t *dip, int result) 5899 { 5900 RIO_DEBUG((CE_NOTE, "e_ddi_offline_finalize(): entry: result=%s, " 5901 "dip=%p", result == DDI_SUCCESS ? "SUCCESS" : "FAILURE", 5902 (void *)dip)); 5903 5904 contract_device_negend(dip, DDI_DEV_T_ANY, 0, result == DDI_SUCCESS ? 5905 CT_EV_SUCCESS : CT_EV_FAILURE); 5906 5907 ldi_invoke_finalize(dip, DDI_DEV_T_ANY, 0, 5908 LDI_EV_OFFLINE, result == DDI_SUCCESS ? 5909 LDI_EV_SUCCESS : LDI_EV_FAILURE, NULL); 5910 5911 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_finalize(): exit: dip=%p", 5912 (void *)dip)); 5913 } 5914 5915 void 5916 e_ddi_degrade_finalize(dev_info_t *dip) 5917 { 5918 RIO_DEBUG((CE_NOTE, "e_ddi_degrade_finalize(): entry: " 5919 "result always = DDI_SUCCESS, dip=%p", (void *)dip)); 5920 5921 contract_device_degrade(dip, DDI_DEV_T_ANY, 0); 5922 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_SUCCESS); 5923 5924 ldi_invoke_finalize(dip, DDI_DEV_T_ANY, 0, LDI_EV_DEGRADE, 5925 LDI_EV_SUCCESS, NULL); 5926 5927 RIO_VERBOSE((CE_NOTE, "e_ddi_degrade_finalize(): exit: dip=%p", 5928 (void *)dip)); 5929 } 5930 5931 void 5932 e_ddi_undegrade_finalize(dev_info_t *dip) 5933 { 5934 RIO_DEBUG((CE_NOTE, "e_ddi_undegrade_finalize(): entry: " 5935 "result always = DDI_SUCCESS, dip=%p", (void *)dip)); 5936 5937 contract_device_undegrade(dip, DDI_DEV_T_ANY, 0); 5938 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_SUCCESS); 5939 5940 RIO_VERBOSE((CE_NOTE, "e_ddi_undegrade_finalize(): exit: dip=%p", 5941 (void *)dip)); 5942 } 5943 5944 /* 5945 * detach a node with parent already held busy 5946 */ 5947 static int 5948 devi_detach_node(dev_info_t *dip, uint_t flags) 5949 { 5950 dev_info_t *pdip = ddi_get_parent(dip); 5951 int ret = NDI_SUCCESS; 5952 ddi_eventcookie_t cookie; 5953 char *path = NULL; 5954 char *class = NULL; 5955 char *driver = NULL; 5956 int instance = -1; 5957 int post_event = 0; 5958 5959 ASSERT(pdip && DEVI_BUSY_OWNED(pdip)); 5960 5961 /* 5962 * Invoke notify if offlining 5963 */ 5964 if (flags & NDI_DEVI_OFFLINE) { 5965 RIO_DEBUG((CE_NOTE, "devi_detach_node: offlining dip=%p", 5966 (void *)dip)); 5967 if (e_ddi_offline_notify(dip) != DDI_SUCCESS) { 5968 RIO_DEBUG((CE_NOTE, "devi_detach_node: offline NACKed" 5969 "dip=%p", (void *)dip)); 5970 return (NDI_FAILURE); 5971 } 5972 } 5973 5974 if (flags & NDI_POST_EVENT) { 5975 if (i_ddi_devi_attached(pdip)) { 5976 if (ddi_get_eventcookie(dip, DDI_DEVI_REMOVE_EVENT, 5977 &cookie) == NDI_SUCCESS) 5978 (void) ndi_post_event(dip, dip, cookie, NULL); 5979 } 5980 } 5981 5982 /* 5983 * dv_mknod places a hold on the dev_info_t for each devfs node 5984 * created. If we're to succeed in detaching this device, we must 5985 * first release all outstanding references held by devfs. 5986 */ 5987 (void) devfs_clean(pdip, NULL, DV_CLEAN_FORCE); 5988 5989 if (i_ddi_detachchild(dip, flags) != DDI_SUCCESS) { 5990 if (flags & NDI_DEVI_OFFLINE) { 5991 RIO_DEBUG((CE_NOTE, "devi_detach_node: offline failed." 5992 " Calling e_ddi_offline_finalize with result=%d. " 5993 "dip=%p", DDI_FAILURE, (void *)dip)); 5994 e_ddi_offline_finalize(dip, DDI_FAILURE); 5995 } 5996 return (NDI_FAILURE); 5997 } 5998 5999 if (flags & NDI_DEVI_OFFLINE) { 6000 RIO_DEBUG((CE_NOTE, "devi_detach_node: offline succeeded." 6001 " Calling e_ddi_offline_finalize with result=%d, " 6002 "dip=%p", DDI_SUCCESS, (void *)dip)); 6003 e_ddi_offline_finalize(dip, DDI_SUCCESS); 6004 } 6005 6006 if (flags & NDI_AUTODETACH) 6007 return (NDI_SUCCESS); 6008 6009 /* 6010 * For DR, even bound nodes may need to have offline 6011 * flag set. 6012 */ 6013 if (flags & NDI_DEVI_OFFLINE) { 6014 mutex_enter(&(DEVI(dip)->devi_lock)); 6015 DEVI_SET_DEVICE_OFFLINE(dip); 6016 mutex_exit(&(DEVI(dip)->devi_lock)); 6017 } 6018 6019 if (i_ddi_node_state(dip) == DS_INITIALIZED) { 6020 struct dev_info *devi = DEVI(dip); 6021 6022 if (devi->devi_ev_path == NULL) { 6023 devi->devi_ev_path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 6024 (void) ddi_pathname(dip, devi->devi_ev_path); 6025 } 6026 if (flags & NDI_DEVI_OFFLINE) 6027 i_ndi_devi_report_status_change(dip, 6028 devi->devi_ev_path); 6029 6030 if (need_remove_event(dip, flags)) { 6031 /* 6032 * instance and path data are lost in call to 6033 * ddi_uninitchild 6034 */ 6035 devi->devi_ev_instance = ddi_get_instance(dip); 6036 6037 mutex_enter(&(DEVI(dip)->devi_lock)); 6038 DEVI_SET_EVREMOVE(dip); 6039 mutex_exit(&(DEVI(dip)->devi_lock)); 6040 } 6041 } 6042 6043 if (flags & (NDI_UNCONFIG | NDI_DEVI_REMOVE)) { 6044 ret = ddi_uninitchild(dip); 6045 if (ret == NDI_SUCCESS) { 6046 /* 6047 * Remove uninitialized pseudo nodes because 6048 * system props are lost and the node cannot be 6049 * reattached. 6050 */ 6051 if (!ndi_dev_is_persistent_node(dip)) 6052 flags |= NDI_DEVI_REMOVE; 6053 6054 if (flags & NDI_DEVI_REMOVE) { 6055 /* 6056 * NOTE: If there is a consumer of LDI events, 6057 * ddi_uninitchild above would have failed 6058 * because of active devi_ref from ldi_open(). 6059 */ 6060 6061 if (DEVI_EVREMOVE(dip)) { 6062 path = i_ddi_strdup( 6063 DEVI(dip)->devi_ev_path, 6064 KM_SLEEP); 6065 class = 6066 i_ddi_strdup(i_ddi_devi_class(dip), 6067 KM_SLEEP); 6068 driver = 6069 i_ddi_strdup( 6070 (char *)ddi_driver_name(dip), 6071 KM_SLEEP); 6072 instance = DEVI(dip)->devi_ev_instance; 6073 post_event = 1; 6074 } 6075 6076 ret = ddi_remove_child(dip, 0); 6077 if (post_event && ret == NDI_SUCCESS) { 6078 /* Generate EC_DEVFS_DEVI_REMOVE */ 6079 (void) i_log_devfs_remove_devinfo(path, 6080 class, driver, instance, flags); 6081 } 6082 } 6083 6084 } 6085 } 6086 6087 if (path) 6088 strfree(path); 6089 if (class) 6090 strfree(class); 6091 if (driver) 6092 strfree(driver); 6093 6094 return (ret); 6095 } 6096 6097 /* 6098 * unconfigure immediate children of bus nexus device 6099 */ 6100 static int 6101 unconfig_immediate_children( 6102 dev_info_t *dip, 6103 dev_info_t **dipp, 6104 int flags, 6105 major_t major) 6106 { 6107 int rv = NDI_SUCCESS; 6108 int circ, vcirc; 6109 dev_info_t *child; 6110 dev_info_t *vdip = NULL; 6111 dev_info_t *next; 6112 6113 ASSERT(dipp == NULL || *dipp == NULL); 6114 6115 /* 6116 * Scan forward to see if we will be processing a pHCI child. If we 6117 * have a child that is a pHCI and vHCI and pHCI are not siblings then 6118 * enter vHCI before parent(pHCI) to prevent deadlock with mpxio 6119 * Client power management operations. 6120 */ 6121 ndi_devi_enter(dip, &circ); 6122 for (child = ddi_get_child(dip); child; 6123 child = ddi_get_next_sibling(child)) { 6124 /* skip same nodes we skip below */ 6125 if (((major != DDI_MAJOR_T_NONE) && 6126 (major != ddi_driver_major(child))) || 6127 ((flags & NDI_AUTODETACH) && !is_leaf_node(child))) 6128 continue; 6129 6130 if (MDI_PHCI(child)) { 6131 vdip = mdi_devi_get_vdip(child); 6132 /* 6133 * If vHCI and vHCI is not a sibling of pHCI 6134 * then enter in (vHCI, parent(pHCI)) order. 6135 */ 6136 if (vdip && (ddi_get_parent(vdip) != dip)) { 6137 ndi_devi_exit(dip, circ); 6138 6139 /* use mdi_devi_enter ordering */ 6140 ndi_devi_enter(vdip, &vcirc); 6141 ndi_devi_enter(dip, &circ); 6142 break; 6143 } else 6144 vdip = NULL; 6145 } 6146 } 6147 6148 child = ddi_get_child(dip); 6149 while (child) { 6150 next = ddi_get_next_sibling(child); 6151 6152 if ((major != DDI_MAJOR_T_NONE) && 6153 (major != ddi_driver_major(child))) { 6154 child = next; 6155 continue; 6156 } 6157 6158 /* skip nexus nodes during autodetach */ 6159 if ((flags & NDI_AUTODETACH) && !is_leaf_node(child)) { 6160 child = next; 6161 continue; 6162 } 6163 6164 if (devi_detach_node(child, flags) != NDI_SUCCESS) { 6165 if (dipp && *dipp == NULL) { 6166 ndi_hold_devi(child); 6167 *dipp = child; 6168 } 6169 rv = NDI_FAILURE; 6170 } 6171 6172 /* 6173 * Continue upon failure--best effort algorithm 6174 */ 6175 child = next; 6176 } 6177 6178 ndi_devi_exit(dip, circ); 6179 if (vdip) 6180 ndi_devi_exit(vdip, vcirc); 6181 6182 return (rv); 6183 } 6184 6185 /* 6186 * unconfigure grand children of bus nexus device 6187 */ 6188 static int 6189 unconfig_grand_children( 6190 dev_info_t *dip, 6191 dev_info_t **dipp, 6192 int flags, 6193 major_t major, 6194 struct brevq_node **brevqp) 6195 { 6196 struct mt_config_handle *hdl; 6197 6198 if (brevqp) 6199 *brevqp = NULL; 6200 6201 /* multi-threaded configuration of child nexus */ 6202 hdl = mt_config_init(dip, dipp, flags, major, MT_UNCONFIG_OP, brevqp); 6203 mt_config_children(hdl); 6204 6205 return (mt_config_fini(hdl)); /* wait for threads to exit */ 6206 } 6207 6208 /* 6209 * Unconfigure children/descendants of the dip. 6210 * 6211 * If brevqp is not NULL, on return *brevqp is set to a queue of dip's 6212 * child devinames for which branch remove events need to be generated. 6213 */ 6214 static int 6215 devi_unconfig_common( 6216 dev_info_t *dip, 6217 dev_info_t **dipp, 6218 int flags, 6219 major_t major, 6220 struct brevq_node **brevqp) 6221 { 6222 int rv; 6223 int pm_cookie; 6224 int (*f)(); 6225 ddi_bus_config_op_t bus_op; 6226 6227 if (dipp) 6228 *dipp = NULL; 6229 if (brevqp) 6230 *brevqp = NULL; 6231 6232 /* 6233 * Power up the dip if it is powered off. If the flag bit 6234 * NDI_AUTODETACH is set and the dip is not at its full power, 6235 * skip the rest of the branch. 6236 */ 6237 if (pm_pre_unconfig(dip, flags, &pm_cookie, NULL) != DDI_SUCCESS) 6238 return ((flags & NDI_AUTODETACH) ? NDI_SUCCESS : 6239 NDI_FAILURE); 6240 6241 /* 6242 * Some callers, notably SCSI, need to clear out the devfs 6243 * cache together with the unconfig to prevent stale entries. 6244 */ 6245 if (flags & NDI_DEVFS_CLEAN) 6246 (void) devfs_clean(dip, NULL, 0); 6247 6248 rv = unconfig_grand_children(dip, dipp, flags, major, brevqp); 6249 6250 if ((rv != NDI_SUCCESS) && ((flags & NDI_AUTODETACH) == 0)) { 6251 if (brevqp && *brevqp) { 6252 log_and_free_br_events_on_grand_children(dip, *brevqp); 6253 free_brevq(*brevqp); 6254 *brevqp = NULL; 6255 } 6256 pm_post_unconfig(dip, pm_cookie, NULL); 6257 return (rv); 6258 } 6259 6260 if (dipp && *dipp) { 6261 ndi_rele_devi(*dipp); 6262 *dipp = NULL; 6263 } 6264 6265 /* 6266 * It is possible to have a detached nexus with children 6267 * and grandchildren (for example: a branch consisting 6268 * entirely of bound nodes.) Since the nexus is detached 6269 * the bus_unconfig entry point cannot be used to remove 6270 * or unconfigure the descendants. 6271 */ 6272 if (!i_ddi_devi_attached(dip) || 6273 (DEVI(dip)->devi_ops->devo_bus_ops == NULL) || 6274 (DEVI(dip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) || 6275 (f = DEVI(dip)->devi_ops->devo_bus_ops->bus_unconfig) == NULL) { 6276 rv = unconfig_immediate_children(dip, dipp, flags, major); 6277 } else { 6278 /* 6279 * call bus_unconfig entry point 6280 * It should reset nexus flags if unconfigure succeeds. 6281 */ 6282 bus_op = (major == DDI_MAJOR_T_NONE) ? 6283 BUS_UNCONFIG_ALL : BUS_UNCONFIG_DRIVER; 6284 rv = (*f)(dip, flags, bus_op, (void *)(uintptr_t)major); 6285 } 6286 6287 pm_post_unconfig(dip, pm_cookie, NULL); 6288 6289 if (brevqp && *brevqp) 6290 cleanup_br_events_on_grand_children(dip, brevqp); 6291 6292 return (rv); 6293 } 6294 6295 /* 6296 * called by devfs/framework to unconfigure children bound to major 6297 * If NDI_AUTODETACH is specified, this is invoked by either the 6298 * moduninstall daemon or the modunload -i 0 command. 6299 */ 6300 int 6301 ndi_devi_unconfig_driver(dev_info_t *dip, int flags, major_t major) 6302 { 6303 NDI_CONFIG_DEBUG((CE_CONT, 6304 "ndi_devi_unconfig_driver: par = %s%d (%p), flags = 0x%x\n", 6305 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags)); 6306 6307 return (devi_unconfig_common(dip, NULL, flags, major, NULL)); 6308 } 6309 6310 int 6311 ndi_devi_unconfig(dev_info_t *dip, int flags) 6312 { 6313 NDI_CONFIG_DEBUG((CE_CONT, 6314 "ndi_devi_unconfig: par = %s%d (%p), flags = 0x%x\n", 6315 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags)); 6316 6317 return (devi_unconfig_common(dip, NULL, flags, DDI_MAJOR_T_NONE, NULL)); 6318 } 6319 6320 int 6321 e_ddi_devi_unconfig(dev_info_t *dip, dev_info_t **dipp, int flags) 6322 { 6323 NDI_CONFIG_DEBUG((CE_CONT, 6324 "e_ddi_devi_unconfig: par = %s%d (%p), flags = 0x%x\n", 6325 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags)); 6326 6327 return (devi_unconfig_common(dip, dipp, flags, DDI_MAJOR_T_NONE, NULL)); 6328 } 6329 6330 /* 6331 * Unconfigure child by name 6332 */ 6333 static int 6334 devi_unconfig_one(dev_info_t *pdip, char *devnm, int flags) 6335 { 6336 int rv, circ; 6337 dev_info_t *child; 6338 dev_info_t *vdip = NULL; 6339 int v_circ; 6340 6341 ndi_devi_enter(pdip, &circ); 6342 child = ndi_devi_findchild(pdip, devnm); 6343 6344 /* 6345 * If child is pHCI and vHCI and pHCI are not siblings then enter vHCI 6346 * before parent(pHCI) to avoid deadlock with mpxio Client power 6347 * management operations. 6348 */ 6349 if (child && MDI_PHCI(child)) { 6350 vdip = mdi_devi_get_vdip(child); 6351 if (vdip && (ddi_get_parent(vdip) != pdip)) { 6352 ndi_devi_exit(pdip, circ); 6353 6354 /* use mdi_devi_enter ordering */ 6355 ndi_devi_enter(vdip, &v_circ); 6356 ndi_devi_enter(pdip, &circ); 6357 child = ndi_devi_findchild(pdip, devnm); 6358 } else 6359 vdip = NULL; 6360 } 6361 6362 if (child) { 6363 rv = devi_detach_node(child, flags); 6364 } else { 6365 NDI_CONFIG_DEBUG((CE_CONT, 6366 "devi_unconfig_one: %s not found\n", devnm)); 6367 rv = NDI_SUCCESS; 6368 } 6369 6370 ndi_devi_exit(pdip, circ); 6371 if (vdip) 6372 ndi_devi_exit(vdip, v_circ); 6373 6374 return (rv); 6375 } 6376 6377 int 6378 ndi_devi_unconfig_one( 6379 dev_info_t *pdip, 6380 char *devnm, 6381 dev_info_t **dipp, 6382 int flags) 6383 { 6384 int (*f)(); 6385 int circ, rv; 6386 int pm_cookie; 6387 dev_info_t *child; 6388 dev_info_t *vdip = NULL; 6389 int v_circ; 6390 struct brevq_node *brevq = NULL; 6391 6392 ASSERT(i_ddi_devi_attached(pdip)); 6393 6394 NDI_CONFIG_DEBUG((CE_CONT, 6395 "ndi_devi_unconfig_one: par = %s%d (%p), child = %s\n", 6396 ddi_driver_name(pdip), ddi_get_instance(pdip), 6397 (void *)pdip, devnm)); 6398 6399 if (pm_pre_unconfig(pdip, flags, &pm_cookie, devnm) != DDI_SUCCESS) 6400 return (NDI_FAILURE); 6401 6402 if (dipp) 6403 *dipp = NULL; 6404 6405 ndi_devi_enter(pdip, &circ); 6406 child = ndi_devi_findchild(pdip, devnm); 6407 6408 /* 6409 * If child is pHCI and vHCI and pHCI are not siblings then enter vHCI 6410 * before parent(pHCI) to avoid deadlock with mpxio Client power 6411 * management operations. 6412 */ 6413 if (child && MDI_PHCI(child)) { 6414 vdip = mdi_devi_get_vdip(child); 6415 if (vdip && (ddi_get_parent(vdip) != pdip)) { 6416 ndi_devi_exit(pdip, circ); 6417 6418 /* use mdi_devi_enter ordering */ 6419 ndi_devi_enter(vdip, &v_circ); 6420 ndi_devi_enter(pdip, &circ); 6421 child = ndi_devi_findchild(pdip, devnm); 6422 } else 6423 vdip = NULL; 6424 } 6425 6426 if (child == NULL) { 6427 NDI_CONFIG_DEBUG((CE_CONT, "ndi_devi_unconfig_one: %s" 6428 " not found\n", devnm)); 6429 rv = NDI_SUCCESS; 6430 goto out; 6431 } 6432 6433 /* 6434 * Unconfigure children/descendants of named child 6435 */ 6436 rv = devi_unconfig_branch(child, dipp, flags | NDI_UNCONFIG, &brevq); 6437 if (rv != NDI_SUCCESS) 6438 goto out; 6439 6440 init_bound_node_ev(pdip, child, flags); 6441 6442 if ((DEVI(pdip)->devi_ops->devo_bus_ops == NULL) || 6443 (DEVI(pdip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) || 6444 (f = DEVI(pdip)->devi_ops->devo_bus_ops->bus_unconfig) == NULL) { 6445 rv = devi_detach_node(child, flags); 6446 } else { 6447 /* call bus_config entry point */ 6448 rv = (*f)(pdip, flags, BUS_UNCONFIG_ONE, (void *)devnm); 6449 } 6450 6451 if (brevq) { 6452 if (rv != NDI_SUCCESS) 6453 log_and_free_brevq_dip(child, brevq); 6454 else 6455 free_brevq(brevq); 6456 } 6457 6458 if (dipp && rv != NDI_SUCCESS) { 6459 ndi_hold_devi(child); 6460 ASSERT(*dipp == NULL); 6461 *dipp = child; 6462 } 6463 6464 out: 6465 ndi_devi_exit(pdip, circ); 6466 if (vdip) 6467 ndi_devi_exit(vdip, v_circ); 6468 6469 pm_post_unconfig(pdip, pm_cookie, devnm); 6470 6471 return (rv); 6472 } 6473 6474 struct async_arg { 6475 dev_info_t *dip; 6476 uint_t flags; 6477 }; 6478 6479 /* 6480 * Common async handler for: 6481 * ndi_devi_bind_driver_async 6482 * ndi_devi_online_async 6483 */ 6484 static int 6485 i_ndi_devi_async_common(dev_info_t *dip, uint_t flags, void (*func)()) 6486 { 6487 int tqflag; 6488 int kmflag; 6489 struct async_arg *arg; 6490 dev_info_t *pdip = ddi_get_parent(dip); 6491 6492 ASSERT(pdip); 6493 ASSERT(DEVI(pdip)->devi_taskq); 6494 ASSERT(ndi_dev_is_persistent_node(dip)); 6495 6496 if (flags & NDI_NOSLEEP) { 6497 kmflag = KM_NOSLEEP; 6498 tqflag = TQ_NOSLEEP; 6499 } else { 6500 kmflag = KM_SLEEP; 6501 tqflag = TQ_SLEEP; 6502 } 6503 6504 arg = kmem_alloc(sizeof (*arg), kmflag); 6505 if (arg == NULL) 6506 goto fail; 6507 6508 arg->flags = flags; 6509 arg->dip = dip; 6510 if (ddi_taskq_dispatch(DEVI(pdip)->devi_taskq, func, arg, tqflag) == 6511 DDI_SUCCESS) { 6512 return (NDI_SUCCESS); 6513 } 6514 6515 fail: 6516 NDI_CONFIG_DEBUG((CE_CONT, "%s%d: ddi_taskq_dispatch failed", 6517 ddi_driver_name(pdip), ddi_get_instance(pdip))); 6518 6519 if (arg) 6520 kmem_free(arg, sizeof (*arg)); 6521 return (NDI_FAILURE); 6522 } 6523 6524 static void 6525 i_ndi_devi_bind_driver_cb(struct async_arg *arg) 6526 { 6527 (void) ndi_devi_bind_driver(arg->dip, arg->flags); 6528 kmem_free(arg, sizeof (*arg)); 6529 } 6530 6531 int 6532 ndi_devi_bind_driver_async(dev_info_t *dip, uint_t flags) 6533 { 6534 return (i_ndi_devi_async_common(dip, flags, 6535 (void (*)())i_ndi_devi_bind_driver_cb)); 6536 } 6537 6538 /* 6539 * place the devinfo in the ONLINE state. 6540 */ 6541 int 6542 ndi_devi_online(dev_info_t *dip, uint_t flags) 6543 { 6544 int circ, rv; 6545 dev_info_t *pdip = ddi_get_parent(dip); 6546 int branch_event = 0; 6547 6548 ASSERT(pdip); 6549 6550 NDI_CONFIG_DEBUG((CE_CONT, "ndi_devi_online: %s%d (%p)\n", 6551 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip)); 6552 6553 ndi_devi_enter(pdip, &circ); 6554 /* bind child before merging .conf nodes */ 6555 rv = i_ndi_config_node(dip, DS_BOUND, flags); 6556 if (rv != NDI_SUCCESS) { 6557 ndi_devi_exit(pdip, circ); 6558 return (rv); 6559 } 6560 6561 /* merge .conf properties */ 6562 (void) i_ndi_make_spec_children(pdip, flags); 6563 6564 flags |= (NDI_DEVI_ONLINE | NDI_CONFIG); 6565 6566 if (flags & NDI_NO_EVENT) { 6567 /* 6568 * Caller is specifically asking for not to generate an event. 6569 * Set the following flag so that devi_attach_node() don't 6570 * change the event state. 6571 */ 6572 flags |= NDI_NO_EVENT_STATE_CHNG; 6573 } 6574 6575 if ((flags & (NDI_NO_EVENT | NDI_BRANCH_EVENT_OP)) == 0 && 6576 ((flags & NDI_CONFIG) || DEVI_NEED_NDI_CONFIG(dip))) { 6577 flags |= NDI_BRANCH_EVENT_OP; 6578 branch_event = 1; 6579 } 6580 6581 /* 6582 * devi_attach_node() may remove dip on failure 6583 */ 6584 if ((rv = devi_attach_node(dip, flags)) == NDI_SUCCESS) { 6585 if ((flags & NDI_CONFIG) || DEVI_NEED_NDI_CONFIG(dip)) { 6586 /* 6587 * Hold the attached dip, and exit the parent while 6588 * we drive configuration of children below the 6589 * attached dip. 6590 */ 6591 ndi_hold_devi(dip); 6592 ndi_devi_exit(pdip, circ); 6593 6594 (void) ndi_devi_config(dip, flags); 6595 6596 ndi_devi_enter(pdip, &circ); 6597 ndi_rele_devi(dip); 6598 } 6599 6600 if (branch_event) 6601 (void) i_log_devfs_branch_add(dip); 6602 } 6603 6604 ndi_devi_exit(pdip, circ); 6605 6606 /* 6607 * Notify devfs that we have a new node. Devfs needs to invalidate 6608 * cached directory contents. 6609 * 6610 * For PCMCIA devices, it is possible the pdip is not fully 6611 * attached. In this case, calling back into devfs will 6612 * result in a loop or assertion error. Hence, the check 6613 * on node state. 6614 * 6615 * If we own parent lock, this is part of a branch operation. 6616 * We skip the devfs_clean() step because the cache invalidation 6617 * is done higher up in the device tree. 6618 */ 6619 if (rv == NDI_SUCCESS && i_ddi_devi_attached(pdip) && 6620 !DEVI_BUSY_OWNED(pdip)) 6621 (void) devfs_clean(pdip, NULL, 0); 6622 return (rv); 6623 } 6624 6625 static void 6626 i_ndi_devi_online_cb(struct async_arg *arg) 6627 { 6628 (void) ndi_devi_online(arg->dip, arg->flags); 6629 kmem_free(arg, sizeof (*arg)); 6630 } 6631 6632 int 6633 ndi_devi_online_async(dev_info_t *dip, uint_t flags) 6634 { 6635 /* mark child as need config if requested. */ 6636 if (flags & NDI_CONFIG) { 6637 mutex_enter(&(DEVI(dip)->devi_lock)); 6638 DEVI_SET_NDI_CONFIG(dip); 6639 mutex_exit(&(DEVI(dip)->devi_lock)); 6640 } 6641 6642 return (i_ndi_devi_async_common(dip, flags, 6643 (void (*)())i_ndi_devi_online_cb)); 6644 } 6645 6646 /* 6647 * Take a device node Offline 6648 * To take a device Offline means to detach the device instance from 6649 * the driver and prevent devfs requests from re-attaching the device 6650 * instance. 6651 * 6652 * The flag NDI_DEVI_REMOVE causes removes the device node from 6653 * the driver list and the device tree. In this case, the device 6654 * is assumed to be removed from the system. 6655 */ 6656 int 6657 ndi_devi_offline(dev_info_t *dip, uint_t flags) 6658 { 6659 int circ, rval = 0; 6660 dev_info_t *pdip = ddi_get_parent(dip); 6661 dev_info_t *vdip = NULL; 6662 int v_circ; 6663 struct brevq_node *brevq = NULL; 6664 6665 ASSERT(pdip); 6666 6667 flags |= NDI_DEVI_OFFLINE; 6668 6669 /* 6670 * If child is pHCI and vHCI and pHCI are not siblings then enter vHCI 6671 * before parent(pHCI) to avoid deadlock with mpxio Client power 6672 * management operations. 6673 */ 6674 if (MDI_PHCI(dip)) { 6675 vdip = mdi_devi_get_vdip(dip); 6676 if (vdip && (ddi_get_parent(vdip) != pdip)) 6677 ndi_devi_enter(vdip, &v_circ); 6678 else 6679 vdip = NULL; 6680 } 6681 ndi_devi_enter(pdip, &circ); 6682 6683 if (i_ddi_devi_attached(dip)) { 6684 /* 6685 * If dip is in DS_READY state, there may be cached dv_nodes 6686 * referencing this dip, so we invoke devfs code path. 6687 * Note that we must release busy changing on pdip to 6688 * avoid deadlock against devfs. 6689 */ 6690 char *devname = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 6691 (void) ddi_deviname(dip, devname); 6692 6693 ndi_devi_exit(pdip, circ); 6694 if (vdip) 6695 ndi_devi_exit(vdip, v_circ); 6696 6697 /* 6698 * If we are explictly told to clean, then clean. If we own the 6699 * parent lock then this is part of a branch operation, and we 6700 * skip the devfs_clean() step. 6701 * 6702 * NOTE: A thread performing a devfs file system lookup/ 6703 * bus_config can't call devfs_clean to unconfig without 6704 * causing rwlock problems in devfs. For ndi_devi_offline, this 6705 * means that the NDI_DEVFS_CLEAN flag is safe from ioctl code 6706 * or from an async hotplug thread, but is not safe from a 6707 * nexus driver's bus_config implementation. 6708 */ 6709 if ((flags & NDI_DEVFS_CLEAN) || 6710 (!DEVI_BUSY_OWNED(pdip))) 6711 (void) devfs_clean(pdip, devname + 1, DV_CLEAN_FORCE); 6712 6713 kmem_free(devname, MAXNAMELEN + 1); 6714 6715 rval = devi_unconfig_branch(dip, NULL, flags|NDI_UNCONFIG, 6716 &brevq); 6717 6718 if (rval) 6719 return (NDI_FAILURE); 6720 6721 if (vdip) 6722 ndi_devi_enter(vdip, &v_circ); 6723 ndi_devi_enter(pdip, &circ); 6724 } 6725 6726 init_bound_node_ev(pdip, dip, flags); 6727 6728 rval = devi_detach_node(dip, flags); 6729 if (brevq) { 6730 if (rval != NDI_SUCCESS) 6731 log_and_free_brevq_dip(dip, brevq); 6732 else 6733 free_brevq(brevq); 6734 } 6735 6736 ndi_devi_exit(pdip, circ); 6737 if (vdip) 6738 ndi_devi_exit(vdip, v_circ); 6739 6740 return (rval); 6741 } 6742 6743 /* 6744 * Find the child dev_info node of parent nexus 'p' whose unit address 6745 * matches "cname@caddr". Recommend use of ndi_devi_findchild() instead. 6746 */ 6747 dev_info_t * 6748 ndi_devi_find(dev_info_t *pdip, char *cname, char *caddr) 6749 { 6750 dev_info_t *child; 6751 int circ; 6752 6753 if (pdip == NULL || cname == NULL || caddr == NULL) 6754 return ((dev_info_t *)NULL); 6755 6756 ndi_devi_enter(pdip, &circ); 6757 child = find_sibling(ddi_get_child(pdip), cname, caddr, 6758 FIND_NODE_BY_NODENAME, NULL); 6759 ndi_devi_exit(pdip, circ); 6760 return (child); 6761 } 6762 6763 /* 6764 * Find the child dev_info node of parent nexus 'p' whose unit address 6765 * matches devname "name@addr". Permits caller to hold the parent. 6766 */ 6767 dev_info_t * 6768 ndi_devi_findchild(dev_info_t *pdip, char *devname) 6769 { 6770 dev_info_t *child; 6771 char *cname, *caddr; 6772 char *devstr; 6773 6774 ASSERT(DEVI_BUSY_OWNED(pdip)); 6775 6776 devstr = i_ddi_strdup(devname, KM_SLEEP); 6777 i_ddi_parse_name(devstr, &cname, &caddr, NULL); 6778 6779 if (cname == NULL || caddr == NULL) { 6780 kmem_free(devstr, strlen(devname)+1); 6781 return ((dev_info_t *)NULL); 6782 } 6783 6784 child = find_sibling(ddi_get_child(pdip), cname, caddr, 6785 FIND_NODE_BY_NODENAME, NULL); 6786 kmem_free(devstr, strlen(devname)+1); 6787 return (child); 6788 } 6789 6790 /* 6791 * Misc. routines called by framework only 6792 */ 6793 6794 /* 6795 * Clear the DEVI_MADE_CHILDREN/DEVI_ATTACHED_CHILDREN flags 6796 * if new child spec has been added. 6797 */ 6798 static int 6799 reset_nexus_flags(dev_info_t *dip, void *arg) 6800 { 6801 struct hwc_spec *list; 6802 int circ; 6803 6804 if (((DEVI(dip)->devi_flags & DEVI_MADE_CHILDREN) == 0) || 6805 ((list = hwc_get_child_spec(dip, (major_t)(uintptr_t)arg)) == NULL)) 6806 return (DDI_WALK_CONTINUE); 6807 6808 hwc_free_spec_list(list); 6809 6810 /* coordinate child state update */ 6811 ndi_devi_enter(dip, &circ); 6812 mutex_enter(&DEVI(dip)->devi_lock); 6813 DEVI(dip)->devi_flags &= ~(DEVI_MADE_CHILDREN | DEVI_ATTACHED_CHILDREN); 6814 mutex_exit(&DEVI(dip)->devi_lock); 6815 ndi_devi_exit(dip, circ); 6816 6817 return (DDI_WALK_CONTINUE); 6818 } 6819 6820 /* 6821 * Helper functions, returns NULL if no memory. 6822 */ 6823 6824 /* 6825 * path_to_major: 6826 * 6827 * Return an alternate driver name binding for the leaf device 6828 * of the given pathname, if there is one. The purpose of this 6829 * function is to deal with generic pathnames. The default action 6830 * for platforms that can't do this (ie: x86 or any platform that 6831 * does not have prom_finddevice functionality, which matches 6832 * nodenames and unit-addresses without the drivers participation) 6833 * is to return DDI_MAJOR_T_NONE. 6834 * 6835 * Used in loadrootmodules() in the swapgeneric module to 6836 * associate a given pathname with a given leaf driver. 6837 * 6838 */ 6839 major_t 6840 path_to_major(char *path) 6841 { 6842 dev_info_t *dip; 6843 char *p, *q; 6844 pnode_t nodeid; 6845 major_t major; 6846 6847 /* check for path-oriented alias */ 6848 major = ddi_name_to_major(path); 6849 if (driver_active(major)) { 6850 NDI_CONFIG_DEBUG((CE_NOTE, "path_to_major: %s path bound %s\n", 6851 path, ddi_major_to_name(major))); 6852 return (major); 6853 } 6854 6855 /* 6856 * Get the nodeid of the given pathname, if such a mapping exists. 6857 */ 6858 dip = NULL; 6859 nodeid = prom_finddevice(path); 6860 if (nodeid != OBP_BADNODE) { 6861 /* 6862 * Find the nodeid in our copy of the device tree and return 6863 * whatever name we used to bind this node to a driver. 6864 */ 6865 dip = e_ddi_nodeid_to_dip(nodeid); 6866 } 6867 6868 if (dip == NULL) { 6869 NDI_CONFIG_DEBUG((CE_WARN, 6870 "path_to_major: can't bind <%s>\n", path)); 6871 return (DDI_MAJOR_T_NONE); 6872 } 6873 6874 /* 6875 * If we're bound to something other than the nodename, 6876 * note that in the message buffer and system log. 6877 */ 6878 p = ddi_binding_name(dip); 6879 q = ddi_node_name(dip); 6880 if (p && q && (strcmp(p, q) != 0)) 6881 NDI_CONFIG_DEBUG((CE_NOTE, "path_to_major: %s bound to %s\n", 6882 path, p)); 6883 6884 major = ddi_name_to_major(p); 6885 6886 ndi_rele_devi(dip); /* release e_ddi_nodeid_to_dip hold */ 6887 6888 return (major); 6889 } 6890 6891 /* 6892 * Return the held dip for the specified major and instance, attempting to do 6893 * an attach if specified. Return NULL if the devi can't be found or put in 6894 * the proper state. The caller must release the hold via ddi_release_devi if 6895 * a non-NULL value is returned. 6896 * 6897 * Some callers expect to be able to perform a hold_devi() while in a context 6898 * where using ndi_devi_enter() to ensure the hold might cause deadlock (see 6899 * open-from-attach code in consconfig_dacf.c). Such special-case callers 6900 * must ensure that an ndi_devi_enter(parent)/ndi_hold_devi() from a safe 6901 * context is already active. The hold_devi() implementation must accommodate 6902 * these callers. 6903 */ 6904 static dev_info_t * 6905 hold_devi(major_t major, int instance, int flags) 6906 { 6907 struct devnames *dnp; 6908 dev_info_t *dip; 6909 char *path; 6910 char *vpath; 6911 6912 if ((major >= devcnt) || (instance == -1)) 6913 return (NULL); 6914 6915 /* try to find the instance in the per driver list */ 6916 dnp = &(devnamesp[major]); 6917 LOCK_DEV_OPS(&(dnp->dn_lock)); 6918 for (dip = dnp->dn_head; dip; 6919 dip = (dev_info_t *)DEVI(dip)->devi_next) { 6920 /* skip node if instance field is not valid */ 6921 if (i_ddi_node_state(dip) < DS_INITIALIZED) 6922 continue; 6923 6924 /* look for instance match */ 6925 if (DEVI(dip)->devi_instance == instance) { 6926 /* 6927 * To accommodate callers that can't block in 6928 * ndi_devi_enter() we do an ndi_hold_devi(), and 6929 * afterwards check that the node is in a state where 6930 * the hold prevents detach(). If we did not manage to 6931 * prevent detach then we ndi_rele_devi() and perform 6932 * the slow path below (which can result in a blocking 6933 * ndi_devi_enter() while driving attach top-down). 6934 * This code depends on the ordering of 6935 * DEVI_SET_DETACHING and the devi_ref check in the 6936 * detach_node() code path. 6937 */ 6938 ndi_hold_devi(dip); 6939 if (i_ddi_devi_attached(dip) && 6940 !DEVI_IS_DETACHING(dip)) { 6941 UNLOCK_DEV_OPS(&(dnp->dn_lock)); 6942 return (dip); /* fast-path with devi held */ 6943 } 6944 ndi_rele_devi(dip); 6945 6946 /* try slow-path */ 6947 dip = NULL; 6948 break; 6949 } 6950 } 6951 ASSERT(dip == NULL); 6952 UNLOCK_DEV_OPS(&(dnp->dn_lock)); 6953 6954 if (flags & E_DDI_HOLD_DEVI_NOATTACH) 6955 return (NULL); /* told not to drive attach */ 6956 6957 /* slow-path may block, so it should not occur from interrupt */ 6958 ASSERT(!servicing_interrupt()); 6959 if (servicing_interrupt()) 6960 return (NULL); 6961 6962 /* reconstruct the path and drive attach by path through devfs. */ 6963 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 6964 if (e_ddi_majorinstance_to_path(major, instance, path) == 0) { 6965 dip = e_ddi_hold_devi_by_path(path, flags); 6966 6967 /* 6968 * Verify that we got the correct device - a path_to_inst file 6969 * with a bogus/corrupt path (or a nexus that changes its 6970 * unit-address format) could result in an incorrect answer 6971 * 6972 * Verify major, instance, and path. 6973 */ 6974 vpath = kmem_alloc(MAXPATHLEN, KM_SLEEP); 6975 if (dip && 6976 ((DEVI(dip)->devi_major != major) || 6977 ((DEVI(dip)->devi_instance != instance)) || 6978 (strcmp(path, ddi_pathname(dip, vpath)) != 0))) { 6979 ndi_rele_devi(dip); 6980 dip = NULL; /* no answer better than wrong answer */ 6981 } 6982 kmem_free(vpath, MAXPATHLEN); 6983 } 6984 kmem_free(path, MAXPATHLEN); 6985 return (dip); /* with devi held */ 6986 } 6987 6988 /* 6989 * The {e_}ddi_hold_devi{_by_{instance|dev|path}} hold the devinfo node 6990 * associated with the specified arguments. This hold should be released 6991 * by calling ddi_release_devi. 6992 * 6993 * The E_DDI_HOLD_DEVI_NOATTACH flag argument allows the caller to to specify 6994 * a failure return if the node is not already attached. 6995 * 6996 * NOTE: by the time we make e_ddi_hold_devi public, we should be able to reuse 6997 * ddi_hold_devi again. 6998 */ 6999 dev_info_t * 7000 ddi_hold_devi_by_instance(major_t major, int instance, int flags) 7001 { 7002 return (hold_devi(major, instance, flags)); 7003 } 7004 7005 dev_info_t * 7006 e_ddi_hold_devi_by_dev(dev_t dev, int flags) 7007 { 7008 major_t major = getmajor(dev); 7009 dev_info_t *dip; 7010 struct dev_ops *ops; 7011 dev_info_t *ddip = NULL; 7012 7013 dip = hold_devi(major, dev_to_instance(dev), flags); 7014 7015 /* 7016 * The rest of this routine is legacy support for drivers that 7017 * have broken DDI_INFO_DEVT2INSTANCE implementations but may have 7018 * functional DDI_INFO_DEVT2DEVINFO implementations. This code will 7019 * diagnose inconsistency and, for maximum compatibility with legacy 7020 * drivers, give preference to the drivers DDI_INFO_DEVT2DEVINFO 7021 * implementation over the above derived dip based the driver's 7022 * DDI_INFO_DEVT2INSTANCE implementation. This legacy support should 7023 * be removed when DDI_INFO_DEVT2DEVINFO is deprecated. 7024 * 7025 * NOTE: The following code has a race condition. DEVT2DEVINFO 7026 * returns a dip which is not held. By the time we ref ddip, 7027 * it could have been freed. The saving grace is that for 7028 * most drivers, the dip returned from hold_devi() is the 7029 * same one as the one returned by DEVT2DEVINFO, so we are 7030 * safe for drivers with the correct getinfo(9e) impl. 7031 */ 7032 if (((ops = ddi_hold_driver(major)) != NULL) && 7033 CB_DRV_INSTALLED(ops) && ops->devo_getinfo) { 7034 if ((*ops->devo_getinfo)(NULL, DDI_INFO_DEVT2DEVINFO, 7035 (void *)dev, (void **)&ddip) != DDI_SUCCESS) 7036 ddip = NULL; 7037 } 7038 7039 /* give preference to the driver returned DEVT2DEVINFO dip */ 7040 if (ddip && (dip != ddip)) { 7041 #ifdef DEBUG 7042 cmn_err(CE_WARN, "%s: inconsistent getinfo(9E) implementation", 7043 ddi_driver_name(ddip)); 7044 #endif /* DEBUG */ 7045 ndi_hold_devi(ddip); 7046 if (dip) 7047 ndi_rele_devi(dip); 7048 dip = ddip; 7049 } 7050 7051 if (ops) 7052 ddi_rele_driver(major); 7053 7054 return (dip); 7055 } 7056 7057 /* 7058 * For compatibility only. Do not call this function! 7059 */ 7060 dev_info_t * 7061 e_ddi_get_dev_info(dev_t dev, vtype_t type) 7062 { 7063 dev_info_t *dip = NULL; 7064 if (getmajor(dev) >= devcnt) 7065 return (NULL); 7066 7067 switch (type) { 7068 case VCHR: 7069 case VBLK: 7070 dip = e_ddi_hold_devi_by_dev(dev, 0); 7071 default: 7072 break; 7073 } 7074 7075 /* 7076 * For compatibility reasons, we can only return the dip with 7077 * the driver ref count held. This is not a safe thing to do. 7078 * For certain broken third-party software, we are willing 7079 * to venture into unknown territory. 7080 */ 7081 if (dip) { 7082 (void) ndi_hold_driver(dip); 7083 ndi_rele_devi(dip); 7084 } 7085 return (dip); 7086 } 7087 7088 dev_info_t * 7089 e_ddi_hold_devi_by_path(char *path, int flags) 7090 { 7091 dev_info_t *dip; 7092 7093 /* can't specify NOATTACH by path */ 7094 ASSERT(!(flags & E_DDI_HOLD_DEVI_NOATTACH)); 7095 7096 return (resolve_pathname(path, &dip, NULL, NULL) ? NULL : dip); 7097 } 7098 7099 void 7100 e_ddi_hold_devi(dev_info_t *dip) 7101 { 7102 ndi_hold_devi(dip); 7103 } 7104 7105 void 7106 ddi_release_devi(dev_info_t *dip) 7107 { 7108 ndi_rele_devi(dip); 7109 } 7110 7111 /* 7112 * Associate a streams queue with a devinfo node 7113 * NOTE: This function is called by STREAM driver's put procedure. 7114 * It cannot block. 7115 */ 7116 void 7117 ddi_assoc_queue_with_devi(queue_t *q, dev_info_t *dip) 7118 { 7119 queue_t *rq = _RD(q); 7120 struct stdata *stp; 7121 vnode_t *vp; 7122 7123 /* set flag indicating that ddi_assoc_queue_with_devi was called */ 7124 mutex_enter(QLOCK(rq)); 7125 rq->q_flag |= _QASSOCIATED; 7126 mutex_exit(QLOCK(rq)); 7127 7128 /* get the vnode associated with the queue */ 7129 stp = STREAM(rq); 7130 vp = stp->sd_vnode; 7131 ASSERT(vp); 7132 7133 /* change the hardware association of the vnode */ 7134 spec_assoc_vp_with_devi(vp, dip); 7135 } 7136 7137 /* 7138 * ddi_install_driver(name) 7139 * 7140 * Driver installation is currently a byproduct of driver loading. This 7141 * may change. 7142 */ 7143 int 7144 ddi_install_driver(char *name) 7145 { 7146 major_t major = ddi_name_to_major(name); 7147 7148 if ((major == DDI_MAJOR_T_NONE) || 7149 (ddi_hold_installed_driver(major) == NULL)) { 7150 return (DDI_FAILURE); 7151 } 7152 ddi_rele_driver(major); 7153 return (DDI_SUCCESS); 7154 } 7155 7156 struct dev_ops * 7157 ddi_hold_driver(major_t major) 7158 { 7159 return (mod_hold_dev_by_major(major)); 7160 } 7161 7162 7163 void 7164 ddi_rele_driver(major_t major) 7165 { 7166 mod_rele_dev_by_major(major); 7167 } 7168 7169 7170 /* 7171 * This is called during boot to force attachment order of special dips 7172 * dip must be referenced via ndi_hold_devi() 7173 */ 7174 int 7175 i_ddi_attach_node_hierarchy(dev_info_t *dip) 7176 { 7177 dev_info_t *parent; 7178 int ret, circ; 7179 7180 /* 7181 * Recurse up until attached parent is found. 7182 */ 7183 if (i_ddi_devi_attached(dip)) 7184 return (DDI_SUCCESS); 7185 parent = ddi_get_parent(dip); 7186 if (i_ddi_attach_node_hierarchy(parent) != DDI_SUCCESS) 7187 return (DDI_FAILURE); 7188 7189 /* 7190 * Come top-down, expanding .conf nodes under this parent 7191 * and driving attach. 7192 */ 7193 ndi_devi_enter(parent, &circ); 7194 (void) i_ndi_make_spec_children(parent, 0); 7195 ret = i_ddi_attachchild(dip); 7196 ndi_devi_exit(parent, circ); 7197 7198 return (ret); 7199 } 7200 7201 /* keep this function static */ 7202 static int 7203 attach_driver_nodes(major_t major) 7204 { 7205 struct devnames *dnp; 7206 dev_info_t *dip; 7207 int error = DDI_FAILURE; 7208 7209 dnp = &devnamesp[major]; 7210 LOCK_DEV_OPS(&dnp->dn_lock); 7211 dip = dnp->dn_head; 7212 while (dip) { 7213 ndi_hold_devi(dip); 7214 UNLOCK_DEV_OPS(&dnp->dn_lock); 7215 if (i_ddi_attach_node_hierarchy(dip) == DDI_SUCCESS) 7216 error = DDI_SUCCESS; 7217 /* 7218 * Set the 'ddi-config-driver-node' property on a nexus 7219 * node to cause attach_driver_nodes() to configure all 7220 * immediate children of the nexus. This property should 7221 * be set on nodes with immediate children that bind to 7222 * the same driver as parent. 7223 */ 7224 if ((error == DDI_SUCCESS) && (ddi_prop_exists(DDI_DEV_T_ANY, 7225 dip, DDI_PROP_DONTPASS, "ddi-config-driver-node"))) { 7226 (void) ndi_devi_config(dip, NDI_NO_EVENT); 7227 } 7228 LOCK_DEV_OPS(&dnp->dn_lock); 7229 ndi_rele_devi(dip); 7230 dip = ddi_get_next(dip); 7231 } 7232 if (error == DDI_SUCCESS) 7233 dnp->dn_flags |= DN_NO_AUTODETACH; 7234 UNLOCK_DEV_OPS(&dnp->dn_lock); 7235 7236 7237 return (error); 7238 } 7239 7240 /* 7241 * i_ddi_attach_hw_nodes configures and attaches all hw nodes 7242 * bound to a specific driver. This function replaces calls to 7243 * ddi_hold_installed_driver() for drivers with no .conf 7244 * enumerated nodes. 7245 * 7246 * This facility is typically called at boot time to attach 7247 * platform-specific hardware nodes, such as ppm nodes on xcal 7248 * and grover and keyswitch nodes on cherrystone. It does not 7249 * deal with .conf enumerated node. Calling it beyond the boot 7250 * process is strongly discouraged. 7251 */ 7252 int 7253 i_ddi_attach_hw_nodes(char *driver) 7254 { 7255 major_t major; 7256 7257 major = ddi_name_to_major(driver); 7258 if (major == DDI_MAJOR_T_NONE) 7259 return (DDI_FAILURE); 7260 7261 return (attach_driver_nodes(major)); 7262 } 7263 7264 /* 7265 * i_ddi_attach_pseudo_node configures pseudo drivers which 7266 * has a single node. The .conf nodes must be enumerated 7267 * before calling this interface. The dip is held attached 7268 * upon returning. 7269 * 7270 * This facility should only be called only at boot time 7271 * by the I/O framework. 7272 */ 7273 dev_info_t * 7274 i_ddi_attach_pseudo_node(char *driver) 7275 { 7276 major_t major; 7277 dev_info_t *dip; 7278 7279 major = ddi_name_to_major(driver); 7280 if (major == DDI_MAJOR_T_NONE) 7281 return (NULL); 7282 7283 if (attach_driver_nodes(major) != DDI_SUCCESS) 7284 return (NULL); 7285 7286 dip = devnamesp[major].dn_head; 7287 ASSERT(dip && ddi_get_next(dip) == NULL); 7288 ndi_hold_devi(dip); 7289 return (dip); 7290 } 7291 7292 static void 7293 diplist_to_parent_major(dev_info_t *head, char parents[]) 7294 { 7295 major_t major; 7296 dev_info_t *dip, *pdip; 7297 7298 for (dip = head; dip != NULL; dip = ddi_get_next(dip)) { 7299 pdip = ddi_get_parent(dip); 7300 ASSERT(pdip); /* disallow rootnex.conf nodes */ 7301 major = ddi_driver_major(pdip); 7302 if ((major != DDI_MAJOR_T_NONE) && parents[major] == 0) 7303 parents[major] = 1; 7304 } 7305 } 7306 7307 /* 7308 * Call ddi_hold_installed_driver() on each parent major 7309 * and invoke mt_config_driver() to attach child major. 7310 * This is part of the implementation of ddi_hold_installed_driver. 7311 */ 7312 static int 7313 attach_driver_by_parent(major_t child_major, char parents[]) 7314 { 7315 major_t par_major; 7316 struct mt_config_handle *hdl; 7317 int flags = NDI_DEVI_PERSIST | NDI_NO_EVENT; 7318 7319 hdl = mt_config_init(NULL, NULL, flags, child_major, MT_CONFIG_OP, 7320 NULL); 7321 for (par_major = 0; par_major < devcnt; par_major++) { 7322 /* disallow recursion on the same driver */ 7323 if (parents[par_major] == 0 || par_major == child_major) 7324 continue; 7325 if (ddi_hold_installed_driver(par_major) == NULL) 7326 continue; 7327 hdl->mtc_parmajor = par_major; 7328 mt_config_driver(hdl); 7329 ddi_rele_driver(par_major); 7330 } 7331 (void) mt_config_fini(hdl); 7332 7333 return (i_ddi_devs_attached(child_major)); 7334 } 7335 7336 int 7337 i_ddi_devs_attached(major_t major) 7338 { 7339 dev_info_t *dip; 7340 struct devnames *dnp; 7341 int error = DDI_FAILURE; 7342 7343 /* check for attached instances */ 7344 dnp = &devnamesp[major]; 7345 LOCK_DEV_OPS(&dnp->dn_lock); 7346 for (dip = dnp->dn_head; dip != NULL; dip = ddi_get_next(dip)) { 7347 if (i_ddi_devi_attached(dip)) { 7348 error = DDI_SUCCESS; 7349 break; 7350 } 7351 } 7352 UNLOCK_DEV_OPS(&dnp->dn_lock); 7353 7354 return (error); 7355 } 7356 7357 int 7358 i_ddi_minor_node_count(dev_info_t *ddip, const char *node_type) 7359 { 7360 int circ; 7361 struct ddi_minor_data *dp; 7362 int count = 0; 7363 7364 ndi_devi_enter(ddip, &circ); 7365 for (dp = DEVI(ddip)->devi_minor; dp != NULL; dp = dp->next) { 7366 if (strcmp(dp->ddm_node_type, node_type) == 0) 7367 count++; 7368 } 7369 ndi_devi_exit(ddip, circ); 7370 return (count); 7371 } 7372 7373 /* 7374 * ddi_hold_installed_driver configures and attaches all 7375 * instances of the specified driver. To accomplish this 7376 * it configures and attaches all possible parents of 7377 * the driver, enumerated both in h/w nodes and in the 7378 * driver's .conf file. 7379 * 7380 * NOTE: This facility is for compatibility purposes only and will 7381 * eventually go away. Its usage is strongly discouraged. 7382 */ 7383 static void 7384 enter_driver(struct devnames *dnp) 7385 { 7386 mutex_enter(&dnp->dn_lock); 7387 ASSERT(dnp->dn_busy_thread != curthread); 7388 while (dnp->dn_flags & DN_DRIVER_BUSY) 7389 cv_wait(&dnp->dn_wait, &dnp->dn_lock); 7390 dnp->dn_flags |= DN_DRIVER_BUSY; 7391 dnp->dn_busy_thread = curthread; 7392 mutex_exit(&dnp->dn_lock); 7393 } 7394 7395 static void 7396 exit_driver(struct devnames *dnp) 7397 { 7398 mutex_enter(&dnp->dn_lock); 7399 ASSERT(dnp->dn_busy_thread == curthread); 7400 dnp->dn_flags &= ~DN_DRIVER_BUSY; 7401 dnp->dn_busy_thread = NULL; 7402 cv_broadcast(&dnp->dn_wait); 7403 mutex_exit(&dnp->dn_lock); 7404 } 7405 7406 struct dev_ops * 7407 ddi_hold_installed_driver(major_t major) 7408 { 7409 struct dev_ops *ops; 7410 struct devnames *dnp; 7411 char *parents; 7412 int error; 7413 7414 ops = ddi_hold_driver(major); 7415 if (ops == NULL) 7416 return (NULL); 7417 7418 /* 7419 * Return immediately if all the attach operations associated 7420 * with a ddi_hold_installed_driver() call have already been done. 7421 */ 7422 dnp = &devnamesp[major]; 7423 enter_driver(dnp); 7424 ASSERT(driver_active(major)); 7425 7426 if (dnp->dn_flags & DN_DRIVER_HELD) { 7427 exit_driver(dnp); 7428 if (i_ddi_devs_attached(major) == DDI_SUCCESS) 7429 return (ops); 7430 ddi_rele_driver(major); 7431 return (NULL); 7432 } 7433 7434 LOCK_DEV_OPS(&dnp->dn_lock); 7435 dnp->dn_flags |= (DN_DRIVER_HELD | DN_NO_AUTODETACH); 7436 UNLOCK_DEV_OPS(&dnp->dn_lock); 7437 7438 DCOMPATPRINTF((CE_CONT, 7439 "ddi_hold_installed_driver: %s\n", dnp->dn_name)); 7440 7441 /* 7442 * When the driver has no .conf children, it is sufficient 7443 * to attach existing nodes in the device tree. Nodes not 7444 * enumerated by the OBP are not attached. 7445 */ 7446 if (dnp->dn_pl == NULL) { 7447 if (attach_driver_nodes(major) == DDI_SUCCESS) { 7448 exit_driver(dnp); 7449 return (ops); 7450 } 7451 exit_driver(dnp); 7452 ddi_rele_driver(major); 7453 return (NULL); 7454 } 7455 7456 /* 7457 * Driver has .conf nodes. We find all possible parents 7458 * and recursively all ddi_hold_installed_driver on the 7459 * parent driver; then we invoke ndi_config_driver() 7460 * on all possible parent node in parallel to speed up 7461 * performance. 7462 */ 7463 parents = kmem_zalloc(devcnt * sizeof (char), KM_SLEEP); 7464 7465 LOCK_DEV_OPS(&dnp->dn_lock); 7466 /* find .conf parents */ 7467 (void) impl_parlist_to_major(dnp->dn_pl, parents); 7468 /* find hw node parents */ 7469 diplist_to_parent_major(dnp->dn_head, parents); 7470 UNLOCK_DEV_OPS(&dnp->dn_lock); 7471 7472 error = attach_driver_by_parent(major, parents); 7473 kmem_free(parents, devcnt * sizeof (char)); 7474 if (error == DDI_SUCCESS) { 7475 exit_driver(dnp); 7476 return (ops); 7477 } 7478 7479 exit_driver(dnp); 7480 ddi_rele_driver(major); 7481 return (NULL); 7482 } 7483 7484 /* 7485 * Default bus_config entry point for nexus drivers 7486 */ 7487 int 7488 ndi_busop_bus_config(dev_info_t *pdip, uint_t flags, ddi_bus_config_op_t op, 7489 void *arg, dev_info_t **child, clock_t timeout) 7490 { 7491 major_t major; 7492 7493 /* 7494 * A timeout of 30 minutes or more is probably a mistake 7495 * This is intended to catch uses where timeout is in 7496 * the wrong units. timeout must be in units of ticks. 7497 */ 7498 ASSERT(timeout < SEC_TO_TICK(1800)); 7499 7500 major = DDI_MAJOR_T_NONE; 7501 switch (op) { 7502 case BUS_CONFIG_ONE: 7503 NDI_DEBUG(flags, (CE_CONT, "%s%d: bus config %s timeout=%ld\n", 7504 ddi_driver_name(pdip), ddi_get_instance(pdip), 7505 (char *)arg, timeout)); 7506 return (devi_config_one(pdip, (char *)arg, child, flags, 7507 timeout)); 7508 7509 case BUS_CONFIG_DRIVER: 7510 major = (major_t)(uintptr_t)arg; 7511 /*FALLTHROUGH*/ 7512 case BUS_CONFIG_ALL: 7513 NDI_DEBUG(flags, (CE_CONT, "%s%d: bus config timeout=%ld\n", 7514 ddi_driver_name(pdip), ddi_get_instance(pdip), 7515 timeout)); 7516 if (timeout > 0) { 7517 NDI_DEBUG(flags, (CE_CONT, 7518 "%s%d: bus config all timeout=%ld\n", 7519 ddi_driver_name(pdip), ddi_get_instance(pdip), 7520 timeout)); 7521 delay(timeout); 7522 } 7523 return (config_immediate_children(pdip, flags, major)); 7524 7525 default: 7526 return (NDI_FAILURE); 7527 } 7528 /*NOTREACHED*/ 7529 } 7530 7531 /* 7532 * Default busop bus_unconfig handler for nexus drivers 7533 */ 7534 int 7535 ndi_busop_bus_unconfig(dev_info_t *pdip, uint_t flags, ddi_bus_config_op_t op, 7536 void *arg) 7537 { 7538 major_t major; 7539 7540 major = DDI_MAJOR_T_NONE; 7541 switch (op) { 7542 case BUS_UNCONFIG_ONE: 7543 NDI_DEBUG(flags, (CE_CONT, "%s%d: bus unconfig %s\n", 7544 ddi_driver_name(pdip), ddi_get_instance(pdip), 7545 (char *)arg)); 7546 return (devi_unconfig_one(pdip, (char *)arg, flags)); 7547 7548 case BUS_UNCONFIG_DRIVER: 7549 major = (major_t)(uintptr_t)arg; 7550 /*FALLTHROUGH*/ 7551 case BUS_UNCONFIG_ALL: 7552 NDI_DEBUG(flags, (CE_CONT, "%s%d: bus unconfig all\n", 7553 ddi_driver_name(pdip), ddi_get_instance(pdip))); 7554 return (unconfig_immediate_children(pdip, NULL, flags, major)); 7555 7556 default: 7557 return (NDI_FAILURE); 7558 } 7559 /*NOTREACHED*/ 7560 } 7561 7562 /* 7563 * dummy functions to be removed 7564 */ 7565 void 7566 impl_rem_dev_props(dev_info_t *dip) 7567 { 7568 _NOTE(ARGUNUSED(dip)) 7569 /* do nothing */ 7570 } 7571 7572 /* 7573 * Determine if a node is a leaf node. If not sure, return false (0). 7574 */ 7575 static int 7576 is_leaf_node(dev_info_t *dip) 7577 { 7578 major_t major = ddi_driver_major(dip); 7579 7580 if (major == DDI_MAJOR_T_NONE) 7581 return (0); 7582 7583 return (devnamesp[major].dn_flags & DN_LEAF_DRIVER); 7584 } 7585 7586 /* 7587 * Multithreaded [un]configuration 7588 */ 7589 static struct mt_config_handle * 7590 mt_config_init(dev_info_t *pdip, dev_info_t **dipp, int flags, 7591 major_t major, int op, struct brevq_node **brevqp) 7592 { 7593 struct mt_config_handle *hdl = kmem_alloc(sizeof (*hdl), KM_SLEEP); 7594 7595 mutex_init(&hdl->mtc_lock, NULL, MUTEX_DEFAULT, NULL); 7596 cv_init(&hdl->mtc_cv, NULL, CV_DEFAULT, NULL); 7597 hdl->mtc_pdip = pdip; 7598 hdl->mtc_fdip = dipp; 7599 hdl->mtc_parmajor = DDI_MAJOR_T_NONE; 7600 hdl->mtc_flags = flags; 7601 hdl->mtc_major = major; 7602 hdl->mtc_thr_count = 0; 7603 hdl->mtc_op = op; 7604 hdl->mtc_error = 0; 7605 hdl->mtc_brevqp = brevqp; 7606 7607 #ifdef DEBUG 7608 gethrestime(&hdl->start_time); 7609 hdl->total_time = 0; 7610 #endif /* DEBUG */ 7611 7612 return (hdl); 7613 } 7614 7615 #ifdef DEBUG 7616 static int 7617 time_diff_in_msec(timestruc_t start, timestruc_t end) 7618 { 7619 int nsec, sec; 7620 7621 sec = end.tv_sec - start.tv_sec; 7622 nsec = end.tv_nsec - start.tv_nsec; 7623 if (nsec < 0) { 7624 nsec += NANOSEC; 7625 sec -= 1; 7626 } 7627 7628 return (sec * (NANOSEC >> 20) + (nsec >> 20)); 7629 } 7630 7631 #endif /* DEBUG */ 7632 7633 static int 7634 mt_config_fini(struct mt_config_handle *hdl) 7635 { 7636 int rv; 7637 #ifdef DEBUG 7638 int real_time; 7639 timestruc_t end_time; 7640 #endif /* DEBUG */ 7641 7642 mutex_enter(&hdl->mtc_lock); 7643 while (hdl->mtc_thr_count > 0) 7644 cv_wait(&hdl->mtc_cv, &hdl->mtc_lock); 7645 rv = hdl->mtc_error; 7646 mutex_exit(&hdl->mtc_lock); 7647 7648 #ifdef DEBUG 7649 gethrestime(&end_time); 7650 real_time = time_diff_in_msec(hdl->start_time, end_time); 7651 if ((ddidebug & DDI_MTCONFIG) && hdl->mtc_pdip) 7652 cmn_err(CE_NOTE, 7653 "config %s%d: total time %d msec, real time %d msec", 7654 ddi_driver_name(hdl->mtc_pdip), 7655 ddi_get_instance(hdl->mtc_pdip), 7656 hdl->total_time, real_time); 7657 #endif /* DEBUG */ 7658 7659 cv_destroy(&hdl->mtc_cv); 7660 mutex_destroy(&hdl->mtc_lock); 7661 kmem_free(hdl, sizeof (*hdl)); 7662 7663 return (rv); 7664 } 7665 7666 struct mt_config_data { 7667 struct mt_config_handle *mtc_hdl; 7668 dev_info_t *mtc_dip; 7669 major_t mtc_major; 7670 int mtc_flags; 7671 struct brevq_node *mtc_brn; 7672 struct mt_config_data *mtc_next; 7673 }; 7674 7675 static void 7676 mt_config_thread(void *arg) 7677 { 7678 struct mt_config_data *mcd = (struct mt_config_data *)arg; 7679 struct mt_config_handle *hdl = mcd->mtc_hdl; 7680 dev_info_t *dip = mcd->mtc_dip; 7681 dev_info_t *rdip, **dipp; 7682 major_t major = mcd->mtc_major; 7683 int flags = mcd->mtc_flags; 7684 int rv = 0; 7685 7686 #ifdef DEBUG 7687 timestruc_t start_time, end_time; 7688 gethrestime(&start_time); 7689 #endif /* DEBUG */ 7690 7691 rdip = NULL; 7692 dipp = hdl->mtc_fdip ? &rdip : NULL; 7693 7694 switch (hdl->mtc_op) { 7695 case MT_CONFIG_OP: 7696 rv = devi_config_common(dip, flags, major); 7697 break; 7698 case MT_UNCONFIG_OP: 7699 if (mcd->mtc_brn) { 7700 struct brevq_node *brevq = NULL; 7701 rv = devi_unconfig_common(dip, dipp, flags, major, 7702 &brevq); 7703 mcd->mtc_brn->brn_child = brevq; 7704 } else 7705 rv = devi_unconfig_common(dip, dipp, flags, major, 7706 NULL); 7707 break; 7708 } 7709 7710 mutex_enter(&hdl->mtc_lock); 7711 #ifdef DEBUG 7712 gethrestime(&end_time); 7713 hdl->total_time += time_diff_in_msec(start_time, end_time); 7714 #endif /* DEBUG */ 7715 7716 if ((rv != NDI_SUCCESS) && (hdl->mtc_error == 0)) { 7717 hdl->mtc_error = rv; 7718 #ifdef DEBUG 7719 if ((ddidebug & DDI_DEBUG) && (major != DDI_MAJOR_T_NONE)) { 7720 char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 7721 7722 (void) ddi_pathname(dip, path); 7723 cmn_err(CE_NOTE, "mt_config_thread: " 7724 "op %d.%d.%x at %s failed %d", 7725 hdl->mtc_op, major, flags, path, rv); 7726 kmem_free(path, MAXPATHLEN); 7727 } 7728 #endif /* DEBUG */ 7729 } 7730 7731 if (hdl->mtc_fdip && *hdl->mtc_fdip == NULL) { 7732 *hdl->mtc_fdip = rdip; 7733 rdip = NULL; 7734 } 7735 7736 if (rdip) { 7737 ASSERT(rv != NDI_SUCCESS); 7738 ndi_rele_devi(rdip); 7739 } 7740 7741 ndi_rele_devi(dip); 7742 7743 if (--hdl->mtc_thr_count == 0) 7744 cv_broadcast(&hdl->mtc_cv); 7745 mutex_exit(&hdl->mtc_lock); 7746 kmem_free(mcd, sizeof (*mcd)); 7747 } 7748 7749 /* 7750 * Multi-threaded config/unconfig of child nexus 7751 */ 7752 static void 7753 mt_config_children(struct mt_config_handle *hdl) 7754 { 7755 dev_info_t *pdip = hdl->mtc_pdip; 7756 major_t major = hdl->mtc_major; 7757 dev_info_t *dip; 7758 int circ; 7759 struct brevq_node *brn; 7760 struct mt_config_data *mcd_head = NULL; 7761 struct mt_config_data *mcd_tail = NULL; 7762 struct mt_config_data *mcd; 7763 #ifdef DEBUG 7764 timestruc_t end_time; 7765 7766 /* Update total_time in handle */ 7767 gethrestime(&end_time); 7768 hdl->total_time += time_diff_in_msec(hdl->start_time, end_time); 7769 #endif 7770 7771 ndi_devi_enter(pdip, &circ); 7772 dip = ddi_get_child(pdip); 7773 while (dip) { 7774 if (hdl->mtc_op == MT_UNCONFIG_OP && hdl->mtc_brevqp && 7775 !(DEVI_EVREMOVE(dip)) && 7776 i_ddi_node_state(dip) >= DS_INITIALIZED) { 7777 /* 7778 * Enqueue this dip's deviname. 7779 * No need to hold a lock while enqueuing since this 7780 * is the only thread doing the enqueue and no one 7781 * walks the queue while we are in multithreaded 7782 * unconfiguration. 7783 */ 7784 brn = brevq_enqueue(hdl->mtc_brevqp, dip, NULL); 7785 } else 7786 brn = NULL; 7787 7788 /* 7789 * Hold the child that we are processing so it does not get 7790 * removed. The corrisponding ndi_rele_devi() for children 7791 * that are not being skipped is done at the end of 7792 * mt_config_thread(). 7793 */ 7794 ndi_hold_devi(dip); 7795 7796 /* 7797 * skip leaf nodes and (for configure) nodes not 7798 * fully attached. 7799 */ 7800 if (is_leaf_node(dip) || 7801 (hdl->mtc_op == MT_CONFIG_OP && 7802 i_ddi_node_state(dip) < DS_READY)) { 7803 ndi_rele_devi(dip); 7804 dip = ddi_get_next_sibling(dip); 7805 continue; 7806 } 7807 7808 mcd = kmem_alloc(sizeof (*mcd), KM_SLEEP); 7809 mcd->mtc_dip = dip; 7810 mcd->mtc_hdl = hdl; 7811 mcd->mtc_brn = brn; 7812 7813 /* 7814 * Switch a 'driver' operation to an 'all' operation below a 7815 * node bound to the driver. 7816 */ 7817 if ((major == DDI_MAJOR_T_NONE) || 7818 (major == ddi_driver_major(dip))) 7819 mcd->mtc_major = DDI_MAJOR_T_NONE; 7820 else 7821 mcd->mtc_major = major; 7822 7823 /* 7824 * The unconfig-driver to unconfig-all conversion above 7825 * constitutes an autodetach for NDI_DETACH_DRIVER calls, 7826 * set NDI_AUTODETACH. 7827 */ 7828 mcd->mtc_flags = hdl->mtc_flags; 7829 if ((mcd->mtc_flags & NDI_DETACH_DRIVER) && 7830 (hdl->mtc_op == MT_UNCONFIG_OP) && 7831 (major == ddi_driver_major(pdip))) 7832 mcd->mtc_flags |= NDI_AUTODETACH; 7833 7834 mutex_enter(&hdl->mtc_lock); 7835 hdl->mtc_thr_count++; 7836 mutex_exit(&hdl->mtc_lock); 7837 7838 /* 7839 * Add to end of list to process after ndi_devi_exit to avoid 7840 * locking differences depending on value of mtc_off. 7841 */ 7842 mcd->mtc_next = NULL; 7843 if (mcd_head == NULL) 7844 mcd_head = mcd; 7845 else 7846 mcd_tail->mtc_next = mcd; 7847 mcd_tail = mcd; 7848 7849 dip = ddi_get_next_sibling(dip); 7850 } 7851 ndi_devi_exit(pdip, circ); 7852 7853 /* go through the list of held children */ 7854 for (mcd = mcd_head; mcd; mcd = mcd_head) { 7855 mcd_head = mcd->mtc_next; 7856 if (mtc_off || (mcd->mtc_flags & NDI_MTC_OFF)) 7857 mt_config_thread(mcd); 7858 else 7859 (void) thread_create(NULL, 0, mt_config_thread, mcd, 7860 0, &p0, TS_RUN, minclsyspri); 7861 } 7862 } 7863 7864 static void 7865 mt_config_driver(struct mt_config_handle *hdl) 7866 { 7867 major_t par_major = hdl->mtc_parmajor; 7868 major_t major = hdl->mtc_major; 7869 struct devnames *dnp = &devnamesp[par_major]; 7870 dev_info_t *dip; 7871 struct mt_config_data *mcd_head = NULL; 7872 struct mt_config_data *mcd_tail = NULL; 7873 struct mt_config_data *mcd; 7874 #ifdef DEBUG 7875 timestruc_t end_time; 7876 7877 /* Update total_time in handle */ 7878 gethrestime(&end_time); 7879 hdl->total_time += time_diff_in_msec(hdl->start_time, end_time); 7880 #endif 7881 ASSERT(par_major != DDI_MAJOR_T_NONE); 7882 ASSERT(major != DDI_MAJOR_T_NONE); 7883 7884 LOCK_DEV_OPS(&dnp->dn_lock); 7885 dip = devnamesp[par_major].dn_head; 7886 while (dip) { 7887 /* 7888 * Hold the child that we are processing so it does not get 7889 * removed. The corrisponding ndi_rele_devi() for children 7890 * that are not being skipped is done at the end of 7891 * mt_config_thread(). 7892 */ 7893 ndi_hold_devi(dip); 7894 7895 /* skip leaf nodes and nodes not fully attached */ 7896 if (!i_ddi_devi_attached(dip) || is_leaf_node(dip)) { 7897 ndi_rele_devi(dip); 7898 dip = ddi_get_next(dip); 7899 continue; 7900 } 7901 7902 mcd = kmem_alloc(sizeof (*mcd), KM_SLEEP); 7903 mcd->mtc_dip = dip; 7904 mcd->mtc_hdl = hdl; 7905 mcd->mtc_major = major; 7906 mcd->mtc_flags = hdl->mtc_flags; 7907 7908 mutex_enter(&hdl->mtc_lock); 7909 hdl->mtc_thr_count++; 7910 mutex_exit(&hdl->mtc_lock); 7911 7912 /* 7913 * Add to end of list to process after UNLOCK_DEV_OPS to avoid 7914 * locking differences depending on value of mtc_off. 7915 */ 7916 mcd->mtc_next = NULL; 7917 if (mcd_head == NULL) 7918 mcd_head = mcd; 7919 else 7920 mcd_tail->mtc_next = mcd; 7921 mcd_tail = mcd; 7922 7923 dip = ddi_get_next(dip); 7924 } 7925 UNLOCK_DEV_OPS(&dnp->dn_lock); 7926 7927 /* go through the list of held children */ 7928 for (mcd = mcd_head; mcd; mcd = mcd_head) { 7929 mcd_head = mcd->mtc_next; 7930 if (mtc_off || (mcd->mtc_flags & NDI_MTC_OFF)) 7931 mt_config_thread(mcd); 7932 else 7933 (void) thread_create(NULL, 0, mt_config_thread, mcd, 7934 0, &p0, TS_RUN, minclsyspri); 7935 } 7936 } 7937 7938 /* 7939 * Given the nodeid for a persistent (PROM or SID) node, return 7940 * the corresponding devinfo node 7941 * NOTE: This function will return NULL for .conf nodeids. 7942 */ 7943 dev_info_t * 7944 e_ddi_nodeid_to_dip(pnode_t nodeid) 7945 { 7946 dev_info_t *dip = NULL; 7947 struct devi_nodeid *prev, *elem; 7948 7949 mutex_enter(&devimap->dno_lock); 7950 7951 prev = NULL; 7952 for (elem = devimap->dno_head; elem; elem = elem->next) { 7953 if (elem->nodeid == nodeid) { 7954 ndi_hold_devi(elem->dip); 7955 dip = elem->dip; 7956 break; 7957 } 7958 prev = elem; 7959 } 7960 7961 /* 7962 * Move to head for faster lookup next time 7963 */ 7964 if (elem && prev) { 7965 prev->next = elem->next; 7966 elem->next = devimap->dno_head; 7967 devimap->dno_head = elem; 7968 } 7969 7970 mutex_exit(&devimap->dno_lock); 7971 return (dip); 7972 } 7973 7974 static void 7975 free_cache_task(void *arg) 7976 { 7977 ASSERT(arg == NULL); 7978 7979 mutex_enter(&di_cache.cache_lock); 7980 7981 /* 7982 * The cache can be invalidated without holding the lock 7983 * but it can be made valid again only while the lock is held. 7984 * So if the cache is invalid when the lock is held, it will 7985 * stay invalid until lock is released. 7986 */ 7987 if (!di_cache.cache_valid) 7988 i_ddi_di_cache_free(&di_cache); 7989 7990 mutex_exit(&di_cache.cache_lock); 7991 7992 if (di_cache_debug) 7993 cmn_err(CE_NOTE, "system_taskq: di_cache freed"); 7994 } 7995 7996 extern int modrootloaded; 7997 7998 void 7999 i_ddi_di_cache_free(struct di_cache *cache) 8000 { 8001 int error; 8002 extern int sys_shutdown; 8003 8004 ASSERT(mutex_owned(&cache->cache_lock)); 8005 8006 if (cache->cache_size) { 8007 ASSERT(cache->cache_size > 0); 8008 ASSERT(cache->cache_data); 8009 8010 kmem_free(cache->cache_data, cache->cache_size); 8011 cache->cache_data = NULL; 8012 cache->cache_size = 0; 8013 8014 if (di_cache_debug) 8015 cmn_err(CE_NOTE, "i_ddi_di_cache_free: freed cachemem"); 8016 } else { 8017 ASSERT(cache->cache_data == NULL); 8018 if (di_cache_debug) 8019 cmn_err(CE_NOTE, "i_ddi_di_cache_free: NULL cache"); 8020 } 8021 8022 if (!modrootloaded || rootvp == NULL || 8023 vn_is_readonly(rootvp) || sys_shutdown) { 8024 if (di_cache_debug) { 8025 cmn_err(CE_WARN, "/ not mounted/RDONLY. Skip unlink"); 8026 } 8027 return; 8028 } 8029 8030 error = vn_remove(DI_CACHE_FILE, UIO_SYSSPACE, RMFILE); 8031 if (di_cache_debug && error && error != ENOENT) { 8032 cmn_err(CE_WARN, "%s: unlink failed: %d", DI_CACHE_FILE, error); 8033 } else if (di_cache_debug && !error) { 8034 cmn_err(CE_NOTE, "i_ddi_di_cache_free: unlinked cache file"); 8035 } 8036 } 8037 8038 void 8039 i_ddi_di_cache_invalidate() 8040 { 8041 int cache_valid; 8042 8043 if (!modrootloaded || !i_ddi_io_initialized()) { 8044 if (di_cache_debug) 8045 cmn_err(CE_NOTE, "I/O not inited. Skipping invalidate"); 8046 return; 8047 } 8048 8049 /* Increment devtree generation number. */ 8050 atomic_inc_ulong(&devtree_gen); 8051 8052 /* Invalidate the in-core cache and dispatch free on valid->invalid */ 8053 cache_valid = atomic_swap_uint(&di_cache.cache_valid, 0); 8054 if (cache_valid) { 8055 /* 8056 * This is an optimization to start cleaning up a cached 8057 * snapshot early. For this reason, it is OK for 8058 * taskq_dispatach to fail (and it is OK to not track calling 8059 * context relative to sleep, and assume NOSLEEP). 8060 */ 8061 (void) taskq_dispatch(system_taskq, free_cache_task, NULL, 8062 TQ_NOSLEEP); 8063 } 8064 8065 if (di_cache_debug) { 8066 cmn_err(CE_NOTE, "invalidation"); 8067 } 8068 } 8069 8070 8071 static void 8072 i_bind_vhci_node(dev_info_t *dip) 8073 { 8074 DEVI(dip)->devi_major = ddi_name_to_major(ddi_node_name(dip)); 8075 i_ddi_set_node_state(dip, DS_BOUND); 8076 } 8077 8078 static char vhci_node_addr[2]; 8079 8080 static int 8081 i_init_vhci_node(dev_info_t *dip) 8082 { 8083 add_global_props(dip); 8084 DEVI(dip)->devi_ops = ndi_hold_driver(dip); 8085 if (DEVI(dip)->devi_ops == NULL) 8086 return (-1); 8087 8088 DEVI(dip)->devi_instance = e_ddi_assign_instance(dip); 8089 e_ddi_keep_instance(dip); 8090 vhci_node_addr[0] = '\0'; 8091 ddi_set_name_addr(dip, vhci_node_addr); 8092 i_ddi_set_node_state(dip, DS_INITIALIZED); 8093 return (0); 8094 } 8095 8096 static void 8097 i_link_vhci_node(dev_info_t *dip) 8098 { 8099 ASSERT(MUTEX_HELD(&global_vhci_lock)); 8100 8101 /* 8102 * scsi_vhci should be kept left most of the device tree. 8103 */ 8104 if (scsi_vhci_dip) { 8105 DEVI(dip)->devi_sibling = DEVI(scsi_vhci_dip)->devi_sibling; 8106 DEVI(scsi_vhci_dip)->devi_sibling = DEVI(dip); 8107 } else { 8108 DEVI(dip)->devi_sibling = DEVI(top_devinfo)->devi_child; 8109 DEVI(top_devinfo)->devi_child = DEVI(dip); 8110 } 8111 } 8112 8113 8114 /* 8115 * This a special routine to enumerate vhci node (child of rootnex 8116 * node) without holding the ndi_devi_enter() lock. The device node 8117 * is allocated, initialized and brought into DS_READY state before 8118 * inserting into the device tree. The VHCI node is handcrafted 8119 * here to bring the node to DS_READY, similar to rootnex node. 8120 * 8121 * The global_vhci_lock protects linking the node into the device 8122 * as same lock is held before linking/unlinking any direct child 8123 * of rootnex children. 8124 * 8125 * This routine is a workaround to handle a possible deadlock 8126 * that occurs while trying to enumerate node in a different sub-tree 8127 * during _init/_attach entry points. 8128 */ 8129 /*ARGSUSED*/ 8130 dev_info_t * 8131 ndi_devi_config_vhci(char *drvname, int flags) 8132 { 8133 struct devnames *dnp; 8134 dev_info_t *dip; 8135 major_t major = ddi_name_to_major(drvname); 8136 8137 if (major == -1) 8138 return (NULL); 8139 8140 /* Make sure we create the VHCI node only once */ 8141 dnp = &devnamesp[major]; 8142 LOCK_DEV_OPS(&dnp->dn_lock); 8143 if (dnp->dn_head) { 8144 dip = dnp->dn_head; 8145 UNLOCK_DEV_OPS(&dnp->dn_lock); 8146 return (dip); 8147 } 8148 UNLOCK_DEV_OPS(&dnp->dn_lock); 8149 8150 /* Allocate the VHCI node */ 8151 ndi_devi_alloc_sleep(top_devinfo, drvname, DEVI_SID_NODEID, &dip); 8152 ndi_hold_devi(dip); 8153 8154 /* Mark the node as VHCI */ 8155 DEVI(dip)->devi_node_attributes |= DDI_VHCI_NODE; 8156 8157 i_ddi_add_devimap(dip); 8158 i_bind_vhci_node(dip); 8159 if (i_init_vhci_node(dip) == -1) { 8160 ndi_rele_devi(dip); 8161 (void) ndi_devi_free(dip); 8162 return (NULL); 8163 } 8164 8165 mutex_enter(&(DEVI(dip)->devi_lock)); 8166 DEVI_SET_ATTACHING(dip); 8167 mutex_exit(&(DEVI(dip)->devi_lock)); 8168 8169 if (devi_attach(dip, DDI_ATTACH) != DDI_SUCCESS) { 8170 cmn_err(CE_CONT, "Could not attach %s driver", drvname); 8171 e_ddi_free_instance(dip, vhci_node_addr); 8172 ndi_rele_devi(dip); 8173 (void) ndi_devi_free(dip); 8174 return (NULL); 8175 } 8176 mutex_enter(&(DEVI(dip)->devi_lock)); 8177 DEVI_CLR_ATTACHING(dip); 8178 mutex_exit(&(DEVI(dip)->devi_lock)); 8179 8180 mutex_enter(&global_vhci_lock); 8181 i_link_vhci_node(dip); 8182 mutex_exit(&global_vhci_lock); 8183 i_ddi_set_node_state(dip, DS_READY); 8184 8185 LOCK_DEV_OPS(&dnp->dn_lock); 8186 dnp->dn_flags |= DN_DRIVER_HELD; 8187 dnp->dn_head = dip; 8188 UNLOCK_DEV_OPS(&dnp->dn_lock); 8189 8190 i_ndi_devi_report_status_change(dip, NULL); 8191 8192 return (dip); 8193 } 8194 8195 /* 8196 * Maintain DEVI_DEVICE_REMOVED hotplug devi_state for remove/reinsert hotplug 8197 * of open devices. Currently, because of tight coupling between the devfs file 8198 * system and the Solaris device tree, a driver can't always make the device 8199 * tree state (esp devi_node_state) match device hardware hotplug state. Until 8200 * resolved, to overcome this deficiency we use the following interfaces that 8201 * maintain the DEVI_DEVICE_REMOVED devi_state status bit. These interface 8202 * report current state, and drive operation (like events and cache 8203 * invalidation) when a driver changes remove/insert state of an open device. 8204 * 8205 * The ndi_devi_device_isremoved() returns 1 if the device is currently removed. 8206 * 8207 * The ndi_devi_device_remove() interface declares the device as removed, and 8208 * returns 1 if there was a state change associated with this declaration. 8209 * 8210 * The ndi_devi_device_insert() declares the device as inserted, and returns 1 8211 * if there was a state change associated with this declaration. 8212 */ 8213 int 8214 ndi_devi_device_isremoved(dev_info_t *dip) 8215 { 8216 return (DEVI_IS_DEVICE_REMOVED(dip)); 8217 } 8218 8219 int 8220 ndi_devi_device_remove(dev_info_t *dip) 8221 { 8222 ASSERT(dip && ddi_get_parent(dip) && 8223 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 8224 8225 /* Return if already marked removed. */ 8226 if (ndi_devi_device_isremoved(dip)) 8227 return (0); 8228 8229 /* Mark the device as having been physically removed. */ 8230 mutex_enter(&(DEVI(dip)->devi_lock)); 8231 ndi_devi_set_hidden(dip); /* invisible: lookup/snapshot */ 8232 DEVI_SET_DEVICE_REMOVED(dip); 8233 DEVI_SET_EVREMOVE(dip); /* this clears EVADD too */ 8234 mutex_exit(&(DEVI(dip)->devi_lock)); 8235 8236 /* report remove (as 'removed') */ 8237 i_ndi_devi_report_status_change(dip, NULL); 8238 8239 /* 8240 * Invalidate the cache to ensure accurate 8241 * (di_state() & DI_DEVICE_REMOVED). 8242 */ 8243 i_ddi_di_cache_invalidate(); 8244 8245 /* 8246 * Generate sysevent for those interested in removal (either 8247 * directly via private EC_DEVFS or indirectly via devfsadmd 8248 * generated EC_DEV). This will generate LDI DEVICE_REMOVE 8249 * event too. 8250 */ 8251 i_ddi_log_devfs_device_remove(dip); 8252 8253 return (1); /* DEVICE_REMOVED state changed */ 8254 } 8255 8256 int 8257 ndi_devi_device_insert(dev_info_t *dip) 8258 { 8259 ASSERT(dip && ddi_get_parent(dip) && 8260 DEVI_BUSY_OWNED(ddi_get_parent(dip))); 8261 8262 /* Return if not marked removed. */ 8263 if (!ndi_devi_device_isremoved(dip)) 8264 return (0); 8265 8266 /* Mark the device as having been physically reinserted. */ 8267 mutex_enter(&(DEVI(dip)->devi_lock)); 8268 ndi_devi_clr_hidden(dip); /* visible: lookup/snapshot */ 8269 DEVI_SET_DEVICE_REINSERTED(dip); 8270 DEVI_SET_EVADD(dip); /* this clears EVREMOVE too */ 8271 mutex_exit(&(DEVI(dip)->devi_lock)); 8272 8273 /* report insert (as 'online') */ 8274 i_ndi_devi_report_status_change(dip, NULL); 8275 8276 /* 8277 * Invalidate the cache to ensure accurate 8278 * (di_state() & DI_DEVICE_REMOVED). 8279 */ 8280 i_ddi_di_cache_invalidate(); 8281 8282 /* 8283 * Generate sysevent for those interested in removal (either directly 8284 * via EC_DEVFS or indirectly via devfsadmd generated EC_DEV). 8285 */ 8286 i_ddi_log_devfs_device_insert(dip); 8287 8288 return (1); /* DEVICE_REMOVED state changed */ 8289 } 8290 8291 /* 8292 * ibt_hw_is_present() returns 0 when there is no IB hardware actively 8293 * running. This is primarily useful for modules like rpcmod which 8294 * needs a quick check to decide whether or not it should try to use 8295 * InfiniBand 8296 */ 8297 int ib_hw_status = 0; 8298 int 8299 ibt_hw_is_present() 8300 { 8301 return (ib_hw_status); 8302 } 8303 8304 /* 8305 * ASSERT that constraint flag is not set and then set the "retire attempt" 8306 * flag. 8307 */ 8308 int 8309 e_ddi_mark_retiring(dev_info_t *dip, void *arg) 8310 { 8311 char **cons_array = (char **)arg; 8312 char *path; 8313 int constraint; 8314 int i; 8315 8316 constraint = 0; 8317 if (cons_array) { 8318 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 8319 (void) ddi_pathname(dip, path); 8320 for (i = 0; cons_array[i] != NULL; i++) { 8321 if (strcmp(path, cons_array[i]) == 0) { 8322 constraint = 1; 8323 break; 8324 } 8325 } 8326 kmem_free(path, MAXPATHLEN); 8327 } 8328 8329 mutex_enter(&DEVI(dip)->devi_lock); 8330 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)); 8331 DEVI(dip)->devi_flags |= DEVI_RETIRING; 8332 if (constraint) 8333 DEVI(dip)->devi_flags |= DEVI_R_CONSTRAINT; 8334 mutex_exit(&DEVI(dip)->devi_lock); 8335 8336 RIO_VERBOSE((CE_NOTE, "marked dip as undergoing retire process dip=%p", 8337 (void *)dip)); 8338 8339 if (constraint) 8340 RIO_DEBUG((CE_NOTE, "marked dip as constrained, dip=%p", 8341 (void *)dip)); 8342 8343 if (MDI_PHCI(dip)) 8344 mdi_phci_mark_retiring(dip, cons_array); 8345 8346 return (DDI_WALK_CONTINUE); 8347 } 8348 8349 static void 8350 free_array(char **cons_array) 8351 { 8352 int i; 8353 8354 if (cons_array == NULL) 8355 return; 8356 8357 for (i = 0; cons_array[i] != NULL; i++) { 8358 kmem_free(cons_array[i], strlen(cons_array[i]) + 1); 8359 } 8360 kmem_free(cons_array, (i+1) * sizeof (char *)); 8361 } 8362 8363 /* 8364 * Walk *every* node in subtree and check if it blocks, allows or has no 8365 * comment on a proposed retire. 8366 */ 8367 int 8368 e_ddi_retire_notify(dev_info_t *dip, void *arg) 8369 { 8370 int *constraint = (int *)arg; 8371 8372 RIO_DEBUG((CE_NOTE, "retire notify: dip = %p", (void *)dip)); 8373 8374 (void) e_ddi_offline_notify(dip); 8375 8376 mutex_enter(&(DEVI(dip)->devi_lock)); 8377 if (!(DEVI(dip)->devi_flags & DEVI_RETIRING)) { 8378 RIO_DEBUG((CE_WARN, "retire notify: dip in retire " 8379 "subtree is not marked: dip = %p", (void *)dip)); 8380 *constraint = 0; 8381 } else if (DEVI(dip)->devi_flags & DEVI_R_BLOCKED) { 8382 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)); 8383 RIO_DEBUG((CE_NOTE, "retire notify: BLOCKED: dip = %p", 8384 (void *)dip)); 8385 *constraint = 0; 8386 } else if (!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)) { 8387 RIO_DEBUG((CE_NOTE, "retire notify: NO CONSTRAINT: " 8388 "dip = %p", (void *)dip)); 8389 *constraint = 0; 8390 } else { 8391 RIO_DEBUG((CE_NOTE, "retire notify: CONSTRAINT set: " 8392 "dip = %p", (void *)dip)); 8393 } 8394 mutex_exit(&DEVI(dip)->devi_lock); 8395 8396 if (MDI_PHCI(dip)) 8397 mdi_phci_retire_notify(dip, constraint); 8398 8399 return (DDI_WALK_CONTINUE); 8400 } 8401 8402 int 8403 e_ddi_retire_finalize(dev_info_t *dip, void *arg) 8404 { 8405 int constraint = *(int *)arg; 8406 int finalize; 8407 int phci_only; 8408 8409 mutex_enter(&DEVI(dip)->devi_lock); 8410 if (!(DEVI(dip)->devi_flags & DEVI_RETIRING)) { 8411 RIO_DEBUG((CE_WARN, 8412 "retire: unmarked dip(%p) in retire subtree", 8413 (void *)dip)); 8414 ASSERT(!(DEVI(dip)->devi_flags & DEVI_RETIRED)); 8415 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)); 8416 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_BLOCKED)); 8417 mutex_exit(&DEVI(dip)->devi_lock); 8418 return (DDI_WALK_CONTINUE); 8419 } 8420 8421 /* 8422 * retire the device if constraints have been applied 8423 * or if the device is not in use 8424 */ 8425 finalize = 0; 8426 if (constraint) { 8427 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip))); 8428 8429 ASSERT(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT); 8430 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_BLOCKED)); 8431 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT; 8432 DEVI(dip)->devi_flags &= ~DEVI_RETIRING; 8433 DEVI(dip)->devi_flags |= DEVI_RETIRED; 8434 mutex_exit(&DEVI(dip)->devi_lock); 8435 (void) spec_fence_snode(dip, NULL); 8436 RIO_DEBUG((CE_NOTE, "Fenced off: dip = %p", (void *)dip)); 8437 e_ddi_offline_finalize(dip, DDI_SUCCESS); 8438 } else { 8439 if (DEVI(dip)->devi_flags & DEVI_R_BLOCKED) { 8440 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)); 8441 DEVI(dip)->devi_flags &= ~DEVI_R_BLOCKED; 8442 DEVI(dip)->devi_flags &= ~DEVI_RETIRING; 8443 /* we have already finalized during notify */ 8444 } else if (DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT) { 8445 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT; 8446 DEVI(dip)->devi_flags &= ~DEVI_RETIRING; 8447 finalize = 1; 8448 } else { 8449 DEVI(dip)->devi_flags &= ~DEVI_RETIRING; 8450 /* 8451 * even if no contracts, need to call finalize 8452 * to clear the contract barrier on the dip 8453 */ 8454 finalize = 1; 8455 } 8456 mutex_exit(&DEVI(dip)->devi_lock); 8457 RIO_DEBUG((CE_NOTE, "finalize: NOT retired: dip = %p", 8458 (void *)dip)); 8459 if (finalize) 8460 e_ddi_offline_finalize(dip, DDI_FAILURE); 8461 } 8462 8463 /* 8464 * phci_only variable indicates no client checking, just 8465 * offline the PHCI. We set that to 0 to enable client 8466 * checking 8467 */ 8468 phci_only = 0; 8469 if (MDI_PHCI(dip)) 8470 mdi_phci_retire_finalize(dip, phci_only, arg); 8471 8472 return (DDI_WALK_CONTINUE); 8473 } 8474 8475 /* 8476 * Returns 8477 * DDI_SUCCESS if constraints allow retire 8478 * DDI_FAILURE if constraints don't allow retire. 8479 * cons_array is a NULL terminated array of node paths for 8480 * which constraints have already been applied. 8481 */ 8482 int 8483 e_ddi_retire_device(char *path, char **cons_array) 8484 { 8485 dev_info_t *dip; 8486 dev_info_t *pdip; 8487 int circ; 8488 int circ2; 8489 int constraint; 8490 char *devnm; 8491 8492 /* 8493 * First, lookup the device 8494 */ 8495 dip = e_ddi_hold_devi_by_path(path, 0); 8496 if (dip == NULL) { 8497 /* 8498 * device does not exist. This device cannot be 8499 * a critical device since it is not in use. Thus 8500 * this device is always retireable. Return DDI_SUCCESS 8501 * to indicate this. If this device is ever 8502 * instantiated, I/O framework will consult the 8503 * the persistent retire store, mark it as 8504 * retired and fence it off. 8505 */ 8506 RIO_DEBUG((CE_NOTE, "Retire device: device doesn't exist." 8507 " NOP. Just returning SUCCESS. path=%s", path)); 8508 free_array(cons_array); 8509 return (DDI_SUCCESS); 8510 } 8511 8512 RIO_DEBUG((CE_NOTE, "Retire device: found dip = %p.", (void *)dip)); 8513 8514 pdip = ddi_get_parent(dip); 8515 ndi_hold_devi(pdip); 8516 8517 /* 8518 * Run devfs_clean() in case dip has no constraints and is 8519 * not in use, so is retireable but there are dv_nodes holding 8520 * ref-count on the dip. Note that devfs_clean() always returns 8521 * success. 8522 */ 8523 devnm = kmem_alloc(MAXNAMELEN + 1, KM_SLEEP); 8524 (void) ddi_deviname(dip, devnm); 8525 (void) devfs_clean(pdip, devnm + 1, DV_CLEAN_FORCE); 8526 kmem_free(devnm, MAXNAMELEN + 1); 8527 8528 ndi_devi_enter(pdip, &circ); 8529 8530 /* release hold from e_ddi_hold_devi_by_path */ 8531 ndi_rele_devi(dip); 8532 8533 /* 8534 * If it cannot make a determination, is_leaf_node() assumes 8535 * dip is a nexus. 8536 */ 8537 (void) e_ddi_mark_retiring(dip, cons_array); 8538 if (!is_leaf_node(dip)) { 8539 ndi_devi_enter(dip, &circ2); 8540 ddi_walk_devs(ddi_get_child(dip), e_ddi_mark_retiring, 8541 cons_array); 8542 ndi_devi_exit(dip, circ2); 8543 } 8544 free_array(cons_array); 8545 8546 /* 8547 * apply constraints 8548 */ 8549 RIO_DEBUG((CE_NOTE, "retire: subtree retire notify: path = %s", path)); 8550 8551 constraint = 1; /* assume constraints allow retire */ 8552 (void) e_ddi_retire_notify(dip, &constraint); 8553 if (!is_leaf_node(dip)) { 8554 ndi_devi_enter(dip, &circ2); 8555 ddi_walk_devs(ddi_get_child(dip), e_ddi_retire_notify, 8556 &constraint); 8557 ndi_devi_exit(dip, circ2); 8558 } 8559 8560 /* 8561 * Now finalize the retire 8562 */ 8563 (void) e_ddi_retire_finalize(dip, &constraint); 8564 if (!is_leaf_node(dip)) { 8565 ndi_devi_enter(dip, &circ2); 8566 ddi_walk_devs(ddi_get_child(dip), e_ddi_retire_finalize, 8567 &constraint); 8568 ndi_devi_exit(dip, circ2); 8569 } 8570 8571 if (!constraint) { 8572 RIO_DEBUG((CE_WARN, "retire failed: path = %s", path)); 8573 } else { 8574 RIO_DEBUG((CE_NOTE, "retire succeeded: path = %s", path)); 8575 } 8576 8577 ndi_devi_exit(pdip, circ); 8578 ndi_rele_devi(pdip); 8579 return (constraint ? DDI_SUCCESS : DDI_FAILURE); 8580 } 8581 8582 static int 8583 unmark_and_unfence(dev_info_t *dip, void *arg) 8584 { 8585 char *path = (char *)arg; 8586 8587 ASSERT(path); 8588 8589 (void) ddi_pathname(dip, path); 8590 8591 mutex_enter(&DEVI(dip)->devi_lock); 8592 DEVI(dip)->devi_flags &= ~DEVI_RETIRED; 8593 DEVI_SET_DEVICE_ONLINE(dip); 8594 mutex_exit(&DEVI(dip)->devi_lock); 8595 8596 RIO_VERBOSE((CE_NOTE, "Cleared RETIRED flag: dip=%p, path=%s", 8597 (void *)dip, path)); 8598 8599 (void) spec_unfence_snode(dip); 8600 RIO_DEBUG((CE_NOTE, "Unfenced device: %s", path)); 8601 8602 if (MDI_PHCI(dip)) 8603 mdi_phci_unretire(dip); 8604 8605 return (DDI_WALK_CONTINUE); 8606 } 8607 8608 struct find_dip { 8609 char *fd_buf; 8610 char *fd_path; 8611 dev_info_t *fd_dip; 8612 }; 8613 8614 static int 8615 find_dip_fcn(dev_info_t *dip, void *arg) 8616 { 8617 struct find_dip *findp = (struct find_dip *)arg; 8618 8619 (void) ddi_pathname(dip, findp->fd_buf); 8620 8621 if (strcmp(findp->fd_path, findp->fd_buf) != 0) 8622 return (DDI_WALK_CONTINUE); 8623 8624 ndi_hold_devi(dip); 8625 findp->fd_dip = dip; 8626 8627 return (DDI_WALK_TERMINATE); 8628 } 8629 8630 int 8631 e_ddi_unretire_device(char *path) 8632 { 8633 int circ; 8634 int circ2; 8635 char *path2; 8636 dev_info_t *pdip; 8637 dev_info_t *dip; 8638 struct find_dip find_dip; 8639 8640 ASSERT(path); 8641 ASSERT(*path == '/'); 8642 8643 if (strcmp(path, "/") == 0) { 8644 cmn_err(CE_WARN, "Root node cannot be retired. Skipping " 8645 "device unretire: %s", path); 8646 return (0); 8647 } 8648 8649 /* 8650 * We can't lookup the dip (corresponding to path) via 8651 * e_ddi_hold_devi_by_path() because the dip may be offline 8652 * and may not attach. Use ddi_walk_devs() instead; 8653 */ 8654 find_dip.fd_buf = kmem_alloc(MAXPATHLEN, KM_SLEEP); 8655 find_dip.fd_path = path; 8656 find_dip.fd_dip = NULL; 8657 8658 pdip = ddi_root_node(); 8659 8660 ndi_devi_enter(pdip, &circ); 8661 ddi_walk_devs(ddi_get_child(pdip), find_dip_fcn, &find_dip); 8662 ndi_devi_exit(pdip, circ); 8663 8664 kmem_free(find_dip.fd_buf, MAXPATHLEN); 8665 8666 if (find_dip.fd_dip == NULL) { 8667 cmn_err(CE_WARN, "Device not found in device tree. Skipping " 8668 "device unretire: %s", path); 8669 return (0); 8670 } 8671 8672 dip = find_dip.fd_dip; 8673 8674 pdip = ddi_get_parent(dip); 8675 8676 ndi_hold_devi(pdip); 8677 8678 ndi_devi_enter(pdip, &circ); 8679 8680 path2 = kmem_alloc(MAXPATHLEN, KM_SLEEP); 8681 8682 (void) unmark_and_unfence(dip, path2); 8683 if (!is_leaf_node(dip)) { 8684 ndi_devi_enter(dip, &circ2); 8685 ddi_walk_devs(ddi_get_child(dip), unmark_and_unfence, path2); 8686 ndi_devi_exit(dip, circ2); 8687 } 8688 8689 kmem_free(path2, MAXPATHLEN); 8690 8691 /* release hold from find_dip_fcn() */ 8692 ndi_rele_devi(dip); 8693 8694 ndi_devi_exit(pdip, circ); 8695 8696 ndi_rele_devi(pdip); 8697 8698 return (0); 8699 } 8700 8701 /* 8702 * Called before attach on a dip that has been retired. 8703 */ 8704 static int 8705 mark_and_fence(dev_info_t *dip, void *arg) 8706 { 8707 char *fencepath = (char *)arg; 8708 8709 /* 8710 * We have already decided to retire this device. The various 8711 * constraint checking should not be set. 8712 * NOTE that the retire flag may already be set due to 8713 * fenced -> detach -> fenced transitions. 8714 */ 8715 mutex_enter(&DEVI(dip)->devi_lock); 8716 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)); 8717 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_BLOCKED)); 8718 ASSERT(!(DEVI(dip)->devi_flags & DEVI_RETIRING)); 8719 DEVI(dip)->devi_flags |= DEVI_RETIRED; 8720 mutex_exit(&DEVI(dip)->devi_lock); 8721 RIO_VERBOSE((CE_NOTE, "marked as RETIRED dip=%p", (void *)dip)); 8722 8723 if (fencepath) { 8724 (void) spec_fence_snode(dip, NULL); 8725 RIO_DEBUG((CE_NOTE, "Fenced: %s", 8726 ddi_pathname(dip, fencepath))); 8727 } 8728 8729 return (DDI_WALK_CONTINUE); 8730 } 8731 8732 /* 8733 * Checks the retire database and: 8734 * 8735 * - if device is present in the retire database, marks the device retired 8736 * and fences it off. 8737 * - if device is not in retire database, allows the device to attach normally 8738 * 8739 * To be called only by framework attach code on first attach attempt. 8740 * 8741 */ 8742 static int 8743 i_ddi_check_retire(dev_info_t *dip) 8744 { 8745 char *path; 8746 dev_info_t *pdip; 8747 int circ; 8748 int phci_only; 8749 int constraint; 8750 8751 pdip = ddi_get_parent(dip); 8752 8753 /* 8754 * Root dip is treated special and doesn't take this code path. 8755 * Also root can never be retired. 8756 */ 8757 ASSERT(pdip); 8758 ASSERT(DEVI_BUSY_OWNED(pdip)); 8759 ASSERT(i_ddi_node_state(dip) < DS_ATTACHED); 8760 8761 path = kmem_alloc(MAXPATHLEN, KM_SLEEP); 8762 8763 (void) ddi_pathname(dip, path); 8764 8765 RIO_VERBOSE((CE_NOTE, "Checking if dip should attach: dip=%p, path=%s", 8766 (void *)dip, path)); 8767 8768 /* 8769 * Check if this device is in the "retired" store i.e. should 8770 * be retired. If not, we have nothing to do. 8771 */ 8772 if (e_ddi_device_retired(path) == 0) { 8773 RIO_VERBOSE((CE_NOTE, "device is NOT retired: path=%s", path)); 8774 if (DEVI(dip)->devi_flags & DEVI_RETIRED) 8775 (void) e_ddi_unretire_device(path); 8776 kmem_free(path, MAXPATHLEN); 8777 return (0); 8778 } 8779 8780 RIO_DEBUG((CE_NOTE, "attach: device is retired: path=%s", path)); 8781 8782 /* 8783 * Mark dips and fence off snodes (if any) 8784 */ 8785 RIO_DEBUG((CE_NOTE, "attach: Mark and fence subtree: path=%s", path)); 8786 (void) mark_and_fence(dip, path); 8787 if (!is_leaf_node(dip)) { 8788 ndi_devi_enter(dip, &circ); 8789 ddi_walk_devs(ddi_get_child(dip), mark_and_fence, path); 8790 ndi_devi_exit(dip, circ); 8791 } 8792 8793 kmem_free(path, MAXPATHLEN); 8794 8795 /* 8796 * We don't want to check the client. We just want to 8797 * offline the PHCI 8798 */ 8799 phci_only = 1; 8800 constraint = 1; 8801 if (MDI_PHCI(dip)) 8802 mdi_phci_retire_finalize(dip, phci_only, &constraint); 8803 return (1); 8804 } 8805 8806 8807 #define VAL_ALIAS(array, x) (strlen(array[x].pair_alias)) 8808 #define VAL_CURR(array, x) (strlen(array[x].pair_curr)) 8809 #define SWAP(array, x, y) \ 8810 { \ 8811 alias_pair_t tmpair = array[x]; \ 8812 array[x] = array[y]; \ 8813 array[y] = tmpair; \ 8814 } 8815 8816 static int 8817 partition_curr(alias_pair_t *array, int start, int end) 8818 { 8819 int i = start - 1; 8820 int j = end + 1; 8821 int pivot = start; 8822 8823 for (;;) { 8824 do { 8825 j--; 8826 } while (VAL_CURR(array, j) > VAL_CURR(array, pivot)); 8827 8828 do { 8829 i++; 8830 } while (VAL_CURR(array, i) < VAL_CURR(array, pivot)); 8831 8832 if (i < j) 8833 SWAP(array, i, j) 8834 else 8835 return (j); 8836 } 8837 } 8838 8839 static int 8840 partition_aliases(alias_pair_t *array, int start, int end) 8841 { 8842 int i = start - 1; 8843 int j = end + 1; 8844 int pivot = start; 8845 8846 for (;;) { 8847 do { 8848 j--; 8849 } while (VAL_ALIAS(array, j) > VAL_ALIAS(array, pivot)); 8850 8851 do { 8852 i++; 8853 } while (VAL_ALIAS(array, i) < VAL_ALIAS(array, pivot)); 8854 8855 if (i < j) 8856 SWAP(array, i, j) 8857 else 8858 return (j); 8859 } 8860 } 8861 static void 8862 sort_alias_pairs(alias_pair_t *array, int start, int end) 8863 { 8864 int mid; 8865 8866 if (start < end) { 8867 mid = partition_aliases(array, start, end); 8868 sort_alias_pairs(array, start, mid); 8869 sort_alias_pairs(array, mid + 1, end); 8870 } 8871 } 8872 8873 static void 8874 sort_curr_pairs(alias_pair_t *array, int start, int end) 8875 { 8876 int mid; 8877 8878 if (start < end) { 8879 mid = partition_curr(array, start, end); 8880 sort_curr_pairs(array, start, mid); 8881 sort_curr_pairs(array, mid + 1, end); 8882 } 8883 } 8884 8885 static void 8886 create_sorted_pairs(plat_alias_t *pali, int npali) 8887 { 8888 int i; 8889 int j; 8890 int k; 8891 int count; 8892 8893 count = 0; 8894 for (i = 0; i < npali; i++) { 8895 count += pali[i].pali_naliases; 8896 } 8897 8898 ddi_aliases.dali_alias_pairs = kmem_zalloc( 8899 (sizeof (alias_pair_t)) * count, KM_NOSLEEP); 8900 if (ddi_aliases.dali_alias_pairs == NULL) { 8901 cmn_err(CE_PANIC, "alias path-pair alloc failed"); 8902 /*NOTREACHED*/ 8903 } 8904 8905 ddi_aliases.dali_curr_pairs = kmem_zalloc( 8906 (sizeof (alias_pair_t)) * count, KM_NOSLEEP); 8907 if (ddi_aliases.dali_curr_pairs == NULL) { 8908 cmn_err(CE_PANIC, "curr path-pair alloc failed"); 8909 /*NOTREACHED*/ 8910 } 8911 8912 for (i = 0, k = 0; i < npali; i++) { 8913 for (j = 0; j < pali[i].pali_naliases; j++, k++) { 8914 ddi_aliases.dali_alias_pairs[k].pair_curr = 8915 ddi_aliases.dali_curr_pairs[k].pair_curr = 8916 pali[i].pali_current; 8917 ddi_aliases.dali_alias_pairs[k].pair_alias = 8918 ddi_aliases.dali_curr_pairs[k].pair_alias = 8919 pali[i].pali_aliases[j]; 8920 } 8921 } 8922 8923 ASSERT(k == count); 8924 8925 ddi_aliases.dali_num_pairs = count; 8926 8927 /* Now sort the array based on length of pair_alias */ 8928 sort_alias_pairs(ddi_aliases.dali_alias_pairs, 0, count - 1); 8929 sort_curr_pairs(ddi_aliases.dali_curr_pairs, 0, count - 1); 8930 } 8931 8932 void 8933 ddi_register_aliases(plat_alias_t *pali, uint64_t npali) 8934 { 8935 8936 ASSERT((pali == NULL) ^ (npali != 0)); 8937 8938 if (npali == 0) { 8939 ddi_err(DER_PANIC, NULL, "npali == 0"); 8940 /*NOTREACHED*/ 8941 } 8942 8943 if (ddi_aliases_present == B_TRUE) { 8944 ddi_err(DER_PANIC, NULL, "multiple init"); 8945 /*NOTREACHED*/ 8946 } 8947 8948 ddi_aliases.dali_alias_TLB = mod_hash_create_strhash( 8949 "ddi-alias-tlb", DDI_ALIAS_HASH_SIZE, mod_hash_null_valdtor); 8950 if (ddi_aliases.dali_alias_TLB == NULL) { 8951 ddi_err(DER_PANIC, NULL, "alias TLB hash alloc failed"); 8952 /*NOTREACHED*/ 8953 } 8954 8955 ddi_aliases.dali_curr_TLB = mod_hash_create_strhash( 8956 "ddi-curr-tlb", DDI_ALIAS_HASH_SIZE, mod_hash_null_valdtor); 8957 if (ddi_aliases.dali_curr_TLB == NULL) { 8958 ddi_err(DER_PANIC, NULL, "curr TLB hash alloc failed"); 8959 /*NOTREACHED*/ 8960 } 8961 8962 create_sorted_pairs(pali, npali); 8963 8964 tsd_create(&tsd_ddi_redirect, NULL); 8965 8966 ddi_aliases_present = B_TRUE; 8967 } 8968 8969 static dev_info_t * 8970 path_to_dip(char *path) 8971 { 8972 dev_info_t *currdip; 8973 int error; 8974 char *pdup; 8975 8976 pdup = ddi_strdup(path, KM_NOSLEEP); 8977 if (pdup == NULL) { 8978 cmn_err(CE_PANIC, "path strdup failed: %s", path); 8979 /*NOTREACHED*/ 8980 } 8981 8982 error = resolve_pathname(pdup, &currdip, NULL, NULL); 8983 8984 kmem_free(pdup, strlen(path) + 1); 8985 8986 return (error ? NULL : currdip); 8987 } 8988 8989 dev_info_t * 8990 ddi_alias_to_currdip(char *alias, int i) 8991 { 8992 alias_pair_t *pair; 8993 char *curr; 8994 dev_info_t *currdip = NULL; 8995 char *aliasdup; 8996 int rv, len; 8997 8998 pair = &(ddi_aliases.dali_alias_pairs[i]); 8999 len = strlen(pair->pair_alias); 9000 9001 curr = NULL; 9002 aliasdup = ddi_strdup(alias, KM_NOSLEEP); 9003 if (aliasdup == NULL) { 9004 cmn_err(CE_PANIC, "aliasdup alloc failed"); 9005 /*NOTREACHED*/ 9006 } 9007 9008 if (strncmp(alias, pair->pair_alias, len) != 0) 9009 goto out; 9010 9011 if (alias[len] != '/' && alias[len] != '\0') 9012 goto out; 9013 9014 curr = kmem_alloc(MAXPATHLEN, KM_NOSLEEP); 9015 if (curr == NULL) { 9016 cmn_err(CE_PANIC, "curr alloc failed"); 9017 /*NOTREACHED*/ 9018 } 9019 (void) strlcpy(curr, pair->pair_curr, MAXPATHLEN); 9020 if (alias[len] == '/') { 9021 (void) strlcat(curr, "/", MAXPATHLEN); 9022 (void) strlcat(curr, &alias[len + 1], MAXPATHLEN); 9023 } 9024 9025 currdip = path_to_dip(curr); 9026 9027 out: 9028 if (currdip) { 9029 rv = mod_hash_insert(ddi_aliases.dali_alias_TLB, 9030 (mod_hash_key_t)aliasdup, (mod_hash_val_t)curr); 9031 if (rv != 0) { 9032 kmem_free(curr, MAXPATHLEN); 9033 strfree(aliasdup); 9034 } 9035 } else { 9036 rv = mod_hash_insert(ddi_aliases.dali_alias_TLB, 9037 (mod_hash_key_t)aliasdup, (mod_hash_val_t)NULL); 9038 if (rv != 0) { 9039 strfree(aliasdup); 9040 } 9041 if (curr) 9042 kmem_free(curr, MAXPATHLEN); 9043 } 9044 9045 return (currdip); 9046 } 9047 9048 char * 9049 ddi_curr_to_alias(char *curr, int i) 9050 { 9051 alias_pair_t *pair; 9052 char *alias; 9053 char *currdup; 9054 int len; 9055 int rv; 9056 9057 pair = &(ddi_aliases.dali_curr_pairs[i]); 9058 9059 len = strlen(pair->pair_curr); 9060 9061 alias = NULL; 9062 9063 currdup = ddi_strdup(curr, KM_NOSLEEP); 9064 if (currdup == NULL) { 9065 cmn_err(CE_PANIC, "currdup alloc failed"); 9066 /*NOTREACHED*/ 9067 } 9068 9069 if (strncmp(curr, pair->pair_curr, len) != 0) 9070 goto out; 9071 9072 if (curr[len] != '/' && curr[len] != '\0') 9073 goto out; 9074 9075 alias = kmem_alloc(MAXPATHLEN, KM_NOSLEEP); 9076 if (alias == NULL) { 9077 cmn_err(CE_PANIC, "alias alloc failed"); 9078 /*NOTREACHED*/ 9079 } 9080 9081 (void) strlcpy(alias, pair->pair_alias, MAXPATHLEN); 9082 if (curr[len] == '/') { 9083 (void) strlcat(alias, "/", MAXPATHLEN); 9084 (void) strlcat(alias, &curr[len + 1], MAXPATHLEN); 9085 } 9086 9087 if (e_ddi_path_to_instance(alias) == NULL) { 9088 kmem_free(alias, MAXPATHLEN); 9089 alias = NULL; 9090 } 9091 9092 out: 9093 rv = mod_hash_insert(ddi_aliases.dali_curr_TLB, 9094 (mod_hash_key_t)currdup, (mod_hash_val_t)alias); 9095 if (rv != 0) { 9096 strfree(currdup); 9097 } 9098 9099 return (alias); 9100 } 9101 9102 dev_info_t * 9103 ddi_alias_redirect(char *alias) 9104 { 9105 char *curr; 9106 dev_info_t *currdip; 9107 int i; 9108 9109 if (ddi_aliases_present == B_FALSE) 9110 return (NULL); 9111 9112 if (tsd_get(tsd_ddi_redirect)) 9113 return (NULL); 9114 9115 (void) tsd_set(tsd_ddi_redirect, (void *)1); 9116 9117 ASSERT(ddi_aliases.dali_alias_TLB); 9118 ASSERT(ddi_aliases.dali_alias_pairs); 9119 9120 curr = NULL; 9121 if (mod_hash_find(ddi_aliases.dali_alias_TLB, 9122 (mod_hash_key_t)alias, (mod_hash_val_t *)&curr) == 0) { 9123 currdip = curr ? path_to_dip(curr) : NULL; 9124 goto out; 9125 } 9126 9127 /* The TLB has no translation, do it the hard way */ 9128 currdip = NULL; 9129 for (i = ddi_aliases.dali_num_pairs - 1; i >= 0; i--) { 9130 currdip = ddi_alias_to_currdip(alias, i); 9131 if (currdip) 9132 break; 9133 } 9134 out: 9135 (void) tsd_set(tsd_ddi_redirect, NULL); 9136 9137 return (currdip); 9138 } 9139 9140 char * 9141 ddi_curr_redirect(char *curr) 9142 { 9143 char *alias; 9144 int i; 9145 9146 if (ddi_aliases_present == B_FALSE) 9147 return (NULL); 9148 9149 if (tsd_get(tsd_ddi_redirect)) 9150 return (NULL); 9151 9152 (void) tsd_set(tsd_ddi_redirect, (void *)1); 9153 9154 ASSERT(ddi_aliases.dali_curr_TLB); 9155 ASSERT(ddi_aliases.dali_curr_pairs); 9156 9157 alias = NULL; 9158 if (mod_hash_find(ddi_aliases.dali_curr_TLB, 9159 (mod_hash_key_t)curr, (mod_hash_val_t *)&alias) == 0) { 9160 goto out; 9161 } 9162 9163 9164 /* The TLB has no translation, do it the slow way */ 9165 alias = NULL; 9166 for (i = ddi_aliases.dali_num_pairs - 1; i >= 0; i--) { 9167 alias = ddi_curr_to_alias(curr, i); 9168 if (alias) 9169 break; 9170 } 9171 9172 out: 9173 (void) tsd_set(tsd_ddi_redirect, NULL); 9174 9175 return (alias); 9176 } 9177 9178 void 9179 ddi_err(ddi_err_t ade, dev_info_t *rdip, const char *fmt, ...) 9180 { 9181 va_list ap; 9182 char strbuf[256]; 9183 char *buf; 9184 size_t buflen, tlen; 9185 int ce; 9186 int de; 9187 const char *fmtbad = "Invalid arguments to ddi_err()"; 9188 9189 de = DER_CONT; 9190 strbuf[1] = '\0'; 9191 9192 switch (ade) { 9193 case DER_CONS: 9194 strbuf[0] = '^'; 9195 break; 9196 case DER_LOG: 9197 strbuf[0] = '!'; 9198 break; 9199 case DER_VERB: 9200 strbuf[0] = '?'; 9201 break; 9202 default: 9203 strbuf[0] = '\0'; 9204 de = ade; 9205 break; 9206 } 9207 9208 tlen = strlen(strbuf); 9209 buf = strbuf + tlen; 9210 buflen = sizeof (strbuf) - tlen; 9211 9212 if (rdip && ddi_get_instance(rdip) == -1) { 9213 (void) snprintf(buf, buflen, "%s: ", 9214 ddi_driver_name(rdip)); 9215 } else if (rdip) { 9216 (void) snprintf(buf, buflen, "%s%d: ", 9217 ddi_driver_name(rdip), ddi_get_instance(rdip)); 9218 } 9219 9220 tlen = strlen(strbuf); 9221 buf = strbuf + tlen; 9222 buflen = sizeof (strbuf) - tlen; 9223 9224 va_start(ap, fmt); 9225 switch (de) { 9226 case DER_CONT: 9227 (void) vsnprintf(buf, buflen, fmt, ap); 9228 if (ade != DER_CONT) { 9229 (void) strlcat(strbuf, "\n", sizeof (strbuf)); 9230 } 9231 ce = CE_CONT; 9232 break; 9233 case DER_NOTE: 9234 (void) vsnprintf(buf, buflen, fmt, ap); 9235 ce = CE_NOTE; 9236 break; 9237 case DER_WARN: 9238 (void) vsnprintf(buf, buflen, fmt, ap); 9239 ce = CE_WARN; 9240 break; 9241 case DER_MODE: 9242 (void) vsnprintf(buf, buflen, fmt, ap); 9243 if (ddi_err_panic == B_TRUE) { 9244 ce = CE_PANIC; 9245 } else { 9246 ce = CE_WARN; 9247 } 9248 break; 9249 case DER_DEBUG: 9250 (void) snprintf(buf, buflen, "DEBUG: "); 9251 tlen = strlen("DEBUG: "); 9252 (void) vsnprintf(buf + tlen, buflen - tlen, fmt, ap); 9253 ce = CE_CONT; 9254 break; 9255 case DER_PANIC: 9256 (void) vsnprintf(buf, buflen, fmt, ap); 9257 ce = CE_PANIC; 9258 break; 9259 case DER_INVALID: 9260 default: 9261 (void) snprintf(buf, buflen, fmtbad); 9262 tlen = strlen(fmtbad); 9263 (void) vsnprintf(buf + tlen, buflen - tlen, fmt, ap); 9264 ce = CE_PANIC; 9265 break; 9266 } 9267 va_end(ap); 9268 9269 cmn_err(ce, strbuf); 9270 } 9271 9272 /*ARGSUSED*/ 9273 void 9274 ddi_mem_update(uint64_t addr, uint64_t size) 9275 { 9276 #if defined(__x86) && !defined(__xpv) 9277 extern void immu_physmem_update(uint64_t addr, uint64_t size); 9278 immu_physmem_update(addr, size); 9279 #else 9280 /*LINTED*/ 9281 ; 9282 #endif 9283 } 9284