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  */
2520aa1b4dSJoshua M. Clulow /*
2620aa1b4dSJoshua M. Clulow  * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
2720aa1b4dSJoshua 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 
5525e8c5aaSvikram /*
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 
667c478bd9Sstevel@tonic-gate /*
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 *);
75*489c4c5eSRichard Lowe extern int ldi_mlink_fp(struct stdata *, struct file *, int, int);
76*489c4c5eSRichard Lowe extern int 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 
14520aa1b4dSJoshua M. Clulow /*
14620aa1b4dSJoshua M. Clulow  * Members of "struct ldi_ev_callback_list" are protected by their le_lock
14720aa1b4dSJoshua M. Clulow  * member.  The struct is currently only used once, as a file-level global,
14820aa1b4dSJoshua M. Clulow  * and the locking protocol is currently implemented in ldi_ev_lock() and
14920aa1b4dSJoshua M. Clulow  * ldi_ev_unlock().
15020aa1b4dSJoshua M. Clulow  *
15120aa1b4dSJoshua M. Clulow  * When delivering events to subscribers, ldi_invoke_notify() and
15220aa1b4dSJoshua M. Clulow  * ldi_invoke_finalize() will walk the list of callbacks: le_head.  It is
15320aa1b4dSJoshua M. Clulow  * possible that an invoked callback function will need to unregister an
15420aa1b4dSJoshua M. Clulow  * arbitrary number of callbacks from this list.
15520aa1b4dSJoshua M. Clulow  *
15620aa1b4dSJoshua M. Clulow  * To enable ldi_ev_remove_callbacks() to remove elements from the list
15720aa1b4dSJoshua M. Clulow  * without breaking the walk-in-progress, we store the next element in the
15820aa1b4dSJoshua M. Clulow  * walk direction on the struct as le_walker_next and le_walker_prev.
15920aa1b4dSJoshua M. Clulow  */
16025e8c5aaSvikram struct ldi_ev_callback_list {
16120aa1b4dSJoshua M. Clulow 	kmutex_t		le_lock;
16220aa1b4dSJoshua M. Clulow 	kcondvar_t		le_cv;
16320aa1b4dSJoshua M. Clulow 	int			le_busy;
16420aa1b4dSJoshua M. Clulow 	void			*le_thread;
16520aa1b4dSJoshua M. Clulow 	list_t			le_head;
16620aa1b4dSJoshua M. Clulow 	ldi_ev_callback_impl_t	*le_walker_next;
16720aa1b4dSJoshua 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