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