17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 525e8c5aaSvikram * Common Development and Distribution License (the "License"). 625e8c5aaSvikram * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 2225e8c5aaSvikram * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 25*20aa1b4dSJoshua M. Clulow /* 26*20aa1b4dSJoshua M. Clulow * Copyright (c) 2013, Joyent, Inc. All rights reserved. 27*20aa1b4dSJoshua M. Clulow */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #ifndef _SYS_SUNLDI_IMPL_H 307c478bd9Sstevel@tonic-gate #define _SYS_SUNLDI_IMPL_H 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #ifdef __cplusplus 337c478bd9Sstevel@tonic-gate extern "C" { 347c478bd9Sstevel@tonic-gate #endif 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <sys/dditypes.h> 377c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate /* 407c478bd9Sstevel@tonic-gate * NOTE 417c478bd9Sstevel@tonic-gate * 427c478bd9Sstevel@tonic-gate * The contents of this file are private to this implementation 437c478bd9Sstevel@tonic-gate * of Solaris and are subject to change at any time without notice. 447c478bd9Sstevel@tonic-gate * 457c478bd9Sstevel@tonic-gate * Applications and drivers using these interfaces will fail 467c478bd9Sstevel@tonic-gate * to run on future releases. 477c478bd9Sstevel@tonic-gate */ 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * LDI hash definitions 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate #define LH_HASH_SZ 32 537c478bd9Sstevel@tonic-gate #define LI_HASH_SZ 32 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate /* 5625e8c5aaSvikram * Obsolete LDI event interfaces are available for now but are deprecated and a 5725e8c5aaSvikram * warning will be issued to consumers. 5825e8c5aaSvikram */ 5925e8c5aaSvikram #define LDI_OBSOLETE_EVENT 1 6025e8c5aaSvikram 6125e8c5aaSvikram /* 6225e8c5aaSvikram * Flag for LDI handle's lh_flags field 6325e8c5aaSvikram */ 6425e8c5aaSvikram #define LH_FLAGS_NOTIFY 0x0001 /* invoked in context of a notify */ 6525e8c5aaSvikram 6625e8c5aaSvikram /* 677c478bd9Sstevel@tonic-gate * LDI initialization function 687c478bd9Sstevel@tonic-gate */ 697c478bd9Sstevel@tonic-gate void ldi_init(void); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /* 727c478bd9Sstevel@tonic-gate * LDI streams linking interfaces 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate extern int ldi_mlink_lh(vnode_t *, int, intptr_t, cred_t *, int *); 757c478bd9Sstevel@tonic-gate extern void ldi_mlink_fp(struct stdata *, struct file *, int, int); 767c478bd9Sstevel@tonic-gate extern void ldi_munlink_fp(struct stdata *, struct file *, int); 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate /* 797c478bd9Sstevel@tonic-gate * LDI module identifier 807c478bd9Sstevel@tonic-gate */ 817c478bd9Sstevel@tonic-gate struct ldi_ident { 827c478bd9Sstevel@tonic-gate /* protected by ldi_ident_hash_lock */ 837c478bd9Sstevel@tonic-gate struct ldi_ident *li_next; 847c478bd9Sstevel@tonic-gate uint_t li_ref; 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate /* unique/static fields in the ident */ 877c478bd9Sstevel@tonic-gate char li_modname[MODMAXNAMELEN]; 887c478bd9Sstevel@tonic-gate modid_t li_modid; 897c478bd9Sstevel@tonic-gate major_t li_major; 907c478bd9Sstevel@tonic-gate dev_info_t *li_dip; 917c478bd9Sstevel@tonic-gate dev_t li_dev; 927c478bd9Sstevel@tonic-gate }; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * LDI handle 967c478bd9Sstevel@tonic-gate */ 977c478bd9Sstevel@tonic-gate struct ldi_handle { 987c478bd9Sstevel@tonic-gate /* protected by ldi_handle_hash_lock */ 997c478bd9Sstevel@tonic-gate struct ldi_handle *lh_next; 1007c478bd9Sstevel@tonic-gate uint_t lh_ref; 10125e8c5aaSvikram uint_t lh_flags; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* unique/static fields in the handle */ 1047c478bd9Sstevel@tonic-gate uint_t lh_type; 1057c478bd9Sstevel@tonic-gate struct ldi_ident *lh_ident; 1067c478bd9Sstevel@tonic-gate vnode_t *lh_vp; 1077c478bd9Sstevel@tonic-gate 10825e8c5aaSvikram #ifdef LDI_OBSOLETE_EVENT 1097c478bd9Sstevel@tonic-gate /* fields protected by lh_lock */ 1107c478bd9Sstevel@tonic-gate kmutex_t lh_lock[1]; 1117c478bd9Sstevel@tonic-gate struct ldi_event *lh_events; 11225e8c5aaSvikram #endif 1137c478bd9Sstevel@tonic-gate }; 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate /* 1167c478bd9Sstevel@tonic-gate * LDI event information 1177c478bd9Sstevel@tonic-gate */ 11825e8c5aaSvikram #ifdef LDI_OBSOLETE_EVENT 1197c478bd9Sstevel@tonic-gate typedef struct ldi_event { 1207c478bd9Sstevel@tonic-gate /* fields protected by le_lhp->lh_lock */ 1217c478bd9Sstevel@tonic-gate struct ldi_event *le_next; 1227c478bd9Sstevel@tonic-gate struct ldi_event *le_prev; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate /* unique/static fields in the handle */ 1257c478bd9Sstevel@tonic-gate struct ldi_handle *le_lhp; 1267c478bd9Sstevel@tonic-gate void (*le_handler)(); 1277c478bd9Sstevel@tonic-gate void *le_arg; 1287c478bd9Sstevel@tonic-gate ddi_callback_id_t le_id; 1297c478bd9Sstevel@tonic-gate } ldi_event_t; 13025e8c5aaSvikram #endif 13125e8c5aaSvikram 13225e8c5aaSvikram typedef struct ldi_ev_callback_impl { 13325e8c5aaSvikram struct ldi_handle *lec_lhp; 13425e8c5aaSvikram dev_info_t *lec_dip; 13525e8c5aaSvikram dev_t lec_dev; 13625e8c5aaSvikram int lec_spec; 13725e8c5aaSvikram int (*lec_notify)(); 13825e8c5aaSvikram void (*lec_finalize)(); 13925e8c5aaSvikram void *lec_arg; 14025e8c5aaSvikram void *lec_cookie; 14125e8c5aaSvikram void *lec_id; 14225e8c5aaSvikram list_node_t lec_list; 14325e8c5aaSvikram } ldi_ev_callback_impl_t; 14425e8c5aaSvikram 145*20aa1b4dSJoshua M. Clulow /* 146*20aa1b4dSJoshua M. Clulow * Members of "struct ldi_ev_callback_list" are protected by their le_lock 147*20aa1b4dSJoshua M. Clulow * member. The struct is currently only used once, as a file-level global, 148*20aa1b4dSJoshua M. Clulow * and the locking protocol is currently implemented in ldi_ev_lock() and 149*20aa1b4dSJoshua M. Clulow * ldi_ev_unlock(). 150*20aa1b4dSJoshua M. Clulow * 151*20aa1b4dSJoshua M. Clulow * When delivering events to subscribers, ldi_invoke_notify() and 152*20aa1b4dSJoshua M. Clulow * ldi_invoke_finalize() will walk the list of callbacks: le_head. It is 153*20aa1b4dSJoshua M. Clulow * possible that an invoked callback function will need to unregister an 154*20aa1b4dSJoshua M. Clulow * arbitrary number of callbacks from this list. 155*20aa1b4dSJoshua M. Clulow * 156*20aa1b4dSJoshua M. Clulow * To enable ldi_ev_remove_callbacks() to remove elements from the list 157*20aa1b4dSJoshua M. Clulow * without breaking the walk-in-progress, we store the next element in the 158*20aa1b4dSJoshua M. Clulow * walk direction on the struct as le_walker_next and le_walker_prev. 159*20aa1b4dSJoshua M. Clulow */ 16025e8c5aaSvikram struct ldi_ev_callback_list { 16125e8c5aaSvikram kmutex_t le_lock; 16225e8c5aaSvikram kcondvar_t le_cv; 16325e8c5aaSvikram int le_busy; 16425e8c5aaSvikram void *le_thread; 16525e8c5aaSvikram list_t le_head; 166*20aa1b4dSJoshua M. Clulow ldi_ev_callback_impl_t *le_walker_next; 167*20aa1b4dSJoshua M. Clulow ldi_ev_callback_impl_t *le_walker_prev; 16825e8c5aaSvikram }; 16925e8c5aaSvikram 17025e8c5aaSvikram int ldi_invoke_notify(dev_info_t *dip, dev_t dev, int spec_type, char *event, 17125e8c5aaSvikram void *ev_data); 17225e8c5aaSvikram void ldi_invoke_finalize(dev_info_t *dip, dev_t dev, int spec_type, char *event, 17325e8c5aaSvikram int ldi_result, void *ev_data); 17425e8c5aaSvikram int e_ddi_offline_notify(dev_info_t *dip); 17525e8c5aaSvikram void e_ddi_offline_finalize(dev_info_t *dip, int result); 17625e8c5aaSvikram 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate /* 1797c478bd9Sstevel@tonic-gate * LDI device usage interfaces 1807c478bd9Sstevel@tonic-gate * 1817c478bd9Sstevel@tonic-gate * ldi_usage_count(), ldi_usage_walker(), and ldi_usage_t 1827c478bd9Sstevel@tonic-gate * 1837c478bd9Sstevel@tonic-gate * These functions are used by the devinfo driver and fuser to get a 1847c478bd9Sstevel@tonic-gate * device usage information from the LDI. These functions along with 1857c478bd9Sstevel@tonic-gate * the ldi_usage_t data structure allow these other subsystems to have 1867c478bd9Sstevel@tonic-gate * no knowledge of how the LDI stores it's internal state. 1877c478bd9Sstevel@tonic-gate * 1887c478bd9Sstevel@tonic-gate * ldi_usage_count() provides an count of how many kernel 1897c478bd9Sstevel@tonic-gate * device clients currently exist. 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * ldi_usage_walker() reports all kernel device usage information. 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate #define LDI_USAGE_CONTINUE 0 1947c478bd9Sstevel@tonic-gate #define LDI_USAGE_TERMINATE 1 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate typedef struct ldi_usage { 1977c478bd9Sstevel@tonic-gate /* 1987c478bd9Sstevel@tonic-gate * information about the kernel subsystem that is accessing 1997c478bd9Sstevel@tonic-gate * the target device 2007c478bd9Sstevel@tonic-gate */ 2017c478bd9Sstevel@tonic-gate modid_t src_modid; 2027c478bd9Sstevel@tonic-gate char *src_name; 2037c478bd9Sstevel@tonic-gate dev_info_t *src_dip; 2047c478bd9Sstevel@tonic-gate dev_t src_devt; 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * information about the target device that is open 2087c478bd9Sstevel@tonic-gate */ 2097c478bd9Sstevel@tonic-gate modid_t tgt_modid; 2107c478bd9Sstevel@tonic-gate char *tgt_name; 2117c478bd9Sstevel@tonic-gate dev_info_t *tgt_dip; 2127c478bd9Sstevel@tonic-gate dev_t tgt_devt; 2137c478bd9Sstevel@tonic-gate int tgt_spec_type; 2147c478bd9Sstevel@tonic-gate } ldi_usage_t; 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate int ldi_usage_count(); 2177c478bd9Sstevel@tonic-gate void ldi_usage_walker(void *arg, 2187c478bd9Sstevel@tonic-gate int (*callback)(const ldi_usage_t *ldi_usage, void *arg)); 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate #ifdef __cplusplus 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate #endif 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate #endif /* _SYS_SUNLDI_IMPL_H */ 225