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