summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Horne <Chris.Horne@Sun.COM>2009-02-26 10:16:09 -0700
committerChris Horne <Chris.Horne@Sun.COM>2009-02-26 10:16:09 -0700
commit027021c7b9f04b74ae04cb1c3ddba52f2a2f9fd1 (patch)
tree892af8329770bffbab80b12ffc33d44556b4c5ff
parent7a71c13f9776768e00d7d5ccc8c8adc8eeb6888d (diff)
downloadillumos-gate-027021c7b9f04b74ae04cb1c3ddba52f2a2f9fd1.tar.gz
6808900 PSARC/2009/103 ndi hidden nodes
PSARC/2009/103 ndi hidden nodes
-rw-r--r--usr/src/uts/common/fs/devfs/devfs_subr.c32
-rw-r--r--usr/src/uts/common/io/devinfo.c50
-rw-r--r--usr/src/uts/common/os/devcfg.c20
-rw-r--r--usr/src/uts/common/os/sunndi.c29
-rw-r--r--usr/src/uts/common/sys/ddi_impldefs.h20
-rw-r--r--usr/src/uts/common/sys/sunddi.h5
-rw-r--r--usr/src/uts/common/sys/sunndi.h13
7 files changed, 116 insertions, 53 deletions
diff --git a/usr/src/uts/common/fs/devfs/devfs_subr.c b/usr/src/uts/common/fs/devfs/devfs_subr.c
index 0d2791d326..06dd76cc3d 100644
--- a/usr/src/uts/common/fs/devfs/devfs_subr.c
+++ b/usr/src/uts/common/fs/devfs/devfs_subr.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* miscellaneous routines for the devfs
*/
@@ -135,11 +133,11 @@ extern dev_info_t *clone_dip;
extern major_t clone_major;
extern struct dev_ops *ddi_hold_driver(major_t);
-/* dev_info node cache constructor */
-/*ARGSUSED1*/
+/* dv_node node constructor for kmem cache */
static int
i_dv_node_ctor(void *buf, void *cfarg, int flag)
{
+ _NOTE(ARGUNUSED(cfarg, flag))
struct dv_node *dv = (struct dv_node *)buf;
struct vnode *vp;
@@ -153,11 +151,11 @@ i_dv_node_ctor(void *buf, void *cfarg, int flag)
return (0);
}
-/* dev_info node cache destructor */
-/*ARGSUSED1*/
+/* dv_node node destructor for kmem cache */
static void
i_dv_node_dtor(void *buf, void *arg)
{
+ _NOTE(ARGUNUSED(arg))
struct dv_node *dv = (struct dv_node *)buf;
struct vnode *vp = DVTOV(dv);
@@ -167,7 +165,7 @@ i_dv_node_dtor(void *buf, void *arg)
}
-/* initialize dev_info node cache */
+/* initialize dv_node node cache */
void
dv_node_cache_init()
{
@@ -179,7 +177,7 @@ dv_node_cache_init()
tsd_create(&devfs_clean_key, NULL);
}
-/* destroy dev_info node cache */
+/* destroy dv_node node cache */
void
dv_node_cache_fini()
{
@@ -410,7 +408,7 @@ dv_mknod(struct dv_node *ddv, dev_info_t *devi, char *nm,
ASSERT(DEVI_BUSY_OWNED(devi));
mutex_enter(&DEVI(devi)->devi_lock);
dv->dv_devi = devi;
- DEVI(devi)->devi_ref++;
+ DEVI(devi)->devi_ref++; /* ndi_hold_devi(dip) */
mutex_exit(&DEVI(devi)->devi_lock);
dv->dv_ino = dv_mkino(devi, vp->v_type, vp->v_rdev);
@@ -449,7 +447,6 @@ dv_mknod(struct dv_node *ddv, dev_info_t *devi, char *nm,
* Destroy what we created in dv_mkdir or dv_mknod.
* In the case of a *referenced* directory, do nothing.
*/
-/*ARGSUSED1*/
void
dv_destroy(struct dv_node *dv, uint_t flags)
{
@@ -1098,6 +1095,15 @@ founddv:
}
/*
+ * If we configured a hidden node, consider it notfound.
+ */
+ if (ndi_dev_is_hidden_node(devi)) {
+ ndi_rele_devi(devi);
+ rv = ENOENT;
+ goto notfound;
+ }
+
+ /*
* Don't make vhci clients visible under phci, unless we
* are in miniroot.
*/
@@ -1248,6 +1254,10 @@ dv_filldir(struct dv_node *ddv)
if (i_ddi_node_state(devi) < DS_PROBED)
continue;
+ /* skip hidden nodes */
+ if (ndi_dev_is_hidden_node(devi))
+ continue;
+
dcmn_err3(("dv_filldir: node %s\n", ddi_node_name(devi)));
ndi_devi_enter(devi, &ccirc);
diff --git a/usr/src/uts/common/io/devinfo.c b/usr/src/uts/common/io/devinfo.c
index 55d05f7342..cff9b3ac4f 100644
--- a/usr/src/uts/common/io/devinfo.c
+++ b/usr/src/uts/common/io/devinfo.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1696,7 +1696,7 @@ di_copynode(struct dev_info *node, struct di_stack *dsp, struct di_state *st)
{
di_off_t off;
struct di_node *me;
- size_t size;
+ size_t size; struct dev_info *n;
dcmn_err2((CE_CONT, "di_copynode: depth = %x\n", dsp->depth));
ASSERT((node != NULL) && (node == TOP_NODE(dsp)));
@@ -1941,36 +1941,42 @@ subtree:
child:
/*
- * If there is a child--push child onto stack.
- * Hold the parent busy while doing so.
- */
- if (node->devi_child) {
- me->child = off;
- PUSH_STACK(dsp, node->devi_child, &me->child);
- return (me->child);
+ * If there is a visible child--push child onto stack.
+ * Hold the parent (me) busy while doing so.
+ */
+ if ((n = node->devi_child) != NULL) {
+ /* skip hidden nodes */
+ while (n && ndi_dev_is_hidden_node((dev_info_t *)n))
+ n = n->devi_sibling;
+ if (n) {
+ me->child = off;
+ PUSH_STACK(dsp, n, &me->child);
+ return (me->child);
+ }
}
sibling:
/*
- * no child node, unroll the stack till a sibling of
- * a parent node is found or root node is reached
+ * Done with any child nodes, unroll the stack till a visible
+ * sibling of a parent node is found or root node is reached.
*/
POP_STACK(dsp);
- while (!EMPTY_STACK(dsp) && (node->devi_sibling == NULL)) {
+ while (!EMPTY_STACK(dsp)) {
+ if ((n = node->devi_sibling) != NULL) {
+ /* skip hidden nodes */
+ while (n && ndi_dev_is_hidden_node((dev_info_t *)n))
+ n = n->devi_sibling;
+ if (n) {
+ me->sibling = DI_ALIGN(off);
+ PUSH_STACK(dsp, n, &me->sibling);
+ return (me->sibling);
+ }
+ }
node = TOP_NODE(dsp);
me = DI_NODE(di_mem_addr(st, *(TOP_OFFSET(dsp))));
POP_STACK(dsp);
}
- if (!EMPTY_STACK(dsp)) {
- /*
- * a sibling is found, replace top of stack by its sibling
- */
- me->sibling = off;
- PUSH_STACK(dsp, node->devi_sibling, &me->sibling);
- return (me->sibling);
- }
-
/*
* DONE with all nodes
*/
@@ -2211,7 +2217,7 @@ struct i_layer_data {
int lnode_count;
int link_count;
di_off_t lnode_off;
- di_off_t link_off;
+ di_off_t link_off;
};
/*ARGSUSED*/
diff --git a/usr/src/uts/common/os/devcfg.c b/usr/src/uts/common/os/devcfg.c
index 0cd8614d3d..cfdcd14495 100644
--- a/usr/src/uts/common/os/devcfg.c
+++ b/usr/src/uts/common/os/devcfg.c
@@ -275,16 +275,22 @@ i_ddi_alloc_node(dev_info_t *pdip, char *node_name, pnode_t nodeid,
*
* DEVI_PSEUDO_NODEID DDI_NC_PSEUDO A
* DEVI_SID_NODEID DDI_NC_PSEUDO A,P
+ * DEVI_SID_HIDDEN_NODEID DDI_NC_PSEUDO A,P,H
* other DDI_NC_PROM P
*
* Where A = DDI_AUTO_ASSIGNED_NODEID (auto-assign a nodeid)
* and P = DDI_PERSISTENT
+ * and H = DDI_HIDDEN_NODE
*
* auto-assigned nodeids are also auto-freed.
*/
+ devi->devi_node_attributes = 0;
switch (nodeid) {
+ case DEVI_SID_HIDDEN_NODEID:
+ devi->devi_node_attributes |= DDI_HIDDEN_NODE;
+ /*FALLTHROUGH*/
case DEVI_SID_NODEID:
- devi->devi_node_attributes = DDI_PERSISTENT;
+ devi->devi_node_attributes |= DDI_PERSISTENT;
if ((elem = kmem_zalloc(sizeof (*elem), flag)) == NULL)
goto fail;
/*FALLTHROUGH*/
@@ -711,7 +717,7 @@ unlink_node(dev_info_t *dip)
* Solaris implementation binds nodename after compatible.
*
* If we find a binding,
- * - set the binding name to the the string,
+ * - set the binding name to the string,
* - set major number to driver major
*
* If we don't find a binding,
@@ -912,7 +918,7 @@ init_node(dev_info_t *dip)
/* Unbind: demote the node back to DS_LINKED. */
if ((error = ndi_devi_unbind_driver(dip)) != DDI_SUCCESS) {
- ndi_rele_devi(pdip); /* relrease initial hold */
+ ndi_rele_devi(pdip); /* release initial hold */
cmn_err(CE_WARN, "init_node: unbind for rebind "
"of node %s failed", path);
goto out;
@@ -932,7 +938,7 @@ init_node(dev_info_t *dip)
* Start by rebinding node to the path-bound driver.
*/
if ((error = ndi_devi_bind_driver(dip, 0)) != DDI_SUCCESS) {
- ndi_rele_devi(pdip); /* relrease initial hold */
+ ndi_rele_devi(pdip); /* release initial hold */
cmn_err(CE_WARN, "init_node: rebind "
"of node %s failed", path);
goto out;
@@ -2074,11 +2080,13 @@ i_ddi_devi_attached(dev_info_t *dip)
* alternative match strategies are supported:
*
* FIND_NODE_BY_NODENAME: Match on node name - typical use.
+ *
* FIND_NODE_BY_DRIVER: A match on driver name bound to node is conducted.
* This support is used for support of OBP generic names and
* for the conversion from driver names to generic names. When
* more consistency in the generic name environment is achieved
* (and not needed for upgrade) this support can be removed.
+ *
* FIND_NODE_BY_ADDR: Match on just the addr.
* This support is only used/needed during boot to match
* a node bound via a path-based driver alias.
@@ -2544,7 +2552,7 @@ ndi_merge_node(dev_info_t *dip, int (*name_node)(dev_info_t *, char *, int))
* hardware nodes have already been initialized and attached.
*
* N.B. We return success here because the node was *intended*
- * to be a merge node because there is a hw node with the name.
+ * to be a merge node because there is a hw node with the name.
*/
mutex_enter(&DEVI(hwdip)->devi_lock);
if (ndi_dev_is_persistent_node(hwdip) == 0) {
@@ -8038,7 +8046,7 @@ e_ddi_retire_finalize(dev_info_t *dip, void *arg)
/*
* Returns
- * DDI_SUCCESS if constraints allow retire
+ * DDI_SUCCESS if constraints allow retire
* DDI_FAILURE if constraints don't allow retire.
* cons_array is a NULL terminated array of node paths for
* which constraints have already been applied.
diff --git a/usr/src/uts/common/os/sunndi.c b/usr/src/uts/common/os/sunndi.c
index c3d52cfb9e..71f54e5429 100644
--- a/usr/src/uts/common/os/sunndi.c
+++ b/usr/src/uts/common/os/sunndi.c
@@ -173,8 +173,8 @@ ndi_prop_remove_all(dev_info_t *dip)
* requests to remove an eventcall would bubble up the tree. Today, this
* parameter is ignored.
* Input Parameters:
- * dip - Ignored.
- * rdip - device driver posting the event
+ * dip - Ignored.
+ * rdip - device driver posting the event
* cookie - valid ddi_eventcookie_t, obtained by caller prior to
* invocation of this routine
* impl_data - used by framework
@@ -1722,7 +1722,7 @@ ndi_event_add_callback(ndi_event_hdl_t handle, dev_info_t *child_dip,
cb->ndi_evtcb_callback = event_callback;
cb->ndi_evtcb_arg = arg;
cb->ndi_evtcb_cookie = cookie;
- cb->devname = (char *)ddi_driver_name(child_dip);
+ cb->devname = (char *)ddi_driver_name(child_dip);
*cb_id = (ddi_callback_id_t)cb;
mutex_enter(&ndi_event_hdl->ndi_evthdl_cb_mutex);
@@ -2155,8 +2155,9 @@ ndi_dev_is_pseudo_node(dev_info_t *dip)
{
/*
* NOTE: this does NOT mean the pseudo branch of the device tree,
- * it means the node was created by software (DEVI_SID_NODEID |
- * DEVI_PSEUDO_NODEID) instead of being generated from a PROM node.
+ * it means the node was created by software (DEVI_SID_NODEID ||
+ * DEVI_PSEUDO_NODEID || DEVI_SID_HIDDEN_NODEID) instead of being
+ * generated from a PROM node.
*/
return (DEVI(dip)->devi_node_class == DDI_NC_PSEUDO);
}
@@ -2168,6 +2169,24 @@ ndi_dev_is_persistent_node(dev_info_t *dip)
}
int
+ndi_dev_is_hidden_node(dev_info_t *dip)
+{
+ return ((DEVI(dip)->devi_node_attributes & DDI_HIDDEN_NODE) != 0);
+}
+
+void
+ndi_devi_set_hidden(dev_info_t *dip)
+{
+ DEVI(dip)->devi_node_attributes |= DDI_HIDDEN_NODE;
+}
+
+void
+ndi_devi_clr_hidden(dev_info_t *dip)
+{
+ DEVI(dip)->devi_node_attributes &= ~DDI_HIDDEN_NODE;
+}
+
+int
i_ndi_dev_is_auto_assigned_node(dev_info_t *dip)
{
return ((DEVI(dip)->devi_node_attributes &
diff --git a/usr/src/uts/common/sys/ddi_impldefs.h b/usr/src/uts/common/sys/ddi_impldefs.h
index 71849552c8..1f178911d3 100644
--- a/usr/src/uts/common/sys/ddi_impldefs.h
+++ b/usr/src/uts/common/sys/ddi_impldefs.h
@@ -688,10 +688,14 @@ struct ddi_minor {
*
* DDI_VHCI_NODE indicates that the node type is VHCI. This flag
* must be set by ndi_devi_config_vhci() routine only.
+ *
+ * DDI_HIDDEN_NODE indicates that the node should not show up in snapshots
+ * or in /devices.
*/
#define DDI_PERSISTENT 0x01
#define DDI_AUTO_ASSIGNED_NODEID 0x02
#define DDI_VHCI_NODE 0x04
+#define DDI_HIDDEN_NODE 0x08
#define DEVI_VHCI_NODE(dip) \
(DEVI(dip)->devi_node_attributes & DDI_VHCI_NODE)
@@ -1042,11 +1046,11 @@ typedef struct impl_devid {
* 'A' | // DEVID_ATA_SERIAL <ascii_id>
* 'u' | // unknown <hex_id>
* 'U' // unknown <ascii_id>
- * // NOTE: lower case -> <hex_id>
- * // upper case -> <ascii_id>
- * // NOTE: this covers all types currently
+ * // NOTE:lower case -> <hex_id>
+ * // upper case -> <ascii_id>
+ * // NOTE:this covers all types currently
* // defined for <revision> 1.
- * // NOTE: a <type> can be added
+ * // NOTE:a <type> can be added
* // without changing the <revision>.
*
* <id> -> <ascii_id> | // <type> is upper case
@@ -1056,8 +1060,8 @@ typedef struct impl_devid {
* // are in the set:
* // [A-Z][a-z][0-9]+-.= and space and 0x00
* // the encoded form is:
- * // [A-Z][a-z][0-9]+-.= and _ and ~
- * // NOTE: ' ' <=> '_', 0x00 <=> '~'
+ * // [A-Z][a-z][0-9]+-.= and _ and ~
+ * // NOTE: ' ' <=> '_', 0x00 <=> '~'
* // these sets are chosen to avoid shell
* // and conflicts with DDI node names.
*
@@ -1070,11 +1074,11 @@ typedef struct impl_devid {
*
* Fibre:
* sbus@6,0/SUNW,socal@d,10000/sf@1,0/ssd@w21000020370bb488,0:c,raw
- * id1,ssd@w20000020370bb488:c,raw
+ * id1,ssd@w20000020370bb488:c,raw
*
* Copper:
* sbus@7,0/SUNW,fas@3,8800000/sd@a,0:c
- * id1,sd@SIBM_____1XY210__________:c
+ * id1,sd@SIBM_____1XY210__________:c
*/
/* determine if a byte of an id meets ASCII representation requirements */
#define DEVID_IDBYTE_ISASCII(b) ( \
diff --git a/usr/src/uts/common/sys/sunddi.h b/usr/src/uts/common/sys/sunddi.h
index 619f2a1c07..e7cad49b67 100644
--- a/usr/src/uts/common/sys/sunddi.h
+++ b/usr/src/uts/common/sys/sunddi.h
@@ -99,6 +99,10 @@ extern "C" {
*
* o DEVI_PSEUDO_NODEID specifics a node without persistence.
* o DEVI_SID_NODEID specifies a node with persistence.
+ * o DEVI_SID_HIDDEN_NODEID specifies a hidden node with persistence.
+ *
+ * A node with the 'hidden' attribute will not show up in devinfo snapshots
+ * or in /devices file system.
*
* A node with the 'persistent' attribute will not be automatically removed by
* the framework in the current implementation - driver.conf nodes are without
@@ -111,6 +115,7 @@ extern "C" {
#define DEVI_PSEUDO_NODEID ((int)-1)
#define DEVI_SID_NODEID ((int)-2)
+#define DEVI_SID_HIDDEN_NODEID ((int)-3)
#define DEVI_PSEUDO_NEXNAME "pseudo"
#define DEVI_ISA_NEXNAME "isa"
diff --git a/usr/src/uts/common/sys/sunndi.h b/usr/src/uts/common/sys/sunndi.h
index 5cd117e42d..80bbdca329 100644
--- a/usr/src/uts/common/sys/sunndi.h
+++ b/usr/src/uts/common/sys/sunndi.h
@@ -30,7 +30,6 @@
* Sun Specific NDI definitions
*/
-
#include <sys/esunddi.h>
#include <sys/sunddi.h>
#include <sys/obpdefs.h>
@@ -729,6 +728,18 @@ int ndi_dev_is_pseudo_node(dev_info_t *);
int ndi_dev_is_persistent_node(dev_info_t *);
/*
+ * ndi_dev_is_hidden_node: Return non-zero if the node is hidden.
+ */
+int ndi_dev_is_hidden_node(dev_info_t *);
+
+/*
+ * ndi_devi_set_hidden: mark a node as hidden
+ * ndi_devi_clr_hidden: mark a node as visible
+ */
+void ndi_devi_set_hidden(dev_info_t *);
+void ndi_devi_clr_hidden(dev_info_t *);
+
+/*
* Event posted when a fault is reported
*/
#define DDI_DEVI_FAULT_EVENT "DDI:DEVI_FAULT"