Merge commit '7e3488dc6cdcb0c04e1ce167a1a3bfef83b5f2e0'
[unleashed.git] / include / sys / sunldi_impl.h
blobe9fdb431bfb84682d3e03a8b8b8eb3d648d7d362
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29 #ifndef _SYS_SUNLDI_IMPL_H
30 #define _SYS_SUNLDI_IMPL_H
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
36 #include <sys/dditypes.h>
37 #include <sys/vnode.h>
40 * NOTE
42 * The contents of this file are private to this implementation
43 * of Solaris and are subject to change at any time without notice.
45 * Applications and drivers using these interfaces will fail
46 * to run on future releases.
50 * LDI hash definitions
52 #define LH_HASH_SZ 32
53 #define LI_HASH_SZ 32
56 * Obsolete LDI event interfaces are available for now but are deprecated and a
57 * warning will be issued to consumers.
59 #define LDI_OBSOLETE_EVENT 1
62 * Flag for LDI handle's lh_flags field
64 #define LH_FLAGS_NOTIFY 0x0001 /* invoked in context of a notify */
67 * LDI initialization function
69 void ldi_init(void);
72 * LDI streams linking interfaces
74 extern int ldi_mlink_lh(vnode_t *, int, intptr_t, cred_t *, int *);
75 extern void ldi_mlink_fp(struct stdata *, struct file *, int, int);
76 extern void ldi_munlink_fp(struct stdata *, struct file *, int);
79 * LDI module identifier
81 struct ldi_ident {
82 /* protected by ldi_ident_hash_lock */
83 struct ldi_ident *li_next;
84 uint_t li_ref;
86 /* unique/static fields in the ident */
87 char li_modname[MODMAXNAMELEN];
88 modid_t li_modid;
89 major_t li_major;
90 dev_info_t *li_dip;
91 dev_t li_dev;
95 * LDI handle
97 struct ldi_handle {
98 /* protected by ldi_handle_hash_lock */
99 struct ldi_handle *lh_next;
100 uint_t lh_ref;
101 uint_t lh_flags;
103 /* unique/static fields in the handle */
104 uint_t lh_type;
105 struct ldi_ident *lh_ident;
106 vnode_t *lh_vp;
108 #ifdef LDI_OBSOLETE_EVENT
109 /* fields protected by lh_lock */
110 kmutex_t lh_lock[1];
111 struct ldi_event *lh_events;
112 #endif
116 * LDI event information
118 #ifdef LDI_OBSOLETE_EVENT
119 typedef struct ldi_event {
120 /* fields protected by le_lhp->lh_lock */
121 struct ldi_event *le_next;
122 struct ldi_event *le_prev;
124 /* unique/static fields in the handle */
125 struct ldi_handle *le_lhp;
126 void (*le_handler)();
127 void *le_arg;
128 ddi_callback_id_t le_id;
129 } ldi_event_t;
130 #endif
132 typedef struct ldi_ev_callback_impl {
133 struct ldi_handle *lec_lhp;
134 dev_info_t *lec_dip;
135 dev_t lec_dev;
136 int lec_spec;
137 int (*lec_notify)();
138 void (*lec_finalize)();
139 void *lec_arg;
140 void *lec_cookie;
141 void *lec_id;
142 list_node_t lec_list;
143 } ldi_ev_callback_impl_t;
146 * Members of "struct ldi_ev_callback_list" are protected by their le_lock
147 * member. The struct is currently only used once, as a file-level global,
148 * and the locking protocol is currently implemented in ldi_ev_lock() and
149 * ldi_ev_unlock().
151 * When delivering events to subscribers, ldi_invoke_notify() and
152 * ldi_invoke_finalize() will walk the list of callbacks: le_head. It is
153 * possible that an invoked callback function will need to unregister an
154 * arbitrary number of callbacks from this list.
156 * To enable ldi_ev_remove_callbacks() to remove elements from the list
157 * without breaking the walk-in-progress, we store the next element in the
158 * walk direction on the struct as le_walker_next and le_walker_prev.
160 struct ldi_ev_callback_list {
161 kmutex_t le_lock;
162 kcondvar_t le_cv;
163 int le_busy;
164 void *le_thread;
165 list_t le_head;
166 ldi_ev_callback_impl_t *le_walker_next;
167 ldi_ev_callback_impl_t *le_walker_prev;
170 int ldi_invoke_notify(dev_info_t *dip, dev_t dev, int spec_type, char *event,
171 void *ev_data);
172 void ldi_invoke_finalize(dev_info_t *dip, dev_t dev, int spec_type, char *event,
173 int ldi_result, void *ev_data);
174 int e_ddi_offline_notify(dev_info_t *dip);
175 void e_ddi_offline_finalize(dev_info_t *dip, int result);
179 * LDI device usage interfaces
181 * ldi_usage_count(), ldi_usage_walker(), and ldi_usage_t
183 * These functions are used by the devinfo driver and fuser to get a
184 * device usage information from the LDI. These functions along with
185 * the ldi_usage_t data structure allow these other subsystems to have
186 * no knowledge of how the LDI stores it's internal state.
188 * ldi_usage_count() provides an count of how many kernel
189 * device clients currently exist.
191 * ldi_usage_walker() reports all kernel device usage information.
193 #define LDI_USAGE_CONTINUE 0
194 #define LDI_USAGE_TERMINATE 1
196 typedef struct ldi_usage {
198 * information about the kernel subsystem that is accessing
199 * the target device
201 modid_t src_modid;
202 char *src_name;
203 dev_info_t *src_dip;
204 dev_t src_devt;
207 * information about the target device that is open
209 modid_t tgt_modid;
210 char *tgt_name;
211 dev_info_t *tgt_dip;
212 dev_t tgt_devt;
213 int tgt_spec_type;
214 } ldi_usage_t;
216 int ldi_usage_count();
217 void ldi_usage_walker(void *arg,
218 int (*callback)(const ldi_usage_t *ldi_usage, void *arg));
220 #ifdef __cplusplus
222 #endif
224 #endif /* _SYS_SUNLDI_IMPL_H */