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 */