1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
25 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
26 * Copyright (c) 2016 by Delphix. All rights reserved.
27 */
28
29 #include <sys/note.h>
30 #include <sys/t_lock.h>
31 #include <sys/cmn_err.h>
32 #include <sys/instance.h>
33 #include <sys/conf.h>
34 #include <sys/stat.h>
35 #include <sys/ddi.h>
36 #include <sys/hwconf.h>
37 #include <sys/sunddi.h>
38 #include <sys/sunndi.h>
39 #include <sys/ddi_impldefs.h>
40 #include <sys/ndi_impldefs.h>
41 #include <sys/modctl.h>
42 #include <sys/contract/device_impl.h>
43 #include <sys/dacf.h>
44 #include <sys/promif.h>
45 #include <sys/pci.h>
154 * (MUTEX_DEFAULT) - it is automatically initialized by being allocated
155 * in zeroed memory (static storage class). Therefore no explicit
156 * initialization of the di_cache structure is needed.
157 */
158 struct di_cache di_cache = {1};
159 int di_cache_debug = 0;
160
161 /* For ddvis, which needs pseudo children under PCI */
162 int pci_allow_pseudo_children = 0;
163
164 /* Allow path-oriented alias driver binding on driver.conf enumerated nodes */
165 int driver_conf_allow_path_alias = 1;
166
167 /*
168 * The following switch is for service people, in case a
169 * 3rd party driver depends on identify(9e) being called.
170 */
171 int identify_9e = 0;
172
173 /*
174 * Add flag so behaviour of preventing attach for retired persistant nodes
175 * can be disabled.
176 */
177 int retire_prevents_attach = 1;
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 *);
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
489 /* free event data */
490 if (devi->devi_ev_path)
491 kmem_free(devi->devi_ev_path, MAXPATHLEN);
492
493 kmem_cache_free(ddi_node_cache, devi);
494 }
495
496
497 /*
498 * Node state transitions
499 */
500
501 /*
502 * Change the node name
503 */
504 int
505 ndi_devi_set_nodename(dev_info_t *dip, char *name, int flags)
506 {
507 _NOTE(ARGUNUSED(flags))
508 char *nname, *oname;
509
510 ASSERT(dip && name);
511
512 oname = DEVI(dip)->devi_node_name;
1343 mutex_exit(&DEVI(dip)->devi_lock);
1344
1345 /* successful attach, return with driver held */
1346
1347 return (DDI_SUCCESS);
1348 }
1349
1350 /*
1351 * Detach devinfo node.
1352 * Per-driver list must be held busy.
1353 */
1354 static int
1355 detach_node(dev_info_t *dip, uint_t flag)
1356 {
1357 struct devnames *dnp;
1358 int rv;
1359
1360 ASSERT(DEVI_BUSY_OWNED(ddi_get_parent(dip)));
1361 ASSERT(i_ddi_node_state(dip) == DS_ATTACHED);
1362
1363 /* check references */
1364 if (DEVI(dip)->devi_ref)
1365 return (DDI_FAILURE);
1366
1367 NDI_CONFIG_DEBUG((CE_CONT, "detach_node: 0x%p(%s%d)\n",
1368 (void *)dip, ddi_driver_name(dip), ddi_get_instance(dip)));
1369
1370 /*
1371 * NOTE: If we are processing a pHCI node then the calling code
1372 * must detect this and ndi_devi_enter() in (vHCI, parent(pHCI))
1373 * order unless pHCI and vHCI are siblings. Code paths leading
1374 * here that must ensure this ordering include:
1375 * unconfig_immediate_children(), devi_unconfig_one(),
1376 * ndi_devi_unconfig_one(), ndi_devi_offline().
1377 */
1378 ASSERT(!MDI_PHCI(dip) ||
1379 (ddi_get_parent(mdi_devi_get_vdip(dip)) == ddi_get_parent(dip)) ||
1380 DEVI_BUSY_OWNED(mdi_devi_get_vdip(dip)));
1381
1382 /* Offline the device node with the mpxio framework. */
1383 if (mdi_devi_offline(dip, flag) != NDI_SUCCESS) {
1384 return (DDI_FAILURE);
1446 dnp = &(devnamesp[DEVI(dip)->devi_major]);
1447 LOCK_DEV_OPS(&dnp->dn_lock);
1448 dnp->dn_flags &= ~DN_DRIVER_HELD;
1449 UNLOCK_DEV_OPS(&dnp->dn_lock);
1450 }
1451
1452 /* successful detach, release the driver */
1453 ndi_rele_driver(dip);
1454 DEVI(dip)->devi_ops = NULL;
1455 return (DDI_SUCCESS);
1456 }
1457
1458 /*
1459 * Run dacf post_attach routines
1460 */
1461 static int
1462 postattach_node(dev_info_t *dip)
1463 {
1464 int rval;
1465
1466 /*
1467 * For hotplug busses like USB, it's possible that devices
1468 * are removed but dip is still around. We don't want to
1469 * run dacf routines as part of detach failure recovery.
1470 *
1471 * Pretend success until we figure out how to prevent
1472 * access to such devinfo nodes.
1473 */
1474 if (DEVI_IS_DEVICE_REMOVED(dip))
1475 return (DDI_SUCCESS);
1476
1477 /*
1478 * if dacf_postattach failed, report it to the framework
1479 * so that it can be retried later at the open time.
1480 */
1481 mutex_enter(&dacf_lock);
1482 rval = dacfc_postattach(dip);
1483 mutex_exit(&dacf_lock);
1484
1485 /*
3804 * (3) if neither exists, a dev_t is faked with minor number = instance.
3805 * As of S9 FCS, no instance of #1 exists. #2 is used by several platforms
3806 * to default the boot partition to :a possibly by other OBP definitions.
3807 * #3 is used for booting off network interfaces, most SPARC network
3808 * drivers support Style-2 only, so only DDM_ALIAS minor exists.
3809 *
3810 * It is possible for OBP to present device args at the end of the path as
3811 * well as in the middle. For example, with IB the following strings are
3812 * valid boot paths.
3813 * a /pci@8,700000/ib@1,2:port=1,pkey=ff,dhcp,...
3814 * b /pci@8,700000/ib@1,1:port=1/ioc@xxxxxx,yyyyyyy:dhcp
3815 * Case (a), we first look for minor node "port=1,pkey...".
3816 * Failing that, we will pass "port=1,pkey..." to the bus_config
3817 * entry point of ib (HCA) driver.
3818 * Case (b), configure ib@1,1 as usual. Then invoke ib's bus_config
3819 * with argument "ioc@xxxxxxx,yyyyyyy:port=1". After configuring
3820 * the ioc, look for minor node dhcp. If not found, pass ":dhcp"
3821 * to ioc's bus_config entry point.
3822 */
3823 int
3824 resolve_pathname(char *pathname,
3825 dev_info_t **dipp, dev_t *devtp, int *spectypep)
3826 {
3827 int error;
3828 dev_info_t *parent, *child;
3829 struct pathname pn;
3830 char *component, *config_name;
3831 char *minorname = NULL;
3832 char *prev_minor = NULL;
3833 dev_t devt = NODEV;
3834 int spectype;
3835 struct ddi_minor_data *dmn;
3836 int circ;
3837
3838 if (*pathname != '/')
3839 return (EINVAL);
3840 parent = ddi_root_node(); /* Begin at the top of the tree */
3841
3842 if (error = pn_get(pathname, UIO_SYSSPACE, &pn))
3843 return (error);
3844 pn_skipslash(&pn);
3845
4583 {
4584 dev_info_t *dip;
4585
4586 ASSERT(DEVI(pdip)->devi_flags & DEVI_MADE_CHILDREN);
4587
4588 /* contiguous instance assignment */
4589 e_ddi_enter_instance();
4590 dip = ddi_get_child(pdip);
4591 while (dip) {
4592 if (ndi_dev_is_persistent_node(dip))
4593 (void) i_ndi_config_node(dip, DS_INITIALIZED, flags);
4594 dip = ddi_get_next_sibling(dip);
4595 }
4596 e_ddi_exit_instance();
4597 }
4598
4599 /*
4600 * report device status
4601 */
4602 static void
4603 i_ndi_devi_report_status_change(dev_info_t *dip, char *path)
4604 {
4605 char *status;
4606
4607 if (!DEVI_NEED_REPORT(dip) ||
4608 (i_ddi_node_state(dip) < DS_INITIALIZED) ||
4609 ndi_dev_is_hidden_node(dip)) {
4610 return;
4611 }
4612
4613 /* Invalidate the devinfo snapshot cache */
4614 i_ddi_di_cache_invalidate();
4615
4616 if (DEVI_IS_DEVICE_REMOVED(dip)) {
4617 status = "removed";
4618 } else if (DEVI_IS_DEVICE_OFFLINE(dip)) {
4619 status = "offline";
4620 } else if (DEVI_IS_DEVICE_DOWN(dip)) {
4621 status = "down";
4622 } else if (DEVI_IS_BUS_QUIESCED(dip)) {
4623 status = "quiesced";
4624 } else if (DEVI_IS_BUS_DOWN(dip)) {
4625 status = "down";
4626 } else if (i_ddi_devi_attached(dip)) {
4627 status = "online";
4628 } else {
4629 status = "unknown";
4630 }
4631
4632 if (path == NULL) {
4633 path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
4634 cmn_err(CE_CONT, "?%s (%s%d) %s\n",
4635 ddi_pathname(dip, path), ddi_driver_name(dip),
4636 ddi_get_instance(dip), status);
4637 kmem_free(path, MAXPATHLEN);
4638 } else {
4639 cmn_err(CE_CONT, "?%s (%s%d) %s\n",
4640 path, ddi_driver_name(dip),
4641 ddi_get_instance(dip), status);
4642 }
4643
4644 mutex_enter(&(DEVI(dip)->devi_lock));
4645 DEVI_REPORT_DONE(dip);
4646 mutex_exit(&(DEVI(dip)->devi_lock));
4647 }
4648
4649 /*
4650 * log a notification that a dev_info node has been configured.
4651 */
4652 static int
4653 i_log_devfs_add_devinfo(dev_info_t *dip, uint_t flags)
4654 {
4655 int se_err;
4656 char *pathname;
4657 sysevent_t *ev;
4658 sysevent_id_t eid;
4659 sysevent_value_t se_val;
4660 sysevent_attr_list_t *ev_attr_list = NULL;
4661 char *class_name;
4662 int no_transport = 0;
5210 }
5211 mutex_exit(&(DEVI(dip)->devi_lock));
5212
5213 if (i_ddi_attachchild(dip) != DDI_SUCCESS) {
5214 mutex_enter(&(DEVI(dip)->devi_lock));
5215 DEVI_SET_EVUNINIT(dip);
5216 mutex_exit(&(DEVI(dip)->devi_lock));
5217
5218 if (ndi_dev_is_persistent_node(dip))
5219 (void) ddi_uninitchild(dip);
5220 else {
5221 /*
5222 * Delete .conf nodes and nodes that are not
5223 * well formed.
5224 */
5225 (void) ddi_remove_child(dip, 0);
5226 }
5227 return (NDI_FAILURE);
5228 }
5229
5230 i_ndi_devi_report_status_change(dip, NULL);
5231
5232 /*
5233 * log an event, but not during devfs lookups in which case
5234 * NDI_NO_EVENT is set.
5235 */
5236 if ((flags & NDI_NO_EVENT) == 0 && !(DEVI_EVADD(dip))) {
5237 (void) i_log_devfs_add_devinfo(dip, flags);
5238
5239 mutex_enter(&(DEVI(dip)->devi_lock));
5240 DEVI_SET_EVADD(dip);
5241 mutex_exit(&(DEVI(dip)->devi_lock));
5242 } else if (!(flags & NDI_NO_EVENT_STATE_CHNG)) {
5243 mutex_enter(&(DEVI(dip)->devi_lock));
5244 DEVI_SET_EVADD(dip);
5245 mutex_exit(&(DEVI(dip)->devi_lock));
5246 }
5247
5248 return (NDI_SUCCESS);
5249 }
5250
5748 case LDI_EV_FAILURE:
5749 contract_device_negend(dip, DDI_DEV_T_ANY, 0, CT_EV_FAILURE);
5750 RIO_DEBUG((CE_NOTE, "LDI callback failed on dip=%p",
5751 (void *)dip));
5752 failure = 1;
5753 goto out;
5754 case LDI_EV_SUCCESS:
5755 constraint = 1;
5756 RIO_DEBUG((CE_NOTE, "LDI callback success on dip=%p",
5757 (void *)dip));
5758 break;
5759 case LDI_EV_NONE:
5760 /* no matching LDI callbacks */
5761 RIO_DEBUG((CE_NOTE, "No LDI callbacks for dip=%p",
5762 (void *)dip));
5763 break;
5764 default:
5765 ASSERT(retval == LDI_EV_NONE);
5766 }
5767
5768 out:
5769 mutex_enter(&(DEVI(dip)->devi_lock));
5770 if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && failure) {
5771 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): setting "
5772 "BLOCKED flag. dip=%p", (void *)dip));
5773 DEVI(dip)->devi_flags |= DEVI_R_BLOCKED;
5774 if (DEVI(dip)->devi_flags & DEVI_R_CONSTRAINT) {
5775 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): "
5776 "blocked. clearing RCM CONSTRAINT flag. dip=%p",
5777 (void *)dip));
5778 DEVI(dip)->devi_flags &= ~DEVI_R_CONSTRAINT;
5779 }
5780 } else if ((DEVI(dip)->devi_flags & DEVI_RETIRING) && constraint) {
5781 RIO_VERBOSE((CE_NOTE, "e_ddi_offline_notify(): setting "
5782 "CONSTRAINT flag. dip=%p", (void *)dip));
5783 DEVI(dip)->devi_flags |= DEVI_R_CONSTRAINT;
5784 } else if ((DEVI(dip)->devi_flags & DEVI_RETIRING) &&
5785 ((DEVI(dip)->devi_ops != NULL &&
5786 DEVI(dip)->devi_ops->devo_bus_ops != NULL) ||
5787 DEVI(dip)->devi_ref == 0)) {
5913 RIO_DEBUG((CE_NOTE, "devi_detach_node: offline succeeded."
5914 " Calling e_ddi_offline_finalize with result=%d, "
5915 "dip=%p", DDI_SUCCESS, (void *)dip));
5916 e_ddi_offline_finalize(dip, DDI_SUCCESS);
5917 }
5918
5919 if (flags & NDI_AUTODETACH)
5920 return (NDI_SUCCESS);
5921
5922 /*
5923 * For DR, even bound nodes may need to have offline
5924 * flag set.
5925 */
5926 if (flags & NDI_DEVI_OFFLINE) {
5927 mutex_enter(&(DEVI(dip)->devi_lock));
5928 DEVI_SET_DEVICE_OFFLINE(dip);
5929 mutex_exit(&(DEVI(dip)->devi_lock));
5930 }
5931
5932 if (i_ddi_node_state(dip) == DS_INITIALIZED) {
5933 struct dev_info *devi = DEVI(dip);
5934
5935 if (devi->devi_ev_path == NULL) {
5936 devi->devi_ev_path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
5937 (void) ddi_pathname(dip, devi->devi_ev_path);
5938 }
5939 if (flags & NDI_DEVI_OFFLINE)
5940 i_ndi_devi_report_status_change(dip,
5941 devi->devi_ev_path);
5942
5943 if (need_remove_event(dip, flags)) {
5944 /*
5945 * instance and path data are lost in call to
5946 * ddi_uninitchild
5947 */
5948 devi->devi_ev_instance = ddi_get_instance(dip);
5949
5950 mutex_enter(&(DEVI(dip)->devi_lock));
5951 DEVI_SET_EVREMOVE(dip);
5952 mutex_exit(&(DEVI(dip)->devi_lock));
5953 }
5954 }
5955
5956 if (flags & (NDI_UNCONFIG | NDI_DEVI_REMOVE)) {
5957 ret = ddi_uninitchild(dip);
5958 if (ret == NDI_SUCCESS) {
5959 /*
5960 * Remove uninitialized pseudo nodes because
5961 * system props are lost and the node cannot be
5962 * reattached.
5963 */
5964 if (!ndi_dev_is_persistent_node(dip))
5965 flags |= NDI_DEVI_REMOVE;
5966
5967 if (flags & NDI_DEVI_REMOVE) {
5968 /*
5969 * NOTE: If there is a consumer of LDI events,
5970 * ddi_uninitchild above would have failed
5971 * because of active devi_ref from ldi_open().
5972 */
5973
5974 if (DEVI_EVREMOVE(dip)) {
5975 path = i_ddi_strdup(
5976 DEVI(dip)->devi_ev_path,
5977 KM_SLEEP);
5978 class =
5979 i_ddi_strdup(i_ddi_devi_class(dip),
5980 KM_SLEEP);
5981 driver =
5982 i_ddi_strdup(
5983 (char *)ddi_driver_name(dip),
5984 KM_SLEEP);
5985 instance = DEVI(dip)->devi_ev_instance;
5986 post_event = 1;
5987 }
5988
5989 ret = ddi_remove_child(dip, 0);
5990 if (post_event && ret == NDI_SUCCESS) {
5991 /* Generate EC_DEVFS_DEVI_REMOVE */
5992 (void) i_log_devfs_remove_devinfo(path,
5993 class, driver, instance, flags);
5994 }
5995 }
5996
5997 }
5998 }
5999
6000 if (path)
6001 strfree(path);
6002 if (class)
6003 strfree(class);
6004 if (driver)
6005 strfree(driver);
6006
6007 return (ret);
6008 }
6009
6010 /*
6011 * unconfigure immediate children of bus nexus device
6012 */
6013 static int
6014 unconfig_immediate_children(
6015 dev_info_t *dip,
6016 dev_info_t **dipp,
6017 int flags,
6018 major_t major)
6019 {
6020 int rv = NDI_SUCCESS;
6021 int circ, vcirc;
6022 dev_info_t *child;
6023 dev_info_t *vdip = NULL;
6024 dev_info_t *next;
6025
6026 ASSERT(dipp == NULL || *dipp == NULL);
6562 * the driver and prevent devfs requests from re-attaching the device
6563 * instance.
6564 *
6565 * The flag NDI_DEVI_REMOVE causes removes the device node from
6566 * the driver list and the device tree. In this case, the device
6567 * is assumed to be removed from the system.
6568 */
6569 int
6570 ndi_devi_offline(dev_info_t *dip, uint_t flags)
6571 {
6572 int circ, rval = 0;
6573 dev_info_t *pdip = ddi_get_parent(dip);
6574 dev_info_t *vdip = NULL;
6575 int v_circ;
6576 struct brevq_node *brevq = NULL;
6577
6578 ASSERT(pdip);
6579
6580 flags |= NDI_DEVI_OFFLINE;
6581
6582 /*
6583 * If child is pHCI and vHCI and pHCI are not siblings then enter vHCI
6584 * before parent(pHCI) to avoid deadlock with mpxio Client power
6585 * management operations.
6586 */
6587 if (MDI_PHCI(dip)) {
6588 vdip = mdi_devi_get_vdip(dip);
6589 if (vdip && (ddi_get_parent(vdip) != pdip))
6590 ndi_devi_enter(vdip, &v_circ);
6591 else
6592 vdip = NULL;
6593 }
6594 ndi_devi_enter(pdip, &circ);
6595
6596 if (i_ddi_devi_attached(dip)) {
6597 /*
6598 * If dip is in DS_READY state, there may be cached dv_nodes
6599 * referencing this dip, so we invoke devfs code path.
6600 * Note that we must release busy changing on pdip to
6601 * avoid deadlock against devfs.
8083 cmn_err(CE_CONT, "Could not attach %s driver", drvname);
8084 e_ddi_free_instance(dip, vhci_node_addr);
8085 ndi_rele_devi(dip);
8086 (void) ndi_devi_free(dip);
8087 return (NULL);
8088 }
8089 mutex_enter(&(DEVI(dip)->devi_lock));
8090 DEVI_CLR_ATTACHING(dip);
8091 mutex_exit(&(DEVI(dip)->devi_lock));
8092
8093 mutex_enter(&global_vhci_lock);
8094 i_link_vhci_node(dip);
8095 mutex_exit(&global_vhci_lock);
8096 i_ddi_set_node_state(dip, DS_READY);
8097
8098 LOCK_DEV_OPS(&dnp->dn_lock);
8099 dnp->dn_flags |= DN_DRIVER_HELD;
8100 dnp->dn_head = dip;
8101 UNLOCK_DEV_OPS(&dnp->dn_lock);
8102
8103 i_ndi_devi_report_status_change(dip, NULL);
8104
8105 return (dip);
8106 }
8107
8108 /*
8109 * Maintain DEVI_DEVICE_REMOVED hotplug devi_state for remove/reinsert hotplug
8110 * of open devices. Currently, because of tight coupling between the devfs file
8111 * system and the Solaris device tree, a driver can't always make the device
8112 * tree state (esp devi_node_state) match device hardware hotplug state. Until
8113 * resolved, to overcome this deficiency we use the following interfaces that
8114 * maintain the DEVI_DEVICE_REMOVED devi_state status bit. These interface
8115 * report current state, and drive operation (like events and cache
8116 * invalidation) when a driver changes remove/insert state of an open device.
8117 *
8118 * The ndi_devi_device_isremoved() returns 1 if the device is currently removed.
8119 *
8120 * The ndi_devi_device_remove() interface declares the device as removed, and
8121 * returns 1 if there was a state change associated with this declaration.
8122 *
8123 * The ndi_devi_device_insert() declares the device as inserted, and returns 1
8130 }
8131
8132 int
8133 ndi_devi_device_remove(dev_info_t *dip)
8134 {
8135 ASSERT(dip && ddi_get_parent(dip) &&
8136 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
8137
8138 /* Return if already marked removed. */
8139 if (ndi_devi_device_isremoved(dip))
8140 return (0);
8141
8142 /* Mark the device as having been physically removed. */
8143 mutex_enter(&(DEVI(dip)->devi_lock));
8144 ndi_devi_set_hidden(dip); /* invisible: lookup/snapshot */
8145 DEVI_SET_DEVICE_REMOVED(dip);
8146 DEVI_SET_EVREMOVE(dip); /* this clears EVADD too */
8147 mutex_exit(&(DEVI(dip)->devi_lock));
8148
8149 /* report remove (as 'removed') */
8150 i_ndi_devi_report_status_change(dip, NULL);
8151
8152 /*
8153 * Invalidate the cache to ensure accurate
8154 * (di_state() & DI_DEVICE_REMOVED).
8155 */
8156 i_ddi_di_cache_invalidate();
8157
8158 /*
8159 * Generate sysevent for those interested in removal (either
8160 * directly via private EC_DEVFS or indirectly via devfsadmd
8161 * generated EC_DEV). This will generate LDI DEVICE_REMOVE
8162 * event too.
8163 */
8164 i_ddi_log_devfs_device_remove(dip);
8165
8166 return (1); /* DEVICE_REMOVED state changed */
8167 }
8168
8169 int
8170 ndi_devi_device_insert(dev_info_t *dip)
8171 {
8172 ASSERT(dip && ddi_get_parent(dip) &&
8173 DEVI_BUSY_OWNED(ddi_get_parent(dip)));
8174
8175 /* Return if not marked removed. */
8176 if (!ndi_devi_device_isremoved(dip))
8177 return (0);
8178
8179 /* Mark the device as having been physically reinserted. */
8180 mutex_enter(&(DEVI(dip)->devi_lock));
8181 ndi_devi_clr_hidden(dip); /* visible: lookup/snapshot */
8182 DEVI_SET_DEVICE_REINSERTED(dip);
8183 DEVI_SET_EVADD(dip); /* this clears EVREMOVE too */
8184 mutex_exit(&(DEVI(dip)->devi_lock));
8185
8186 /* report insert (as 'online') */
8187 i_ndi_devi_report_status_change(dip, NULL);
8188
8189 /*
8190 * Invalidate the cache to ensure accurate
8191 * (di_state() & DI_DEVICE_REMOVED).
8192 */
8193 i_ddi_di_cache_invalidate();
8194
8195 /*
8196 * Generate sysevent for those interested in removal (either directly
8197 * via EC_DEVFS or indirectly via devfsadmd generated EC_DEV).
8198 */
8199 i_ddi_log_devfs_device_insert(dip);
8200
8201 return (1); /* DEVICE_REMOVED state changed */
8202 }
8203
8204 /*
8205 * ibt_hw_is_present() returns 0 when there is no IB hardware actively
8206 * running. This is primarily useful for modules like rpcmod which
8207 * needs a quick check to decide whether or not it should try to use
|
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>
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 *);
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;
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);
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 /*
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
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;
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
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)) {
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);
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.
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
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
|