diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 | 
| commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
| tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/linux/module.h | |
| download | olio-linux-3.10-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.xz olio-linux-3.10-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.zip  | |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/linux/module.h')
| -rw-r--r-- | include/linux/module.h | 570 | 
1 files changed, 570 insertions, 0 deletions
diff --git a/include/linux/module.h b/include/linux/module.h new file mode 100644 index 00000000000..0e432a0f4ae --- /dev/null +++ b/include/linux/module.h @@ -0,0 +1,570 @@ +#ifndef _LINUX_MODULE_H +#define _LINUX_MODULE_H +/* + * Dynamic loading of modules into the kernel. + * + * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996 + * Rewritten again by Rusty Russell, 2002 + */ +#include <linux/config.h> +#include <linux/sched.h> +#include <linux/spinlock.h> +#include <linux/list.h> +#include <linux/stat.h> +#include <linux/compiler.h> +#include <linux/cache.h> +#include <linux/kmod.h> +#include <linux/elf.h> +#include <linux/stringify.h> +#include <linux/kobject.h> +#include <linux/moduleparam.h> +#include <asm/local.h> + +#include <asm/module.h> + +/* Not Yet Implemented */ +#define MODULE_SUPPORTED_DEVICE(name) + +/* v850 toolchain uses a `_' prefix for all user symbols */ +#ifndef MODULE_SYMBOL_PREFIX +#define MODULE_SYMBOL_PREFIX "" +#endif + +#define MODULE_NAME_LEN (64 - sizeof(unsigned long)) + +struct kernel_symbol +{ +	unsigned long value; +	const char *name; +}; + +struct modversion_info +{ +	unsigned long crc; +	char name[MODULE_NAME_LEN]; +}; + +struct module; + +struct module_attribute { +        struct attribute attr; +        ssize_t (*show)(struct module_attribute *, struct module *, char *); +        ssize_t (*store)(struct module_attribute *, struct module *, +			 const char *, size_t count); +}; + +struct module_kobject +{ +	struct kobject kobj; +	struct module *mod; +}; + +/* These are either module local, or the kernel's dummy ones. */ +extern int init_module(void); +extern void cleanup_module(void); + +/* Archs provide a method of finding the correct exception table. */ +struct exception_table_entry; + +const struct exception_table_entry * +search_extable(const struct exception_table_entry *first, +	       const struct exception_table_entry *last, +	       unsigned long value); +void sort_extable(struct exception_table_entry *start, +		  struct exception_table_entry *finish); +void sort_main_extable(void); + +extern struct subsystem module_subsys; + +#ifdef MODULE +#define MODULE_GENERIC_TABLE(gtype,name)			\ +extern const struct gtype##_id __mod_##gtype##_table		\ +  __attribute__ ((unused, alias(__stringify(name)))) + +extern struct module __this_module; +#define THIS_MODULE (&__this_module) +#else  /* !MODULE */ +#define MODULE_GENERIC_TABLE(gtype,name) +#define THIS_MODULE ((struct module *)0) +#endif + +/* Generic info of form tag = "info" */ +#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info) + +/* For userspace: you can also call me... */ +#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias) + +/* + * The following license idents are currently accepted as indicating free + * software modules + * + *	"GPL"				[GNU Public License v2 or later] + *	"GPL v2"			[GNU Public License v2] + *	"GPL and additional rights"	[GNU Public License v2 rights and more] + *	"Dual BSD/GPL"			[GNU Public License v2 + *					 or BSD license choice] + *	"Dual MPL/GPL"			[GNU Public License v2 + *					 or Mozilla license choice] + * + * The following other idents are available + * + *	"Proprietary"			[Non free products] + * + * There are dual licensed components, but when running with Linux it is the + * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL + * is a GPL combined work. + * + * This exists for several reasons + * 1.	So modinfo can show license info for users wanting to vet their setup  + *	is free + * 2.	So the community can ignore bug reports including proprietary modules + * 3.	So vendors can do likewise based on their own policies + */ +#define MODULE_LICENSE(_license) MODULE_INFO(license, _license) + +/* Author, ideally of form NAME <EMAIL>[, NAME <EMAIL>]*[ and NAME <EMAIL>] */ +#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author) +   +/* What your module does. */ +#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description) + +/* One for each parameter, describing how to use it.  Some files do +   multiple of these per line, so can't just use MODULE_INFO. */ +#define MODULE_PARM_DESC(_parm, desc) \ +	__MODULE_INFO(parm, _parm, #_parm ":" desc) + +#define MODULE_DEVICE_TABLE(type,name)		\ +  MODULE_GENERIC_TABLE(type##_device,name) + +/* Version of form [<epoch>:]<version>[-<extra-version>]. +   Or for CVS/RCS ID version, everything but the number is stripped. +  <epoch>: A (small) unsigned integer which allows you to start versions +           anew. If not mentioned, it's zero.  eg. "2:1.0" is after +	   "1:2.0". +  <version>: The <version> may contain only alphanumerics and the +           character `.'.  Ordered by numeric sort for numeric parts, +	   ascii sort for ascii parts (as per RPM or DEB algorithm). +  <extraversion>: Like <version>, but inserted for local +           customizations, eg "rh3" or "rusty1". + +  Using this automatically adds a checksum of the .c files and the +  local headers in "srcversion". +*/ +#define MODULE_VERSION(_version) MODULE_INFO(version, _version) + +/* Given an address, look for it in the exception tables */ +const struct exception_table_entry *search_exception_tables(unsigned long add); + +struct notifier_block; + +#ifdef CONFIG_MODULES + +/* Get/put a kernel symbol (calls must be symmetric) */ +void *__symbol_get(const char *symbol); +void *__symbol_get_gpl(const char *symbol); +#define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) + +#ifndef __GENKSYMS__ +#ifdef CONFIG_MODVERSIONS +/* Mark the CRC weak since genksyms apparently decides not to + * generate a checksums for some symbols */ +#define __CRC_SYMBOL(sym, sec)					\ +	extern void *__crc_##sym __attribute__((weak));		\ +	static const unsigned long __kcrctab_##sym		\ +	__attribute_used__					\ +	__attribute__((section("__kcrctab" sec), unused))	\ +	= (unsigned long) &__crc_##sym; +#else +#define __CRC_SYMBOL(sym, sec) +#endif + +/* For every exported symbol, place a struct in the __ksymtab section */ +#define __EXPORT_SYMBOL(sym, sec)				\ +	__CRC_SYMBOL(sym, sec)					\ +	static const char __kstrtab_##sym[]			\ +	__attribute__((section("__ksymtab_strings")))		\ +	= MODULE_SYMBOL_PREFIX #sym;                    	\ +	static const struct kernel_symbol __ksymtab_##sym	\ +	__attribute_used__					\ +	__attribute__((section("__ksymtab" sec), unused))	\ +	= { (unsigned long)&sym, __kstrtab_##sym } + +#define EXPORT_SYMBOL(sym)					\ +	__EXPORT_SYMBOL(sym, "") + +#define EXPORT_SYMBOL_GPL(sym)					\ +	__EXPORT_SYMBOL(sym, "_gpl") + +#endif + +struct module_ref +{ +	local_t count; +} ____cacheline_aligned; + +enum module_state +{ +	MODULE_STATE_LIVE, +	MODULE_STATE_COMING, +	MODULE_STATE_GOING, +}; + +/* Similar stuff for section attributes. */ +#define MODULE_SECT_NAME_LEN 32 +struct module_sect_attr +{ +	struct module_attribute mattr; +	char name[MODULE_SECT_NAME_LEN]; +	unsigned long address; +}; + +struct module_sect_attrs +{ +	struct attribute_group grp; +	struct module_sect_attr attrs[0]; +}; + +struct module_param_attrs; + +struct module +{ +	enum module_state state; + +	/* Member of list of modules */ +	struct list_head list; + +	/* Unique handle for this module */ +	char name[MODULE_NAME_LEN]; + +	/* Sysfs stuff. */ +	struct module_kobject mkobj; +	struct module_param_attrs *param_attrs; + +	/* Exported symbols */ +	const struct kernel_symbol *syms; +	unsigned int num_syms; +	const unsigned long *crcs; + +	/* GPL-only exported symbols. */ +	const struct kernel_symbol *gpl_syms; +	unsigned int num_gpl_syms; +	const unsigned long *gpl_crcs; + +	/* Exception table */ +	unsigned int num_exentries; +	const struct exception_table_entry *extable; + +	/* Startup function. */ +	int (*init)(void); + +	/* If this is non-NULL, vfree after init() returns */ +	void *module_init; + +	/* Here is the actual code + data, vfree'd on unload. */ +	void *module_core; + +	/* Here are the sizes of the init and core sections */ +	unsigned long init_size, core_size; + +	/* The size of the executable code in each section.  */ +	unsigned long init_text_size, core_text_size; + +	/* Arch-specific module values */ +	struct mod_arch_specific arch; + +	/* Am I unsafe to unload? */ +	int unsafe; + +	/* Am I GPL-compatible */ +	int license_gplok; + +#ifdef CONFIG_MODULE_UNLOAD +	/* Reference counts */ +	struct module_ref ref[NR_CPUS]; + +	/* What modules depend on me? */ +	struct list_head modules_which_use_me; + +	/* Who is waiting for us to be unloaded */ +	struct task_struct *waiter; + +	/* Destruction function. */ +	void (*exit)(void); +#endif + +#ifdef CONFIG_KALLSYMS +	/* We keep the symbol and string tables for kallsyms. */ +	Elf_Sym *symtab; +	unsigned long num_symtab; +	char *strtab; + +	/* Section attributes */ +	struct module_sect_attrs *sect_attrs; +#endif + +	/* Per-cpu data. */ +	void *percpu; + +	/* The command line arguments (may be mangled).  People like +	   keeping pointers to this stuff */ +	char *args; +}; + +/* FIXME: It'd be nice to isolate modules during init, too, so they +   aren't used before they (may) fail.  But presently too much code +   (IDE & SCSI) require entry into the module during init.*/ +static inline int module_is_live(struct module *mod) +{ +	return mod->state != MODULE_STATE_GOING; +} + +/* Is this address in a module? (second is with no locks, for oops) */ +struct module *module_text_address(unsigned long addr); +struct module *__module_text_address(unsigned long addr); + +/* Returns module and fills in value, defined and namebuf, or NULL if +   symnum out of range. */ +struct module *module_get_kallsym(unsigned int symnum, +				  unsigned long *value, +				  char *type, +				  char namebuf[128]); + +/* Look for this name: can be of form module:name. */ +unsigned long module_kallsyms_lookup_name(const char *name); + +int is_exported(const char *name, const struct module *mod); + +extern void __module_put_and_exit(struct module *mod, long code) +	__attribute__((noreturn)); +#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code); + +#ifdef CONFIG_MODULE_UNLOAD +unsigned int module_refcount(struct module *mod); +void __symbol_put(const char *symbol); +#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x) +void symbol_put_addr(void *addr); + +/* Sometimes we know we already have a refcount, and it's easier not +   to handle the error case (which only happens with rmmod --wait). */ +static inline void __module_get(struct module *module) +{ +	if (module) { +		BUG_ON(module_refcount(module) == 0); +		local_inc(&module->ref[get_cpu()].count); +		put_cpu(); +	} +} + +static inline int try_module_get(struct module *module) +{ +	int ret = 1; + +	if (module) { +		unsigned int cpu = get_cpu(); +		if (likely(module_is_live(module))) +			local_inc(&module->ref[cpu].count); +		else +			ret = 0; +		put_cpu(); +	} +	return ret; +} + +static inline void module_put(struct module *module) +{ +	if (module) { +		unsigned int cpu = get_cpu(); +		local_dec(&module->ref[cpu].count); +		/* Maybe they're waiting for us to drop reference? */ +		if (unlikely(!module_is_live(module))) +			wake_up_process(module->waiter); +		put_cpu(); +	} +} + +#else /*!CONFIG_MODULE_UNLOAD*/ +static inline int try_module_get(struct module *module) +{ +	return !module || module_is_live(module); +} +static inline void module_put(struct module *module) +{ +} +static inline void __module_get(struct module *module) +{ +} +#define symbol_put(x) do { } while(0) +#define symbol_put_addr(p) do { } while(0) + +#endif /* CONFIG_MODULE_UNLOAD */ + +/* This is a #define so the string doesn't get put in every .o file */ +#define module_name(mod)			\ +({						\ +	struct module *__mod = (mod);		\ +	__mod ? __mod->name : "kernel";		\ +}) + +#define __unsafe(mod)							     \ +do {									     \ +	if (mod && !(mod)->unsafe) {					     \ +		printk(KERN_WARNING					     \ +		       "Module %s cannot be unloaded due to unsafe usage in" \ +		       " %s:%u\n", (mod)->name, __FILE__, __LINE__);	     \ +		(mod)->unsafe = 1;					     \ +	}								     \ +} while(0) + +/* For kallsyms to ask for address resolution.  NULL means not found. */ +const char *module_address_lookup(unsigned long addr, +				  unsigned long *symbolsize, +				  unsigned long *offset, +				  char **modname); + +/* For extable.c to search modules' exception tables. */ +const struct exception_table_entry *search_module_extables(unsigned long addr); + +int register_module_notifier(struct notifier_block * nb); +int unregister_module_notifier(struct notifier_block * nb); + +extern void print_modules(void); + +struct device_driver; +void module_add_driver(struct module *, struct device_driver *); +void module_remove_driver(struct device_driver *); + +#else /* !CONFIG_MODULES... */ +#define EXPORT_SYMBOL(sym) +#define EXPORT_SYMBOL_GPL(sym) + +/* Given an address, look for it in the exception tables. */ +static inline const struct exception_table_entry * +search_module_extables(unsigned long addr) +{ +	return NULL; +} + +/* Is this address in a module? */ +static inline struct module *module_text_address(unsigned long addr) +{ +	return NULL; +} + +/* Is this address in a module? (don't take a lock, we're oopsing) */ +static inline struct module *__module_text_address(unsigned long addr) +{ +	return NULL; +} + +/* Get/put a kernel symbol (calls should be symmetric) */ +#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); }) +#define symbol_put(x) do { } while(0) +#define symbol_put_addr(x) do { } while(0) + +static inline void __module_get(struct module *module) +{ +} + +static inline int try_module_get(struct module *module) +{ +	return 1; +} + +static inline void module_put(struct module *module) +{ +} + +#define module_name(mod) "kernel" + +#define __unsafe(mod) + +/* For kallsyms to ask for address resolution.  NULL means not found. */ +static inline const char *module_address_lookup(unsigned long addr, +						unsigned long *symbolsize, +						unsigned long *offset, +						char **modname) +{ +	return NULL; +} + +static inline struct module *module_get_kallsym(unsigned int symnum, +						unsigned long *value, +						char *type, +						char namebuf[128]) +{ +	return NULL; +} + +static inline unsigned long module_kallsyms_lookup_name(const char *name) +{ +	return 0; +} + +static inline int is_exported(const char *name, const struct module *mod) +{ +	return 0; +} + +static inline int register_module_notifier(struct notifier_block * nb) +{ +	/* no events will happen anyway, so this can always succeed */ +	return 0; +} + +static inline int unregister_module_notifier(struct notifier_block * nb) +{ +	return 0; +} + +#define module_put_and_exit(code) do_exit(code) + +static inline void print_modules(void) +{ +} + +struct device_driver; +struct module; + +static inline void module_add_driver(struct module *module, struct device_driver *driver) +{ +} + +static inline void module_remove_driver(struct device_driver *driver) +{ +} + +#endif /* CONFIG_MODULES */ + +#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) + +/* BELOW HERE ALL THESE ARE OBSOLETE AND WILL VANISH */ + +struct obsolete_modparm { +	char name[64]; +	char type[64-sizeof(void *)]; +	void *addr; +}; + +static inline void MODULE_PARM_(void) { } +#ifdef MODULE +/* DEPRECATED: Do not use. */ +#define MODULE_PARM(var,type)						    \ +struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \ +{ __stringify(var), type, &MODULE_PARM_ }; \ +__MODULE_PARM_TYPE(var, type); +#else +#define MODULE_PARM(var,type) static void __attribute__((__unused__)) *__parm_##var = &MODULE_PARM_; +#endif + +#define __MODULE_STRING(x) __stringify(x) + +/* Use symbol_get and symbol_put instead.  You'll thank me. */ +#define HAVE_INTER_MODULE +extern void __deprecated inter_module_register(const char *, +		struct module *, const void *); +extern void __deprecated inter_module_unregister(const char *); +extern const void * __deprecated inter_module_get_request(const char *, +		const char *); +extern void __deprecated inter_module_put(const char *); + +#endif /* _LINUX_MODULE_H */  |