Home | History | Annotate | Download | only in sys
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_SYS_SUNNDI_H
     27 #define	_SYS_SUNNDI_H
     28 
     29 /*
     30  * Sun Specific NDI definitions
     31  */
     32 
     33 #include <sys/esunddi.h>
     34 #include <sys/sunddi.h>
     35 #include <sys/obpdefs.h>
     36 
     37 #ifdef	__cplusplus
     38 extern "C" {
     39 #endif
     40 
     41 #ifdef _KERNEL
     42 
     43 #define	NDI_SUCCESS	DDI_SUCCESS	/* successful return */
     44 #define	NDI_FAILURE	DDI_FAILURE	/* unsuccessful return */
     45 #define	NDI_NOMEM	-2		/* failed to allocate resources */
     46 #define	NDI_BADHANDLE	-3		/* bad handle passed to in function */
     47 #define	NDI_FAULT	-4		/* fault during copyin/copyout */
     48 #define	NDI_BUSY	-5		/* device busy - could not offline */
     49 #define	NDI_UNBOUND	-6		/* device not bound to a driver */
     50 #define	NDI_EINVAL	-7		/* invalid request or arguments */
     51 #define	NDI_ENOTSUP	-8		/* operation or event not supported */
     52 #define	NDI_CLAIMED	NDI_SUCCESS	/* event is claimed */
     53 #define	NDI_UNCLAIMED	-9		/* event is not claimed */
     54 
     55 /*
     56  * Property functions:   See also, ddipropdefs.h.
     57  *			In general, the underlying driver MUST be held
     58  *			to call it's property functions.
     59  */
     60 
     61 /*
     62  * Used to create boolean properties
     63  */
     64 int
     65 ndi_prop_create_boolean(dev_t match_dev, dev_info_t *dip, char *name);
     66 
     67 /*
     68  * Used to create, modify, and lookup integer properties
     69  */
     70 int
     71 ndi_prop_update_int(dev_t match_dev, dev_info_t *dip, char *name, int data);
     72 
     73 int
     74 ndi_prop_update_int_array(dev_t match_dev, dev_info_t *dip, char *name,
     75     int *data, uint_t nelements);
     76 
     77 int
     78 ndi_prop_update_int64(dev_t match_dev, dev_info_t *dip, char *name,
     79     int64_t data);
     80 
     81 int
     82 ndi_prop_update_int64_array(dev_t match_dev, dev_info_t *dip, char *name,
     83     int64_t *data, uint_t nelements);
     84 
     85 /*
     86  * Used to create, modify, and lookup string properties
     87  */
     88 int
     89 ndi_prop_update_string(dev_t match_dev, dev_info_t *dip, char *name,
     90     char *data);
     91 
     92 int
     93 ndi_prop_update_string_array(dev_t match_dev, dev_info_t *dip,
     94     char *name, char **data, uint_t nelements);
     95 
     96 /*
     97  * Used to create, modify, and lookup byte properties
     98  */
     99 int
    100 ndi_prop_update_byte_array(dev_t match_dev, dev_info_t *dip,
    101     char *name, uchar_t *data, uint_t nelements);
    102 
    103 /*
    104  * Used to remove properties
    105  */
    106 int
    107 ndi_prop_remove(dev_t dev, dev_info_t *dip, char *name);
    108 
    109 void
    110 ndi_prop_remove_all(dev_info_t *dip);
    111 
    112 /*
    113  * Nexus Driver Functions
    114  */
    115 /*
    116  * Allocate and initialize a new dev_info structure.
    117  * This routine will often be called at interrupt time by a nexus in
    118  * response to a hotplug event, therefore memory allocations are
    119  * not allowed to sleep.
    120  */
    121 int
    122 ndi_devi_alloc(dev_info_t *parent, char *node_name, pnode_t nodeid,
    123     dev_info_t **ret_dip);
    124 
    125 void
    126 ndi_devi_alloc_sleep(dev_info_t *parent, char *node_name, pnode_t nodeid,
    127     dev_info_t **ret_dip);
    128 
    129 /*
    130  * Remove an initialized (but not yet attached) dev_info
    131  * node from it's parent.
    132  */
    133 int
    134 ndi_devi_free(dev_info_t *dip);
    135 
    136 /* devinfo locking: use DEVI_BUSY_OWNED in ASSERTs to verify */
    137 void ndi_devi_enter(dev_info_t *dip, int *circ);
    138 void ndi_devi_exit(dev_info_t *dip, int circ);
    139 int ndi_devi_tryenter(dev_info_t *dip, int *circ);
    140 
    141 /* devinfo ref counting */
    142 void ndi_hold_devi(dev_info_t *dip);
    143 void ndi_rele_devi(dev_info_t *dip);
    144 
    145 /* driver ref counting */
    146 struct dev_ops *ndi_hold_driver(dev_info_t *dip);
    147 void ndi_rele_driver(dev_info_t *dip);
    148 
    149 /*
    150  * Change the node name
    151  */
    152 int
    153 ndi_devi_set_nodename(dev_info_t *dip, char *name, int flags);
    154 
    155 /*
    156  * Place the devinfo in the DS_BOUND state,
    157  * binding a driver to the device
    158  *
    159  * Flags:
    160  *	all flags are ignored.
    161  */
    162 int
    163 ndi_devi_bind_driver(dev_info_t *dip, uint_t flags);
    164 
    165 /*
    166  * Asynchronous version of ndi_devi_bind_driver, callable from
    167  * interrupt context. The dip must be a persistent node.
    168  */
    169 int
    170 ndi_devi_bind_driver_async(dev_info_t *dip, uint_t flags);
    171 
    172 /*
    173  * Return devctl state of the child addressed by "name@addr".
    174  * For use by a driver's DEVCTL_DEVICE_GETSTATE handler.
    175  */
    176 int
    177 ndi_devctl_device_getstate(dev_info_t *parent, struct devctl_iocdata *dcp,
    178 	uint_t *state);
    179 
    180 /*
    181  * Transition the child addressed by "name@addr" to the online state.
    182  * For use by a driver's DEVCTL_DEVICE_ONLINE handler.
    183  */
    184 int
    185 ndi_devctl_device_online(dev_info_t *dip, struct devctl_iocdata *dcp,
    186 	uint_t flags);
    187 
    188 /*
    189  * Transition the child addressed by "name@addr" to the offline state.
    190  * For use by a driver's DEVCTL_DEVICE_OFFLINE handler.
    191  */
    192 int
    193 ndi_devctl_device_offline(dev_info_t *dip, struct devctl_iocdata *dcp,
    194 	uint_t flags);
    195 
    196 /*
    197  * Remove the child addressed by name@addr.
    198  * For use by a driver's DEVCTL_DEVICE_REMOVE handler.
    199  */
    200 int
    201 ndi_devctl_device_remove(dev_info_t *dip, struct devctl_iocdata *dcp,
    202 	uint_t flags);
    203 
    204 /*
    205  * Bus get state
    206  * For use by a driver's DEVCTL_BUS_GETSTATE handler.
    207  */
    208 int
    209 ndi_devctl_bus_getstate(dev_info_t *dip, struct devctl_iocdata *dcp,
    210 	uint_t *state);
    211 
    212 /*
    213  * Place the devinfo in the ONLINE state
    214  */
    215 int
    216 ndi_devi_online(dev_info_t *dip, uint_t flags);
    217 
    218 /*
    219  * Generic devctl ioctl handler
    220  */
    221 int
    222 ndi_devctl_ioctl(dev_info_t *dip, int cmd, intptr_t arg, int mode,
    223 	uint_t flags);
    224 
    225 /*
    226  * Asynchronous version of ndi_devi_online, callable from interrupt
    227  * context. The dip must be a persistent node.
    228  */
    229 int
    230 ndi_devi_online_async(dev_info_t *dip, uint_t flags);
    231 
    232 
    233 /*
    234  * Configure children of a nexus node.
    235  *
    236  * Flags:
    237  *	NDI_ONLINE_ATTACH - Attach driver to devinfo node when placing
    238  *			    the device Online.
    239  *	NDI_CONFIG - Recursively configure children if child is nexus node
    240  */
    241 int
    242 ndi_devi_config(dev_info_t *dip, int flags);
    243 
    244 int
    245 ndi_devi_config_driver(dev_info_t *dip, int flags, major_t major);
    246 
    247 int
    248 ndi_devi_config_one(dev_info_t *dip, char *devnm, dev_info_t **dipp, int flags);
    249 
    250 /*
    251  * Unconfigure children of a nexus node.
    252  *
    253  * Flags:
    254  *	NDI_DEVI_REMOVE - Remove child devinfo nodes
    255  *
    256  *	NDI_UNCONFIG - Put child devinfo nodes to uninitialized state,
    257  *			release resources held by child nodes.
    258  */
    259 int
    260 ndi_devi_unconfig(dev_info_t *dip, int flags);
    261 
    262 int
    263 e_ddi_devi_unconfig(dev_info_t *dip, dev_info_t **dipp, int flags);
    264 
    265 int
    266 ndi_devi_unconfig_one(dev_info_t *dip, char *devnm, dev_info_t **dipp,
    267     int flags);
    268 
    269 int
    270 ndi_devi_unconfig_driver(dev_info_t *dip, int flags, major_t major);
    271 
    272 void
    273 ndi_set_bus_private(dev_info_t *dip, boolean_t up, uint32_t port_type,
    274     void *data);
    275 
    276 void *
    277 ndi_get_bus_private(dev_info_t *dip, boolean_t up);
    278 
    279 boolean_t
    280 ndi_port_type(dev_info_t *dip, boolean_t up, uint32_t port_type);
    281 
    282 /*
    283  * Create/Destroy Interrupt Resource Management (IRM) Pools.
    284  */
    285 int
    286 ndi_irm_create(dev_info_t *dip, ddi_irm_params_t *paramsp,
    287     ddi_irm_pool_t **pool_retp);
    288 
    289 int
    290 ndi_irm_destroy(ddi_irm_pool_t *poolp);
    291 
    292 /*
    293  * Take a device node "Offline".
    294  *
    295  * Offline means to detach the device instance from the bound
    296  * driver and setting the devinfo state to prevent deferred attach
    297  * from re-attaching the device instance.
    298  *
    299  * Flags:
    300  *	NDI_DEVI_REMOVE	- Remove the node from the devinfo tree after
    301  *			  first taking it Offline.
    302  */
    303 
    304 #define	NDI_DEVI_REMOVE		0x00000001 /* remove after unconfig */
    305 #define	NDI_ONLINE_ATTACH	0x00000002 /* online/attach after config */
    306 #define	NDI_MDI_FALLBACK	0x00000004 /* Leadville to fallback to phci */
    307 #define	NDI_CONFIG		0x00000008 /* recursively config descendants */
    308 #define	NDI_UNCONFIG		0x00000010 /* unconfig to uninitialized state */
    309 #define	NDI_DEVI_BIND		0x00000020 /* transition to DS_BOUND state */
    310 #define	NDI_DEVI_PERSIST	0x00000040 /* do not config offlined nodes */
    311 #define	NDI_PROMNAME		0x00000080 /* name comes from prom */
    312 #define	NDI_DEVFS_CLEAN		0x00001000 /* clean dv_nodes only, no detach */
    313 #define	NDI_AUTODETACH		0x00002000 /* moduninstall daemon */
    314 #define	NDI_NO_EVENT		0x00004000 /* don't devfs add/remove events */
    315 #define	NDI_DEVI_DEBUG		0x00008000 /* turn on observability */
    316 #define	NDI_CONFIG_REPROBE	0x00010000 /* force reprobe (deferred attach) */
    317 #define	NDI_DEVI_ONLINE		0x00020000 /* force offlined device to online */
    318 #define	NDI_DEVI_OFFLINE	0x00040000 /* set detached device to offline */
    319 #define	NDI_POST_EVENT		0x00080000 /* Post NDI events before remove */
    320 #define	NDI_BRANCH_EVENT_OP	0x01000000 /* branch op needs branch event */
    321 #define	NDI_NO_EVENT_STATE_CHNG	0x02000000 /* don't change the event state */
    322 #define	NDI_DRV_CONF_REPROBE	0x04000000 /* reprobe conf-enum'd nodes only */
    323 #define	NDI_DETACH_DRIVER	0x08000000 /* performing driver_detach */
    324 #define	NDI_MTC_OFF		0x10000000 /* disable multi-threading */
    325 #define	NDI_USER_REQ		0x20000000 /* user requested operation */
    326 
    327 /* ndi interface flag values */
    328 #define	NDI_SLEEP		0x000000
    329 #define	NDI_NOSLEEP		0x100000
    330 #define	NDI_EVENT_NOPASS	0x200000 /* do not pass event req up the tree */
    331 
    332 int
    333 ndi_devi_offline(dev_info_t *dip, uint_t flags);
    334 
    335 /*
    336  * Find the child dev_info node of parent nexus 'p' whose name
    337  * matches "cname"@"caddr".  Use ndi_devi_findchild() instead.
    338  */
    339 dev_info_t *
    340 ndi_devi_find(dev_info_t *p, char *cname, char *caddr);
    341 
    342 /*
    343  * Find the child dev_info node of parent nexus 'p' whose name
    344  * matches device name "name"@"addr".
    345  */
    346 dev_info_t *
    347 ndi_devi_findchild(dev_info_t *p, char *devname);
    348 
    349 /*
    350  * Find the child dev_info node of parent nexus 'p' whose name
    351  * matches "dname"@"ua". If a child doesn't have a "ua"
    352  * value, it calls the function "make_ua" to create it.
    353  */
    354 dev_info_t *
    355 ndi_devi_findchild_by_callback(dev_info_t *p, char *dname, char *ua,
    356     int (*make_ua)(dev_info_t *, char *, int));
    357 
    358 /*
    359  * Maintain DEVI_DEVICE_REMOVED hotplug devi_state for remove/reinsert hotplug
    360  * of open devices.
    361  */
    362 int
    363 ndi_devi_device_isremoved(dev_info_t *dip);
    364 int
    365 ndi_devi_device_remove(dev_info_t *dip);
    366 int
    367 ndi_devi_device_insert(dev_info_t *dip);
    368 
    369 /*
    370  * generate debug msg via NDI_DEVI_DEBUG flag
    371  */
    372 #define	NDI_DEBUG(flags, args)	\
    373 	if (flags & NDI_DEVI_DEBUG) cmn_err args
    374 
    375 /*
    376  * Copy in the devctl IOCTL data structure and the strings referenced
    377  * by the structure.
    378  *
    379  * Convenience functions for use by nexus drivers as part of the
    380  * implementation of devctl IOCTL handling.
    381  */
    382 int
    383 ndi_dc_allochdl(void *iocarg, struct devctl_iocdata **rdcp);
    384 
    385 void
    386 ndi_dc_freehdl(struct devctl_iocdata *dcp);
    387 
    388 char *
    389 ndi_dc_getpath(struct devctl_iocdata *dcp);
    390 
    391 char *
    392 ndi_dc_getname(struct devctl_iocdata *dcp);
    393 
    394 char *
    395 ndi_dc_getaddr(struct devctl_iocdata *dcp);
    396 
    397 nvlist_t *
    398 ndi_dc_get_ap_data(struct devctl_iocdata *dcp);
    399 
    400 char *
    401 ndi_dc_getminorname(struct devctl_iocdata *dcp);
    402 
    403 int
    404 ndi_dc_return_dev_state(dev_info_t *dip, struct devctl_iocdata *dcp);
    405 
    406 int
    407 ndi_dc_return_ap_state(devctl_ap_state_t *ap, struct devctl_iocdata *dcp);
    408 
    409 int
    410 ndi_dc_return_bus_state(dev_info_t *dip, struct devctl_iocdata *dcp);
    411 
    412 int
    413 ndi_dc_devi_create(struct devctl_iocdata *dcp, dev_info_t *pdip, int flags,
    414     dev_info_t **rdip);
    415 
    416 int
    417 ndi_get_bus_state(dev_info_t *dip, uint_t *rstate);
    418 
    419 int
    420 ndi_set_bus_state(dev_info_t *dip, uint_t state);
    421 
    422 /*
    423  * Post an event notification up the device tree hierarchy to the
    424  * parent nexus, until claimed by a bus nexus driver or the top
    425  * of the dev_info tree is reached.
    426  */
    427 int
    428 ndi_post_event(dev_info_t *dip, dev_info_t *rdip, ddi_eventcookie_t eventhdl,
    429     void *impl_data);
    430 
    431 /*
    432  * Called by the NDI Event Framework to deliver a registration request to the
    433  * appropriate bus nexus driver.
    434  */
    435 int
    436 ndi_busop_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
    437     ddi_eventcookie_t eventhdl, void (*callback)(), void *arg,
    438     ddi_callback_id_t *cb_id);
    439 
    440 /*
    441  * Called by the NDI Event Framework to deliver an unregister request to the
    442  * appropriate bus nexus driver.
    443  */
    444 int
    445 ndi_busop_remove_eventcall(dev_info_t *ddip, ddi_callback_id_t id);
    446 
    447 /*
    448  * Called by the NDI Event Framework and/or a bus nexus driver's
    449  * implementation of the (*bus_get_eventcookie)() interface up the device tree
    450  * hierarchy, until claimed by a bus nexus driver or the top of the dev_info
    451  * tree is reached.  The NDI Event Framework will skip nexus drivers which are
    452  * not configured to handle NDI events.
    453  */
    454 int
    455 ndi_busop_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, char *name,
    456     ddi_eventcookie_t *event_cookiep);
    457 
    458 /*
    459  * ndi event callback support routines:
    460  *
    461  * these functions require an opaque ndi event handle
    462  */
    463 typedef struct ndi_event_hdl *ndi_event_hdl_t;
    464 
    465 /*
    466  * structure for maintaining each registered callback
    467  */
    468 typedef struct ndi_event_callbacks {
    469 	struct ndi_event_callbacks *ndi_evtcb_next;
    470 	struct ndi_event_callbacks *ndi_evtcb_prev;
    471 	dev_info_t	*ndi_evtcb_dip;
    472 	char		*devname; /* name of device defining this callback */
    473 	void		(*ndi_evtcb_callback)();
    474 	void		*ndi_evtcb_arg;
    475 	ddi_eventcookie_t	ndi_evtcb_cookie;
    476 } ndi_event_callbacks_t;
    477 
    478 /*
    479  * a nexus driver defines events that it can support using the
    480  * following structure
    481  */
    482 typedef struct ndi_event_definition {
    483 	int			ndi_event_tag;
    484 	char			*ndi_event_name;
    485 	ddi_plevel_t		ndi_event_plevel;
    486 	uint_t			ndi_event_attributes;
    487 } ndi_event_definition_t;
    488 
    489 typedef struct ndi_event_cookie {
    490 	ndi_event_definition_t	*definition;	/* Event Description */
    491 	dev_info_t		*ddip;		/* Devi defining this event */
    492 	ndi_event_callbacks_t	*callback_list; /* Cb's reg'd to w/ this evt */
    493 	struct ndi_event_cookie *next_cookie;	/* Next cookie def'd in hdl */
    494 } ndi_event_cookie_t;
    495 
    496 
    497 #define	NDI_EVENT(cookie) ((struct ndi_event_cookie *)(void *)(cookie))
    498 #define	NDI_EVENT_NAME(cookie) (NDI_EVENT(cookie)->definition->ndi_event_name)
    499 #define	NDI_EVENT_TAG(cookie) (NDI_EVENT(cookie)->definition->ndi_event_tag)
    500 #define	NDI_EVENT_ATTRIBUTES(cookie) \
    501 	(NDI_EVENT(cookie)->definition->ndi_event_attributes)
    502 #define	NDI_EVENT_PLEVEL(cookie) \
    503 	(NDI_EVENT(cookie)->definition->ndi_event_plevel)
    504 #define	NDI_EVENT_DDIP(cookie) (NDI_EVENT(cookie)->ddip)
    505 
    506 /* ndi_event_attributes */
    507 #define	NDI_EVENT_POST_TO_ALL	0x0 /* broadcast: post to all handlers */
    508 #define	NDI_EVENT_POST_TO_TGT	0x1 /* call only specific child's hdlr */
    509 
    510 typedef struct ndi_event_set {
    511 	ushort_t		ndi_events_version;
    512 	ushort_t		ndi_n_events;
    513 	ndi_event_definition_t	*ndi_event_defs;
    514 } ndi_event_set_t;
    515 
    516 
    517 #define	NDI_EVENTS_REV0			0
    518 #define	NDI_EVENTS_REV1			1
    519 
    520 /*
    521  * allocate an ndi event handle
    522  */
    523 int
    524 ndi_event_alloc_hdl(dev_info_t *dip, ddi_iblock_cookie_t cookie,
    525 	ndi_event_hdl_t *ndi_event_hdl, uint_t flag);
    526 
    527 /*
    528  * free the ndi event handle
    529  */
    530 int
    531 ndi_event_free_hdl(ndi_event_hdl_t handle);
    532 
    533 /*
    534  * bind or unbind a set of events to/from the event handle
    535  */
    536 int
    537 ndi_event_bind_set(ndi_event_hdl_t	handle,
    538 	ndi_event_set_t		*ndi_event_set,
    539 	uint_t			flag);
    540 
    541 int
    542 ndi_event_unbind_set(ndi_event_hdl_t	handle,
    543 	ndi_event_set_t		*ndi_event_set,
    544 	uint_t			flag);
    545 
    546 /*
    547  * get an event cookie
    548  */
    549 int
    550 ndi_event_retrieve_cookie(ndi_event_hdl_t	handle,
    551 	dev_info_t		*child_dip,
    552 	char			*eventname,
    553 	ddi_eventcookie_t	*cookiep,
    554 	uint_t			flag);
    555 
    556 /*
    557  * add an event callback info to the ndi event handle
    558  */
    559 int
    560 ndi_event_add_callback(ndi_event_hdl_t	handle,
    561 	dev_info_t		*child_dip,
    562 	ddi_eventcookie_t	cookie,
    563 	void			(*event_callback)
    564 					(dev_info_t *,
    565 					ddi_eventcookie_t,
    566 					void *arg,
    567 					void *impldata),
    568 	void			*arg,
    569 	uint_t			flag,
    570 	ddi_callback_id_t *cb_id);
    571 
    572 /*
    573  * remove an event callback registration from the ndi event handle
    574  */
    575 int
    576 ndi_event_remove_callback(ndi_event_hdl_t handle, ddi_callback_id_t id);
    577 
    578 /*
    579  * perform callbacks for a specified cookie
    580  */
    581 int
    582 ndi_event_run_callbacks(ndi_event_hdl_t	handle, dev_info_t *child_dip,
    583     ddi_eventcookie_t cookie, void *bus_impldata);
    584 
    585 /*
    586  * do callback for just one child_dip, regardless of attributes
    587  */
    588 int ndi_event_do_callback(ndi_event_hdl_t handle, dev_info_t *child_dip,
    589 	ddi_eventcookie_t cookie, void *bus_impldata);
    590 
    591 /*
    592  * ndi_event_tag_to_cookie: utility function to find an event cookie
    593  * given an event tag
    594  */
    595 ddi_eventcookie_t
    596 ndi_event_tag_to_cookie(ndi_event_hdl_t handle, int event_tag);
    597 
    598 /*
    599  * ndi_event_cookie_to_tag: utility function to find an event tag
    600  * given an event_cookie
    601  */
    602 int
    603 ndi_event_cookie_to_tag(ndi_event_hdl_t handle,
    604 	ddi_eventcookie_t cookie);
    605 
    606 /*
    607  * ndi_event_cookie_to_name: utility function to find an event
    608  * name given an event_cookie
    609  */
    610 char *
    611 ndi_event_cookie_to_name(ndi_event_hdl_t handle,
    612 	ddi_eventcookie_t cookie);
    613 
    614 /*
    615  * ndi_event_tag_to_name: utility function to find an event
    616  * name given an event_tag
    617  */
    618 char *
    619 ndi_event_tag_to_name(ndi_event_hdl_t	handle, int event_tag);
    620 
    621 dev_info_t *
    622 ndi_devi_config_vhci(char *, int);
    623 
    624 #ifdef DEBUG
    625 /*
    626  * ndi_event_dump_hdl: debug functionality used to display event handle
    627  */
    628 void
    629 ndi_event_dump_hdl(struct ndi_event_hdl *hdl, char *location);
    630 #endif
    631 
    632 /*
    633  * Default busop bus_config helper functions
    634  */
    635 int
    636 ndi_busop_bus_config(dev_info_t *pdip, uint_t flags, ddi_bus_config_op_t op,
    637     void *arg, dev_info_t **child, clock_t reset_delay);
    638 
    639 int
    640 ndi_busop_bus_unconfig(dev_info_t *dip, uint_t flags, ddi_bus_config_op_t op,
    641     void *arg);
    642 
    643 /*
    644  * Called by the Nexus/HPC drivers to register, unregister and interact
    645  * with the hotplug framework for the specified hotplug connection.
    646  */
    647 int
    648 ndi_hp_register(dev_info_t *dip, ddi_hp_cn_info_t *info_p);
    649 
    650 int
    651 ndi_hp_unregister(dev_info_t *dip, char *cn_name);
    652 
    653 int
    654 ndi_hp_state_change_req(dev_info_t *dip, char *cn_name,
    655     ddi_hp_cn_state_t state, uint_t flag);
    656 
    657 void
    658 ndi_hp_walk_cn(dev_info_t *dip, int (*f)(ddi_hp_cn_info_t *, void *),
    659     void *arg);
    660 
    661 /*
    662  * Bus Resource allocation structures and function prototypes exported
    663  * by busra module
    664  */
    665 
    666 /* structure for specifying a request */
    667 typedef struct ndi_ra_request {
    668 	uint_t		ra_flags;	/* General flags		*/
    669 					/* see bit definitions below	*/
    670 
    671 	uint64_t	ra_len;		/* Requested allocation length	*/
    672 
    673 	uint64_t	ra_addr;	/* Specific base address requested */
    674 
    675 	uint64_t	ra_boundbase;	/* Base address of the area for	*/
    676 					/* the allocated resource to be	*/
    677 					/* restricted to		*/
    678 
    679 	uint64_t	ra_boundlen;	/* Length of the area, starting	*/
    680 					/* from ra_boundbase, for the	*/
    681 					/* allocated resource to be	*/
    682 					/* restricted to.   		*/
    683 
    684 	uint64_t	ra_align_mask;	/* Alignment mask used for	*/
    685 					/* allocated base address	*/
    686 } ndi_ra_request_t;
    687 
    688 
    689 /* ra_flags bit definitions */
    690 #define	NDI_RA_ALIGN_SIZE	0x0001	/* Set the alignment of the	*/
    691 					/* allocated resource address	*/
    692 					/* according to the ra_len	*/
    693 					/* value (alignment mask will	*/
    694 					/* be (ra_len - 1)). Value of	*/
    695 					/* ra_len has to be power of 2.	*/
    696 					/* If this flag is set, value of */
    697 					/* ra_align_mask will be ignored. */
    698 
    699 
    700 #define	NDI_RA_ALLOC_BOUNDED	0x0002	/* Indicates that the resource	*/
    701 					/* should be restricted to the	*/
    702 					/* area specified by ra_boundbase */
    703 					/* and ra_boundlen */
    704 
    705 #define	NDI_RA_ALLOC_SPECIFIED	0x0004	/* Indicates that a specific	*/
    706 					/* address (ra_addr value) is	*/
    707 					/* requested.			*/
    708 
    709 #define	NDI_RA_ALLOC_PARTIAL_OK	0x0008  /* Indicates if requested size	*/
    710 					/* (ra_len) chunk is not available */
    711 					/* then allocate as big chunk as */
    712 					/* possible which is less than or */
    713 					/* equal to ra_len size. */
    714 
    715 
    716 /* return values specific to bus resource allocator */
    717 #define	NDI_RA_PARTIAL_REQ		-7
    718 
    719 
    720 
    721 
    722 /* Predefined types for generic type of resources */
    723 #define	NDI_RA_TYPE_MEM			"memory"
    724 #define	NDI_RA_TYPE_IO			"io"
    725 #define	NDI_RA_TYPE_PCI_BUSNUM		"pci_bus_number"
    726 #define	NDI_RA_TYPE_PCI_PREFETCH_MEM	"pci_prefetchable_memory"
    727 #define	NDI_RA_TYPE_INTR		"interrupt"
    728 
    729 /* flag bit definition */
    730 #define	NDI_RA_PASS	0x0001		/* pass request up the dev tree */
    731 
    732 /*
    733  * Prototype definitions for functions exported
    734  */
    735 
    736 int
    737 ndi_ra_map_setup(dev_info_t *dip, char *type);
    738 
    739 int
    740 ndi_ra_map_destroy(dev_info_t *dip, char *type);
    741 
    742 int
    743 ndi_ra_alloc(dev_info_t *dip, ndi_ra_request_t *req, uint64_t *basep,
    744 	uint64_t *lenp, char *type, uint_t flag);
    745 
    746 int
    747 ndi_ra_free(dev_info_t *dip, uint64_t base, uint64_t len, char *type,
    748 	uint_t flag);
    749 
    750 /*
    751  * ndi_dev_is_prom_node: Return non-zero if the node is a prom node
    752  */
    753 int ndi_dev_is_prom_node(dev_info_t *);
    754 
    755 /*
    756  * ndi_dev_is_pseudo_node: Return non-zero if the node is a pseudo node.
    757  * NB: all non-prom nodes are pseudo nodes.
    758  * c.f. ndi_dev_is_persistent_node
    759  */
    760 int ndi_dev_is_pseudo_node(dev_info_t *);
    761 
    762 /*
    763  * ndi_dev_is_persistent_node: Return non-zero if the node has the
    764  * property of persistence.
    765  */
    766 int ndi_dev_is_persistent_node(dev_info_t *);
    767 
    768 /*
    769  * ndi_dev_is_hotplug_node: Return non-zero if the node was created by hotplug.
    770  */
    771 int ndi_dev_is_hotplug_node(dev_info_t *);
    772 
    773 /*
    774  * ndi_dev_is_hidden_node: Return non-zero if the node is hidden.
    775  */
    776 int ndi_dev_is_hidden_node(dev_info_t *);
    777 
    778 /*
    779  * ndi_devi_set_hidden: mark a node as hidden
    780  * ndi_devi_clr_hidden: mark a node as visible
    781  */
    782 void ndi_devi_set_hidden(dev_info_t *);
    783 void ndi_devi_clr_hidden(dev_info_t *);
    784 
    785 /*
    786  * Event posted when a fault is reported
    787  */
    788 #define	DDI_DEVI_FAULT_EVENT	"DDI:DEVI_FAULT"
    789 
    790 struct ddi_fault_event_data {
    791 	dev_info_t		*f_dip;
    792 	ddi_fault_impact_t	f_impact;
    793 	ddi_fault_location_t	f_location;
    794 	const char		*f_message;
    795 	ddi_devstate_t		f_oldstate;
    796 };
    797 
    798 /*
    799  * Access handle/DMA handle fault flag setting/clearing functions for nexi
    800  */
    801 void ndi_set_acc_fault(ddi_acc_handle_t ah);
    802 void ndi_clr_acc_fault(ddi_acc_handle_t ah);
    803 void ndi_set_dma_fault(ddi_dma_handle_t dh);
    804 void ndi_clr_dma_fault(ddi_dma_handle_t dh);
    805 
    806 /* Driver.conf property merging */
    807 int	ndi_merge_node(dev_info_t *, int (*)(dev_info_t *, char *, int));
    808 void	ndi_merge_wildcard_node(dev_info_t *);
    809 
    810 /*
    811  * Ndi 'flavor' support: These interfaces are to support a nexus driver
    812  * with multiple 'flavors' of children (devi_flavor of child), coupled
    813  * with a child flavor-specifc private data mechanism (via devi_flavor_v
    814  * of parent). This is provided as an extension to ddi_[sg]et_driver_private,
    815  * where the vanilla 'flavor' is what is stored or retrieved via
    816  * ddi_[sg]et_driver_private.
    817  *
    818  * Flavors are indexed with a small integer. The first flavor, flavor
    819  * zero, is always present and reserved as the 'vanilla' flavor.
    820  * Space for extra flavors can be allocated and private pointers
    821  * with respect to each flavor set and retrieved.
    822  *
    823  * NOTE:For a nexus driver, if the need to support multiple flavors of
    824  *	children is understood from the begining, then a private 'flavor'
    825  *	mechanism can be implemented via ddi_[sg]et_driver_private.
    826  *
    827  *	With SCSA, the need to support multiple flavors of children was not
    828  *	anticipated, and ddi_get_driver_private(9F) of an initiator port
    829  *	devinfo node was publicly defined in the DDI to return a
    830  *	scsi_device(9S) child-flavor specific value: a pointer to
    831  *	scsi_hba_tran(9S).  Over the years, each time the need to support
    832  *	a new flavor of child has occurred, a new form of overload/kludge
    833  *	has been devised. The ndi 'flavors' interfaces provide a simple way
    834  *	to address this issue that can be used by both SCSA nexus support,
    835  *	and by other nexus drivers.
    836  */
    837 
    838 /*
    839  * Interfaces to maintain flavor-specific private data for children of self
    840  */
    841 #define	NDI_FLAVOR_VANILLA	0
    842 
    843 void	ndi_flavorv_alloc(dev_info_t *self, int nflavors);
    844 void	ndi_flavorv_set(dev_info_t *self, ndi_flavor_t child_flavor, void *);
    845 void	*ndi_flavorv_get(dev_info_t *self, ndi_flavor_t child_flavor);
    846 
    847 /* Interfaces for 'self' nexus driver to get/set flavor of child */
    848 void		ndi_flavor_set(dev_info_t *child, ndi_flavor_t child_flavor);
    849 ndi_flavor_t	ndi_flavor_get(dev_info_t *child);
    850 
    851 #endif	/* _KERNEL */
    852 
    853 #ifdef	__cplusplus
    854 }
    855 #endif
    856 
    857 #endif	/* _SYS_SUNNDI_H */
    858