1 /*-
2  * Copyright (c) 1997 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: stable/10/sys/sys/module.h 298493 2016-04-22 21:38:37Z emaste $
27  */
28 
29 #ifndef _SYS_MODULE_H_
30 #define _SYS_MODULE_H_
31 
32 /*
33  * Module metadata types
34  */
35 #define	MDT_DEPEND	1		/* argument is a module name */
36 #define	MDT_MODULE	2		/* module declaration */
37 #define	MDT_VERSION	3		/* module version(s) */
38 #define	MDT_PNP_INFO	4		/* Plug and play hints record */
39 
40 #define	MDT_STRUCT_VERSION	1	/* version of metadata structure */
41 #define	MDT_SETNAME	"modmetadata_set"
42 
43 typedef enum modeventtype {
44 	MOD_LOAD,
45 	MOD_UNLOAD,
46 	MOD_SHUTDOWN,
47 	MOD_QUIESCE
48 } modeventtype_t;
49 
50 typedef struct module *module_t;
51 typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);
52 
53 /*
54  * Struct for registering modules statically via SYSINIT.
55  */
56 typedef struct moduledata {
57 	const char	*name;		/* module name */
58 	modeventhand_t  evhand;		/* event handler */
59 	void		*priv;		/* extra data */
60 } moduledata_t;
61 
62 /*
63  * A module can use this to report module specific data to the user via
64  * kldstat(2).
65  */
66 typedef union modspecific {
67 	int	intval;
68 	u_int	uintval;
69 	long	longval;
70 	u_long	ulongval;
71 } modspecific_t;
72 
73 /*
74  * Module dependency declarartion
75  */
76 struct mod_depend {
77 	int	md_ver_minimum;
78 	int	md_ver_preferred;
79 	int	md_ver_maximum;
80 };
81 
82 /*
83  * Module version declaration
84  */
85 struct mod_version {
86 	int	mv_version;
87 };
88 
89 struct mod_metadata {
90 	int		md_version;	/* structure version MDTV_* */
91 	int		md_type;	/* type of entry MDT_* */
92 	void		*md_data;	/* specific data */
93 	const char	*md_cval;	/* common string label */
94 };
95 
96 #ifdef	_KERNEL
97 
98 #include <sys/linker_set.h>
99 
100 #define	MODULE_METADATA(uniquifier, type, data, cval)			\
101 	static struct mod_metadata _mod_metadata##uniquifier = {	\
102 		MDT_STRUCT_VERSION,					\
103 		type,							\
104 		data,							\
105 		cval							\
106 	};								\
107 	DATA_SET(modmetadata_set, _mod_metadata##uniquifier)
108 
109 #define	MODULE_DEPEND(module, mdepend, vmin, vpref, vmax)		\
110 	static struct mod_depend _##module##_depend_on_##mdepend	\
111 	    __section(".data") = {					\
112 		vmin,							\
113 		vpref,							\
114 		vmax							\
115 	};								\
116 	MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND,	\
117 	    &_##module##_depend_on_##mdepend, #mdepend)
118 
119 /*
120  * Every kernel has a 'kernel' module with the version set to
121  * __FreeBSD_version.  We embed a MODULE_DEPEND() inside every module
122  * that depends on the 'kernel' module.  It uses the current value of
123  * __FreeBSD_version as the minimum and preferred versions.  For the
124  * maximum version it rounds the version up to the end of its branch
125  * (i.e. M99999 for M.x).  This allows a module built on M.x to work
126  * on M.y systems where y >= x, but fail on M.z systems where z < x.
127  */
128 #define	MODULE_KERNEL_MAXVER	(roundup(__FreeBSD_version, 100000) - 1)
129 
130 #define	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver)	\
131 	MODULE_DEPEND(name, kernel, __FreeBSD_version,			\
132 	    __FreeBSD_version, maxver);			\
133 	MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name);		\
134 	SYSINIT(name##module, sub, order, module_register_init, &data);	\
135 	struct __hack
136 
137 #define	DECLARE_MODULE(name, data, sub, order)				\
138 	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER)
139 
140 /*
141  * The module declared with DECLARE_MODULE_TIED can only be loaded
142  * into the kernel with exactly the same __FreeBSD_version.
143  *
144  * Use it for modules that use kernel interfaces that are not stable
145  * even on STABLE/X branches.
146  */
147 #define	DECLARE_MODULE_TIED(name, data, sub, order)				\
148 	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)
149 
150 #define	MODULE_VERSION(module, version)					\
151 	static struct mod_version _##module##_version			\
152 	    __section(".data") = {					\
153 		version							\
154 	};								\
155 	MODULE_METADATA(_##module##_version, MDT_VERSION,		\
156 	    &_##module##_version, #module)
157 
158 extern struct sx modules_sx;
159 
160 #define	MOD_XLOCK	sx_xlock(&modules_sx)
161 #define	MOD_SLOCK	sx_slock(&modules_sx)
162 #define	MOD_XUNLOCK	sx_xunlock(&modules_sx)
163 #define	MOD_SUNLOCK	sx_sunlock(&modules_sx)
164 #define	MOD_LOCK_ASSERT	sx_assert(&modules_sx, SX_LOCKED)
165 #define	MOD_XLOCK_ASSERT	sx_assert(&modules_sx, SX_XLOCKED)
166 
167 struct linker_file;
168 
169 void	module_register_init(const void *);
170 int	module_register(const struct moduledata *, struct linker_file *);
171 module_t	module_lookupbyname(const char *);
172 module_t	module_lookupbyid(int);
173 int	module_quiesce(module_t);
174 void	module_reference(module_t);
175 void	module_release(module_t);
176 int	module_unload(module_t);
177 int	module_getid(module_t);
178 module_t	module_getfnext(module_t);
179 const char *	module_getname(module_t);
180 void	module_setspecific(module_t, modspecific_t *);
181 struct linker_file *module_file(module_t);
182 
183 #ifdef	MOD_DEBUG
184 extern int mod_debug;
185 #define	MOD_DEBUG_REFS	1
186 
187 #define	MOD_DPF(cat, args) do {						\
188 	if (mod_debug & MOD_DEBUG_##cat)				\
189 		printf(args);						\
190 } while (0)
191 
192 #else	/* !MOD_DEBUG */
193 
194 #define	MOD_DPF(cat, args)
195 #endif
196 #endif	/* _KERNEL */
197 
198 #define	MAXMODNAME	32
199 
200 struct module_stat {
201 	int		version;	/* set to sizeof(struct module_stat) */
202 	char		name[MAXMODNAME];
203 	int		refs;
204 	int		id;
205 	modspecific_t	data;
206 };
207 
208 #ifndef _KERNEL
209 
210 #include <sys/cdefs.h>
211 
212 __BEGIN_DECLS
213 int	modnext(int _modid);
214 int	modfnext(int _modid);
215 int	modstat(int _modid, struct module_stat *_stat);
216 int	modfind(const char *_name);
217 __END_DECLS
218 
219 #endif
220 
221 #endif	/* !_SYS_MODULE_H_ */
222