xref: /illumos-gate/usr/src/uts/common/sys/autoconf.h (revision 46b592853d0f4f11781b6b0a7533f267c6aee132)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _SYS_AUTOCONF_H
27 #define	_SYS_AUTOCONF_H
28 
29 /* Derived from autoconf.h, SunOS 4.1.1 1.15 */
30 
31 #ifdef	__cplusplus
32 extern "C" {
33 #endif
34 
35 /*
36  * This defines a parallel structure to the devops list.
37  */
38 
39 #include <sys/dditypes.h>
40 #include <sys/devops.h>
41 #include <sys/mutex.h>
42 #include <sys/thread.h>
43 #include <sys/obpdefs.h>
44 #include <sys/systm.h>
45 #include <sys/hwconf.h>
46 
47 struct devnames {
48 	char		*dn_name;	/* Name of this driver */
49 	int		dn_flags;	/* per-driver flags, see below */
50 	struct par_list	*dn_pl;		/* parent list, for making devinfos */
51 	kmutex_t	dn_lock;	/* Per driver lock (see below) */
52 	dev_info_t	*dn_head;	/* Head of instance list */
53 	int		dn_instance;	/* Next instance no. to assign */
54 	void		*dn_inlist;	/* instance # nodes for this driver */
55 	ddi_prop_list_t	*dn_global_prop_ptr; /* per-driver global properties */
56 	kcondvar_t	dn_wait;	/* for ddi_hold_installed_driver */
57 	kthread_id_t	dn_busy_thread;	/* for debugging only */
58 	struct mperm	*dn_mperm;	/* minor permissions */
59 	struct mperm	*dn_mperm_wild;	/* default minor permission */
60 	struct mperm	*dn_mperm_clone; /* minor permission, clone use */
61 };
62 
63 /*
64  * dn_lock is used to protect the driver initialization/loading
65  * from fini/unloading. It also protects each drivers devops
66  * reference count, the dn_flags, and the dn_head linked list of
67  * driver instances. The busy_changing bit is used to avoid
68  * recursive calls to ddi_hold_installed_driver to hold the
69  * same driver.
70  */
71 
72 /*
73  * Defines for dn_flags.
74  */
75 #define	DN_CONF_PARSED		0x0001
76 #define	DN_DRIVER_BUSY		0x0002	/* for ddi_hold_installed_driver */
77 #define	DN_DRIVER_INACTIVE	0x0004	/* driver not active */
78 #define	DN_DRIVER_HELD		0x0020	/* held via ddi_hold_installed_driver */
79 #define	DN_TAKEN_GETUDEV	0x0040	/* getudev() used this entry */
80 #define	DN_DRIVER_REMOVED	0x0080	/* driver entry removed */
81 
82 #define	DN_FORCE_ATTACH		0x0100	/* DDI_FORCEATTACH prop */
83 #define	DN_LEAF_DRIVER		0x0200	/* this is a leaf driver */
84 #define	DN_NETWORK_DRIVER	0x0400	/* network interface driver */
85 #define	DN_NO_AUTODETACH	0x0800	/* no autodetach */
86 #define	DN_GLDV3_DRIVER		0x1000	/* gldv3 (Nemo) driver */
87 #define	DN_PHCI_DRIVER		0x2000	/* pHCI driver */
88 #define	DN_OPEN_RETURNS_EINTR	0x4000	/* DDI_OPEN_RETURNS_EINTR prop */
89 #define	DN_SCSI_SIZE_CLEAN	0x8000	/* driver is scsi_size_clean() */
90 #define	DN_NETWORK_PHYSDRIVER	0x10000	/* physical network driver */
91 
92 #ifdef _KERNEL
93 
94 /*
95  * Debugging flags and macros
96  */
97 #define	DDI_AUDIT		0x0001
98 #define	DDI_DEBUG		0x0002
99 #define	DDI_MTCONFIG		0x0004
100 #define	DDI_DEBUG_BOOTMOD	0x0008	/* module loading to mount root */
101 #define	DDI_DEBUG_COMPAT	0x0010	/* ddi_hold_install_driver */
102 #define	LDI_DBG_OPENCLOSE	0x0020	/* ldi open/close info */
103 #define	LDI_DBG_ALLOCFREE	0x0040	/* ldi ident alloc/free info */
104 #define	LDI_DBG_STREAMS		0x0080	/* ldi streams link/unlink */
105 #define	LDI_DBG_EVENTCB		0x0100	/* ldi event callback info */
106 #define	DDI_INTR_API		0x0200	/* interrupt interface messages  */
107 #define	DDI_INTR_IMPL		0x0400	/* interrupt implementation msgs */
108 #define	DDI_INTR_NEXUS		0x0800	/* interrupt messages from nexuses */
109 #define	DDI_DBG_RETIRE		0x1000	/* Retire related messages */
110 #define	DDI_DBG_RTR_VRBOSE	0x2000	/* Verbose Retire messages */
111 #define	DDI_DBG_RTR_TRACE	0x4000	/* Trace Retire messages */
112 #define	LDI_EV_DEBUG		0x8000  /* LDI events debug messages */
113 #define	LDI_EV_TRACE		0x10000 /* LDI events trace messages */
114 #define	DDI_INTR_IRM		0x20000 /* interrupt resource management */
115 #define	DDI_HP_API		0x40000	/* Hotplug interface messages  */
116 #define	DDI_HP_IMPL		0x80000	/* Hotplug implementation msgs */
117 #define	DDI_HP_NEXUS		0x100000 /* Hotplug messages from nexuses */
118 
119 extern int ddidebug;
120 
121 #ifdef	DEBUG
122 #define	NDI_CONFIG_DEBUG(args)	if (ddidebug & DDI_DEBUG) cmn_err args
123 #define	BMDPRINTF(args)		if (ddidebug & DDI_DEBUG_BOOTMOD) printf args
124 #define	DCOMPATPRINTF(args)	if (ddidebug & DDI_DEBUG_COMPAT) cmn_err args
125 #define	LDI_OPENCLOSE(args)	if (ddidebug & LDI_DBG_OPENCLOSE) cmn_err args
126 #define	LDI_ALLOCFREE(args)	if (ddidebug & LDI_DBG_ALLOCFREE) cmn_err args
127 #define	LDI_STREAMS_LNK(args)	if (ddidebug & LDI_DBG_STREAMS) cmn_err args
128 #define	LDI_EVENTCB(args)	if (ddidebug & LDI_DBG_EVENTCB) cmn_err args
129 #define	DDI_INTR_APIDBG(args)	if (ddidebug & DDI_INTR_API) cmn_err args
130 #define	DDI_INTR_IMPLDBG(args)	if (ddidebug & DDI_INTR_IMPL) cmn_err args
131 #define	DDI_INTR_NEXDBG(args)	if (ddidebug & DDI_INTR_NEXUS) cmn_err args
132 #define	RIO_DEBUG(args)		if (ddidebug & DDI_DBG_RETIRE) cmn_err args
133 #define	RIO_VERBOSE(args)	if (ddidebug & DDI_DBG_RTR_VRBOSE) cmn_err args
134 #define	RIO_TRACE(args)		if (ddidebug & DDI_DBG_RTR_TRACE) cmn_err args
135 #define	LDI_EVDBG(args)		if (ddidebug & LDI_EV_DEBUG) cmn_err args
136 #define	LDI_EVTRC(args)		if (ddidebug & LDI_EV_TRACE) cmn_err args
137 #define	DDI_INTR_IRMDBG(args)	if (ddidebug & DDI_INTR_IRM) cmn_err args
138 #define	DDI_HP_APIDBG(args)	if (ddidebug & DDI_HP_API) cmn_err args
139 #define	DDI_HP_IMPLDBG(args)	if (ddidebug & DDI_HP_IMPL) cmn_err args
140 #define	DDI_HP_NEXDBG(args)	if (ddidebug & DDI_HP_NEXUS) cmn_err args
141 #else
142 #define	NDI_CONFIG_DEBUG(args)
143 #define	BMDPRINTF(args)
144 #define	DCOMPATPRINTF(args)
145 #define	LDI_OPENCLOSE(args)
146 #define	LDI_ALLOCFREE(args)
147 #define	LDI_STREAMS_LNK(args)
148 #define	LDI_EVENTCB(args)
149 #define	DDI_INTR_APIDBG(args)
150 #define	DDI_INTR_IMPLDBG(args)
151 #define	DDI_INTR_NEXDBG(args)
152 #define	RIO_DEBUG(args)		if (ddidebug & DDI_DBG_RETIRE) cmn_err args
153 #define	RIO_VERBOSE(args)	if (ddidebug & DDI_DBG_RTR_VRBOSE) cmn_err args
154 #define	RIO_TRACE(args)		if (ddidebug & DDI_DBG_RTR_TRACE) cmn_err args
155 #define	LDI_EVDBG(args)		if (ddidebug & LDI_EV_DEBUG) cmn_err args
156 #define	LDI_EVTRC(args)		if (ddidebug & LDI_EV_TRACE) cmn_err args
157 #define	DDI_INTR_IRMDBG(args)
158 #define	DDI_HP_APIDBG(args)
159 #define	DDI_HP_IMPLDBG(args)
160 #define	DDI_HP_NEXDBG(args)
161 #endif
162 
163 
164 /*
165  * DDI configuration logs
166  */
167 #define	DDI_STACK_DEPTH		14
168 
169 typedef struct devinfo_audit {
170 	dev_info_t		*da_devinfo;	/* address of devinfo node */
171 	hrtime_t		da_timestamp;	/* audit time */
172 	kthread_id_t		da_thread;	/* thread of transaction */
173 	struct devinfo_audit	*da_lastlog;	/* last log of state change */
174 	ddi_node_state_t	da_node_state;	/* devinfo state at log time */
175 	int			da_device_state;	/* device state */
176 	int			da_depth;
177 	pc_t			da_stack[DDI_STACK_DEPTH];
178 } devinfo_audit_t;
179 
180 typedef struct {
181 	kmutex_t	dh_lock;
182 	int		dh_max;
183 	int		dh_curr;
184 	int		dh_hits;
185 	devinfo_audit_t	dh_entry[1];
186 } devinfo_log_header_t;
187 
188 struct di_cache {
189 	uint32_t	cache_valid;	/* no lock needed - field atomic updt */
190 	kmutex_t	cache_lock;	/* protects fields below */
191 	void		*cache_data;
192 	size_t		cache_size;
193 };
194 
195 extern struct di_cache di_cache;
196 extern int di_cache_debug;
197 extern volatile ulong_t devtree_gen;
198 
199 /*
200  * Special dev_info nodes
201  */
202 #define	PSEUDO_PATH	"/"DEVI_PSEUDO_NEXNAME
203 #define	CLONE_PATH	PSEUDO_PATH"/clone@0"
204 
205 #define	DI_CACHE_FILE	"/etc/devices/snapshot_cache"
206 #define	DI_CACHE_TEMP	DI_CACHE_FILE".tmp"
207 
208 extern dev_info_t *options_dip;
209 extern dev_info_t *pseudo_dip;
210 extern dev_info_t *clone_dip;
211 extern major_t clone_major;
212 extern major_t mm_major;
213 extern major_t nulldriver_major;
214 
215 extern struct devnames *devnamesp;
216 extern struct devnames orphanlist;
217 
218 extern struct dev_ops nodev_ops, mod_nodev_ops;
219 
220 /*
221  * Obsolete interface, no longer used, to be removed.
222  * Retained only for driver compatibility.
223  */
224 extern krwlock_t devinfo_tree_lock;		/* obsolete */
225 
226 /*
227  * Acquires dn_lock, as above.
228  */
229 #define	LOCK_DEV_OPS(lp)	mutex_enter((lp))
230 #define	UNLOCK_DEV_OPS(lp)	mutex_exit((lp))
231 
232 /*
233  * Not to be used without obtaining the per-driver lock.
234  */
235 #define	INCR_DEV_OPS_REF(opsp)	(opsp)->devo_refcnt++
236 #define	DECR_DEV_OPS_REF(opsp)	(opsp)->devo_refcnt--
237 #define	CB_DRV_INSTALLED(opsp)	((opsp) != &nodev_ops && \
238 				(opsp) != &mod_nodev_ops)
239 #define	DRV_UNLOADABLE(opsp)	((opsp)->devo_refcnt == 0)
240 #define	DEV_OPS_HELD(opsp)	((opsp)->devo_refcnt > 0)
241 #define	NEXUS_DRV(opsp)		((opsp)->devo_bus_ops != NULL)
242 #define	NETWORK_DRV(maj)	(devnamesp[(maj)].dn_flags & DN_NETWORK_DRIVER)
243 #define	GLDV3_DRV(maj)		(devnamesp[(maj)].dn_flags & DN_GLDV3_DRIVER)
244 #define	NETWORK_PHYSDRV(maj)	\
245 			(devnamesp[(maj)].dn_flags & DN_NETWORK_PHYSDRIVER)
246 
247 extern void impl_rem_dev_props(dev_info_t *);
248 extern void add_class(char *, char *);
249 
250 extern int make_mbind(char *, int, char *, struct bind **);
251 extern void delete_mbind(char *, struct bind **);
252 extern void purge_mbind(int, struct bind **);
253 
254 extern void configure(void);
255 #if defined(__sparc)
256 extern void setcputype(void);
257 #endif
258 extern void devtree_freeze(void);
259 extern void reset_leaves(void);
260 extern void quiesce_devices(dev_info_t *, void *);
261 
262 extern void setup_ddi(void);
263 extern void setup_ddi_poststartup(void);
264 extern void impl_ddi_callback_init(void);
265 extern void impl_fix_props(dev_info_t *, dev_info_t *, char *, int, caddr_t);
266 extern int impl_check_cpu(dev_info_t *);
267 extern int check_status(int, char *, dev_info_t *);
268 
269 extern int exclude_settrap(int);
270 extern int exclude_level(int);
271 
272 extern major_t path_to_major(char *);
273 extern void i_ddi_node_cache_init(void);
274 extern dev_info_t *i_ddi_alloc_node(dev_info_t *, char *, pnode_t, int,
275     ddi_prop_t *, int);
276 extern void i_ddi_forceattach_drivers(void);
277 extern int i_ddi_io_initialized(void);
278 extern dev_info_t *i_ddi_create_branch(dev_info_t *, int);
279 extern void i_ddi_add_devimap(dev_info_t *dip);
280 extern void i_ddi_di_cache_invalidate(void);
281 extern void i_ddi_di_cache_free(struct di_cache *cache);
282 
283 /* devname_state - for /dev to denote reconfig and system available */
284 #define	DS_RECONFIG	0x01		/* reconfig boot */
285 #define	DS_SYSAVAIL	0x02		/* implicit reconfig enabled */
286 
287 extern int i_ddi_sysavail(void);
288 extern int i_ddi_reconfig(void);
289 extern void i_ddi_set_sysavail(void);
290 extern void i_ddi_set_reconfig(void);
291 
292 /* I/O retire related */
293 extern int e_ddi_retire_device(char *path, char **cons_array);
294 extern int e_ddi_unretire_device(char *path);
295 extern int e_ddi_mark_retiring(dev_info_t *dip, void *arg);
296 extern int e_ddi_retire_notify(dev_info_t *dip, void *arg);
297 extern int e_ddi_retire_finalize(dev_info_t *dip, void *arg);
298 extern void e_ddi_degrade_finalize(dev_info_t *dip);
299 extern void e_ddi_undegrade_finalize(dev_info_t *dip);
300 
301 extern int check_driver_quiesce(dev_info_t *dip, void *arg);
302 
303 #endif /* _KERNEL */
304 
305 #ifdef	__cplusplus
306 }
307 #endif
308 
309 #endif /* _SYS_AUTOCONF_H */
310