summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/autoconf.h
blob: dcff2318deeb023844ecc6728cf631cc691366d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_AUTOCONF_H
#define	_SYS_AUTOCONF_H


/* Derived from autoconf.h, SunOS 4.1.1 1.15 */

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * This defines a parallel structure to the devops list.
 */

#include <sys/dditypes.h>
#include <sys/devops.h>
#include <sys/mutex.h>
#include <sys/thread.h>
#include <sys/obpdefs.h>
#include <sys/systm.h>

struct devnames {
	char		*dn_name;	/* Name of this driver */
	int		dn_flags;	/* per-driver flags, see below */
	struct par_list	*dn_pl;		/* parent list, for making devinfos */
	kmutex_t	dn_lock;	/* Per driver lock (see below) */
	dev_info_t	*dn_head;	/* Head of instance list */
	int		dn_instance;	/* Next instance no. to assign */
	void		*dn_inlist;	/* instance # nodes for this driver */
	ddi_prop_list_t	*dn_global_prop_ptr; /* per-driver global properties */
	kcondvar_t	dn_wait;	/* for ddi_hold_installed_driver */
	kthread_id_t	dn_busy_thread;	/* for debugging only */
	struct mperm	*dn_mperm;	/* minor permissions */
	struct mperm	*dn_mperm_wild;	/* default minor permission */
	struct mperm	*dn_mperm_clone; /* minor permission, clone use */
};

/*
 * dn_lock is used to protect the driver initialization/loading
 * from fini/unloading. It also protects each drivers devops
 * reference count, the dn_flags, and the dn_head linked list of
 * driver instances. The busy_changing bit is used to avoid
 * recursive calls to ddi_hold_installed_driver to hold the
 * same driver.
 */

/*
 * Defines for dn_flags.
 */
#define	DN_CONF_PARSED		0x0001
#define	DN_DRIVER_BUSY		0x0002	/* for ddi_hold_installed_driver */
#define	DN_DRIVER_HELD		0x0020	/* held via ddi_hold_installed_driver */
#define	DN_TAKEN_GETUDEV	0x0040	/* getudev() used this entry */
#define	DN_DRIVER_REMOVED	0x0080	/* driver entry removed */

#define	DN_FORCE_ATTACH		0x0100	/* DDI_FORCEATTACH prop */
#define	DN_LEAF_DRIVER		0x0200	/* this is a leaf driver */
#define	DN_NETWORK_DRIVER	0x0400	/* network interface driver */
#define	DN_NO_AUTODETACH	0x0800	/* no autodetach */
#define	DN_GLDV3_DRIVER		0x1000	/* gldv3 (Nemo) driver */
#define	DN_PHCI_DRIVER		0x2000	/* pHCI driver */
#define	DN_OPEN_RETURNS_EINTR	0x4000	/* DDI_OPEN_RETURNS_EINTR prop */
#define	DN_SCSI_SIZE_CLEAN	0x8000	/* driver is scsi_size_clean() */

#ifdef _KERNEL

/*
 * Debugging flags and macros
 */
#define	DDI_AUDIT		0x0001
#define	DDI_DEBUG		0x0002
#define	DDI_MTCONFIG		0x0004
#define	DDI_DEBUG_BOOTMOD	0x0008	/* module loading to mount root */
#define	DDI_DEBUG_COMPAT	0x0010	/* ddi_hold_install_driver */
#define	LDI_DBG_OPENCLOSE	0x0020	/* ldi open/close info */
#define	LDI_DBG_ALLOCFREE	0x0040	/* ldi ident alloc/free info */
#define	LDI_DBG_STREAMS		0x0080	/* ldi streams link/unlink */
#define	LDI_DBG_EVENTCB		0x0100	/* ldi event callback info */
#define	DDI_INTR_API		0x0200	/* interrupt interface messages  */
#define	DDI_INTR_IMPL		0x0400	/* interrupt implementation msgs */
#define	DDI_INTR_NEXUS		0x0800	/* interrupt messages from nexuses */
#define	DDI_DBG_RETIRE		0x1000	/* Retire related messages */
#define	DDI_DBG_RTR_VRBOSE	0x2000	/* Verbose Retire messages */
#define	DDI_DBG_RTR_TRACE	0x4000	/* Trace Retire messages */
#define	LDI_EV_DEBUG		0x8000  /* LDI events debug messages */
#define	LDI_EV_TRACE		0x10000 /* LDI events trace messages */

