From: Frank Mori Hess Date: Mon, 12 Jun 2006 01:10:38 +0000 (+0000) Subject: Patch from abbotti@mev.co.uk (Ian Abbott): X-Git-Tag: r0_7_71~27 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f3e0c5fe8c5a7f0ca7490a9cee5d932ff1dde031;p=comedi.git Patch from abbotti@mev.co.uk (Ian Abbott): The (few) module parameters used by comedi (for debugging and for specifying irq_mask or irq_list for some PCMCIA drivers) haven't worked since kernel 2.6.11. If you try and specify a module parameter when loading a module, the module fails to load due to missing symbols. I have implemented a linux/moduleparam.h compatibility header using code borrowed from the 2.4.25 kernel with some additions, and a patch to use it. The module_param() macro has been implemented for 2.4 kernels. Unfortunately, it is not possible to implement module_param_array() for 2.4 kernels, so I implemented a similar MODULE_PARAM_ARRAY() macro instead. The third parameter is different, being the length of the array rather than a (optionally null) pointer to a variable set to the number of elements of the array that have been filled in (that information is not available in 2.4 so I thought it best to omit it entirely). There is one restriction on the "length of array" parameter; it has to be a decimal number (or a macro that expands to a decimal number), not a fancy C expression, otherwise insmod won't parse it properly (if at all!). --- diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index 0d392995..79a09883 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); #ifdef CONFIG_COMEDI_DEBUG int comedi_debug; -MODULE_PARM(comedi_debug, "i"); +module_param(comedi_debug, int, 0644); #endif comedi_device *comedi_devices; diff --git a/comedi/drivers/cb_das16_cs.c b/comedi/drivers/cb_das16_cs.c index 6ef4bfcb..883b95bb 100644 --- a/comedi/drivers/cb_das16_cs.c +++ b/comedi/drivers/cb_das16_cs.c @@ -620,7 +620,7 @@ static int das16cs_timer_insn_config(comedi_device *dev,comedi_subdevice *s, #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); +module_param(pc_debug, int, 0644); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)"; diff --git a/comedi/drivers/comedi_bond.c b/comedi/drivers/comedi_bond.c index 57c601ce..d8be8f95 100644 --- a/comedi/drivers/comedi_bond.c +++ b/comedi/drivers/comedi_bond.c @@ -103,7 +103,7 @@ Configuration Options: #endif int debug = 0; -MODULE_PARM(debug, "i"); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "If true, print extra cryptic debugging output useful only to developers probably."); #define LOG_MSG(x...) printk(KERN_INFO MODULE_NAME": "x) diff --git a/comedi/drivers/das08_cs.c b/comedi/drivers/das08_cs.c index b3da0235..ec5e34bc 100644 --- a/comedi/drivers/das08_cs.c +++ b/comedi/drivers/das08_cs.c @@ -129,7 +129,7 @@ static int das08_cs_attach(comedi_device *dev,comedi_devconfig *it) #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); +module_param(pc_debug, int, 0644); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)"; diff --git a/comedi/drivers/ni_daq_dio24.c b/comedi/drivers/ni_daq_dio24.c index ee816342..f8baf838 100644 --- a/comedi/drivers/ni_daq_dio24.c +++ b/comedi/drivers/ni_daq_dio24.c @@ -210,7 +210,7 @@ static int dio24_detach(comedi_device *dev) */ #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); +module_param(pc_debug, int, 0644); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = "ni_daq_dio24.c, based on dummy_cs.c"; diff --git a/comedi/drivers/ni_labpc_cs.c b/comedi/drivers/ni_labpc_cs.c index 31dc5a33..e9d70787 100644 --- a/comedi/drivers/ni_labpc_cs.c +++ b/comedi/drivers/ni_labpc_cs.c @@ -144,7 +144,7 @@ static int labpc_attach(comedi_device *dev, comedi_devconfig *it) */ #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); +module_param(pc_debug, int, 0644); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13"; diff --git a/comedi/drivers/quatech_daqp_cs.c b/comedi/drivers/quatech_daqp_cs.c index 9cbbb325..ebf09573 100644 --- a/comedi/drivers/quatech_daqp_cs.c +++ b/comedi/drivers/quatech_daqp_cs.c @@ -67,7 +67,7 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308 #ifdef PCMCIA_DEBUG static int pc_debug = PCMCIA_DEBUG; -MODULE_PARM(pc_debug, "i"); +module_param(pc_debug, int, 0644); #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)"; @@ -154,10 +154,11 @@ static local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */ }; /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */ static u_int irq_mask = 0xdeb8; /* Newer, simpler way of listing specific interrupts */ -static int irq_list[4] = { -1 }; +#define IRQ_LIST_LEN 4 +static int irq_list[IRQ_LIST_LEN] = { -1 }; -MODULE_PARM(irq_mask, "i"); -MODULE_PARM(irq_list, "1-4i"); +module_param(irq_mask, uint, 0444); +MODULE_PARAM_ARRAY(irq_list, int, IRQ_LIST_LEN, 0444); /*====================================================================*/ diff --git a/include/linux/module.h b/include/linux/module.h index 661f34ee..d692a17b 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -34,6 +34,10 @@ static inline void module_put(struct module *module) #define MOD_IN_USE (0) #endif +#ifndef module_param +#include +#endif + #endif /* _COMPAT_MODULE_H */ diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h new file mode 100644 index 00000000..4fbbdb7b --- /dev/null +++ b/include/linux/moduleparam.h @@ -0,0 +1,104 @@ +/* + * moduleparam.h compatibility header + */ + +#ifndef _COMPAT_MODULEPARAM_H +#define _COMPAT_MODULEPARAM_H + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25) +/* We should have so include it. */ +/* (We don't care about 2.5 kernels.) */ +#include_next +#else +/* Need to fake contents of */ +#include + +#define module_param(name, type, perm) \ + static inline void *__check_existence_##name(void) { return &name; } \ + MODULE_PARM(name, _MODULE_PARM_STRING_##type) + +#define _MODULE_PARM_STRING_byte "b" +#define _MODULE_PARM_STRING_short "h" +#define _MODULE_PARM_STRING_ushort "h" +#define _MODULE_PARM_STRING_int "i" +#define _MODULE_PARM_STRING_uint "i" +#define _MODULE_PARM_STRING_long "l" +#define _MODULE_PARM_STRING_ulong "l" +#define _MODULE_PARM_STRING_bool "i" + +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + +/* + * Extend support for 2.4. + * + * Additionally supported: + * 'charp' parameters + * Not supported: + * 'invbool' parameters + * module_param_named() + * module_param_array() + * module_param_array_named() + */ + +/* Support charp parameters */ +#define _MODULE_PARM_STRING_charp "s" + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */ + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) +/* + * 2.6 kernels before 2.6.10 use an unsigned int lvalue for third parameter of + * module_param_array() instead of the pointer to unsigned int used in + * 2.6.10 onwards. Comedi code goes with 2.6.10, so cope with the change here. + * To make things more difficult, the pointer can be null and we need to + * substitute that with a pointer to a unique lvalue. + */ + +#undef module_param_array_named +#define module_param_array_named(name, array, type, nump, perm) \ + static unsigned int __missing_num_##name; \ + static struct kparam_array __param_arr_##name \ + = { ARRAY_SIZE(array), nump ?: &__missing_num_##name, \ + param_set_##type, param_get_##type, \ + sizeof(array[0]), array }; \ + module_param_call(name, param_array_set, param_array_get, \ + &__param_arr_##name, perm) + +#undef module_param_array +#define module_param_array(name, type, nump, perm) \ + module_param_array_named(name, name, type, nump, perm) + +#endif /* (L_V_C >= K_V(2,6,0)) && (L_V_C < K_V(2,6,10)) */ + +/* + * Define a Comedi-specific macro MODULE_PARAM_ARRAY(name,type,len,perm) + * supported on 2.4 and 2.6 kernels, because + * module_param_array(name,type,nump,perm) * is only available for 2.6. + * + * name - Name of module parameter and array variable. + * type - Module parameter type: byte, short, ushort, int, uint, long, ulong, + * bool, charp. Note that invbool is not supported. + * len - Length of array variable; needed for 2.4 kernel; ignored for 2.6 + * kernel. Note that this must be specified as a sequence of decimal + * digits or a macro that expands to a sequence of decimal digits. + * Using ARRAY_SIZE() or sizeof() is not allowed. + * perm - Permissions for module parameter in sysfs, e.g. 0444. Only used + * for 2.6 kernels. + */ +#ifdef module_param_array +#define MODULE_PARAM_ARRAY(name,type,len,perm) \ + module_param_array(name,type,0,perm) +#else +#define MODULE_PARAM_ARRAY(name,type,len,perm) \ + static inline void *__check_existence_##name(void) \ + { return &name[0]; } \ + MODULE_PARM(name, "1-" __MODULE_STRING(len) _MODULE_PARM_STRING_##type) +#endif /* module_param_array */ + +#endif /* _COMPAT_MODULEPARAM_H */ +