提交 9bbb9e5a 编写于 作者: R Rusty Russell

param: use ops in struct kernel_param, rather than get and set fns directly

This is more kernel-ish, saves some space, and also allows us to
expand the ops without breaking all the callers who are happy for the
new members to be NULL.

The few places which defined their own param types are changed to the
new scheme (more which crept in recently fixed in following patches).

Since we're touching them anyway, we change get() and set() to take a
const struct kernel_param (which they really are).  This causes some
harmless warnings until we fix them (in following patches).

To reduce churn, module_param_call creates the ops struct so the callers
don't have to change (and casts the functions to reduce warnings).
The modern version which takes an ops struct is called module_param_cb.
Signed-off-by: NRusty Russell <rusty@rustcorp.com.au>
Reviewed-by: NTakashi Iwai <tiwai@suse.de>
Tested-by: NPhil Carmody <ext-phil.2.carmody@nokia.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Ville Syrjala <syrjala@sci.fi>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Alessandro Rubini <rubini@ipvvis.unipv.it>
Cc: Michal Januszewski <spock@gentoo.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Neil Brown <neilb@suse.de>
Cc: linux-kernel@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-fbdev-devel@lists.sourceforge.net
Cc: linux-nfs@vger.kernel.org
Cc: netdev@vger.kernel.org
上级 a14fe249
...@@ -38,7 +38,8 @@ enum { ...@@ -38,7 +38,8 @@ enum {
}; };
static int ati_remote2_set_mask(const char *val, static int ati_remote2_set_mask(const char *val,
struct kernel_param *kp, unsigned int max) const struct kernel_param *kp,
unsigned int max)
{ {
unsigned long mask; unsigned long mask;
int ret; int ret;
...@@ -59,28 +60,31 @@ static int ati_remote2_set_mask(const char *val, ...@@ -59,28 +60,31 @@ static int ati_remote2_set_mask(const char *val,
} }
static int ati_remote2_set_channel_mask(const char *val, static int ati_remote2_set_channel_mask(const char *val,
struct kernel_param *kp) const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK); return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_CHANNEL_MASK);
} }
static int ati_remote2_get_channel_mask(char *buffer, struct kernel_param *kp) static int ati_remote2_get_channel_mask(char *buffer,
const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg);
} }
static int ati_remote2_set_mode_mask(const char *val, struct kernel_param *kp) static int ati_remote2_set_mode_mask(const char *val,
const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK); return ati_remote2_set_mask(val, kp, ATI_REMOTE2_MAX_MODE_MASK);
} }
static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) static int ati_remote2_get_mode_mask(char *buffer,
const struct kernel_param *kp)
{ {
pr_debug("%s()\n", __func__); pr_debug("%s()\n", __func__);
...@@ -89,15 +93,19 @@ static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp) ...@@ -89,15 +93,19 @@ static int ati_remote2_get_mode_mask(char *buffer, struct kernel_param *kp)
static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK;
#define param_check_channel_mask(name, p) __param_check(name, p, unsigned int) #define param_check_channel_mask(name, p) __param_check(name, p, unsigned int)
#define param_set_channel_mask ati_remote2_set_channel_mask static struct kernel_param_ops param_ops_channel_mask = {
#define param_get_channel_mask ati_remote2_get_channel_mask .set = ati_remote2_set_channel_mask,
.get = ati_remote2_get_channel_mask,
};
module_param(channel_mask, channel_mask, 0644); module_param(channel_mask, channel_mask, 0644);
MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>"); MODULE_PARM_DESC(channel_mask, "Bitmask of channels to accept <15:Channel16>...<1:Channel2><0:Channel1>");
static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK; static unsigned int mode_mask = ATI_REMOTE2_MAX_MODE_MASK;
#define param_check_mode_mask(name, p) __param_check(name, p, unsigned int) #define param_check_mode_mask(name, p) __param_check(name, p, unsigned int)
#define param_set_mode_mask ati_remote2_set_mode_mask static struct kernel_param_ops param_ops_mode_mask = {
#define param_get_mode_mask ati_remote2_get_mode_mask .set = ati_remote2_set_mode_mask,
.get = ati_remote2_get_mode_mask,
};
module_param(mode_mask, mode_mask, 0644); module_param(mode_mask, mode_mask, 0644);
MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>"); MODULE_PARM_DESC(mode_mask, "Bitmask of modes to accept <4:PC><3:AUX4><2:AUX3><1:AUX2><0:AUX1>");
......
...@@ -39,11 +39,13 @@ MODULE_DESCRIPTION(DRIVER_DESC); ...@@ -39,11 +39,13 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static unsigned int psmouse_max_proto = PSMOUSE_AUTO; static unsigned int psmouse_max_proto = PSMOUSE_AUTO;
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp); static int psmouse_set_maxproto(const char *val, const struct kernel_param *);
static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp); static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp);
static struct kernel_param_ops param_ops_proto_abbrev = {
.set = psmouse_set_maxproto,
.get = psmouse_get_maxproto,
};
#define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int) #define param_check_proto_abbrev(name, p) __param_check(name, p, unsigned int)
#define param_set_proto_abbrev psmouse_set_maxproto
#define param_get_proto_abbrev psmouse_get_maxproto
module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644); module_param_named(proto, psmouse_max_proto, proto_abbrev, 0644);
MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches."); MODULE_PARM_DESC(proto, "Highest protocol extension to probe (bare, imps, exps, any). Useful for KVM switches.");
...@@ -1679,7 +1681,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, ...@@ -1679,7 +1681,7 @@ static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data,
} }
static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) static int psmouse_set_maxproto(const char *val, const struct kernel_param *kp)
{ {
const struct psmouse_protocol *proto; const struct psmouse_protocol *proto;
...@@ -1696,7 +1698,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) ...@@ -1696,7 +1698,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp)
return 0; return 0;
} }
static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp) static int psmouse_get_maxproto(char *buffer, const struct kernel_param *kp)
{ {
int type = *((unsigned int *)kp->arg); int type = *((unsigned int *)kp->arg);
......
...@@ -1977,8 +1977,7 @@ static void __devexit uvesafb_exit(void) ...@@ -1977,8 +1977,7 @@ static void __devexit uvesafb_exit(void)
module_exit(uvesafb_exit); module_exit(uvesafb_exit);
#define param_get_scroll NULL static int param_set_scroll(const char *val, const struct kernel_param *kp)
static int param_set_scroll(const char *val, struct kernel_param *kp)
{ {
ypan = 0; ypan = 0;
...@@ -1993,7 +1992,9 @@ static int param_set_scroll(const char *val, struct kernel_param *kp) ...@@ -1993,7 +1992,9 @@ static int param_set_scroll(const char *val, struct kernel_param *kp)
return 0; return 0;
} }
static struct kernel_param_ops param_ops_scroll = {
.set = param_set_scroll,
};
#define param_check_scroll(name, p) __param_check(name, p, void) #define param_check_scroll(name, p) __param_check(name, p, void)
module_param_named(scroll, ypan, scroll, 0); module_param_named(scroll, ypan, scroll, 0);
......
...@@ -45,7 +45,7 @@ unsigned short nfs_callback_tcpport; ...@@ -45,7 +45,7 @@ unsigned short nfs_callback_tcpport;
unsigned short nfs_callback_tcpport6; unsigned short nfs_callback_tcpport6;
#define NFS_CALLBACK_MAXPORTNR (65535U) #define NFS_CALLBACK_MAXPORTNR (65535U)
static int param_set_portnr(const char *val, struct kernel_param *kp) static int param_set_portnr(const char *val, const struct kernel_param *kp)
{ {
unsigned long num; unsigned long num;
int ret; int ret;
...@@ -58,11 +58,10 @@ static int param_set_portnr(const char *val, struct kernel_param *kp) ...@@ -58,11 +58,10 @@ static int param_set_portnr(const char *val, struct kernel_param *kp)
*((unsigned int *)kp->arg) = num; *((unsigned int *)kp->arg) = num;
return 0; return 0;
} }
static struct kernel_param_ops param_ops_portnr = {
static int param_get_portnr(char *buffer, struct kernel_param *kp) .set = param_set_portnr,
{ .get = param_get_uint,
return param_get_uint(buffer, kp); };
}
#define param_check_portnr(name, p) __param_check(name, p, unsigned int); #define param_check_portnr(name, p) __param_check(name, p, unsigned int);
module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
......
...@@ -31,20 +31,21 @@ static const char __module_cat(name,__LINE__)[] \ ...@@ -31,20 +31,21 @@ static const char __module_cat(name,__LINE__)[] \
struct kernel_param; struct kernel_param;
/* Returns 0, or -errno. arg is in kp->arg. */ struct kernel_param_ops {
typedef int (*param_set_fn)(const char *val, struct kernel_param *kp); /* Returns 0, or -errno. arg is in kp->arg. */
/* Returns length written or -errno. Buffer is 4k (ie. be short!) */ int (*set)(const char *val, const struct kernel_param *kp);
typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp); /* Returns length written or -errno. Buffer is 4k (ie. be short!) */
int (*get)(char *buffer, const struct kernel_param *kp);
};
/* Flag bits for kernel_param.flags */ /* Flag bits for kernel_param.flags */
#define KPARAM_ISBOOL 2 #define KPARAM_ISBOOL 2
struct kernel_param { struct kernel_param {
const char *name; const char *name;
const struct kernel_param_ops *ops;
u16 perm; u16 perm;
u16 flags; u16 flags;
param_set_fn set;
param_get_fn get;
union { union {
void *arg; void *arg;
const struct kparam_string *str; const struct kparam_string *str;
...@@ -63,8 +64,7 @@ struct kparam_array ...@@ -63,8 +64,7 @@ struct kparam_array
{ {
unsigned int max; unsigned int max;
unsigned int *num; unsigned int *num;
param_set_fn set; const struct kernel_param_ops *ops;
param_get_fn get;
unsigned int elemsize; unsigned int elemsize;
void *elem; void *elem;
}; };
...@@ -83,7 +83,7 @@ struct kparam_array ...@@ -83,7 +83,7 @@ struct kparam_array
parameters. perm sets the visibility in sysfs: 000 means it's parameters. perm sets the visibility in sysfs: 000 means it's
not there, read bits mean it's readable, write bits mean it's not there, read bits mean it's readable, write bits mean it's
writable. */ writable. */
#define __module_param_call(prefix, name, set, get, arg, isbool, perm) \ #define __module_param_call(prefix, name, ops, arg, isbool, perm) \
/* Default value instead of permissions? */ \ /* Default value instead of permissions? */ \
static int __param_perm_check_##name __attribute__((unused)) = \ static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \
...@@ -92,20 +92,37 @@ struct kparam_array ...@@ -92,20 +92,37 @@ struct kparam_array
static struct kernel_param __moduleparam_const __param_##name \ static struct kernel_param __moduleparam_const __param_##name \
__used \ __used \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \ __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, perm, isbool ? KPARAM_ISBOOL : 0, \ = { __param_str_##name, ops, perm, isbool ? KPARAM_ISBOOL : 0, \
set, get, { arg } } { arg } }
/* Obsolete - use module_param_cb() */
#define module_param_call(name, set, get, arg, perm) \
static struct kernel_param_ops __param_ops_##name = \
{ (void *)set, (void *)get }; \
__module_param_call(MODULE_PARAM_PREFIX, \
name, &__param_ops_##name, arg, \
__same_type(*(arg), bool), \
(perm) + sizeof(__check_old_set_param(set))*0)
/* We don't get oldget: it's often a new-style param_get_uint, etc. */
static inline int
__check_old_set_param(int (*oldset)(const char *, struct kernel_param *))
{
return 0;
}
#define module_param_call(name, set, get, arg, perm) \ #define module_param_cb(name, ops, arg, perm) \
__module_param_call(MODULE_PARAM_PREFIX, \ __module_param_call(MODULE_PARAM_PREFIX, \
name, set, get, arg, \ name, ops, arg, __same_type(*(arg), bool), perm)
__same_type(*(arg), bool), perm)
/* Helper functions: type is byte, short, ushort, int, uint, long, /*
ulong, charp, bool or invbool, or XXX if you define param_get_XXX, * Helper functions: type is byte, short, ushort, int, uint, long,
param_set_XXX and param_check_XXX. */ * ulong, charp, bool or invbool, or XXX if you define param_ops_XXX
* and param_check_XXX.
*/
#define module_param_named(name, value, type, perm) \ #define module_param_named(name, value, type, perm) \
param_check_##type(name, &(value)); \ param_check_##type(name, &(value)); \
module_param_call(name, param_set_##type, param_get_##type, &value, perm); \ module_param_cb(name, &param_ops_##type, &value, perm); \
__MODULE_PARM_TYPE(name, #type) __MODULE_PARM_TYPE(name, #type)
#define module_param(name, type, perm) \ #define module_param(name, type, perm) \
...@@ -126,7 +143,7 @@ struct kparam_array ...@@ -126,7 +143,7 @@ struct kparam_array
*/ */
#define core_param(name, var, type, perm) \ #define core_param(name, var, type, perm) \
param_check_##type(name, &(var)); \ param_check_##type(name, &(var)); \
__module_param_call("", name, param_set_##type, param_get_##type, \ __module_param_call("", name, &param_ops_##type, \
&var, __same_type(var, bool), perm) &var, __same_type(var, bool), perm)
#endif /* !MODULE */ #endif /* !MODULE */
...@@ -135,7 +152,7 @@ struct kparam_array ...@@ -135,7 +152,7 @@ struct kparam_array
static const struct kparam_string __param_string_##name \ static const struct kparam_string __param_string_##name \
= { len, string }; \ = { len, string }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \ __module_param_call(MODULE_PARAM_PREFIX, name, \
param_set_copystring, param_get_string, \ &param_ops_string, \
.str = &__param_string_##name, 0, perm); \ .str = &__param_string_##name, 0, perm); \
__MODULE_PARM_TYPE(name, "string") __MODULE_PARM_TYPE(name, "string")
...@@ -162,41 +179,50 @@ static inline void destroy_params(const struct kernel_param *params, ...@@ -162,41 +179,50 @@ static inline void destroy_params(const struct kernel_param *params,
#define __param_check(name, p, type) \ #define __param_check(name, p, type) \
static inline type *__check_##name(void) { return(p); } static inline type *__check_##name(void) { return(p); }
extern int param_set_byte(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_byte;
extern int param_get_byte(char *buffer, struct kernel_param *kp); extern int param_set_byte(const char *val, const struct kernel_param *kp);
extern int param_get_byte(char *buffer, const struct kernel_param *kp);
#define param_check_byte(name, p) __param_check(name, p, unsigned char) #define param_check_byte(name, p) __param_check(name, p, unsigned char)
extern int param_set_short(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_short;
extern int param_get_short(char *buffer, struct kernel_param *kp); extern int param_set_short(const char *val, const struct kernel_param *kp);
extern int param_get_short(char *buffer, const struct kernel_param *kp);
#define param_check_short(name, p) __param_check(name, p, short) #define param_check_short(name, p) __param_check(name, p, short)
extern int param_set_ushort(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_ushort;
extern int param_get_ushort(char *buffer, struct kernel_param *kp); extern int param_set_ushort(const char *val, const struct kernel_param *kp);
extern int param_get_ushort(char *buffer, const struct kernel_param *kp);
#define param_check_ushort(name, p) __param_check(name, p, unsigned short) #define param_check_ushort(name, p) __param_check(name, p, unsigned short)
extern int param_set_int(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_int;
extern int param_get_int(char *buffer, struct kernel_param *kp); extern int param_set_int(const char *val, const struct kernel_param *kp);
extern int param_get_int(char *buffer, const struct kernel_param *kp);
#define param_check_int(name, p) __param_check(name, p, int) #define param_check_int(name, p) __param_check(name, p, int)
extern int param_set_uint(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_uint;
extern int param_get_uint(char *buffer, struct kernel_param *kp); extern int param_set_uint(const char *val, const struct kernel_param *kp);
extern int param_get_uint(char *buffer, const struct kernel_param *kp);
#define param_check_uint(name, p) __param_check(name, p, unsigned int) #define param_check_uint(name, p) __param_check(name, p, unsigned int)
extern int param_set_long(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_long;
extern int param_get_long(char *buffer, struct kernel_param *kp); extern int param_set_long(const char *val, const struct kernel_param *kp);
extern int param_get_long(char *buffer, const struct kernel_param *kp);
#define param_check_long(name, p) __param_check(name, p, long) #define param_check_long(name, p) __param_check(name, p, long)
extern int param_set_ulong(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_ulong;
extern int param_get_ulong(char *buffer, struct kernel_param *kp); extern int param_set_ulong(const char *val, const struct kernel_param *kp);
extern int param_get_ulong(char *buffer, const struct kernel_param *kp);
#define param_check_ulong(name, p) __param_check(name, p, unsigned long) #define param_check_ulong(name, p) __param_check(name, p, unsigned long)
extern int param_set_charp(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_charp;
extern int param_get_charp(char *buffer, struct kernel_param *kp); extern int param_set_charp(const char *val, const struct kernel_param *kp);
extern int param_get_charp(char *buffer, const struct kernel_param *kp);
#define param_check_charp(name, p) __param_check(name, p, char *) #define param_check_charp(name, p) __param_check(name, p, char *)
/* For historical reasons "bool" parameters can be (unsigned) "int". */ /* For historical reasons "bool" parameters can be (unsigned) "int". */
extern int param_set_bool(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_bool;
extern int param_get_bool(char *buffer, struct kernel_param *kp); extern int param_set_bool(const char *val, const struct kernel_param *kp);
extern int param_get_bool(char *buffer, const struct kernel_param *kp);
#define param_check_bool(name, p) \ #define param_check_bool(name, p) \
static inline void __check_##name(void) \ static inline void __check_##name(void) \
{ \ { \
...@@ -205,17 +231,18 @@ extern int param_get_bool(char *buffer, struct kernel_param *kp); ...@@ -205,17 +231,18 @@ extern int param_get_bool(char *buffer, struct kernel_param *kp);
!__same_type(*(p), int)); \ !__same_type(*(p), int)); \
} }
extern int param_set_invbool(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_invbool;
extern int param_get_invbool(char *buffer, struct kernel_param *kp); extern int param_set_invbool(const char *val, const struct kernel_param *kp);
extern int param_get_invbool(char *buffer, const struct kernel_param *kp);
#define param_check_invbool(name, p) __param_check(name, p, bool) #define param_check_invbool(name, p) __param_check(name, p, bool)
/* Comma-separated array: *nump is set to number they actually specified. */ /* Comma-separated array: *nump is set to number they actually specified. */
#define module_param_array_named(name, array, type, nump, perm) \ #define module_param_array_named(name, array, type, nump, perm) \
static const struct kparam_array __param_arr_##name \ static const struct kparam_array __param_arr_##name \
= { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,\ = { ARRAY_SIZE(array), nump, &param_ops_##type, \
sizeof(array[0]), array }; \ sizeof(array[0]), array }; \
__module_param_call(MODULE_PARAM_PREFIX, name, \ __module_param_call(MODULE_PARAM_PREFIX, name, \
param_array_set, param_array_get, \ &param_array_ops, \
.arr = &__param_arr_##name, \ .arr = &__param_arr_##name, \
__same_type(array[0], bool), perm); \ __same_type(array[0], bool), perm); \
__MODULE_PARM_TYPE(name, "array of " #type) __MODULE_PARM_TYPE(name, "array of " #type)
...@@ -223,11 +250,11 @@ extern int param_get_invbool(char *buffer, struct kernel_param *kp); ...@@ -223,11 +250,11 @@ extern int param_get_invbool(char *buffer, struct kernel_param *kp);
#define module_param_array(name, type, nump, perm) \ #define module_param_array(name, type, nump, perm) \
module_param_array_named(name, name, type, nump, perm) module_param_array_named(name, name, type, nump, perm)
extern int param_array_set(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_array_ops;
extern int param_array_get(char *buffer, struct kernel_param *kp);
extern int param_set_copystring(const char *val, struct kernel_param *kp); extern struct kernel_param_ops param_ops_string;
extern int param_get_string(char *buffer, struct kernel_param *kp); extern int param_set_copystring(const char *val, const struct kernel_param *);
extern int param_get_string(char *buffer, const struct kernel_param *kp);
/* for exporting parameters in /sys/parameters */ /* for exporting parameters in /sys/parameters */
...@@ -235,13 +262,13 @@ struct module; ...@@ -235,13 +262,13 @@ struct module;
#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES) #if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
extern int module_param_sysfs_setup(struct module *mod, extern int module_param_sysfs_setup(struct module *mod,
struct kernel_param *kparam, const struct kernel_param *kparam,
unsigned int num_params); unsigned int num_params);
extern void module_param_sysfs_remove(struct module *mod); extern void module_param_sysfs_remove(struct module *mod);
#else #else
static inline int module_param_sysfs_setup(struct module *mod, static inline int module_param_sysfs_setup(struct module *mod,
struct kernel_param *kparam, const struct kernel_param *kparam,
unsigned int num_params) unsigned int num_params)
{ {
return 0; return 0;
......
...@@ -59,11 +59,11 @@ static int parse_one(char *param, ...@@ -59,11 +59,11 @@ static int parse_one(char *param,
for (i = 0; i < num_params; i++) { for (i = 0; i < num_params; i++) {
if (parameq(param, params[i].name)) { if (parameq(param, params[i].name)) {
/* Noone handled NULL, so do it here. */ /* Noone handled NULL, so do it here. */
if (!val && params[i].set != param_set_bool) if (!val && params[i].ops->set != param_set_bool)
return -EINVAL; return -EINVAL;
DEBUGP("They are equal! Calling %p\n", DEBUGP("They are equal! Calling %p\n",
params[i].set); params[i].ops->set);
return params[i].set(val, &params[i]); return params[i].ops->set(val, &params[i]);
} }
} }
...@@ -179,7 +179,7 @@ int parse_args(const char *name, ...@@ -179,7 +179,7 @@ int parse_args(const char *name,
/* Lazy bastard, eh? */ /* Lazy bastard, eh? */
#define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \
int param_set_##name(const char *val, struct kernel_param *kp) \ int param_set_##name(const char *val, const struct kernel_param *kp) \
{ \ { \
tmptype l; \ tmptype l; \
int ret; \ int ret; \
...@@ -190,12 +190,18 @@ int parse_args(const char *name, ...@@ -190,12 +190,18 @@ int parse_args(const char *name,
*((type *)kp->arg) = l; \ *((type *)kp->arg) = l; \
return 0; \ return 0; \
} \ } \
int param_get_##name(char *buffer, struct kernel_param *kp) \ int param_get_##name(char *buffer, const struct kernel_param *kp) \
{ \ { \
return sprintf(buffer, format, *((type *)kp->arg)); \ return sprintf(buffer, format, *((type *)kp->arg)); \
} \ } \
struct kernel_param_ops param_ops_##name = { \
.set = param_set_##name, \
.get = param_get_##name, \
}; \
EXPORT_SYMBOL(param_set_##name); \ EXPORT_SYMBOL(param_set_##name); \
EXPORT_SYMBOL(param_get_##name) EXPORT_SYMBOL(param_get_##name); \
EXPORT_SYMBOL(param_ops_##name)
STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol);
...@@ -205,7 +211,7 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul); ...@@ -205,7 +211,7 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul);
STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol);
STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul);
int param_set_charp(const char *val, struct kernel_param *kp) int param_set_charp(const char *val, const struct kernel_param *kp)
{ {
if (strlen(val) > 1024) { if (strlen(val) > 1024) {
printk(KERN_ERR "%s: string parameter too long\n", printk(KERN_ERR "%s: string parameter too long\n",
...@@ -226,14 +232,20 @@ int param_set_charp(const char *val, struct kernel_param *kp) ...@@ -226,14 +232,20 @@ int param_set_charp(const char *val, struct kernel_param *kp)
} }
EXPORT_SYMBOL(param_set_charp); EXPORT_SYMBOL(param_set_charp);
int param_get_charp(char *buffer, struct kernel_param *kp) int param_get_charp(char *buffer, const struct kernel_param *kp)
{ {
return sprintf(buffer, "%s", *((char **)kp->arg)); return sprintf(buffer, "%s", *((char **)kp->arg));
} }
EXPORT_SYMBOL(param_get_charp); EXPORT_SYMBOL(param_get_charp);
struct kernel_param_ops param_ops_charp = {
.set = param_set_charp,
.get = param_get_charp,
};
EXPORT_SYMBOL(param_ops_charp);
/* Actually could be a bool or an int, for historical reasons. */ /* Actually could be a bool or an int, for historical reasons. */
int param_set_bool(const char *val, struct kernel_param *kp) int param_set_bool(const char *val, const struct kernel_param *kp)
{ {
bool v; bool v;
...@@ -260,7 +272,7 @@ int param_set_bool(const char *val, struct kernel_param *kp) ...@@ -260,7 +272,7 @@ int param_set_bool(const char *val, struct kernel_param *kp)
} }
EXPORT_SYMBOL(param_set_bool); EXPORT_SYMBOL(param_set_bool);
int param_get_bool(char *buffer, struct kernel_param *kp) int param_get_bool(char *buffer, const struct kernel_param *kp)
{ {
bool val; bool val;
if (kp->flags & KPARAM_ISBOOL) if (kp->flags & KPARAM_ISBOOL)
...@@ -273,8 +285,14 @@ int param_get_bool(char *buffer, struct kernel_param *kp) ...@@ -273,8 +285,14 @@ int param_get_bool(char *buffer, struct kernel_param *kp)
} }
EXPORT_SYMBOL(param_get_bool); EXPORT_SYMBOL(param_get_bool);
struct kernel_param_ops param_ops_bool = {
.set = param_set_bool,
.get = param_get_bool,
};
EXPORT_SYMBOL(param_ops_bool);
/* This one must be bool. */ /* This one must be bool. */
int param_set_invbool(const char *val, struct kernel_param *kp) int param_set_invbool(const char *val, const struct kernel_param *kp)
{ {
int ret; int ret;
bool boolval; bool boolval;
...@@ -289,18 +307,24 @@ int param_set_invbool(const char *val, struct kernel_param *kp) ...@@ -289,18 +307,24 @@ int param_set_invbool(const char *val, struct kernel_param *kp)
} }
EXPORT_SYMBOL(param_set_invbool); EXPORT_SYMBOL(param_set_invbool);
int param_get_invbool(char *buffer, struct kernel_param *kp) int param_get_invbool(char *buffer, const struct kernel_param *kp)
{ {
return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
} }
EXPORT_SYMBOL(param_get_invbool); EXPORT_SYMBOL(param_get_invbool);
struct kernel_param_ops param_ops_invbool = {
.set = param_set_invbool,
.get = param_get_invbool,
};
EXPORT_SYMBOL(param_ops_invbool);
/* We break the rule and mangle the string. */ /* We break the rule and mangle the string. */
static int param_array(const char *name, static int param_array(const char *name,
const char *val, const char *val,
unsigned int min, unsigned int max, unsigned int min, unsigned int max,
void *elem, int elemsize, void *elem, int elemsize,
int (*set)(const char *, struct kernel_param *kp), int (*set)(const char *, const struct kernel_param *kp),
u16 flags, u16 flags,
unsigned int *num) unsigned int *num)
{ {
...@@ -345,18 +369,17 @@ static int param_array(const char *name, ...@@ -345,18 +369,17 @@ static int param_array(const char *name,
return 0; return 0;
} }
int param_array_set(const char *val, struct kernel_param *kp) static int param_array_set(const char *val, const struct kernel_param *kp)
{ {
const struct kparam_array *arr = kp->arr; const struct kparam_array *arr = kp->arr;
unsigned int temp_num; unsigned int temp_num;
return param_array(kp->name, val, 1, arr->max, arr->elem, return param_array(kp->name, val, 1, arr->max, arr->elem,
arr->elemsize, arr->set, kp->flags, arr->elemsize, arr->ops->set, kp->flags,
arr->num ?: &temp_num); arr->num ?: &temp_num);
} }
EXPORT_SYMBOL(param_array_set);
int param_array_get(char *buffer, struct kernel_param *kp) static int param_array_get(char *buffer, const struct kernel_param *kp)
{ {
int i, off, ret; int i, off, ret;
const struct kparam_array *arr = kp->arr; const struct kparam_array *arr = kp->arr;
...@@ -367,7 +390,7 @@ int param_array_get(char *buffer, struct kernel_param *kp) ...@@ -367,7 +390,7 @@ int param_array_get(char *buffer, struct kernel_param *kp)
if (i) if (i)
buffer[off++] = ','; buffer[off++] = ',';
p.arg = arr->elem + arr->elemsize * i; p.arg = arr->elem + arr->elemsize * i;
ret = arr->get(buffer + off, &p); ret = arr->ops->get(buffer + off, &p);
if (ret < 0) if (ret < 0)
return ret; return ret;
off += ret; off += ret;
...@@ -375,9 +398,14 @@ int param_array_get(char *buffer, struct kernel_param *kp) ...@@ -375,9 +398,14 @@ int param_array_get(char *buffer, struct kernel_param *kp)
buffer[off] = '\0'; buffer[off] = '\0';
return off; return off;
} }
EXPORT_SYMBOL(param_array_get);
int param_set_copystring(const char *val, struct kernel_param *kp) struct kernel_param_ops param_array_ops = {
.set = param_array_set,
.get = param_array_get,
};
EXPORT_SYMBOL(param_array_ops);
int param_set_copystring(const char *val, const struct kernel_param *kp)
{ {
const struct kparam_string *kps = kp->str; const struct kparam_string *kps = kp->str;
...@@ -391,13 +419,19 @@ int param_set_copystring(const char *val, struct kernel_param *kp) ...@@ -391,13 +419,19 @@ int param_set_copystring(const char *val, struct kernel_param *kp)
} }
EXPORT_SYMBOL(param_set_copystring); EXPORT_SYMBOL(param_set_copystring);
int param_get_string(char *buffer, struct kernel_param *kp) int param_get_string(char *buffer, const struct kernel_param *kp)
{ {
const struct kparam_string *kps = kp->str; const struct kparam_string *kps = kp->str;
return strlcpy(buffer, kps->string, kps->maxlen); return strlcpy(buffer, kps->string, kps->maxlen);
} }
EXPORT_SYMBOL(param_get_string); EXPORT_SYMBOL(param_get_string);
struct kernel_param_ops param_ops_string = {
.set = param_set_copystring,
.get = param_get_string,
};
EXPORT_SYMBOL(param_ops_string);
/* sysfs output in /sys/modules/XYZ/parameters/ */ /* sysfs output in /sys/modules/XYZ/parameters/ */
#define to_module_attr(n) container_of(n, struct module_attribute, attr) #define to_module_attr(n) container_of(n, struct module_attribute, attr)
#define to_module_kobject(n) container_of(n, struct module_kobject, kobj) #define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
...@@ -407,7 +441,7 @@ extern struct kernel_param __start___param[], __stop___param[]; ...@@ -407,7 +441,7 @@ extern struct kernel_param __start___param[], __stop___param[];
struct param_attribute struct param_attribute
{ {
struct module_attribute mattr; struct module_attribute mattr;
struct kernel_param *param; const struct kernel_param *param;
}; };
struct module_param_attrs struct module_param_attrs
...@@ -426,10 +460,10 @@ static ssize_t param_attr_show(struct module_attribute *mattr, ...@@ -426,10 +460,10 @@ static ssize_t param_attr_show(struct module_attribute *mattr,
int count; int count;
struct param_attribute *attribute = to_param_attr(mattr); struct param_attribute *attribute = to_param_attr(mattr);
if (!attribute->param->get) if (!attribute->param->ops->get)
return -EPERM; return -EPERM;
count = attribute->param->get(buf, attribute->param); count = attribute->param->ops->get(buf, attribute->param);
if (count > 0) { if (count > 0) {
strcat(buf, "\n"); strcat(buf, "\n");
++count; ++count;
...@@ -445,10 +479,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr, ...@@ -445,10 +479,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
int err; int err;
struct param_attribute *attribute = to_param_attr(mattr); struct param_attribute *attribute = to_param_attr(mattr);
if (!attribute->param->set) if (!attribute->param->ops->set)
return -EPERM; return -EPERM;
err = attribute->param->set(buf, attribute->param); err = attribute->param->ops->set(buf, attribute->param);
if (!err) if (!err)
return len; return len;
return err; return err;
...@@ -473,7 +507,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, ...@@ -473,7 +507,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
* if there's an error. * if there's an error.
*/ */
static __modinit int add_sysfs_param(struct module_kobject *mk, static __modinit int add_sysfs_param(struct module_kobject *mk,
struct kernel_param *kp, const struct kernel_param *kp,
const char *name) const char *name)
{ {
struct module_param_attrs *new; struct module_param_attrs *new;
...@@ -555,7 +589,7 @@ static void free_module_param_attrs(struct module_kobject *mk) ...@@ -555,7 +589,7 @@ static void free_module_param_attrs(struct module_kobject *mk)
* /sys/module/[mod->name]/parameters/ * /sys/module/[mod->name]/parameters/
*/ */
int module_param_sysfs_setup(struct module *mod, int module_param_sysfs_setup(struct module *mod,
struct kernel_param *kparam, const struct kernel_param *kparam,
unsigned int num_params) unsigned int num_params)
{ {
int i, err; int i, err;
......
...@@ -2577,7 +2577,8 @@ void cleanup_socket_xprt(void) ...@@ -2577,7 +2577,8 @@ void cleanup_socket_xprt(void)
xprt_unregister_transport(&xs_bc_tcp_transport); xprt_unregister_transport(&xs_bc_tcp_transport);
} }
static int param_set_uint_minmax(const char *val, struct kernel_param *kp, static int param_set_uint_minmax(const char *val,
const struct kernel_param *kp,
unsigned int min, unsigned int max) unsigned int min, unsigned int max)
{ {
unsigned long num; unsigned long num;
...@@ -2592,34 +2593,37 @@ static int param_set_uint_minmax(const char *val, struct kernel_param *kp, ...@@ -2592,34 +2593,37 @@ static int param_set_uint_minmax(const char *val, struct kernel_param *kp,
return 0; return 0;
} }
static int param_set_portnr(const char *val, struct kernel_param *kp) static int param_set_portnr(const char *val, const struct kernel_param *kp)
{ {
return param_set_uint_minmax(val, kp, return param_set_uint_minmax(val, kp,
RPC_MIN_RESVPORT, RPC_MIN_RESVPORT,
RPC_MAX_RESVPORT); RPC_MAX_RESVPORT);
} }
static int param_get_portnr(char *buffer, struct kernel_param *kp) static struct kernel_param_ops param_ops_portnr = {
{ .set = param_set_portnr,
return param_get_uint(buffer, kp); .get = param_get_uint,
} };
#define param_check_portnr(name, p) \ #define param_check_portnr(name, p) \
__param_check(name, p, unsigned int); __param_check(name, p, unsigned int);
module_param_named(min_resvport, xprt_min_resvport, portnr, 0644); module_param_named(min_resvport, xprt_min_resvport, portnr, 0644);
module_param_named(max_resvport, xprt_max_resvport, portnr, 0644); module_param_named(max_resvport, xprt_max_resvport, portnr, 0644);
static int param_set_slot_table_size(const char *val, struct kernel_param *kp) static int param_set_slot_table_size(const char *val,
const struct kernel_param *kp)
{ {
return param_set_uint_minmax(val, kp, return param_set_uint_minmax(val, kp,
RPC_MIN_SLOT_TABLE, RPC_MIN_SLOT_TABLE,
RPC_MAX_SLOT_TABLE); RPC_MAX_SLOT_TABLE);
} }
static int param_get_slot_table_size(char *buffer, struct kernel_param *kp) static struct kernel_param_ops param_ops_slot_table_size = {
{ .set = param_set_slot_table_size,
return param_get_uint(buffer, kp); .get = param_get_uint,
} };
#define param_check_slot_table_size(name, p) \ #define param_check_slot_table_size(name, p) \
__param_check(name, p, unsigned int); __param_check(name, p, unsigned int);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册