extern int ddidebug;

#ifdef	DEBUG
#define	NDI_CONFIG_DEBUG(args)	if (ddidebug & DDI_DEBUG) cmn_err args
#define	BMDPRINTF(args)		if (ddidebug & DDI_DEBUG_BOOTMOD) printf args
#define	DCOMPATPRINTF(args)	if (ddidebug & DDI_DEBUG_COMPAT) cmn_err args
#define	LDI_OPENCLOSE(args)	if (ddidebug & LDI_DBG_OPENCLOSE) cmn_err args
#define	LDI_ALLOCFREE(args)	if (ddidebug & LDI_DBG_ALLOCFREE) cmn_err args
#define	LDI_STREAMS_LNK(args)	if (ddidebug & LDI_DBG_STREAMS) cmn_err args
#define	LDI_EVENTCB(args)	if (ddidebug & LDI_DBG_EVENTCB) cmn_err args
#define	DDI_INTR_APIDBG(args)	if (ddidebug & DDI_INTR_API) cmn_err args
#define	DDI_INTR_IMPLDBG(args)	if (ddidebug & DDI_INTR_IMPL) cmn_err args
#define	DDI_INTR_NEXDBG(args)	if (ddidebug & DDI_INTR_NEXUS) cmn_err args
#define	RIO_DEBUG(args)		if (ddidebug & DDI_DBG_RETIRE) cmn_err args
#define	RIO_VERBOSE(args)	if (ddidebug & DDI_DBG_RTR_VRBOSE) cmn_err args
#define	RIO_TRACE(args)		if (ddidebug & DDI_DBG_RTR_TRACE) cmn_err args
#define	LDI_EVDBG(args)		if (ddidebug & LDI_EV_DEBUG) cmn_err args
#define	LDI_EVTRC(args)		if (ddidebug & LDI_EV_TRACE) cmn_err args
#else
#define	NDI_CONFIG_DEBUG(args)
#define	BMDPRINTF(args)
#define	DCOMPATPRINTF(args)
#define	LDI_OPENCLOSE(args)
#define	LDI_ALLOCFREE(args)
#define	LDI_STREAMS_LNK(args)
#define	LDI_EVENTCB(args)
#define	DDI_INTR_APIDBG(args)
#define	DDI_INTR_IMPLDBG(args)
#define	DDI_INTR_NEXDBG(args)
#define	RIO_DEBUG(args)		if (ddidebug & DDI_DBG_RETIRE) cmn_err args
#define	RIO_VERBOSE(args)	if (ddidebug & DDI_DBG_RTR_VRBOSE) cmn_err args
#define	RIO_TRACE(args)		if (ddidebug & DDI_DBG_RTR_TRACE) cmn_err args
#define	LDI_EVDBG(args)		if (ddidebug & LDI_EV_DEBUG) cmn_err args
#define	LDI_EVTRC(args)		if (ddidebug & LDI_EV_TRACE) cmn_err args
#endif


/*
 * DDI configuration logs
 */
#define	DDI_STACK_DEPTH		14

typedef struct devinfo_audit {
	dev_info_t		*da_devinfo;	/* address of devinfo node */
	hrtime_t		da_timestamp;	/* audit time */
	kthread_id_t		da_thread;	/* thread of transaction */
	struct devinfo_audit	*da_lastlog;	/* last log of state change */
	ddi_node_state_t	da_node_state;	/* devinfo state at log time */
	int			da_device_state;	/* device state */
	int			da_depth;
	pc_t			da_stack[DDI_STACK_DEPTH];
} devinfo_audit_t;

typedef struct {
	kmutex_t	dh_lock;
	int		dh_max;
	int		dh_curr;
	int		dh_hits;
	devinfo_audit_t	dh_entry[1];
} devinfo_log_header_t;

struct di_cache {
	uint32_t	cache_valid;	/* no lock needed - field atomic updt */
	kmutex_t	cache_lock;	/* protects fields below */
	void		*cache_data;
	size_t		cache_size;
};

extern struct di_cache di_cache;
extern int di_cache_debug;
extern volatile ulong_t devtree_gen;

/*
 * Special dev_info nodes
 */
#define	PSEUDO_PATH	"/"DEVI_PSEUDO_NEXNAME
#define	CLONE_PATH	PSEUDO_PATH"/clone@0"

