1*199767f8SToomas Soome /*- 2*199767f8SToomas Soome * Copyright (c) 1997 Doug Rabson 3*199767f8SToomas Soome * All rights reserved. 4*199767f8SToomas Soome * 5*199767f8SToomas Soome * Redistribution and use in source and binary forms, with or without 6*199767f8SToomas Soome * modification, are permitted provided that the following conditions 7*199767f8SToomas Soome * are met: 8*199767f8SToomas Soome * 1. Redistributions of source code must retain the above copyright 9*199767f8SToomas Soome * notice, this list of conditions and the following disclaimer. 10*199767f8SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright 11*199767f8SToomas Soome * notice, this list of conditions and the following disclaimer in the 12*199767f8SToomas Soome * documentation and/or other materials provided with the distribution. 13*199767f8SToomas Soome * 14*199767f8SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*199767f8SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*199767f8SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*199767f8SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*199767f8SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*199767f8SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*199767f8SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*199767f8SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*199767f8SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*199767f8SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*199767f8SToomas Soome * SUCH DAMAGE. 25*199767f8SToomas Soome * 26*199767f8SToomas Soome * $FreeBSD$ 27*199767f8SToomas Soome */ 28*199767f8SToomas Soome 29*199767f8SToomas Soome #ifndef _SYS_MODULE_H_ 30*199767f8SToomas Soome #define _SYS_MODULE_H_ 31*199767f8SToomas Soome 32*199767f8SToomas Soome /* 33*199767f8SToomas Soome * Module metadata types 34*199767f8SToomas Soome */ 35*199767f8SToomas Soome #define MDT_DEPEND 1 /* argument is a module name */ 36*199767f8SToomas Soome #define MDT_MODULE 2 /* module declaration */ 37*199767f8SToomas Soome #define MDT_VERSION 3 /* module version(s) */ 38*199767f8SToomas Soome #define MDT_PNP_INFO 4 /* Plug and play hints record */ 39*199767f8SToomas Soome 40*199767f8SToomas Soome #define MDT_STRUCT_VERSION 1 /* version of metadata structure */ 41*199767f8SToomas Soome #define MDT_SETNAME "modmetadata_set" 42*199767f8SToomas Soome 43*199767f8SToomas Soome typedef enum modeventtype { 44*199767f8SToomas Soome MOD_LOAD, 45*199767f8SToomas Soome MOD_UNLOAD, 46*199767f8SToomas Soome MOD_SHUTDOWN, 47*199767f8SToomas Soome MOD_QUIESCE 48*199767f8SToomas Soome } modeventtype_t; 49*199767f8SToomas Soome 50*199767f8SToomas Soome typedef struct module *module_t; 51*199767f8SToomas Soome typedef int (*modeventhand_t)(module_t, int /* modeventtype_t */, void *); 52*199767f8SToomas Soome 53*199767f8SToomas Soome /* 54*199767f8SToomas Soome * Struct for registering modules statically via SYSINIT. 55*199767f8SToomas Soome */ 56*199767f8SToomas Soome typedef struct moduledata { 57*199767f8SToomas Soome const char *name; /* module name */ 58*199767f8SToomas Soome modeventhand_t evhand; /* event handler */ 59*199767f8SToomas Soome void *priv; /* extra data */ 60*199767f8SToomas Soome } moduledata_t; 61*199767f8SToomas Soome 62*199767f8SToomas Soome /* 63*199767f8SToomas Soome * A module can use this to report module specific data to the user via 64*199767f8SToomas Soome * kldstat(2). 65*199767f8SToomas Soome */ 66*199767f8SToomas Soome typedef union modspecific { 67*199767f8SToomas Soome int intval; 68*199767f8SToomas Soome u_int uintval; 69*199767f8SToomas Soome long longval; 70*199767f8SToomas Soome u_long ulongval; 71*199767f8SToomas Soome } modspecific_t; 72*199767f8SToomas Soome 73*199767f8SToomas Soome /* 74*199767f8SToomas Soome * Module dependency declaration 75*199767f8SToomas Soome */ 76*199767f8SToomas Soome struct mod_depend { 77*199767f8SToomas Soome int md_ver_minimum; 78*199767f8SToomas Soome int md_ver_preferred; 79*199767f8SToomas Soome int md_ver_maximum; 80*199767f8SToomas Soome }; 81*199767f8SToomas Soome 82*199767f8SToomas Soome /* 83*199767f8SToomas Soome * Module version declaration 84*199767f8SToomas Soome */ 85*199767f8SToomas Soome struct mod_version { 86*199767f8SToomas Soome int mv_version; 87*199767f8SToomas Soome }; 88*199767f8SToomas Soome 89*199767f8SToomas Soome struct mod_metadata { 90*199767f8SToomas Soome int md_version; /* structure version MDTV_* */ 91*199767f8SToomas Soome int md_type; /* type of entry MDT_* */ 92*199767f8SToomas Soome const void *md_data; /* specific data */ 93*199767f8SToomas Soome const char *md_cval; /* common string label */ 94*199767f8SToomas Soome }; 95*199767f8SToomas Soome 96*199767f8SToomas Soome struct mod_pnp_match_info 97*199767f8SToomas Soome { 98*199767f8SToomas Soome const char *descr; /* Description of the table */ 99*199767f8SToomas Soome const char *bus; /* Name of the bus for this table */ 100*199767f8SToomas Soome const void *table; /* Pointer to pnp table */ 101*199767f8SToomas Soome int entry_len; /* Length of each entry in the table (may be */ 102*199767f8SToomas Soome /* longer than descr describes). */ 103*199767f8SToomas Soome int num_entry; /* Number of entries in the table */ 104*199767f8SToomas Soome }; 105*199767f8SToomas Soome #ifdef _KERNEL 106*199767f8SToomas Soome 107*199767f8SToomas Soome #include <sys/linker_set.h> 108*199767f8SToomas Soome 109*199767f8SToomas Soome #define MODULE_METADATA(uniquifier, type, data, cval) \ 110*199767f8SToomas Soome static struct mod_metadata _mod_metadata##uniquifier = { \ 111*199767f8SToomas Soome MDT_STRUCT_VERSION, \ 112*199767f8SToomas Soome type, \ 113*199767f8SToomas Soome data, \ 114*199767f8SToomas Soome cval \ 115*199767f8SToomas Soome }; \ 116*199767f8SToomas Soome DATA_SET(modmetadata_set, _mod_metadata##uniquifier) 117*199767f8SToomas Soome 118*199767f8SToomas Soome #define MODULE_DEPEND(module, mdepend, vmin, vpref, vmax) \ 119*199767f8SToomas Soome static struct mod_depend _##module##_depend_on_##mdepend \ 120*199767f8SToomas Soome __section(".data") = { \ 121*199767f8SToomas Soome vmin, \ 122*199767f8SToomas Soome vpref, \ 123*199767f8SToomas Soome vmax \ 124*199767f8SToomas Soome }; \ 125*199767f8SToomas Soome MODULE_METADATA(_md_##module##_on_##mdepend, MDT_DEPEND, \ 126*199767f8SToomas Soome &_##module##_depend_on_##mdepend, #mdepend) 127*199767f8SToomas Soome 128*199767f8SToomas Soome /* 129*199767f8SToomas Soome * Every kernel has a 'kernel' module with the version set to 130*199767f8SToomas Soome * __FreeBSD_version. We embed a MODULE_DEPEND() inside every module 131*199767f8SToomas Soome * that depends on the 'kernel' module. It uses the current value of 132*199767f8SToomas Soome * __FreeBSD_version as the minimum and preferred versions. For the 133*199767f8SToomas Soome * maximum version it rounds the version up to the end of its branch 134*199767f8SToomas Soome * (i.e. M99999 for M.x). This allows a module built on M.x to work 135*199767f8SToomas Soome * on M.y systems where y >= x, but fail on M.z systems where z < x. 136*199767f8SToomas Soome */ 137*199767f8SToomas Soome #define MODULE_KERNEL_MAXVER (roundup(__FreeBSD_version, 100000) - 1) 138*199767f8SToomas Soome 139*199767f8SToomas Soome #define DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, maxver) \ 140*199767f8SToomas Soome MODULE_DEPEND(name, kernel, __FreeBSD_version, \ 141*199767f8SToomas Soome __FreeBSD_version, maxver); \ 142*199767f8SToomas Soome MODULE_METADATA(_md_##name, MDT_MODULE, &data, #name); \ 143*199767f8SToomas Soome SYSINIT(name##module, sub, order, module_register_init, &data); \ 144*199767f8SToomas Soome struct __hack 145*199767f8SToomas Soome 146*199767f8SToomas Soome #define DECLARE_MODULE(name, data, sub, order) \ 147*199767f8SToomas Soome DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, MODULE_KERNEL_MAXVER) 148*199767f8SToomas Soome 149*199767f8SToomas Soome /* 150*199767f8SToomas Soome * The module declared with DECLARE_MODULE_TIED can only be loaded 151*199767f8SToomas Soome * into the kernel with exactly the same __FreeBSD_version. 152*199767f8SToomas Soome * 153*199767f8SToomas Soome * Use it for modules that use kernel interfaces that are not stable 154*199767f8SToomas Soome * even on STABLE/X branches. 155*199767f8SToomas Soome */ 156*199767f8SToomas Soome #define DECLARE_MODULE_TIED(name, data, sub, order) \ 157*199767f8SToomas Soome DECLARE_MODULE_WITH_MAXVER(name, data, sub, order, __FreeBSD_version) 158*199767f8SToomas Soome 159*199767f8SToomas Soome #define MODULE_VERSION(module, version) \ 160*199767f8SToomas Soome static struct mod_version _##module##_version \ 161*199767f8SToomas Soome __section(".data") = { \ 162*199767f8SToomas Soome version \ 163*199767f8SToomas Soome }; \ 164*199767f8SToomas Soome MODULE_METADATA(_##module##_version, MDT_VERSION, \ 165*199767f8SToomas Soome &_##module##_version, #module) 166*199767f8SToomas Soome 167*199767f8SToomas Soome /** 168*199767f8SToomas Soome * Generic macros to create pnp info hints that modules may export 169*199767f8SToomas Soome * to allow external tools to parse their intenral device tables 170*199767f8SToomas Soome * to make an informed guess about what driver(s) to load. 171*199767f8SToomas Soome */ 172*199767f8SToomas Soome #define MODULE_PNP_INFO(d, b, unique, t, l, n) \ 173*199767f8SToomas Soome static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \ 174*199767f8SToomas Soome .descr = d, \ 175*199767f8SToomas Soome .bus = #b, \ 176*199767f8SToomas Soome .table = t, \ 177*199767f8SToomas Soome .entry_len = l, \ 178*199767f8SToomas Soome .num_entry = n \ 179*199767f8SToomas Soome }; \ 180*199767f8SToomas Soome MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \ 181*199767f8SToomas Soome &_module_pnp_##b##_##unique, #b); 182*199767f8SToomas Soome /** 183*199767f8SToomas Soome * descr is a string that describes each entry in the table. The general 184*199767f8SToomas Soome * form is (TYPE:pnp_name[/pnp_name];)* 185*199767f8SToomas Soome * where TYPE is one of the following: 186*199767f8SToomas Soome * U8 uint8_t element 187*199767f8SToomas Soome * V8 like U8 and 0xff means match any 188*199767f8SToomas Soome * G16 uint16_t element, any value >= matches 189*199767f8SToomas Soome * L16 uint16_t element, any value <= matches 190*199767f8SToomas Soome * M16 uint16_t element, mask of which of the following fields to use. 191*199767f8SToomas Soome * U16 uint16_t element 192*199767f8SToomas Soome * V16 like U16 and 0xffff means match any 193*199767f8SToomas Soome * U32 uint32_t element 194*199767f8SToomas Soome * V32 like U32 and 0xffffffff means match any 195*199767f8SToomas Soome * W32 Two 16-bit values with first pnp_name in LSW and second in MSW. 196*199767f8SToomas Soome * Z pointer to a string to match exactly 197*199767f8SToomas Soome * D like Z, but is the string passed to device_set_descr() 198*199767f8SToomas Soome * P A pointer that should be ignored 199*199767f8SToomas Soome * E EISA PNP Identifier (in binary, but bus publishes string) 200*199767f8SToomas Soome * K Key for whole table. pnp_name=value. must be last, if present. 201*199767f8SToomas Soome * 202*199767f8SToomas Soome * The pnp_name "#" is reserved for other fields that should be ignored. 203*199767f8SToomas Soome */ 204*199767f8SToomas Soome 205*199767f8SToomas Soome extern struct sx modules_sx; 206*199767f8SToomas Soome 207*199767f8SToomas Soome #define MOD_XLOCK sx_xlock(&modules_sx) 208*199767f8SToomas Soome #define MOD_SLOCK sx_slock(&modules_sx) 209*199767f8SToomas Soome #define MOD_XUNLOCK sx_xunlock(&modules_sx) 210*199767f8SToomas Soome #define MOD_SUNLOCK sx_sunlock(&modules_sx) 211*199767f8SToomas Soome #define MOD_LOCK_ASSERT sx_assert(&modules_sx, SX_LOCKED) 212*199767f8SToomas Soome #define MOD_XLOCK_ASSERT sx_assert(&modules_sx, SX_XLOCKED) 213*199767f8SToomas Soome 214*199767f8SToomas Soome struct linker_file; 215*199767f8SToomas Soome 216*199767f8SToomas Soome void module_register_init(const void *); 217*199767f8SToomas Soome int module_register(const struct moduledata *, struct linker_file *); 218*199767f8SToomas Soome module_t module_lookupbyname(const char *); 219*199767f8SToomas Soome module_t module_lookupbyid(int); 220*199767f8SToomas Soome int module_quiesce(module_t); 221*199767f8SToomas Soome void module_reference(module_t); 222*199767f8SToomas Soome void module_release(module_t); 223*199767f8SToomas Soome int module_unload(module_t); 224*199767f8SToomas Soome int module_getid(module_t); 225*199767f8SToomas Soome module_t module_getfnext(module_t); 226*199767f8SToomas Soome const char * module_getname(module_t); 227*199767f8SToomas Soome void module_setspecific(module_t, modspecific_t *); 228*199767f8SToomas Soome struct linker_file *module_file(module_t); 229*199767f8SToomas Soome 230*199767f8SToomas Soome #ifdef MOD_DEBUG 231*199767f8SToomas Soome extern int mod_debug; 232*199767f8SToomas Soome #define MOD_DEBUG_REFS 1 233*199767f8SToomas Soome 234*199767f8SToomas Soome #define MOD_DPF(cat, args) do { \ 235*199767f8SToomas Soome if (mod_debug & MOD_DEBUG_##cat) \ 236*199767f8SToomas Soome printf(args); \ 237*199767f8SToomas Soome } while (0) 238*199767f8SToomas Soome 239*199767f8SToomas Soome #else /* !MOD_DEBUG */ 240*199767f8SToomas Soome 241*199767f8SToomas Soome #define MOD_DPF(cat, args) 242*199767f8SToomas Soome #endif 243*199767f8SToomas Soome #endif /* _KERNEL */ 244*199767f8SToomas Soome 245*199767f8SToomas Soome #define MAXMODNAME 32 246*199767f8SToomas Soome 247*199767f8SToomas Soome struct module_stat { 248*199767f8SToomas Soome int version; /* set to sizeof(struct module_stat) */ 249*199767f8SToomas Soome char name[MAXMODNAME]; 250*199767f8SToomas Soome int refs; 251*199767f8SToomas Soome int id; 252*199767f8SToomas Soome modspecific_t data; 253*199767f8SToomas Soome }; 254*199767f8SToomas Soome 255*199767f8SToomas Soome #ifndef _KERNEL 256*199767f8SToomas Soome 257*199767f8SToomas Soome #include <sys/cdefs.h> 258*199767f8SToomas Soome 259*199767f8SToomas Soome __BEGIN_DECLS 260*199767f8SToomas Soome int modnext(int _modid); 261*199767f8SToomas Soome int modfnext(int _modid); 262*199767f8SToomas Soome int modstat(int _modid, struct module_stat *_stat); 263*199767f8SToomas Soome int modfind(const char *_name); 264*199767f8SToomas Soome __END_DECLS 265*199767f8SToomas Soome 266*199767f8SToomas Soome #endif 267*199767f8SToomas Soome 268*199767f8SToomas Soome #endif /* !_SYS_MODULE_H_ */ 269