module.h revision 283254
125537Sdfr/*-
225537Sdfr * Copyright (c) 1997 Doug Rabson
325537Sdfr * All rights reserved.
425537Sdfr *
525537Sdfr * Redistribution and use in source and binary forms, with or without
625537Sdfr * modification, are permitted provided that the following conditions
725537Sdfr * are met:
825537Sdfr * 1. Redistributions of source code must retain the above copyright
925537Sdfr *    notice, this list of conditions and the following disclaimer.
1025537Sdfr * 2. Redistributions in binary form must reproduce the above copyright
1125537Sdfr *    notice, this list of conditions and the following disclaimer in the
1225537Sdfr *    documentation and/or other materials provided with the distribution.
1325537Sdfr *
1425537Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1525537Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1625537Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1725537Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1825537Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1925537Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2025537Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2125537Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2225537Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2325537Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2425537Sdfr * SUCH DAMAGE.
2525537Sdfr *
2650477Speter * $FreeBSD: head/sys/sys/module.h 283254 2015-05-21 17:40:53Z dim $
2725537Sdfr */
2825537Sdfr
2925537Sdfr#ifndef _SYS_MODULE_H_
3025537Sdfr#define _SYS_MODULE_H_
3125537Sdfr
3259751Speter/*
3359751Speter * Module metadata types
3459751Speter */
3559751Speter#define	MDT_DEPEND	1		/* argument is a module name */
3659751Speter#define	MDT_MODULE	2		/* module declaration */
3759751Speter#define	MDT_VERSION	3		/* module version(s) */
38277205Simp#define	MDT_PNP_INFO	4		/* Plug and play hints record */
3959751Speter
4059751Speter#define	MDT_STRUCT_VERSION	1	/* version of metadata structure */
4159751Speter#define	MDT_SETNAME	"modmetadata_set"
4259751Speter
4341153Swollmantypedef enum modeventtype {
4491472Sarr	MOD_LOAD,
4591472Sarr	MOD_UNLOAD,
46132117Sphk	MOD_SHUTDOWN,
47132117Sphk	MOD_QUIESCE
4825537Sdfr} modeventtype_t;
4925537Sdfr
5091472Sarrtypedef struct module *module_t;
5191472Sarrtypedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *);
5225537Sdfr
5325537Sdfr/*
5425537Sdfr * Struct for registering modules statically via SYSINIT.
5525537Sdfr */
5625537Sdfrtypedef struct moduledata {
5791472Sarr	const char	*name;		/* module name */
5891472Sarr	modeventhand_t  evhand;		/* event handler */
5991472Sarr	void		*priv;		/* extra data */
6025537Sdfr} moduledata_t;
6125537Sdfr
6242435Sdfr/*
6391472Sarr * A module can use this to report module specific data to the user via
6491472Sarr * kldstat(2).
6542435Sdfr */
6642435Sdfrtypedef union modspecific {
6791472Sarr	int	intval;
6891472Sarr	u_int	uintval;
6991472Sarr	long	longval;
7091472Sarr	u_long	ulongval;
7142435Sdfr} modspecific_t;
7242435Sdfr
7359751Speter/*
74281463Smarkm * Module dependency declaration
7559751Speter */
7659751Speterstruct mod_depend {
7791472Sarr	int	md_ver_minimum;
7891472Sarr	int	md_ver_preferred;
7991472Sarr	int	md_ver_maximum;
8059751Speter};
8159751Speter
8259751Speter/*
8359751Speter * Module version declaration
8459751Speter */
8559751Speterstruct mod_version {
8691472Sarr	int	mv_version;
8759751Speter};
8859751Speter
8959751Speterstruct mod_metadata {
9091472Sarr	int		md_version;	/* structure version MDTV_* */
9191472Sarr	int		md_type;	/* type of entry MDT_* */
9291472Sarr	void		*md_data;	/* specific data */
9391472Sarr	const char	*md_cval;	/* common string label */
9459751Speter};
9559751Speter
9691472Sarr#ifdef	_KERNEL
9740137Speter
9859751Speter#include <sys/linker_set.h>
9959751Speter
10091472Sarr#define	MODULE_METADATA(uniquifier, type, data, cval)			\
10191472Sarr	static struct mod_metadata _mod_metadata##uniquifier = {	\
10291472Sarr		MDT_STRUCT_VERSION,					\
10391472Sarr		type,							\
10491472Sarr		data,							\
10591472Sarr		cval							\
10691472Sarr	};								\
10791472Sarr	DATA_SET(modmetadata_set, _mod_metadata##uniquifier)
10859751Speter
10991472Sarr#define	MODULE_DEPEND(module, mdepend, vmin, vpref, vmax)		\
110283254Sdim	static struct mod_depend _##module##_depend_on_##mdepend	\
111283254Sdim	    __section(".data") = {					\
11291472Sarr		vmin,							\
11391472Sarr		vpref,							\
11491472Sarr		vmax							\
11591472Sarr	};								\
11691472Sarr	MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND,	\
11791472Sarr	    &_##module##_depend_on_##mdepend, #mdepend)
11859751Speter
119176252Sjhb/*
120176252Sjhb * Every kernel has a 'kernel' module with the version set to
121176252Sjhb * __FreeBSD_version.  We embed a MODULE_DEPEND() inside every module
122176252Sjhb * that depends on the 'kernel' module.  It uses the current value of
123176252Sjhb * __FreeBSD_version as the minimum and preferred versions.  For the
124176252Sjhb * maximum version it rounds the version up to the end of its branch
125176252Sjhb * (i.e. M99999 for M.x).  This allows a module built on M.x to work
126176252Sjhb * on M.y systems where y >= x, but fail on M.z systems where z < x.
127176252Sjhb */
128176252Sjhb#define	MODULE_KERNEL_MAXVER	(roundup(__FreeBSD_version, 100000) - 1)
129176252Sjhb
130213716Skib#define	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver)	\
131176252Sjhb	MODULE_DEPEND(name, kernel, __FreeBSD_version,			\
132213716Skib	    __FreeBSD_version, maxver);			\
13391472Sarr	MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name);		\
134177253Srwatson	SYSINIT(name##module, sub, order, module_register_init, &data);	\
13591472Sarr	struct __hack
13625537Sdfr
137213716Skib#define	DECLARE_MODULE(name, data, sub, order)				\
138213716Skib	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER)
139213716Skib
140213716Skib/*
141213716Skib * The module declared with DECLARE_MODULE_TIED can only be loaded
142213716Skib * into the kernel with exactly the same __FreeBSD_version.
143213716Skib *
144213716Skib * Use it for modules that use kernel interfaces that are not stable
145213716Skib * even on STABLE/X branches.
146213716Skib */
147213716Skib#define	DECLARE_MODULE_TIED(name, data, sub, order)				\
148213716Skib	DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)
149213716Skib
15091472Sarr#define	MODULE_VERSION(module, version)					\
151283254Sdim	static struct mod_version _##module##_version			\
152283254Sdim	    __section(".data") = {					\
15391472Sarr		version							\
15491472Sarr	};								\
15591472Sarr	MODULE_METADATA(_##module##_version, MDT_VERSION,		\
15691472Sarr	    &_##module##_version, #module)
15759751Speter
15892547Sarrextern struct sx modules_sx;
15992547Sarr
16092547Sarr#define	MOD_XLOCK	sx_xlock(&modules_sx)
16192547Sarr#define	MOD_SLOCK	sx_slock(&modules_sx)
16292547Sarr#define	MOD_XUNLOCK	sx_xunlock(&modules_sx)
16392547Sarr#define	MOD_SUNLOCK	sx_sunlock(&modules_sx)
16492547Sarr#define	MOD_LOCK_ASSERT	sx_assert(&modules_sx, SX_LOCKED)
16592547Sarr#define	MOD_XLOCK_ASSERT	sx_assert(&modules_sx, SX_XLOCKED)
16692547Sarr
16746693Speterstruct linker_file;
16825537Sdfr
16991472Sarrvoid	module_register_init(const void *);
17091472Sarrint	module_register(const struct moduledata *, struct linker_file *);
17191472Sarrmodule_t	module_lookupbyname(const char *);
17291472Sarrmodule_t	module_lookupbyid(int);
173185635Sjhbint	module_quiesce(module_t);
17491472Sarrvoid	module_reference(module_t);
17591472Sarrvoid	module_release(module_t);
176185635Sjhbint	module_unload(module_t);
17791472Sarrint	module_getid(module_t);
17891472Sarrmodule_t	module_getfnext(module_t);
179185635Sjhbconst char *	module_getname(module_t);
18091472Sarrvoid	module_setspecific(module_t, modspecific_t *);
181157818Sjhbstruct linker_file *module_file(module_t);
18225537Sdfr
18391472Sarr#ifdef	MOD_DEBUG
18425537Sdfrextern int mod_debug;
18591472Sarr#define	MOD_DEBUG_REFS	1
18625537Sdfr
18791520Sobrien#define	MOD_DPF(cat, args) do {						\
18891472Sarr	if (mod_debug & MOD_DEBUG_##cat)				\
18991472Sarr		printf(args);						\
19091472Sarr} while (0)
19125537Sdfr
19291472Sarr#else	/* !MOD_DEBUG */
19325537Sdfr
19491472Sarr#define	MOD_DPF(cat, args)
19525537Sdfr#endif
19691472Sarr#endif	/* _KERNEL */
19725537Sdfr
19891472Sarr#define	MAXMODNAME	32
19925537Sdfr
20025537Sdfrstruct module_stat {
20191472Sarr	int		version;	/* set to sizeof(struct module_stat) */
20291472Sarr	char		name[MAXMODNAME];
20391472Sarr	int		refs;
20491472Sarr	int		id;
20591472Sarr	modspecific_t	data;
20625537Sdfr};
20725537Sdfr
20855205Speter#ifndef _KERNEL
20925537Sdfr
21025537Sdfr#include <sys/cdefs.h>
21125537Sdfr
21225537Sdfr__BEGIN_DECLS
21383248Sddint	modnext(int _modid);
21483248Sddint	modfnext(int _modid);
21591472Sarrint	modstat(int _modid, struct module_stat *_stat);
21683248Sddint	modfind(const char *_name);
21725537Sdfr__END_DECLS
21825537Sdfr
21925537Sdfr#endif
22025537Sdfr
22125537Sdfr#endif	/* !_SYS_MODULE_H_ */
222