diff options
author | Chris Horne <Chris.Horne@Sun.COM> | 2009-02-26 10:16:09 -0700 |
---|---|---|
committer | Chris Horne <Chris.Horne@Sun.COM> | 2009-02-26 10:16:09 -0700 |
commit | 027021c7b9f04b74ae04cb1c3ddba52f2a2f9fd1 (patch) | |
tree | 892af8329770bffbab80b12ffc33d44556b4c5ff | |
parent | 7a71c13f9776768e00d7d5ccc8c8adc8eeb6888d (diff) | |
download | illumos-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.c | 32 | ||||
-rw-r--r-- | usr/src/uts/common/io/devinfo.c | 50 | ||||
-rw-r--r-- | usr/src/uts/common/os/devcfg.c | 20 | ||||
-rw-r--r-- | usr/src/uts/common/os/sunndi.c | 29 | ||||
-rw-r--r-- | usr/src/uts/common/sys/ddi_impldefs.h | 20 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sunddi.h | 5 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sunndi.h | 13 |
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" |