Lines Matching refs:dip

83 	dev_info_t *mtc_pdip;	/* parent dip for mt_config_children */
84 dev_info_t **mtc_fdip; /* "a" dip where unconfigure failed */
99 dev_info_t *dip;
127 dev_info_t *scsi_vhci_dip; /* MPXIO dip */
221 static void ndi_devi_exit_and_wait(dev_info_t *dip,
223 static int ndi_devi_unbind_driver(dev_info_t *dip);
225 static int i_ddi_check_retire(dev_info_t *dip);
389 "dip=%p, name=%s", (void *)devi, node_name));
418 i_ddi_free_node(dev_info_t *dip)
420 struct dev_info *devi = DEVI(dip);
433 if (i_ndi_dev_is_auto_assigned_node(dip))
434 impl_ddi_free_nodeid(DEVI(dip)->devi_nodeid);
436 if (ndi_dev_is_persistent_node(dip)) {
445 if (DEVI(dip)->devi_compat_names)
446 kmem_free(DEVI(dip)->devi_compat_names,
447 DEVI(dip)->devi_compat_length);
448 if (DEVI(dip)->devi_rebinding_name)
449 kmem_free(DEVI(dip)->devi_rebinding_name,
450 strlen(DEVI(dip)->devi_rebinding_name) + 1);
452 ddi_prop_remove_all(dip); /* remove driver properties */
458 if (DEVI(dip)->devi_devid_str)
459 ddi_devid_str_free(DEVI(dip)->devi_devid_str);
461 i_ddi_set_node_state(dip, DS_INVAL);
462 da_log_enter(dip);
475 "dip=%p", (void *)dip));
476 contract_device_remove_dip(dip);
484 "dip=%p, name=%s", (void *)dip, devi->devi_node_name));
504 ndi_devi_set_nodename(dev_info_t *dip, char *name, int flags)
509 ASSERT(dip && name);
511 oname = DEVI(dip)->devi_node_name;
520 if (i_ddi_node_state(dip) >= DS_BOUND) {
525 "ndi_devi_set_nodename: node already bound dip = %p,"
526 " %s -> %s", (void *)dip, ddi_node_name(dip), name);
531 DEVI(dip)->devi_node_name = nname;
532 i_ddi_set_binding_name(dip, nname);
535 da_log_enter(dip);
540 i_ddi_add_devimap(dev_info_t *dip)
544 ASSERT(dip);
546 if (!ndi_dev_is_persistent_node(dip))
549 ASSERT(ddi_get_parent(dip) == NULL || (DEVI_VHCI_NODE(dip)) ||
550 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
559 elem->nodeid = ddi_get_nodeid(dip);
560 elem->dip = dip;
570 i_ddi_remove_devimap(dev_info_t *dip)
575 ASSERT(dip);
577 if (!ndi_dev_is_persistent_node(dip))
584 * to prevent race between dip removal and
587 if (e_ddi_devi_holdcnt(dip)) {
597 if (elem->dip == dip) {
598 ASSERT(elem->nodeid == ddi_get_nodeid(dip));
610 fcn, (void *)dip);
615 elem->dip = NULL;
630 link_node(dev_info_t *dip)
632 struct dev_info *devi = DEVI(dip);
653 while (*dipp && (*dipp != dip)) {
661 i_ddi_add_devimap(dip);
682 i_link_vhci_node(dip);
685 *dipp = dip;
686 DEVI(dip)->devi_sibling = NULL;
697 if (ndi_dev_is_persistent_node(dip))
698 add_to_dn_list(&orphanlist, dip);
705 unlink_node(dev_info_t *dip)
707 struct dev_info *devi = DEVI(dip);
716 ddi_node_name(dip)));
719 if (devi->devi_ref || i_ddi_remove_devimap(dip) != DDI_SUCCESS)
730 while (*dipp && (*dipp != dip)) {
749 if (ndi_dev_is_persistent_node(dip)) {
750 remove_from_dn_list(&orphanlist, dip);
755 if (hdlp->cn_info.cn_child == dip)
776 bind_node(dev_info_t *dip)
780 struct dev_info *devi = DEVI(dip);
781 dev_info_t *parent = ddi_get_parent(dip);
786 (void *)dip, ddi_node_name(dip)));
788 mutex_enter(&DEVI(dip)->devi_lock);
789 if (DEVI(dip)->devi_flags & DEVI_NO_BIND) {
790 mutex_exit(&DEVI(dip)->devi_lock);
793 mutex_exit(&DEVI(dip)->devi_lock);
796 major = ddi_compatible_driver_major(dip, &p);
802 i_ddi_set_binding_name(dip, p);
808 link_to_driver_list(dip);
813 if (ndi_dev_is_persistent_node(dip)) {
827 unbind_node(dev_info_t *dip)
829 ASSERT(DEVI(dip)->devi_node_state == DS_BOUND);
830 ASSERT(DEVI(dip)->devi_major != DDI_MAJOR_T_NONE);
833 if (DEVI(dip)->devi_ref)
837 (void *)dip, ddi_node_name(dip)));
839 unlink_from_driver_list(dip);
841 DEVI(dip)->devi_major = DDI_MAJOR_T_NONE;
842 DEVI(dip)->devi_binding_name = DEVI(dip)->devi_node_name;
853 init_node(dev_info_t *dip)
856 dev_info_t *pdip = ddi_get_parent(dip);
862 ASSERT(i_ddi_node_state(dip) == DS_BOUND);
868 (void) ddi_pathname(dip, path);
870 path, (void *)dip));
881 add_global_props(dip);
888 error = (*f)(pdip, pdip, DDI_CTLOPS_INITCHILD, dip, NULL);
891 path, (void *)dip));
892 remove_global_props(dip);
900 * added to the cache, against the client dip, by use of
902 * of the client fails, we need to purge the client dip from
906 mutex_enter(&DEVI(dip)->devi_lock);
907 if ((DEVI(dip)->devi_flags & DEVI_CACHED_DEVID) ||
908 DEVI(dip)->devi_devid_str) {
909 DEVI(dip)->devi_flags &= ~DEVI_CACHED_DEVID;
910 mutex_exit(&DEVI(dip)->devi_lock);
911 ddi_devid_unregister(dip);
913 mutex_exit(&DEVI(dip)->devi_lock);
916 ddi_set_name_addr(dip, NULL);
924 (void) ddi_pathname(dip, path);
927 if (find_duplicate_child(pdip, dip) != NULL) {
932 if ((error = uninit_node(dip)) != DDI_SUCCESS) {
938 "%s 0x%p%s\n", path, (void *)dip,
949 if (!(DEVI(dip)->devi_flags & DEVI_CACHED_DEVID) &&
950 (ddi_devid_get(dip, &devid) == DDI_SUCCESS)) {
951 if (e_devid_cache_register(dip, devid) == DDI_SUCCESS) {
952 mutex_enter(&DEVI(dip)->devi_lock);
953 DEVI(dip)->devi_flags |= DEVI_CACHED_DEVID;
954 mutex_exit(&DEVI(dip)->devi_lock);
977 if (driver_active(major) && (major != DEVI(dip)->devi_major) &&
978 (ndi_dev_is_persistent_node(dip) || driver_conf_allow_path_alias)) {
981 mutex_enter(&DEVI(dip)->devi_lock);
982 DEVI(dip)->devi_flags |= DEVI_REBIND;
983 mutex_exit(&DEVI(dip)->devi_lock);
997 if ((error = uninit_node(dip)) != DDI_SUCCESS) {
1006 if ((error = ndi_devi_unbind_driver(dip)) != DDI_SUCCESS) {
1014 if (DEVI(dip)->devi_rebinding_name == NULL)
1015 DEVI(dip)->devi_rebinding_name =
1026 if ((error = ndi_devi_bind_driver(dip, 0)) != DDI_SUCCESS) {
1037 if (ndi_dev_is_persistent_node(dip))
1044 error = ddi_initchild(pdip, dip);
1046 "%s 0x%p\n", path, (void *)dip));
1059 DEVI(dip)->devi_instance = e_ddi_assign_instance(dip);
1060 ddi_optimize_dtree(dip);
1065 mutex_enter(&DEVI(dip)->devi_lock);
1066 DEVI(dip)->devi_flags &= ~DEVI_REBIND;
1067 mutex_exit(&DEVI(dip)->devi_lock);
1080 uninit_node(dev_info_t *dip)
1091 * dip cannot be downgraded by the framework.
1093 node_state_entry = i_ddi_node_state(dip);
1096 pdip = ddi_get_parent(dip);
1100 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1113 addr = ddi_get_name_addr(dip);
1120 error = (*f)(pdip, pdip, DDI_CTLOPS_UNINITCHILD, dip, (void *)NULL);
1123 mutex_enter(&DEVI(dip)->devi_lock);
1124 if ((DEVI(dip)->devi_flags & DEVI_CACHED_DEVID)) {
1125 DEVI(dip)->devi_flags &= ~DEVI_CACHED_DEVID;
1126 mutex_exit(&DEVI(dip)->devi_lock);
1127 ddi_devid_unregister(dip);
1129 mutex_exit(&DEVI(dip)->devi_lock);
1132 ddi_set_name_addr(dip, NULL);
1141 e_ddi_free_instance(dip, addr);
1142 DEVI(dip)->devi_instance = -1;
1148 remove_global_props(dip);
1173 if (!((ndi_dev_is_persistent_node(dip) == 0) &&
1174 (DEVI(dip)->devi_flags & DEVI_REBIND)))
1175 e_ddi_prop_remove_all(dip);
1178 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1193 probe_node(dev_info_t *dip)
1197 ASSERT(i_ddi_node_state(dip) == DS_INITIALIZED);
1200 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1203 DEVI(dip)->devi_ops = ndi_hold_driver(dip);
1204 if (DEVI(dip)->devi_ops == NULL) {
1207 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1212 (void) devi_identify(dip);
1214 rv = devi_probe(dip);
1217 ndi_rele_driver(dip);
1218 DEVI(dip)->devi_ops = NULL;
1223 e_ddi_keep_instance(dip); /* persist instance */
1231 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip),
1239 ddi_driver_name(dip), ddi_get_instance(dip));
1252 unprobe_node(dev_info_t *dip)
1254 ASSERT(i_ddi_node_state(dip) == DS_PROBED);
1258 * dip cannot be downgraded by the framework.
1262 (void *)dip, ddi_node_name(dip)));
1271 attach_node(dev_info_t *dip)
1275 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1276 ASSERT(i_ddi_node_state(dip) == DS_PROBED);
1279 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1284 if ((rv = mdi_devi_online(dip, 0)) != NDI_SUCCESS) {
1289 ASSERT(DEVI(dip)->devi_ops == NULL);
1294 DEVI(dip)->devi_ops = ndi_hold_driver(dip);
1295 if (DEVI(dip)->devi_ops == NULL) {
1301 DEVI(dip)->devi_major);
1305 if (NEXUS_DRV(DEVI(dip)->devi_ops))
1306 DEVI(dip)->devi_taskq = ddi_taskq_create(dip,
1310 mutex_enter(&(DEVI(dip)->devi_lock));
1311 DEVI_SET_ATTACHING(dip);
1312 DEVI_SET_NEED_RESET(dip);
1313 mutex_exit(&(DEVI(dip)->devi_lock));
1315 rv = devi_attach(dip, DDI_ATTACH);
1317 mutex_enter(&(DEVI(dip)->devi_lock));
1318 DEVI_CLR_ATTACHING(dip);
1321 DEVI_CLR_NEED_RESET(dip);
1322 mutex_exit(&DEVI(dip)->devi_lock);
1328 dacf_clr_rsrvs(dip, DACF_OPID_POSTATTACH);
1329 dacf_clr_rsrvs(dip, DACF_OPID_PREDETACH);
1331 if (DEVI(dip)->devi_taskq)
1332 ddi_taskq_destroy(DEVI(dip)->devi_taskq);
1333 ddi_remove_minor_node(dip, NULL);
1336 ndi_rele_driver(dip);
1337 DEVI(dip)->devi_ops = NULL;
1339 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1342 mutex_exit(&DEVI(dip)->devi_lock);
1354 detach_node(dev_info_t *dip, uint_t flag)
1359 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1360 ASSERT(i_ddi_node_state(dip) == DS_ATTACHED);
1363 if (DEVI(dip)->devi_ref)
1367 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1377 ASSERT(!MDI_PHCI(dip) ||
1378 (ddi_get_parent(mdi_devi_get_vdip(dip)) == ddi_get_parent(dip)) ||
1379 DEVI_BUSY_OWNED(mdi_devi_get_vdip(dip)));
1382 if (mdi_devi_offline(dip, flag) != NDI_SUCCESS) {
1387 if (DEVI(dip)->devi_taskq)
1388 ddi_taskq_wait(DEVI(dip)->devi_taskq);
1390 rv = devi_detach(dip, DDI_DETACH);
1395 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1399 mutex_enter(&(DEVI(dip)->devi_lock));
1400 DEVI_CLR_NEED_RESET(dip);
1401 mutex_exit(&(DEVI(dip)->devi_lock));
1407 if (IOMMU_USED(dip))
1408 iommulib_nex_close(dip);
1412 if (DEVI(dip)->devi_taskq) {
1413 ddi_taskq_destroy(DEVI(dip)->devi_taskq);
1414 DEVI(dip)->devi_taskq = NULL;
1419 dacf_clr_rsrvs(dip, DACF_OPID_POSTATTACH);
1420 dacf_clr_rsrvs(dip, DACF_OPID_PREDETACH);
1424 if (DEVI(dip)->devi_flavorv_n > 1 && DEVI(dip)->devi_flavorv != NULL) {
1425 kmem_free(DEVI(dip)->devi_flavorv,
1426 (DEVI(dip)->devi_flavorv_n - 1) * sizeof (void *));
1427 DEVI(dip)->devi_flavorv = NULL;
1431 ddi_remove_minor_node(dip, NULL);
1432 ddi_prop_remove_all(dip);
1435 mutex_enter(&DEVI(dip)->devi_lock);
1436 DEVI(dip)->devi_flags &= ~(DEVI_MADE_CHILDREN|DEVI_ATTACHED_CHILDREN);
1437 mutex_exit(&DEVI(dip)->devi_lock);
1445 dnp = &(devnamesp[DEVI(dip)->devi_major]);
1452 ndi_rele_driver(dip);
1453 DEVI(dip)->devi_ops = NULL;
1461 postattach_node(dev_info_t *dip)
1467 * are removed but dip is still around. We don't want to
1473 if (DEVI_IS_DEVICE_REMOVED(dip))
1481 rval = dacfc_postattach(dip);
1492 ddi_driver_name(dip), ddi_get_instance(dip));
1503 predetach_node(dev_info_t *dip, uint_t flag)
1515 if ((ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1517 (ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1522 dnp = &devnamesp[DEVI(dip)->devi_major];
1532 ret = dacfc_predetach(dip);
1549 i_ndi_config_node(dev_info_t *dip, ddi_node_state_t state, uint_t flag)
1554 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1556 while ((i_ddi_node_state(dip) < state) && (rv == DDI_SUCCESS)) {
1564 switch (i_ddi_node_state(dip)) {
1570 link_node(dip);
1571 translate_devid((dev_info_t *)dip);
1572 i_ddi_set_node_state(dip, DS_LINKED);
1586 if ((rv = bind_node(dip)) == DDI_SUCCESS)
1587 i_ddi_set_node_state(dip, DS_BOUND);
1596 if ((rv = init_node(dip)) == DDI_SUCCESS)
1597 i_ddi_set_node_state(dip, DS_INITIALIZED);
1600 if ((rv = probe_node(dip)) == DDI_SUCCESS)
1601 i_ddi_set_node_state(dip, DS_PROBED);
1609 if (i_ddi_check_retire(dip) == 1 &&
1610 ndi_dev_is_persistent_node(dip) &&
1616 if ((rv = attach_node(dip)) == DDI_SUCCESS)
1617 i_ddi_set_node_state(dip, DS_ATTACHED);
1621 if ((rv = postattach_node(dip)) == DDI_SUCCESS)
1622 i_ddi_set_node_state(dip, DS_READY);
1633 da_log_enter(dip);
1641 i_ndi_unconfig_node(dev_info_t *dip, ddi_node_state_t state, uint_t flag)
1645 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1647 while ((i_ddi_node_state(dip) > state) && (rv == DDI_SUCCESS)) {
1655 switch (i_ddi_node_state(dip)) {
1663 if ((rv = unlink_node(dip)) == DDI_SUCCESS)
1664 i_ddi_set_node_state(dip, DS_PROTO);
1672 if ((rv = unbind_node(dip)) == DDI_SUCCESS)
1673 i_ddi_set_node_state(dip, DS_LINKED);
1676 if ((rv = uninit_node(dip)) == DDI_SUCCESS)
1677 i_ddi_set_node_state(dip, DS_BOUND);
1680 if ((rv = unprobe_node(dip)) == DDI_SUCCESS)
1681 i_ddi_set_node_state(dip, DS_INITIALIZED);
1686 mutex_enter(&(DEVI(dip)->devi_lock));
1687 DEVI_SET_DETACHING(dip);
1688 mutex_exit(&(DEVI(dip)->devi_lock));
1692 if ((rv = detach_node(dip, flag)) == DDI_SUCCESS)
1693 i_ddi_set_node_state(dip, DS_PROBED);
1695 mutex_enter(&(DEVI(dip)->devi_lock));
1696 DEVI_CLR_DETACHING(dip);
1697 mutex_exit(&(DEVI(dip)->devi_lock));
1702 if ((rv = predetach_node(dip, flag)) == DDI_SUCCESS)
1703 i_ddi_set_node_state(dip, DS_ATTACHED);
1709 da_log_enter(dip);
1732 ddi_uninitchild(dev_info_t *dip)
1735 dev_info_t *parent = ddi_get_parent(dip);
1739 ret = i_ndi_unconfig_node(dip, DS_BOUND, 0);
1749 i_ddi_attachchild(dev_info_t *dip)
1751 dev_info_t *parent = ddi_get_parent(dip);
1756 if ((i_ddi_node_state(dip) < DS_BOUND) || DEVI_IS_DEVICE_OFFLINE(dip))
1759 ret = i_ndi_config_node(dip, DS_READY, 0);
1767 (void) i_ndi_unconfig_node(dip, DS_INITIALIZED, 0);
1782 i_ddi_detachchild(dev_info_t *dip, uint_t flags)
1784 dev_info_t *parent = ddi_get_parent(dip);
1789 ret = i_ndi_unconfig_node(dip, DS_PROBED, flags);
1791 (void) i_ndi_config_node(dip, DS_READY, 0);
1794 (void) i_ndi_unconfig_node(dip, DS_INITIALIZED, 0);
1805 dev_info_t *dip;
1808 dip = i_ddi_alloc_node(pdip, name, nodeid, (int)unit, NULL, KM_SLEEP);
1811 (void) i_ndi_config_node(dip, DS_BOUND, 0);
1813 return (dip);
1817 * ddi_remove_child: remove the dip. The parent must be attached and held
1820 ddi_remove_child(dev_info_t *dip, int dummy)
1824 dev_info_t *parent = ddi_get_parent(dip);
1833 if (DEVI(dip)->devi_child) {
1834 ret = ndi_devi_unconfig(dip, NDI_DEVI_REMOVE);
1839 ASSERT(DEVI(dip)->devi_child == NULL);
1842 ret = i_ndi_unconfig_node(dip, DS_PROTO, 0);
1848 ASSERT(i_ddi_node_state(dip) == DS_PROTO);
1849 i_ddi_free_node(dip);
1862 ndi_hold_devi(dev_info_t *dip)
1864 mutex_enter(&DEVI(dip)->devi_lock);
1865 ASSERT(DEVI(dip)->devi_ref >= 0);
1866 DEVI(dip)->devi_ref++;
1868 mutex_exit(&DEVI(dip)->devi_lock);
1872 ndi_rele_devi(dev_info_t *dip)
1874 ASSERT(DEVI(dip)->devi_ref > 0);
1876 mutex_enter(&DEVI(dip)->devi_lock);
1877 DEVI(dip)->devi_ref--;
1879 mutex_exit(&DEVI(dip)->devi_lock);
1883 e_ddi_devi_holdcnt(dev_info_t *dip)
1885 return (DEVI(dip)->devi_ref);
1892 ndi_hold_driver(dev_info_t *dip)
1894 if (i_ddi_node_state(dip) < DS_BOUND)
1897 ASSERT(DEVI(dip)->devi_major != -1);
1898 return (mod_hold_dev_by_major(DEVI(dip)->devi_major));
1902 ndi_rele_driver(dev_info_t *dip)
1904 ASSERT(i_ddi_node_state(dip) >= DS_BOUND);
1905 mod_rele_dev_by_major(DEVI(dip)->devi_major);
1913 ndi_devi_enter(dev_info_t *dip, int *circular)
1915 struct dev_info *devi = DEVI(dip);
1916 ASSERT(dip != NULL);
1919 ASSERT(!MDI_VHCI(dip) || (mdi_devi_pdip_entered(dip) == 0) ||
1920 DEVI_BUSY_OWNED(dip));
1943 ndi_devi_exit(dev_info_t *dip, int circular)
1945 struct dev_info *devi = DEVI(dip);
1947 ASSERT(dip != NULL);
1967 if (MDI_PHCI(dip)) {
1968 vdevi = DEVI(mdi_devi_get_vdip(dip));
1985 ndi_devi_exit_and_wait(dev_info_t *dip, int circular, clock_t end_time)
1987 struct dev_info *devi = DEVI(dip);
1988 ASSERT(dip != NULL);
2015 ndi_devi_tryenter(dev_info_t *dip, int *circular)
2018 struct dev_info *devi = DEVI(dip);
2019 ASSERT(dip != NULL);
2081 ndi_devi_free(dev_info_t *dip)
2083 ASSERT(dip != NULL);
2085 if (i_ddi_node_state(dip) >= DS_INITIALIZED)
2089 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip));
2091 (void) ddi_remove_child(dip, 0);
2102 ndi_devi_bind_driver(dev_info_t *dip, uint_t flags)
2106 dev_info_t *pdip = ddi_get_parent(dip);
2111 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags));
2114 if (i_ndi_config_node(dip, DS_BOUND, flags) == DDI_SUCCESS)
2122 * ndi_devi_unbind_driver: unbind the dip
2125 ndi_devi_unbind_driver(dev_info_t *dip)
2127 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
2129 return (i_ndi_unconfig_node(dip, DS_LINKED, 0));
2140 i_ddi_node_state(dev_info_t *dip)
2142 return (DEVI(dip)->devi_node_state);
2149 i_ddi_set_node_state(dev_info_t *dip, ddi_node_state_t state)
2151 DEVI(dip)->devi_node_state = state;
2162 i_ddi_devi_attached(dev_info_t *dip)
2164 return (DEVI(dip)->devi_node_state >= DS_ATTACHED);
2202 dev_info_t *dip;
2232 for (dip = head; dip; dip = ddi_get_next_sibling(dip)) {
2235 if (strcmp(cname, DEVI(dip)->devi_node_name) != 0)
2239 if (DEVI(dip)->devi_major != major)
2243 if ((addr = DEVI(dip)->devi_addr) == NULL) {
2246 if (ddi_initchild(ddi_get_parent(dip), dip)
2249 addr = DEVI(dip)->devi_addr;
2252 dip, buf, MAXNAMELEN) != DDI_SUCCESS))
2268 return (dip);
2276 find_duplicate_child(dev_info_t *pdip, dev_info_t *dip)
2279 char *cname = DEVI(dip)->devi_node_name;
2280 char *caddr = DEVI(dip)->devi_addr;
2282 /* search nodes before dip */
2285 if (dup != dip)
2289 * search nodes after dip; normally this is not needed,
2291 return (find_sibling(ddi_get_next_sibling(dip), cname, caddr,
2317 dev_info_t *dip;
2320 dip = find_sibling(ddi_get_child(pdip), cname, caddr,
2322 if (dip)
2323 return (dip);
2336 dev_info_t *dip;
2339 dip = find_sibling(ddi_get_child(pdip), cname, caddr,
2341 if (dip)
2342 return (dip);
2363 dev_info_t *dip;
2370 dip = find_sibling(ddi_get_child(pdip), NULL, caddr,
2372 if (dip)
2373 return (dip);
2494 * Get all classes exported by dip
2497 i_ddi_get_exported_classes(dev_info_t *dip, char ***classes)
2507 ASSERT(i_ddi_node_state(dip) >= DS_BOUND);
2509 if (dip == ddi_root_node()) /* rootnode exports class "root" */
2512 nclass += get_class(ddi_driver_name(dip), NULL);
2519 if (dip == ddi_root_node()) {
2523 n += get_class(ddi_driver_name(dip), buf);
2623 ndi_merge_node(dev_info_t *dip, int (*make_ua)(dev_info_t *, char *, int))
2627 ASSERT(ndi_dev_is_persistent_node(dip) == 0);
2628 ASSERT(ddi_get_name_addr(dip) != NULL);
2630 hwdip = ndi_devi_findchild_by_callback(ddi_get_parent(dip),
2631 ddi_binding_name(dip), ddi_get_name_addr(dip), make_ua);
2637 if ((hwdip == NULL) || (hwdip == dip)) {
2640 ddi_deviname(dip, buf)));
2660 ddi_deviname(dip, buf)));
2679 ddi_deviname(dip, buf), (void *)hwdip));
2684 mutex_enter(&DEVI(dip)->devi_lock);
2685 DEVI(hwdip)->devi_sys_prop_ptr = DEVI(dip)->devi_sys_prop_ptr;
2686 DEVI(hwdip)->devi_drv_prop_ptr = DEVI(dip)->devi_drv_prop_ptr;
2687 DEVI(dip)->devi_sys_prop_ptr = NULL;
2688 DEVI(dip)->devi_drv_prop_ptr = NULL;
2689 mutex_exit(&DEVI(dip)->devi_lock);
2704 ndi_merge_wildcard_node(dev_info_t *dip)
2707 dev_info_t *pdip = ddi_get_parent(dip);
2708 major_t major = ddi_driver_major(dip);
2711 ASSERT(ndi_dev_is_persistent_node(dip) == 0);
2719 mutex_enter(&DEVI(dip)->devi_lock);
2745 (void *)hwdip, ddi_node_name(dip)));
2750 i_ddi_prop_list_dup(DEVI(dip)->devi_sys_prop_ptr, KM_SLEEP);
2752 i_ddi_prop_list_dup(DEVI(dip)->devi_drv_prop_ptr, KM_SLEEP);
2755 mutex_exit(&DEVI(dip)->devi_lock);
2766 ddi_compatible_driver_major(dev_info_t *dip, char **formp)
2768 struct dev_info *devi = DEVI(dip);
2777 if (ddi_prop_exists(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
2811 (void) lookup_compatible(dip, KM_SLEEP);
2829 major = ddi_name_to_major(ddi_node_name(dip));
2846 lookup_compatible(dev_info_t *dip, uint_t flag)
2855 if (DEVI(dip)->devi_compat_names) {
2865 if (ndi_dev_is_prom_node(dip) == 0) {
2869 rv = ddi_prop_lookup_common(DDI_DEV_T_ANY, dip, prop_flags,
2889 DEVI(dip)->devi_compat_names = di_compat_strp;
2890 DEVI(dip)->devi_compat_length = di_compat_strlen;
2942 link_to_driver_list(dev_info_t *dip)
2944 major_t major = DEVI(dip)->devi_major;
2952 if (ndi_dev_is_persistent_node(dip)) {
2954 remove_from_dn_list(dnp, dip);
2961 add_to_dn_list(dnp, dip);
2965 unlink_from_driver_list(dev_info_t *dip)
2967 major_t major = DEVI(dip)->devi_major;
2976 remove_from_dn_list(dnp, dip);
2981 if (ndi_dev_is_persistent_node(dip)) {
2983 add_to_dn_list(dnp, dip);
2988 * scan the per-driver list looking for dev_info "dip"
2991 in_dn_list(struct devnames *dnp, dev_info_t *dip)
2999 if (idevi == DEVI(dip))
3000 return (dip);
3007 * insert devinfo node 'dip' into the per-driver instance list
3014 add_to_ordered_dn_list(struct devnames *dnp, dev_info_t *dip)
3021 if (ndi_dev_is_prom_node(dip)) {
3028 } else if (ndi_dev_is_persistent_node(dip)) {
3044 DEVI(dip)->devi_next = DEVI(*dipp);
3045 *dipp = dip;
3053 add_to_dn_list(struct devnames *dnp, dev_info_t *dip)
3059 if (in_dn_list(dnp, dip)) {
3061 DEVI(dip)->devi_node_name);
3063 add_to_ordered_dn_list(dnp, dip);
3069 remove_from_dn_list(struct devnames *dnp, dev_info_t *dip)
3076 while (*plist && (*plist != dip)) {
3081 ASSERT(*plist == dip);
3082 *plist = (dev_info_t *)(DEVI(dip)->devi_next);
3083 DEVI(dip)->devi_next = NULL;
3087 DEVI(dip)->devi_node_name));
3097 add_global_props(dev_info_t *dip)
3102 ASSERT(DEVI(dip)->devi_global_prop_list == NULL);
3103 ASSERT(DEVI(dip)->devi_major != DDI_MAJOR_T_NONE);
3105 dnp = &devnamesp[DEVI(dip)->devi_major];
3115 mutex_enter(&DEVI(dip)->devi_lock);
3116 DEVI(dip)->devi_global_prop_list = plist;
3117 mutex_exit(&DEVI(dip)->devi_lock);
3121 remove_global_props(dev_info_t *dip)
3125 mutex_enter(&DEVI(dip)->devi_lock);
3126 proplist = DEVI(dip)->devi_global_prop_list;
3127 DEVI(dip)->devi_global_prop_list = NULL;
3128 mutex_exit(&DEVI(dip)->devi_lock);
3134 major = ddi_driver_major(dip);
3298 da_log_enter(dev_info_t *dip)
3300 devinfo_audit_t *da_log, *da = DEVI(dip)->devi_audit;
3308 da->da_devinfo = dip;
3311 da->da_node_state = DEVI(dip)->devi_node_state;
3312 da->da_device_state = DEVI(dip)->devi_state;
3432 dev_info_t *dip;
3446 append_node(struct walk_elem **list, dev_info_t *dip)
3452 elem->dip = dip;
3470 walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg,
3477 * dip on the sibling list. Second pass invoke callback on
3478 * children of each dip.
3480 while (dip) {
3481 switch ((*f)(dip, arg)) {
3487 /* ignore sibling by setting dip to NULL */
3488 append_node(&head, dip);
3489 dip = NULL;
3494 dip = ddi_get_next_sibling(dip);
3499 append_node(&head, dip);
3500 dip = ddi_get_next_sibling(dip);
3512 ndi_devi_enter(head->dip, &circ);
3513 if (walk_devs(ddi_get_child(head->dip), f, arg, do_locking) ==
3516 ndi_devi_exit(head->dip, circ);
3521 ndi_devi_exit(head->dip, circ);
3544 * the parent of dip is held against changes, unless the parent
3562 ddi_walk_devs(dev_info_t *dip, int (*f)(dev_info_t *, void *), void *arg)
3565 ASSERT(dip == NULL || ddi_get_parent(dip) == NULL ||
3566 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
3568 (void) walk_devs(dip, f, arg, 1);
3586 dev_info_t *dip;
3594 dip = dnp->dn_head;
3595 while (dip) {
3596 ndi_hold_devi(dip);
3598 if ((*f)(dip, arg) == DDI_WALK_TERMINATE) {
3599 ndi_rele_devi(dip);
3603 ndi_rele_devi(dip);
3604 dip = ddi_get_next(dip);
3613 dev_info_t *dip; /* result */
3620 i_find_devi(dev_info_t *dip, void *arg)
3625 (strcmp(ddi_node_name(dip), info->nodename) == 0)) &&
3627 (ddi_get_instance(dip) == info->instance)) &&
3628 ((info->attached == 0) || i_ddi_devi_attached(dip))) {
3629 info->dip = dip;
3630 ndi_hold_devi(dip);
3638 * Find dip with a known node name and instance and return with it held
3648 info.dip = NULL;
3651 return (info.dip);
3762 ddi_is_pci_dip(dev_info_t *dip)
3766 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3970 * so we have no way of passing back the held dip. Not holding
3971 * the dip allows detaches to occur - which can cause problems
3974 * Instead of holding the dip, we place a ddi-no-autodetach
4020 dev_info_t *dip = NULL;
4026 error = resolve_pathname(prompath, &dip, &devt, &spectype);
4029 ASSERT(dip && devt != NODEV);
4034 (void) ddi_pathname(dip, devfspath);
4036 ndi_devi_enter(dip, &circ);
4037 minor_name = i_ddi_devtspectype_to_minorname(dip, devt, spectype);
4047 CLONE_PATH, ddi_driver_name(dip));
4049 ndi_devi_exit(dip, circ);
4052 ndi_rele_devi(dip);
4067 should_implement_quiesce(dev_info_t *dip)
4069 struct dev_info *devi = DEVI(dip);
4073 * If dip is pseudo and skip_pseudo is set, driver doesn't have to
4077 strncmp(ddi_binding_name(dip), "pseudo", sizeof ("pseudo")) == 0)
4081 * If parent dip is pseudo and skip_pseudo is set, driver doesn't have
4084 if (skip_pseudo && (pdip = ddi_get_parent(dip)) != NULL &&
4091 if (!i_ddi_devi_attached(dip))
4095 * If dip has no hardware property and skip_non_hw is set,
4119 check_driver_quiesce(dev_info_t *dip, void *arg)
4123 if (!should_implement_quiesce(dip))
4126 if ((ops = ddi_get_driver(dip)) == NULL)
4133 "quiesced", ddi_driver_name(dip));
4136 ddi_driver_name(dip));
4141 cmn_err(CE_WARN, "%s has no quiesce()", ddi_driver_name(dip));
4151 quiesce_one_device(dev_info_t *dip, void *arg)
4159 if (!i_ddi_devi_attached(dip))
4162 if ((ops = ddi_get_driver(dip)) == NULL)
4165 should_quiesce = should_implement_quiesce(dip);
4179 rc = devi_quiesce(dip);
4184 ddi_driver_name(dip), ddi_get_instance(dip));
4196 * children first. All subtrees under the parent of dip will be quiesced.
4199 quiesce_devices(dev_info_t *dip, void *arg)
4207 for (; dip != NULL; dip = ddi_get_next_sibling(dip)) {
4208 quiesce_devices(ddi_get_child(dip), arg);
4210 quiesce_one_device(dip, arg);
4218 reset_leaf_device(dev_info_t *dip, void *arg)
4224 if (!DEVI_NEED_RESET(dip))
4231 ops = ddi_get_driver(dip);
4237 if (DEVI_IS_ATTACHING(dip) || DEVI_IS_DETACHING(dip)) {
4246 ddi_pathname(dip, path));
4251 ddi_driver_name(dip), ddi_get_instance(dip)));
4253 (void) devi_reset(dip, DDI_RESET_FORCE);
4312 bind_dip(dev_info_t *dip, void *arg)
4322 if (i_ddi_node_state(dip) >= DS_BOUND) {
4323 major = ddi_compatible_driver_major(dip, NULL);
4324 if ((DEVI(dip)->devi_major == major) &&
4325 (i_ddi_node_state(dip) >= DS_INITIALIZED)) {
4331 (void) ddi_pathname(dip, path);
4340 (major != DEVI(dip)->devi_major))
4341 (void) ndi_devi_unbind_driver(dip);
4345 if (i_ddi_node_state(dip) < DS_BOUND)
4346 (void) ndi_devi_bind_driver(dip, 0);
4374 unbind_alias_dev_in_use(dev_info_t *dip, char *alias)
4378 ddi_driver_name(dip), ddi_get_instance(dip),
4379 i_ddi_node_state(dip), alias);
4388 unbind_children_by_alias(dev_info_t *dip, void *arg)
4404 ndi_devi_enter(dip, &circ);
4405 for (cdip = ddi_get_child(dip); cdip; cdip = next) {
4422 ndi_devi_exit(dip, circ);
4458 unbind_children_by_driver(dev_info_t *dip, void *arg)
4474 ndi_devi_enter(dip, &circ);
4475 for (cdip = ddi_get_child(dip); cdip; cdip = next) {
4488 ndi_devi_exit(dip, circ);
4517 dev_info_t *dip;
4531 dip = i_ddi_alloc_node(pdip, node_name, (pnode_t)DEVI_PSEUDO_NODEID,
4534 if (dip == NULL)
4537 if (ddi_initchild(pdip, dip) != DDI_SUCCESS)
4538 (void) ddi_remove_child(dip, 0);
4583 dev_info_t *dip;
4589 dip = ddi_get_child(pdip);
4590 while (dip) {
4591 if (ndi_dev_is_persistent_node(dip))
4592 (void) i_ndi_config_node(dip, DS_INITIALIZED, flags);
4593 dip = ddi_get_next_sibling(dip);
4602 i_ndi_devi_report_status_change(dev_info_t *dip, char *path)
4606 if (!DEVI_NEED_REPORT(dip) ||
4607 (i_ddi_node_state(dip) < DS_INITIALIZED) ||
4608 ndi_dev_is_hidden_node(dip)) {
4615 if (DEVI_IS_DEVICE_REMOVED(dip)) {
4617 } else if (DEVI_IS_DEVICE_OFFLINE(dip)) {
4619 } else if (DEVI_IS_DEVICE_DOWN(dip)) {
4621 } else if (DEVI_IS_BUS_QUIESCED(dip)) {
4623 } else if (DEVI_IS_BUS_DOWN(dip)) {
4625 } else if (i_ddi_devi_attached(dip)) {
4634 ddi_pathname(dip, path), ddi_driver_name(dip),
4635 ddi_get_instance(dip), status);
4639 path, ddi_driver_name(dip),
4640 ddi_get_instance(dip), status);
4643 mutex_enter(&(DEVI(dip)->devi_lock));
4644 DEVI_REPORT_DONE(dip);
4645 mutex_exit(&(DEVI(dip)->devi_lock));
4652 i_log_devfs_add_devinfo(dev_info_t *dip, uint_t flags)
4663 ASSERT(dip && ddi_get_parent(dip) &&
4664 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
4677 (void) ddi_pathname(dip, pathname);
4688 if ((class_name = i_ddi_devi_class(dip)) != NULL) {
4741 ddi_driver_name(dip), ddi_driver_name(dip));
4847 i_ddi_log_devfs_device_remove(dev_info_t *dip)
4851 ASSERT(dip && ddi_get_parent(dip) &&
4852 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
4853 ASSERT(DEVI_IS_DEVICE_REMOVED(dip));
4855 ASSERT(i_ddi_node_state(dip) >= DS_INITIALIZED);
4856 if (i_ddi_node_state(dip) < DS_INITIALIZED)
4860 ldi_invoke_finalize(dip, DDI_DEV_T_ANY, 0, LDI_EV_DEVICE_REMOVE,
4865 (void) i_log_devfs_remove_devinfo(ddi_pathname(dip, path),
4866 i_ddi_devi_class(dip), (char *)ddi_driver_name(dip),
4867 ddi_get_instance(dip), 0);
4872 i_ddi_log_devfs_device_insert(dev_info_t *dip)
4874 ASSERT(dip && ddi_get_parent(dip) &&
4875 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
4876 ASSERT(!DEVI_IS_DEVICE_REMOVED(dip));
4878 (void) i_log_devfs_add_devinfo(dip, 0);
4939 i_log_devfs_branch_add(dev_info_t *dip)
4945 (void) ddi_pathname(dip, node_path);
4962 * enqueue the dip's deviname on the branch event queue.
4965 brevq_enqueue(struct brevq_node **brevqp, dev_info_t *dip,
4972 (void) ddi_deviname(dip, deviname);
5024 * associated memory. Same as the previous function but operates on dip.
5027 log_and_free_brevq_dip(dev_info_t *dip, struct brevq_node *brevq)
5032 (void) ddi_pathname(dip, path);
5038 * log the outstanding branch remove events for the grand children of the dip
5042 log_and_free_br_events_on_grand_children(dev_info_t *dip,
5050 (void) ddi_pathname(dip, path);
5055 /* now path contains the node path to the dip's child */
5064 * log and cleanup branch remove events for the grand children of the dip.
5067 cleanup_br_events_on_grand_children(dev_info_t *dip, struct brevq_node **brevqp)
5078 ndi_devi_enter(dip, &circ);
5081 for (child = ddi_get_child(dip); child != NULL;
5099 (void) ddi_pathname(dip, path);
5126 ndi_devi_exit(dip, circ);
5131 need_remove_event(dev_info_t *dip, int flags)
5135 !(DEVI_EVREMOVE(dip)))
5142 * Unconfigure children/descendants of the dip.
5146 * a queue of dip's child devinames for which branch remove events need
5150 devi_unconfig_branch(dev_info_t *dip, dev_info_t **dipp, int flags,
5157 if ((!(flags & NDI_BRANCH_EVENT_OP)) && need_remove_event(dip, flags))
5161 rval = devi_unconfig_common(dip, dipp, flags, DDI_MAJOR_T_NONE,
5165 log_and_free_brevq_dip(dip, *brevqp);
5169 rval = devi_unconfig_common(dip, dipp, flags, DDI_MAJOR_T_NONE,
5176 * If the dip is already bound to a driver transition to DS_INITIALIZED
5182 init_bound_node_ev(dev_info_t *pdip, dev_info_t *dip, int flags)
5184 if (need_remove_event(dip, flags) &&
5185 i_ddi_node_state(dip) == DS_BOUND &&
5186 i_ddi_devi_attached(pdip) && !DEVI_IS_DEVICE_OFFLINE(dip))
5187 (void) ddi_initchild(pdip, dip);
5194 devi_attach_node(dev_info_t *dip, uint_t flags)
5196 dev_info_t *pdip = ddi_get_parent(dip);
5200 mutex_enter(&(DEVI(dip)->devi_lock));
5202 if (!i_ddi_devi_attached(dip))
5203 DEVI_SET_REPORT(dip);
5204 DEVI_SET_DEVICE_ONLINE(dip);
5206 if (DEVI_IS_DEVICE_OFFLINE(dip)) {
5207 mutex_exit(&(DEVI(dip)->devi_lock));
5210 mutex_exit(&(DEVI(dip)->devi_lock));
5212 if (i_ddi_attachchild(dip) != DDI_SUCCESS) {
5213 mutex_enter(&(DEVI(dip)->devi_lock));
5214 DEVI_SET_EVUNINIT(dip);
5215 mutex_exit(&(DEVI(dip)->devi_lock));
5217 if (ndi_dev_is_persistent_node(dip))
5218 (void) ddi_uninitchild(dip);
5224 (void) ddi_remove_child(dip, 0);
5229 i_ndi_devi_report_status_change(dip, NULL);
5235 if ((flags & NDI_NO_EVENT) == 0 && !(DEVI_EVADD(dip))) {
5236 (void) i_log_devfs_add_devinfo(dip, flags);
5238 mutex_enter(&(DEVI(dip)->devi_lock));
5239 DEVI_SET_EVADD(dip);
5240 mutex_exit(&(DEVI(dip)->devi_lock));
5242 mutex_enter(&(DEVI(dip)->devi_lock));
5243 DEVI_SET_EVADD(dip);
5244 mutex_exit(&(DEVI(dip)->devi_lock));
5279 /* NOTE: devi_attach_node() may remove the dip */
5318 devi_config_common(dev_info_t *dip, int flags, major_t major)
5323 if (!i_ddi_devi_attached(dip))
5326 if (pm_pre_config(dip, NULL) != DDI_SUCCESS)
5329 if ((DEVI(dip)->devi_ops->devo_bus_ops == NULL) ||
5330 (DEVI(dip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) ||
5331 (f = DEVI(dip)->devi_ops->devo_bus_ops->bus_config) == NULL) {
5332 error = config_immediate_children(dip, flags, major);
5337 error = (*f)(dip,
5342 pm_post_config(dip, NULL);
5351 (void) devfs_clean(dip, NULL, 0);
5354 (void) config_grand_children(dip, flags, major);
5356 pm_post_config(dip, NULL);
5365 ndi_devi_config(dev_info_t *dip, int flags)
5369 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags));
5371 return (devi_config_common(dip, flags, DDI_MAJOR_T_NONE));
5378 ndi_devi_config_driver(dev_info_t *dip, int flags, major_t major)
5385 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags));
5387 return (devi_config_common(dip, flags, major));
5695 * Mark the dip as having passed the constraint and allow
5704 * flag on the dip. If the constraint flag is set (implying that it passed
5705 * a constraint) we allow the dip to be retired. If not, we don't allow
5709 e_ddi_offline_notify(dev_info_t *dip)
5715 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): entered: dip=%p",
5716 (void *) dip));
5724 retval = contract_device_offline(dip, DDI_DEV_T_ANY, 0);
5727 RIO_DEBUG((CE_NOTE, "Received NACK for dip=%p", (void *)dip));
5732 RIO_DEBUG((CE_NOTE, "Received ACK for dip=%p", (void *)dip));
5736 RIO_DEBUG((CE_NOTE, "No contracts on dip=%p", (void *)dip));
5745 retval = ldi_invoke_notify(dip, DDI_DEV_T_ANY, 0, LDI_EV_OFFLINE, NULL);
5748 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_FAILURE);
5749 RIO_DEBUG((CE_NOTE, "LDI callback failed on dip=%p",
5750 (void *)dip));
5755 RIO_DEBUG((CE_NOTE, "LDI callback success on dip=%p",
5756 (void *)dip));
5760 RIO_DEBUG((CE_NOTE, "No LDI callbacks for dip=%p",
5761 (void *)dip));
5768 mutex_enter(&(DEVI(dip)->devi_lock));
5769 if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && failure) {
5771 "BLOCKED flag. dip=%p", (void *)dip));
5772 DEVI(dip)->devi_flags |= DEVI_R_BLOCKED;
5773 if (DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT) {
5775 "blocked. clearing RCM CONSTRAINT flag. dip=%p",
5776 (void *)dip));
5777 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT;
5779 } else if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && constraint) {
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)) {
5789 "use. Setting CONSTRAINT flag. dip=%p", (void *)dip));
5790 DEVI(dip)->devi_flags |= DEVI_R_CONSTRAINT;
5798 "constraint flag. dip=%p", (void *)dip));
5800 mutex_exit(&(DEVI(dip)->devi_lock));
5803 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): exit: dip=%p",
5804 (void *) dip));
5810 e_ddi_offline_finalize(dev_info_t *dip, int result)
5813 "dip=%p", result == DDI_SUCCESS ? "SUCCESS" : "FAILURE",
5814 (void *)dip));
5816 contract_device_negend(dip, DDI_DEV_T_ANY, 0, result == DDI_SUCCESS ?
5819 ldi_invoke_finalize(dip, DDI_DEV_T_ANY, 0,
5823 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_finalize(): exit: dip=%p",
5824 (void *)dip));
5828 e_ddi_degrade_finalize(dev_info_t *dip)
5831 "result always = DDI_SUCCESS, dip=%p", (void *)dip));
5833 contract_device_degrade(dip, DDI_DEV_T_ANY, 0);
5834 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_SUCCESS);
5836 ldi_invoke_finalize(dip, DDI_DEV_T_ANY, 0, LDI_EV_DEGRADE,
5839 RIO_VERBOSE((CE_NOTE, "e_ddi_degrade_finalize(): exit: dip=%p",
5840 (void *)dip));
5844 e_ddi_undegrade_finalize(dev_info_t *dip)
5847 "result always = DDI_SUCCESS, dip=%p", (void *)dip));
5849 contract_device_undegrade(dip, DDI_DEV_T_ANY, 0);
5850 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_SUCCESS);
5852 RIO_VERBOSE((CE_NOTE, "e_ddi_undegrade_finalize(): exit: dip=%p",
5853 (void *)dip));
5860 devi_detach_node(dev_info_t *dip, uint_t flags)
5862 dev_info_t *pdip = ddi_get_parent(dip);
5877 RIO_DEBUG((CE_NOTE, "devi_detach_node: offlining dip=%p",
5878 (void *)dip));
5879 if (e_ddi_offline_notify(dip) != DDI_SUCCESS) {
5881 "dip=%p", (void *)dip));
5888 if (ddi_get_eventcookie(dip, DDI_DEVI_REMOVE_EVENT,
5890 (void) ndi_post_event(dip, dip, cookie, NULL);
5901 if (i_ddi_detachchild(dip, flags) != DDI_SUCCESS) {
5905 "dip=%p", DDI_FAILURE, (void *)dip));
5906 e_ddi_offline_finalize(dip, DDI_FAILURE);
5914 "dip=%p", DDI_SUCCESS, (void *)dip));
5915 e_ddi_offline_finalize(dip, DDI_SUCCESS);
5926 mutex_enter(&(DEVI(dip)->devi_lock));
5927 DEVI_SET_DEVICE_OFFLINE(dip);
5928 mutex_exit(&(DEVI(dip)->devi_lock));
5931 if (i_ddi_node_state(dip) == DS_INITIALIZED) {
5932 struct dev_info *devi = DEVI(dip);
5936 (void) ddi_pathname(dip, devi->devi_ev_path);
5939 i_ndi_devi_report_status_change(dip,
5942 if (need_remove_event(dip, flags)) {
5947 devi->devi_ev_instance = ddi_get_instance(dip);
5949 mutex_enter(&(DEVI(dip)->devi_lock));
5950 DEVI_SET_EVREMOVE(dip);
5951 mutex_exit(&(DEVI(dip)->devi_lock));
5956 ret = ddi_uninitchild(dip);
5963 if (!ndi_dev_is_persistent_node(dip))
5973 if (DEVI_EVREMOVE(dip)) {
5975 DEVI(dip)->devi_ev_path,
5978 i_ddi_strdup(i_ddi_devi_class(dip),
5982 (char *)ddi_driver_name(dip),
5984 instance = DEVI(dip)->devi_ev_instance;
5988 ret = ddi_remove_child(dip, 0);
6014 dev_info_t *dip,
6033 ndi_devi_enter(dip, &circ);
6034 for (child = ddi_get_child(dip); child;
6048 if (vdip && (ddi_get_parent(vdip) != dip)) {
6049 ndi_devi_exit(dip, circ);
6053 ndi_devi_enter(dip, &circ);
6060 child = ddi_get_child(dip);
6090 ndi_devi_exit(dip, circ);
6102 dev_info_t *dip,
6114 hdl = mt_config_init(dip, dipp, flags, major, MT_UNCONFIG_OP, brevqp);
6121 * Unconfigure children/descendants of the dip.
6123 * If brevqp is not NULL, on return *brevqp is set to a queue of dip's
6128 dev_info_t *dip,
6145 * Power up the dip if it is powered off. If the flag bit
6146 * NDI_AUTODETACH is set and the dip is not at its full power,
6149 if (pm_pre_unconfig(dip, flags, &pm_cookie, NULL) != DDI_SUCCESS)
6158 (void) devfs_clean(dip, NULL, 0);
6160 rv = unconfig_grand_children(dip, dipp, flags, major, brevqp);
6164 log_and_free_br_events_on_grand_children(dip, *brevqp);
6168 pm_post_unconfig(dip, pm_cookie, NULL);
6184 if (!i_ddi_devi_attached(dip) ||
6185 (DEVI(dip)->devi_ops->devo_bus_ops == NULL) ||
6186 (DEVI(dip)->devi_ops->devo_bus_ops->busops_rev < BUSO_REV_5) ||
6187 (f = DEVI(dip)->devi_ops->devo_bus_ops->bus_unconfig) == NULL) {
6188 rv = unconfig_immediate_children(dip, dipp, flags, major);
6196 rv = (*f)(dip, flags, bus_op, (void *)(uintptr_t)major);
6199 pm_post_unconfig(dip, pm_cookie, NULL);
6202 cleanup_br_events_on_grand_children(dip, brevqp);
6213 ndi_devi_unconfig_driver(dev_info_t *dip, int flags, major_t major)
6217 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags));
6219 return (devi_unconfig_common(dip, NULL, flags, major, NULL));
6223 ndi_devi_unconfig(dev_info_t *dip, int flags)
6227 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags));
6229 return (devi_unconfig_common(dip, NULL, flags, DDI_MAJOR_T_NONE, NULL));
6233 e_ddi_devi_unconfig(dev_info_t *dip, dev_info_t **dipp, int flags)
6237 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip, flags));
6239 return (devi_unconfig_common(dip, dipp, flags, DDI_MAJOR_T_NONE, NULL));
6387 dev_info_t *dip;
6397 i_ndi_devi_async_common(dev_info_t *dip, uint_t flags, void (*func)())
6402 dev_info_t *pdip = ddi_get_parent(dip);
6406 ASSERT(ndi_dev_is_persistent_node(dip));
6421 arg->dip = dip;
6439 (void) ndi_devi_bind_driver(arg->dip, arg->flags);
6444 ndi_devi_bind_driver_async(dev_info_t *dip, uint_t flags)
6446 return (i_ndi_devi_async_common(dip, flags,
6454 ndi_devi_online(dev_info_t *dip, uint_t flags)
6457 dev_info_t *pdip = ddi_get_parent(dip);
6463 ddi_driver_name(dip), ddi_get_instance(dip), (void *)dip));
6467 rv = i_ndi_config_node(dip, DS_BOUND, flags);
6488 ((flags & NDI_CONFIG) || DEVI_NEED_NDI_CONFIG(dip))) {
6494 * devi_attach_node() may remove dip on failure
6496 if ((rv = devi_attach_node(dip, flags)) == NDI_SUCCESS) {
6497 if ((flags & NDI_CONFIG) || DEVI_NEED_NDI_CONFIG(dip)) {
6499 * Hold the attached dip, and exit the parent while
6501 * attached dip.
6503 ndi_hold_devi(dip);
6506 (void) ndi_devi_config(dip, flags);
6509 ndi_rele_devi(dip);
6513 (void) i_log_devfs_branch_add(dip);
6540 (void) ndi_devi_online(arg->dip, arg->flags);
6545 ndi_devi_online_async(dev_info_t *dip, uint_t flags)
6549 mutex_enter(&(DEVI(dip)->devi_lock));
6550 DEVI_SET_NDI_CONFIG(dip);
6551 mutex_exit(&(DEVI(dip)->devi_lock));
6554 return (i_ndi_devi_async_common(dip, flags,
6569 ndi_devi_offline(dev_info_t *dip, uint_t flags)
6572 dev_info_t *pdip = ddi_get_parent(dip);
6586 if (MDI_PHCI(dip)) {
6587 vdip = mdi_devi_get_vdip(dip);
6595 if (i_ddi_devi_attached(dip)) {
6597 * If dip is in DS_READY state, there may be cached dv_nodes
6598 * referencing this dip, so we invoke devfs code path.
6603 (void) ddi_deviname(dip, devname);
6627 rval = devi_unconfig_branch(dip, NULL, flags|NDI_UNCONFIG,
6638 init_bound_node_ev(pdip, dip, flags);
6640 rval = devi_detach_node(dip, flags);
6643 log_and_free_brevq_dip(dip, brevq);
6711 reset_nexus_flags(dev_info_t *dip, void *arg)
6716 if (((DEVI(dip)->devi_flags & DEVI_MADE_CHILDREN) == 0) ||
6717 ((list = hwc_get_child_spec(dip, (major_t)(uintptr_t)arg)) == NULL))
6723 ndi_devi_enter(dip, &circ);
6724 mutex_enter(&DEVI(dip)->devi_lock);
6725 DEVI(dip)->devi_flags &= ~(DEVI_MADE_CHILDREN | DEVI_ATTACHED_CHILDREN);
6726 mutex_exit(&DEVI(dip)->devi_lock);
6727 ndi_devi_exit(dip, circ);
6754 dev_info_t *dip;
6770 dip = NULL;
6777 dip = e_ddi_nodeid_to_dip(nodeid);
6780 if (dip == NULL) {
6790 p = ddi_binding_name(dip);
6791 q = ddi_node_name(dip);
6798 ndi_rele_devi(dip); /* release e_ddi_nodeid_to_dip hold */
6804 * Return the held dip for the specified major and instance, attempting to do
6820 dev_info_t *dip;
6830 for (dip = dnp->dn_head; dip;
6831 dip = (dev_info_t *)DEVI(dip)->devi_next) {
6833 if (i_ddi_node_state(dip) < DS_INITIALIZED)
6837 if (DEVI(dip)->devi_instance == instance) {
6850 ndi_hold_devi(dip);
6851 if (i_ddi_devi_attached(dip) &&
6852 !DEVI_IS_DETACHING(dip)) {
6854 return (dip); /* fast-path with devi held */
6856 ndi_rele_devi(dip);
6859 dip = NULL;
6863 ASSERT(dip == NULL);
6877 dip = e_ddi_hold_devi_by_path(path, flags);
6887 if (dip &&
6888 ((DEVI(dip)->devi_major != major) ||
6889 ((DEVI(dip)->devi_instance != instance)) ||
6890 (strcmp(path, ddi_pathname(dip, vpath)) != 0))) {
6891 ndi_rele_devi(dip);
6892 dip = NULL; /* no answer better than wrong answer */
6897 return (dip); /* with devi held */
6921 dev_info_t *dip;
6925 dip = hold_devi(major, dev_to_instance(dev), flags);
6933 * implementation over the above derived dip based the driver's
6938 * returns a dip which is not held. By the time we ref ddip,
6940 * most drivers, the dip returned from hold_devi() is the
6951 /* give preference to the driver returned DEVT2DEVINFO dip */
6952 if (ddip && (dip != ddip)) {
6958 if (dip)
6959 ndi_rele_devi(dip);
6960 dip = ddip;
6966 return (dip);
6975 dev_info_t *dip = NULL;
6982 dip = e_ddi_hold_devi_by_dev(dev, 0);
6988 * For compatibility reasons, we can only return the dip with
6993 if (dip) {
6994 (void) ndi_hold_driver(dip);
6995 ndi_rele_devi(dip);
6997 return (dip);
7003 dev_info_t *dip;
7008 return (resolve_pathname(path, &dip, NULL, NULL) ? NULL : dip);
7012 e_ddi_hold_devi(dev_info_t *dip)
7014 ndi_hold_devi(dip);
7018 ddi_release_devi(dev_info_t *dip)
7020 ndi_rele_devi(dip);
7029 ddi_assoc_queue_with_devi(queue_t *q, dev_info_t *dip)
7046 spec_assoc_vp_with_devi(vp, dip);
7084 * dip must be referenced via ndi_hold_devi()
7087 i_ddi_attach_node_hierarchy(dev_info_t *dip)
7095 if (i_ddi_devi_attached(dip))
7097 parent = ddi_get_parent(dip);
7107 ret = i_ddi_attachchild(dip);
7118 dev_info_t *dip;
7123 dip = dnp->dn_head;
7124 while (dip) {
7125 ndi_hold_devi(dip);
7127 if (i_ddi_attach_node_hierarchy(dip) == DDI_SUCCESS)
7137 dip, DDI_PROP_DONTPASS, "ddi-config-driver-node"))) {
7138 (void) ndi_devi_config(dip, NDI_NO_EVENT);
7141 ndi_rele_devi(dip);
7142 dip = ddi_get_next(dip);
7179 * before calling this interface. The dip is held attached
7189 dev_info_t *dip;
7198 dip = devnamesp[major].dn_head;
7199 ASSERT(dip && ddi_get_next(dip) == NULL);
7200 ndi_hold_devi(dip);
7201 return (dip);
7208 dev_info_t *dip, *pdip;
7210 for (dip = head; dip != NULL; dip = ddi_get_next(dip)) {
7211 pdip = ddi_get_parent(dip);
7251 dev_info_t *dip;
7258 for (dip = dnp->dn_head; dip != NULL; dip = ddi_get_next(dip)) {
7259 if (i_ddi_devi_attached(dip)) {
7478 impl_rem_dev_props(dev_info_t *dip)
7480 _NOTE(ARGUNUSED(dip))
7488 is_leaf_node(dev_info_t *dip)
7490 major_t major = ddi_driver_major(dip);
7592 dev_info_t *dip = mcd->mtc_dip;
7608 rv = devi_config_common(dip, flags, major);
7613 rv = devi_unconfig_common(dip, dipp, flags, major,
7617 rv = devi_unconfig_common(dip, dipp, flags, major,
7634 (void) ddi_pathname(dip, path);
7653 ndi_rele_devi(dip);
7669 dev_info_t *dip;
7684 dip = ddi_get_child(pdip);
7685 while (dip) {
7687 !(DEVI_EVREMOVE(dip)) &&
7688 i_ddi_node_state(dip) >= DS_INITIALIZED) {
7690 * Enqueue this dip's deviname.
7696 brn = brevq_enqueue(hdl->mtc_brevqp, dip, NULL);
7706 ndi_hold_devi(dip);
7712 if (is_leaf_node(dip) ||
7714 i_ddi_node_state(dip) < DS_READY)) {
7715 ndi_rele_devi(dip);
7716 dip = ddi_get_next_sibling(dip);
7721 mcd->mtc_dip = dip;
7730 (major == ddi_driver_major(dip)))
7761 dip = ddi_get_next_sibling(dip);
7782 dev_info_t *dip;
7797 dip = devnamesp[par_major].dn_head;
7798 while (dip) {
7805 ndi_hold_devi(dip);
7808 if (!i_ddi_devi_attached(dip) || is_leaf_node(dip)) {
7809 ndi_rele_devi(dip);
7810 dip = ddi_get_next(dip);
7815 mcd->mtc_dip = dip;
7835 dip = ddi_get_next(dip);
7858 dev_info_t *dip = NULL;
7866 ndi_hold_devi(elem->dip);
7867 dip = elem->dip;
7883 return (dip);
7984 i_bind_vhci_node(dev_info_t *dip)
7986 DEVI(dip)->devi_major = ddi_name_to_major(ddi_node_name(dip));
7987 i_ddi_set_node_state(dip, DS_BOUND);
7993 i_init_vhci_node(dev_info_t *dip)
7995 add_global_props(dip);
7996 DEVI(dip)->devi_ops = ndi_hold_driver(dip);
7997 if (DEVI(dip)->devi_ops == NULL)
8000 DEVI(dip)->devi_instance = e_ddi_assign_instance(dip);
8001 e_ddi_keep_instance(dip);
8003 ddi_set_name_addr(dip, vhci_node_addr);
8004 i_ddi_set_node_state(dip, DS_INITIALIZED);
8009 i_link_vhci_node(dev_info_t *dip)
8017 DEVI(dip)->devi_sibling = DEVI(scsi_vhci_dip)->devi_sibling;
8018 DEVI(scsi_vhci_dip)->devi_sibling = DEVI(dip);
8020 DEVI(dip)->devi_sibling = DEVI(top_devinfo)->devi_child;
8021 DEVI(top_devinfo)->devi_child = DEVI(dip);
8046 dev_info_t *dip;
8056 dip = dnp->dn_head;
8058 return (dip);
8063 ndi_devi_alloc_sleep(top_devinfo, drvname, DEVI_SID_NODEID, &dip);
8064 ndi_hold_devi(dip);
8067 DEVI(dip)->devi_node_attributes |= DDI_VHCI_NODE;
8069 i_ddi_add_devimap(dip);
8070 i_bind_vhci_node(dip);
8071 if (i_init_vhci_node(dip) == -1) {
8072 ndi_rele_devi(dip);
8073 (void) ndi_devi_free(dip);
8077 mutex_enter(&(DEVI(dip)->devi_lock));
8078 DEVI_SET_ATTACHING(dip);
8079 mutex_exit(&(DEVI(dip)->devi_lock));
8081 if (devi_attach(dip, DDI_ATTACH) != DDI_SUCCESS) {
8083 e_ddi_free_instance(dip, vhci_node_addr);
8084 ndi_rele_devi(dip);
8085 (void) ndi_devi_free(dip);
8088 mutex_enter(&(DEVI(dip)->devi_lock));
8089 DEVI_CLR_ATTACHING(dip);
8090 mutex_exit(&(DEVI(dip)->devi_lock));
8093 i_link_vhci_node(dip);
8095 i_ddi_set_node_state(dip, DS_READY);
8099 dnp->dn_head = dip;
8102 i_ndi_devi_report_status_change(dip, NULL);
8104 return (dip);
8126 ndi_devi_device_isremoved(dev_info_t *dip)
8128 return (DEVI_IS_DEVICE_REMOVED(dip));
8132 ndi_devi_device_remove(dev_info_t *dip)
8134 ASSERT(dip && ddi_get_parent(dip) &&
8135 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
8138 if (ndi_devi_device_isremoved(dip))
8142 mutex_enter(&(DEVI(dip)->devi_lock));
8143 ndi_devi_set_hidden(dip); /* invisible: lookup/snapshot */
8144 DEVI_SET_DEVICE_REMOVED(dip);
8145 DEVI_SET_EVREMOVE(dip); /* this clears EVADD too */
8146 mutex_exit(&(DEVI(dip)->devi_lock));
8149 i_ndi_devi_report_status_change(dip, NULL);
8163 i_ddi_log_devfs_device_remove(dip);
8169 ndi_devi_device_insert(dev_info_t *dip)
8171 ASSERT(dip && ddi_get_parent(dip) &&
8172 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
8175 if (!ndi_devi_device_isremoved(dip))
8179 mutex_enter(&(DEVI(dip)->devi_lock));
8180 ndi_devi_clr_hidden(dip); /* visible: lookup/snapshot */
8181 DEVI_SET_DEVICE_REINSERTED(dip);
8182 DEVI_SET_EVADD(dip); /* this clears EVREMOVE too */
8183 mutex_exit(&(DEVI(dip)->devi_lock));
8186 i_ndi_devi_report_status_change(dip, NULL);
8198 i_ddi_log_devfs_device_insert(dip);
8221 e_ddi_mark_retiring(dev_info_t *dip, void *arg)
8231 (void) ddi_pathname(dip, path);
8241 mutex_enter(&DEVI(dip)->devi_lock);
8242 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT));
8243 DEVI(dip)->devi_flags |= DEVI_RETIRING;
8245 DEVI(dip)->devi_flags |= DEVI_R_CONSTRAINT;
8246 mutex_exit(&DEVI(dip)->devi_lock);
8248 RIO_VERBOSE((CE_NOTE, "marked dip as undergoing retire process dip=%p",
8249 (void *)dip));
8252 RIO_DEBUG((CE_NOTE, "marked dip as constrained, dip=%p",
8253 (void *)dip));
8255 if (MDI_PHCI(dip))
8256 mdi_phci_mark_retiring(dip, cons_array);
8280 e_ddi_retire_notify(dev_info_t *dip, void *arg)
8284 RIO_DEBUG((CE_NOTE, "retire notify: dip = %p", (void *)dip));
8286 (void) e_ddi_offline_notify(dip);
8288 mutex_enter(&(DEVI(dip)->devi_lock));
8289 if (!(DEVI(dip)->devi_flags & DEVI_RETIRING)) {
8290 RIO_DEBUG((CE_WARN, "retire notify: dip in retire "
8291 "subtree is not marked: dip = %p", (void *)dip));
8293 } else if (DEVI(dip)->devi_flags & DEVI_R_BLOCKED) {
8294 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT));
8295 RIO_DEBUG((CE_NOTE, "retire notify: BLOCKED: dip = %p",
8296 (void *)dip));
8298 } else if (!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT)) {
8300 "dip = %p", (void *)dip));
8304 "dip = %p", (void *)dip));
8306 mutex_exit(&DEVI(dip)->devi_lock);
8308 if (MDI_PHCI(dip))
8309 mdi_phci_retire_notify(dip, constraint);
8315 e_ddi_retire_finalize(dev_info_t *dip, void *arg)
8321 mutex_enter(&DEVI(dip)->devi_lock);
8322 if (!(DEVI(dip)->devi_flags & DEVI_RETIRING)) {
8324 "retire: unmarked dip(%p) in retire subtree",
8325 (void *)dip));
8326 ASSERT(!(DEVI(dip)->devi_flags & DEVI_RETIRED));
8327 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT));
8328 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_BLOCKED));
8329 mutex_exit(&DEVI(dip)->devi_lock);
8339 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
8341 ASSERT(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT);
8342 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_BLOCKED));
8343 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT;
8344 DEVI(dip)->devi_flags &= ~DEVI_RETIRING;
8345 DEVI(dip)->devi_flags |= DEVI_RETIRED;
8346 mutex_exit(&DEVI(dip)->devi_lock);
8347 (void) spec_fence_snode(dip, NULL);
8348 RIO_DEBUG((CE_NOTE, "Fenced off: dip = %p", (void *)dip));
8349 e_ddi_offline_finalize(dip, DDI_SUCCESS);
8351 if (DEVI(dip)->devi_flags & DEVI_R_BLOCKED) {
8352 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT));
8353 DEVI(dip)->devi_flags &= ~DEVI_R_BLOCKED;
8354 DEVI(dip)->devi_flags &= ~DEVI_RETIRING;
8356 } else if (DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT) {
8357 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT;
8358 DEVI(dip)->devi_flags &= ~DEVI_RETIRING;
8361 DEVI(dip)->devi_flags &= ~DEVI_RETIRING;
8364 * to clear the contract barrier on the dip
8368 mutex_exit(&DEVI(dip)->devi_lock);
8369 RIO_DEBUG((CE_NOTE, "finalize: NOT retired: dip = %p",
8370 (void *)dip));
8372 e_ddi_offline_finalize(dip, DDI_FAILURE);
8381 if (MDI_PHCI(dip))
8382 mdi_phci_retire_finalize(dip, phci_only, arg);
8397 dev_info_t *dip;
8407 dip = e_ddi_hold_devi_by_path(path, 0);
8408 if (dip == NULL) {
8424 RIO_DEBUG((CE_NOTE, "Retire device: found dip = %p.", (void *)dip));
8426 pdip = ddi_get_parent(dip);
8430 * Run devfs_clean() in case dip has no constraints and is
8432 * ref-count on the dip. Note that devfs_clean() always returns
8436 (void) ddi_deviname(dip, devnm);
8443 ndi_rele_devi(dip);
8447 * dip is a nexus.
8449 (void) e_ddi_mark_retiring(dip, cons_array);
8450 if (!is_leaf_node(dip)) {
8451 ndi_devi_enter(dip, &circ2);
8452 ddi_walk_devs(ddi_get_child(dip), e_ddi_mark_retiring,
8454 ndi_devi_exit(dip, circ2);
8464 (void) e_ddi_retire_notify(dip, &constraint);
8465 if (!is_leaf_node(dip)) {
8466 ndi_devi_enter(dip, &circ2);
8467 ddi_walk_devs(ddi_get_child(dip), e_ddi_retire_notify,
8469 ndi_devi_exit(dip, circ2);
8475 (void) e_ddi_retire_finalize(dip, &constraint);
8476 if (!is_leaf_node(dip)) {
8477 ndi_devi_enter(dip, &circ2);
8478 ddi_walk_devs(ddi_get_child(dip), e_ddi_retire_finalize,
8480 ndi_devi_exit(dip, circ2);
8495 unmark_and_unfence(dev_info_t *dip, void *arg)
8501 (void) ddi_pathname(dip, path);
8503 mutex_enter(&DEVI(dip)->devi_lock);
8504 DEVI(dip)->devi_flags &= ~DEVI_RETIRED;
8505 DEVI_SET_DEVICE_ONLINE(dip);
8506 mutex_exit(&DEVI(dip)->devi_lock);
8508 RIO_VERBOSE((CE_NOTE, "Cleared RETIRED flag: dip=%p, path=%s",
8509 (void *)dip, path));
8511 (void) spec_unfence_snode(dip);
8514 if (MDI_PHCI(dip))
8515 mdi_phci_unretire(dip);
8527 find_dip_fcn(dev_info_t *dip, void *arg)
8531 (void) ddi_pathname(dip, findp->fd_buf);
8536 ndi_hold_devi(dip);
8537 findp->fd_dip = dip;
8549 dev_info_t *dip;
8562 * We can't lookup the dip (corresponding to path) via
8563 * e_ddi_hold_devi_by_path() because the dip may be offline
8584 dip = find_dip.fd_dip;
8586 pdip = ddi_get_parent(dip);
8594 (void) unmark_and_unfence(dip, path2);
8595 if (!is_leaf_node(dip)) {
8596 ndi_devi_enter(dip, &circ2);
8597 ddi_walk_devs(ddi_get_child(dip), unmark_and_unfence, path2);
8598 ndi_devi_exit(dip, circ2);
8604 ndi_rele_devi(dip);
8614 * Called before attach on a dip that has been retired.
8617 mark_and_fence(dev_info_t *dip, void *arg)
8627 mutex_enter(&DEVI(dip)->devi_lock);
8628 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT));
8629 ASSERT(!(DEVI(dip)->devi_flags & DEVI_R_BLOCKED));
8630 ASSERT(!(DEVI(dip)->devi_flags & DEVI_RETIRING));
8631 DEVI(dip)->devi_flags |= DEVI_RETIRED;
8632 mutex_exit(&DEVI(dip)->devi_lock);
8633 RIO_VERBOSE((CE_NOTE, "marked as RETIRED dip=%p", (void *)dip));
8636 (void) spec_fence_snode(dip, NULL);
8638 ddi_pathname(dip, fencepath)));
8655 i_ddi_check_retire(dev_info_t *dip)
8663 pdip = ddi_get_parent(dip);
8666 * Root dip is treated special and doesn't take this code path.
8671 ASSERT(i_ddi_node_state(dip) < DS_ATTACHED);
8675 (void) ddi_pathname(dip, path);
8677 RIO_VERBOSE((CE_NOTE, "Checking if dip should attach: dip=%p, path=%s",
8678 (void *)dip, path));
8686 if (DEVI(dip)->devi_flags & DEVI_RETIRED)
8698 (void) mark_and_fence(dip, path);
8699 if (!is_leaf_node(dip)) {
8700 ndi_devi_enter(dip, &circ);
8701 ddi_walk_devs(ddi_get_child(dip), mark_and_fence, path);
8702 ndi_devi_exit(dip, circ);
8713 if (MDI_PHCI(dip))
8714 mdi_phci_retire_finalize(dip, phci_only, &constraint);