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