#define	DI_CACHE_FILE	"/etc/devices/snapshot_cache"
#define	DI_CACHE_TEMP	DI_CACHE_FILE".tmp"

extern dev_info_t *options_dip;
extern dev_info_t *pseudo_dip;
extern dev_info_t *clone_dip;
extern major_t clone_major;
extern major_t mm_major;
extern major_t nulldriver_major;

extern struct devnames *devnamesp;
extern struct devnames orphanlist;

extern struct dev_ops nodev_ops, mod_nodev_ops;

/*
 * Obsolete interface, no longer used, to be removed.
 * Retained only for driver compatibility.
 */
extern krwlock_t devinfo_tree_lock;		/* obsolete */

/*
 * Acquires dn_lock, as above.
 */
#define	LOCK_DEV_OPS(lp)	mutex_enter((lp))
#define	UNLOCK_DEV_OPS(lp)	mutex_exit((lp))

/*
 * Not to be used without obtaining the per-driver lock.
 */
#define	INCR_DEV_OPS_REF(opsp)	(opsp)->devo_refcnt++
#define	DECR_DEV_OPS_REF(opsp)	(opsp)->devo_refcnt--
#define	CB_DRV_INSTALLED(opsp)	((opsp) != &nodev_ops && \
				(opsp) != &mod_nodev_ops)
#define	DRV_UNLOADABLE(opsp)	((opsp)->devo_refcnt == 0)
#define	DEV_OPS_HELD(opsp)	((opsp)->devo_refcnt > 0)
#define	NEXUS_DRV(opsp)		((opsp)->devo_bus_ops != NULL)
#define	NETWORK_DRV(major)	(devnamesp[major].dn_flags & DN_NETWORK_DRIVER)
#define	GLDV3_DRV(major)	(devnamesp[major].dn_flags & DN_GLDV3_DRIVER)

extern void impl_rem_dev_props(dev_info_t *);
extern void add_class(char *, char *);

struct bind;
extern int make_mbind(char *, int, char *, struct bind **);
extern void delete_mbind(char *, struct bind **);

extern void configure(void);
#if defined(__sparc)
extern void setcputype(void);
#endif
extern void devtree_freeze(void);
extern void reset_leaves(void);
extern void quiesce_devices(dev_info_t *, void *);

extern void setup_ddi(void);
extern void setup_ddi_poststartup(void);
extern void impl_ddi_callback_init(void);
extern void impl_fix_props(dev_info_t *, dev_info_t *, char *, int, caddr_t);
extern int impl_check_cpu(dev_info_t *);
extern int check_status(int, char *, dev_info_t *);

extern int exclude_settrap(int);
extern int exclude_level(int);

extern major_t path_to_major(char *);
extern void i_ddi_node_cache_init(void);
extern dev_info_t *i_ddi_alloc_node(dev_info_t *, char *, pnode_t, int,
    ddi_prop_t *, int);
extern void i_ddi_forceattach_drivers(void);
extern int i_ddi_io_initialized(void);
extern dev_info_t *i_ddi_create_branch(dev_info_t *, int);
extern void i_ddi_add_devimap(dev_info_t *dip);
extern void i_ddi_di_cache_invalidate(int kmflag);
extern void i_ddi_di_cache_free(struct di_cache *cache);

/* devname_state - for /dev to denote reconfig and system available */
#define	DS_RECONFIG	0x01		/* reconfig boot */
#define	DS_SYSAVAIL	0x02		/* implicit reconfig enabled */

extern int i_ddi_sysavail(void);
extern int i_ddi_reconfig(void);
extern void i_ddi_set_sysavail(void);
extern void i_ddi_set_reconfig(void);

/* I/O retire related */
extern int e_ddi_retire_device(char *path, char **cons_array);
extern int e_ddi_unretire_device(char *path);
extern int e_ddi_mark_retiring(dev_info_t *dip, void *arg);
extern int e_ddi_retire_notify(dev_info_t *dip, void *arg);
extern int e_ddi_retire_finalize(dev_info_t *dip, void *arg);
extern void e_ddi_degrade_finalize(dev_info_t *dip);
extern void e_ddi_undegrade_finalize(dev_info_t *dip);

extern int check_driver_quiesce(dev_info_t *dip, void *arg);

#endif /* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_AUTOCONF_H */