#ifndef _SYS_MODULE_H_
#define _SYS_MODULE_H_
#define MDT_DEPEND 1
#define MDT_MODULE 2
#define MDT_VERSION 3
#define MDT_PNP_INFO 4
#define MDT_STRUCT_VERSION 1
#define MDT_SETNAME "modmetadata_set"
typedef enum modeventtype {
MOD_LOAD,
MOD_UNLOAD,
MOD_SHUTDOWN,
MOD_QUIESCE
} modeventtype_t;
typedef struct module *module_t;
typedef int (*modeventhand_t)(module_t, int , void *);
typedef struct moduledata {
const char *name;
modeventhand_t evhand;
void *priv;
} moduledata_t;
typedef union modspecific {
int intval;
u_int uintval;
long longval;
u_long ulongval;
} modspecific_t;
struct mod_depend {
int md_ver_minimum;
int md_ver_preferred;
int md_ver_maximum;
};
struct mod_version {
int mv_version;
};
struct mod_metadata {
int md_version;
int md_type;
const void *md_data;
const char *md_cval;
};
struct mod_pnp_match_info
{
const char *descr;
const char *bus;
const void *table;
int entry_len;
int num_entry;
};
#ifdef _KERNEL
#include <sys/linker_set.h>
#define MODULE_METADATA_CONCAT(uniquifier) _mod_metadata##uniquifier
#define MODULE_METADATA(uniquifier, type, data, cval) \
static struct mod_metadata MODULE_METADATA_CONCAT(uniquifier) = { \
MDT_STRUCT_VERSION, \
type, \
data, \
cval \
}; \
DATA_SET(modmetadata_set, MODULE_METADATA_CONCAT(uniquifier))
#define MODULE_DEPEND_CONCAT(module, mdepend) _##module##_depend_on_##mdepend
#define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax) \
static struct mod_depend MODULE_DEPEND_CONCAT(module, mdepend) \
__section(".data") = { \
vmin, \
vpref, \
vmax \
}; \
MODULE_METADATA(MODULE_DEPEND_CONCAT(module, mdepend), \
MDT_DEPEND, &MODULE_DEPEND_CONCAT(module, mdepend), \
__XSTRING(mdepend))
#define MODULE_KERNEL_MAXVER (roundup(__FreeBSD_version, 100000) - 1)
#define DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver) \
MODULE_DEPEND(name, kernel, __FreeBSD_version, \
__FreeBSD_version, maxver); \
MODULE_METADATA(_md_##name, MDT_MODULE, &data, __XSTRING(name));\
SYSINIT(name##module, sub, order, module_register_init, &data); \
struct __hack
#ifdef KLD_TIED
#define DECLARE_MODULE(name, data, sub, order) \
DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)
#else
#define DECLARE_MODULE(name, data, sub, order) \
DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER)
#endif
#define DECLARE_MODULE_TIED(name, data, sub, order) \
DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version)
#define MODULE_VERSION_CONCAT(module, version) _##module##_version
#define MODULE_VERSION(module, version) \
static struct mod_version MODULE_VERSION_CONCAT(module, version)\
__section(".data") = { \
version \
}; \
MODULE_METADATA(MODULE_VERSION_CONCAT(module, version), MDT_VERSION,\
&MODULE_VERSION_CONCAT(module, version), __XSTRING(module))
#define MODULE_PNP_INFO(d, b, unique, t, n) \
static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \
.descr = d, \
.bus = #b, \
.table = t, \
.entry_len = sizeof((t)[0]), \
.num_entry = n \
}; \
MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \
&_module_pnp_##b##_##unique, #b);
extern struct sx modules_sx;
#define MOD_XLOCK sx_xlock(&modules_sx)
#define MOD_SLOCK sx_slock(&modules_sx)
#define MOD_XUNLOCK sx_xunlock(&modules_sx)
#define MOD_SUNLOCK sx_sunlock(&modules_sx)
#define MOD_LOCK_ASSERT sx_assert(&modules_sx, SX_LOCKED)
#define MOD_XLOCK_ASSERT sx_assert(&modules_sx, SX_XLOCKED)
struct linker_file;
void module_register_init(const void *);
int module_register(const struct moduledata *, struct linker_file *);
module_t module_lookupbyname(const char *);
module_t module_lookupbyid(int);
int module_quiesce(module_t);
void module_reference(module_t);
void module_release(module_t);
int module_unload(module_t);
int module_getid(module_t);
module_t module_getfnext(module_t);
const char * module_getname(module_t);
void module_setspecific(module_t, modspecific_t *);
struct linker_file *module_file(module_t);
#ifdef MOD_DEBUG
extern int mod_debug;
#define MOD_DEBUG_REFS 1
#define MOD_DPF(cat, args) do { \
if (mod_debug & MOD_DEBUG_##cat) \
printf args; \
} while (0)
#else
#define MOD_DPF(cat, args)
#endif
#endif
#define MAXMODNAMEV1V2 32
#define MAXMODNAMEV3 MAXPATHLEN
#define MAXMODNAME MAXMODNAMEV3
struct module_stat {
int version;
char name[MAXMODNAME];
int refs;
int id;
modspecific_t data;
};
#ifndef _KERNEL
#include <sys/cdefs.h>
__BEGIN_DECLS
int modnext(int _modid);
int modfnext(int _modid);
int modstat(int _modid, struct module_stat *_stat);
int modfind(const char *_name);
__END_DECLS
#endif
#endif