xref: /illumos-gate/usr/src/uts/common/sys/sunldi_impl.h (revision 89b2a9fbeabf42fa54594df0e5927bcc50a07cc9)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_SUNLDI_IMPL_H
27 #define	_SYS_SUNLDI_IMPL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 #include <sys/dditypes.h>
36 #include <sys/vnode.h>
37 
38 /*
39  * NOTE
40  *
41  * The contents of this file are private to this implementation
42  * of Solaris and are subject to change at any time without notice.
43  *
44  * Applications and drivers using these interfaces will fail
45  * to run on future releases.
46  */
47 
48 /*
49  * LDI hash definitions
50  */
51 #define	LH_HASH_SZ	32
52 #define	LI_HASH_SZ	32
53 
54 /*
55  * Obsolete LDI event interfaces are available for now but are deprecated and a
56  * warning will be issued to consumers.
57  */
58 #define	LDI_OBSOLETE_EVENT	1
59 
60 /*
61  * Flag for LDI handle's lh_flags field
62  */
63 #define	LH_FLAGS_NOTIFY	0x0001		/* invoked in context of a notify */
64 
65 /*
66  * LDI initialization function
67  */
68 void ldi_init(void);
69 
70 /*
71  * LDI streams linking interfaces
72  */
73 extern int ldi_mlink_lh(vnode_t *, int, intptr_t, cred_t *, int *);
74 extern void ldi_mlink_fp(struct stdata *, struct file *, int, int);
75 extern void ldi_munlink_fp(struct stdata *, struct file *, int);
76 
77 /*
78  * LDI module identifier
79  */
80 struct ldi_ident {
81 	/* protected by ldi_ident_hash_lock */
82 	struct ldi_ident		*li_next;
83 	uint_t				li_ref;
84 
85 	/* unique/static fields in the ident */
86 	char				li_modname[MODMAXNAMELEN];
87 	modid_t				li_modid;
88 	major_t				li_major;
89 	dev_info_t			*li_dip;
90 	dev_t				li_dev;
91 };
92 
93 /*
94  * LDI handle
95  */
96 struct ldi_handle {
97 	/* protected by ldi_handle_hash_lock */
98 	struct ldi_handle		*lh_next;
99 	uint_t				lh_ref;
100 	uint_t				lh_flags;
101 
102 	/* unique/static fields in the handle */
103 	uint_t				lh_type;
104 	struct ldi_ident		*lh_ident;
105 	vnode_t				*lh_vp;
106 
107 #ifdef	LDI_OBSOLETE_EVENT
108 	/* fields protected by lh_lock */
109 	kmutex_t			lh_lock[1];
110 	struct ldi_event		*lh_events;
111 #endif
112 };
113 
114 /*
115  * LDI event information
116  */
117 #ifdef	LDI_OBSOLETE_EVENT
118 typedef struct ldi_event {
119 	/* fields protected by le_lhp->lh_lock */
120 	struct ldi_event	*le_next;
121 	struct ldi_event	*le_prev;
122 
123 	/* unique/static fields in the handle */
124 	struct ldi_handle	*le_lhp;
125 	void			(*le_handler)();
126 	void			*le_arg;
127 	ddi_callback_id_t	le_id;
128 } ldi_event_t;
129 #endif
130 
131 typedef struct ldi_ev_callback_impl {
132 	struct ldi_handle	*lec_lhp;
133 	dev_info_t		*lec_dip;
134 	dev_t			lec_dev;
135 	int			lec_spec;
136 	int			(*lec_notify)();
137 	void			(*lec_finalize)();
138 	void			*lec_arg;
139 	void			*lec_cookie;
140 	void			*lec_id;
141 	list_node_t		lec_list;
142 } ldi_ev_callback_impl_t;
143 
144 struct ldi_ev_callback_list {
145 	kmutex_t	le_lock;
146 	kcondvar_t	le_cv;
147 	int		le_busy;
148 	void		*le_thread;
149 	list_t		le_head;
150 };
151 
152 int ldi_invoke_notify(dev_info_t *dip, dev_t dev, int spec_type, char *event,
153     void *ev_data);
154 void ldi_invoke_finalize(dev_info_t *dip, dev_t dev, int spec_type, char *event,
155     int ldi_result, void *ev_data);
156 int e_ddi_offline_notify(dev_info_t *dip);
157 void e_ddi_offline_finalize(dev_info_t *dip, int result);
158 
159 
160 /*
161  * LDI device usage interfaces
162  *
163  * ldi_usage_count(), ldi_usage_walker(), and ldi_usage_t
164  *
165  * These functions are used by the devinfo driver and fuser to get a
166  * device usage information from the LDI. These functions along with
167  * the ldi_usage_t data structure allow these other subsystems to have
168  * no knowledge of how the LDI stores it's internal state.
169  *
170  * ldi_usage_count() provides an count of how many kernel
171  *	device clients currently exist.
172  *
173  * ldi_usage_walker() reports all kernel device usage information.
174  */
175 #define	LDI_USAGE_CONTINUE	0
176 #define	LDI_USAGE_TERMINATE	1
177 
178 typedef struct ldi_usage {
179 	/*
180 	 * information about the kernel subsystem that is accessing
181 	 * the target device
182 	 */
183 	modid_t		src_modid;
184 	char		*src_name;
185 	dev_info_t	*src_dip;
186 	dev_t		src_devt;
187 
188 	/*
189 	 * information about the target device that is open
190 	 */
191 	modid_t		tgt_modid;
192 	char		*tgt_name;
193 	dev_info_t	*tgt_dip;
194 	dev_t		tgt_devt;
195 	int		tgt_spec_type;
196 } ldi_usage_t;
197 
198 int ldi_usage_count();
199 void ldi_usage_walker(void *arg,
200     int (*callback)(const ldi_usage_t *ldi_usage, void *arg));
201 
202 #ifdef __cplusplus
203 }
204 #endif
205 
206 #endif	/* _SYS_SUNLDI_IMPL_H */
207