xref: /titanic_41/usr/src/uts/common/sys/ddi_hp_impl.h (revision 4f6e674fbbae301788090311a9ecf340d0ef7f8b)
1*26947304SEvan Yan /*
2*26947304SEvan Yan  * CDDL HEADER START
3*26947304SEvan Yan  *
4*26947304SEvan Yan  * The contents of this file are subject to the terms of the
5*26947304SEvan Yan  * Common Development and Distribution License (the "License").
6*26947304SEvan Yan  * You may not use this file except in compliance with the License.
7*26947304SEvan Yan  *
8*26947304SEvan Yan  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*26947304SEvan Yan  * or http://www.opensolaris.org/os/licensing.
10*26947304SEvan Yan  * See the License for the specific language governing permissions
11*26947304SEvan Yan  * and limitations under the License.
12*26947304SEvan Yan  *
13*26947304SEvan Yan  * When distributing Covered Code, include this CDDL HEADER in each
14*26947304SEvan Yan  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*26947304SEvan Yan  * If applicable, add the following below this CDDL HEADER, with the
16*26947304SEvan Yan  * fields enclosed by brackets "[]" replaced with your own identifying
17*26947304SEvan Yan  * information: Portions Copyright [yyyy] [name of copyright owner]
18*26947304SEvan Yan  *
19*26947304SEvan Yan  * CDDL HEADER END
20*26947304SEvan Yan  */
21*26947304SEvan Yan /*
22*26947304SEvan Yan  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*26947304SEvan Yan  * Use is subject to license terms.
24*26947304SEvan Yan  */
25*26947304SEvan Yan 
26*26947304SEvan Yan #ifndef	_SYS_DDI_HP_IMPL_H
27*26947304SEvan Yan #define	_SYS_DDI_HP_IMPL_H
28*26947304SEvan Yan 
29*26947304SEvan Yan /*
30*26947304SEvan Yan  * Sun DDI hotplug implementation specific definitions
31*26947304SEvan Yan  */
32*26947304SEvan Yan 
33*26947304SEvan Yan #ifdef	__cplusplus
34*26947304SEvan Yan extern "C" {
35*26947304SEvan Yan #endif
36*26947304SEvan Yan 
37*26947304SEvan Yan #ifdef _KERNEL
38*26947304SEvan Yan 
39*26947304SEvan Yan /* Flags for sync request and async hotplug request */
40*26947304SEvan Yan #define	DDI_HP_REQ_SYNC 0x0001
41*26947304SEvan Yan #define	DDI_HP_REQ_ASYNC 0x0002
42*26947304SEvan Yan 
43*26947304SEvan Yan /* Check if a handle represents a port or a connector */
44*26947304SEvan Yan #define	DDI_HP_IS_VIRTUAL_PORT(hdlp)		\
45*26947304SEvan Yan 	(hdlp->cn_info.cn_type == DDI_HP_CN_TYPE_VIRTUAL_PORT)
46*26947304SEvan Yan 
47*26947304SEvan Yan /*
48*26947304SEvan Yan  * ddi_hp_cn_handle_t
49*26947304SEvan Yan  *
50*26947304SEvan Yan  * DDI handle for a registered Hotplug Connection (CN)
51*26947304SEvan Yan  */
52*26947304SEvan Yan typedef struct ddi_hp_cn_handle {
53*26947304SEvan Yan 	dev_info_t		*cn_dip; /* The dip that the handle is linked */
54*26947304SEvan Yan 	ddi_hp_cn_info_t	cn_info; /* Connection info */
55*26947304SEvan Yan 	struct ddi_hp_cn_handle	*next;	 /* Next Connector/Port. */
56*26947304SEvan Yan } ddi_hp_cn_handle_t;
57*26947304SEvan Yan 
58*26947304SEvan Yan typedef struct ddi_hp_cn_async_event_entry {
59*26947304SEvan Yan 	dev_info_t			*dip;
60*26947304SEvan Yan 	char				*cn_name;
61*26947304SEvan Yan 	ddi_hp_cn_state_t		target_state;
62*26947304SEvan Yan } ddi_hp_cn_async_event_entry_t;
63*26947304SEvan Yan 
64*26947304SEvan Yan /*
65*26947304SEvan Yan  * ddi_hp_op_t
66*26947304SEvan Yan  *
67*26947304SEvan Yan  * Typedef for Hotplug OPS commands used with bus_hp_op()
68*26947304SEvan Yan  */
69*26947304SEvan Yan typedef enum {
70*26947304SEvan Yan 	DDI_HPOP_CN_GET_STATE = 1,	/* Get Connection state */
71*26947304SEvan Yan 	DDI_HPOP_CN_CHANGE_STATE,	/* Change Connection state */
72*26947304SEvan Yan 	DDI_HPOP_CN_PROBE,		/* Probe Connection */
73*26947304SEvan Yan 	DDI_HPOP_CN_UNPROBE,		/* Unprobe Connection */
74*26947304SEvan Yan 	DDI_HPOP_CN_GET_PROPERTY,	/* Get bus specific property */
75*26947304SEvan Yan 	DDI_HPOP_CN_SET_PROPERTY,	/* Set bus specific property */
76*26947304SEvan Yan 	DDI_HPOP_CN_CREATE_PORT,	/* Create a port for virtual hotplug */
77*26947304SEvan Yan 	DDI_HPOP_CN_REMOVE_PORT		/* Remove an empty port */
78*26947304SEvan Yan } ddi_hp_op_t;
79*26947304SEvan Yan 
80*26947304SEvan Yan #define	DDIHP_CN_OPS(hdlp, op, arg, result, ret)		\
81*26947304SEvan Yan 	if (DDI_HP_IS_VIRTUAL_PORT(hdlp))			\
82*26947304SEvan Yan 		ret = ddihp_port_ops(hdlp, op, arg, result);	\
83*26947304SEvan Yan 	else							\
84*26947304SEvan Yan 		ret = ddihp_connector_ops(hdlp, op, arg, result);
85*26947304SEvan Yan 
86*26947304SEvan Yan #define	NEXUS_HAS_HP_OP(dip)						\
87*26947304SEvan Yan 	((DEVI(dip)->devi_ops->devo_bus_ops) &&				\
88*26947304SEvan Yan 	(DEVI(dip)->devi_ops->devo_bus_ops->busops_rev >= BUSO_REV_10) && \
89*26947304SEvan Yan 	(DEVI(dip)->devi_ops->devo_bus_ops->bus_hp_op))
90*26947304SEvan Yan 
91*26947304SEvan Yan /*
92*26947304SEvan Yan  * ddi_hp_cn_sysevent_t
93*26947304SEvan Yan  *
94*26947304SEvan Yan  * The following correspond to sysevent defined subclasses
95*26947304SEvan Yan  */
96*26947304SEvan Yan typedef enum {
97*26947304SEvan Yan 	DDI_HP_CN_STATE_CHANGE,
98*26947304SEvan Yan 	DDI_HP_CN_REQ
99*26947304SEvan Yan } ddi_hp_cn_sysevent_t;
100*26947304SEvan Yan 
101*26947304SEvan Yan /*
102*26947304SEvan Yan  * Misc
103*26947304SEvan Yan  */
104*26947304SEvan Yan 
105*26947304SEvan Yan /* Append a node to list */
106*26947304SEvan Yan #define	DDIHP_LIST_APPEND(type, head, node)				\
107*26947304SEvan Yan if (node) {								\
108*26947304SEvan Yan 	type *curr, *prev = NULL;					\
109*26947304SEvan Yan 	(node)->next = NULL;						\
110*26947304SEvan Yan 	for (curr = (head); curr; prev = curr, curr = curr->next);	\
111*26947304SEvan Yan 	if (prev == NULL)						\
112*26947304SEvan Yan 		(head) = (node);					\
113*26947304SEvan Yan 	else								\
114*26947304SEvan Yan 		prev->next = (node);					\
115*26947304SEvan Yan }
116*26947304SEvan Yan 
117*26947304SEvan Yan /* Remove a node from a list */
118*26947304SEvan Yan #define	DDIHP_LIST_REMOVE(type, head, node)				\
119*26947304SEvan Yan if (node) {								\
120*26947304SEvan Yan 	type *curr, *prev = NULL;					\
121*26947304SEvan Yan 	for (curr = (head); curr; prev = curr, curr = curr->next) {	\
122*26947304SEvan Yan 		if (curr == (node))					\
123*26947304SEvan Yan 			break;						\
124*26947304SEvan Yan 	}								\
125*26947304SEvan Yan     if (curr) {								\
126*26947304SEvan Yan 	if (prev == NULL)						\
127*26947304SEvan Yan 		(head) = (head)->next;					\
128*26947304SEvan Yan 	else								\
129*26947304SEvan Yan 		prev->next = curr->next;				\
130*26947304SEvan Yan 	}								\
131*26947304SEvan Yan }
132*26947304SEvan Yan 
133*26947304SEvan Yan int ddihp_modctl(int hp_op, char *path, char *cn_name, uintptr_t arg,
134*26947304SEvan Yan     uintptr_t rval);
135*26947304SEvan Yan ddi_hp_cn_handle_t *ddihp_cn_name_to_handle(dev_info_t *dip, char *cn_name);
136*26947304SEvan Yan int ddihp_cn_getstate(ddi_hp_cn_handle_t *hdlp);
137*26947304SEvan Yan int ddihp_port_ops(ddi_hp_cn_handle_t *hdlp, ddi_hp_op_t op,
138*26947304SEvan Yan     void *arg, void *result);
139*26947304SEvan Yan int ddihp_connector_ops(ddi_hp_cn_handle_t *hdlp,
140*26947304SEvan Yan     ddi_hp_op_t op, void *arg, void *result);
141*26947304SEvan Yan void ddihp_cn_gen_sysevent(ddi_hp_cn_handle_t *hdlp,
142*26947304SEvan Yan     ddi_hp_cn_sysevent_t event_sub_class, int hint, int kmflag);
143*26947304SEvan Yan int ddihp_cn_unregister(ddi_hp_cn_handle_t *hdlp);
144*26947304SEvan Yan 
145*26947304SEvan Yan #endif /* _KERNEL */
146*26947304SEvan Yan 
147*26947304SEvan Yan #ifdef	__cplusplus
148*26947304SEvan Yan }
149*26947304SEvan Yan #endif
150*26947304SEvan Yan 
151*26947304SEvan Yan #endif	/* _SYS_DDI_HP_IMPL_H */
152