Commit ecc86170 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by Greg Kroah-Hartman

module: add extra argument for parse_params() callback

This adds an extra argument onto parse_params() to be used
as a way to make the unused callback a bit more useful and
generic by allowing the caller to pass on a data structure
of its choice. An example use case is to allow us to easily
make module parameters for every module which we will do
next.

@ parse @
identifier name, args, params, num, level_min, level_max;
identifier unknown, param, val, doing;
type s16;
@@
 extern char *parse_args(const char *name,
 			 char *args,
 			 const struct kernel_param *params,
 			 unsigned num,
 			 s16 level_min,
 			 s16 level_max,
+			 void *arg,
 			 int (*unknown)(char *param, char *val,
					const char *doing
+					, void *arg
					));

@ parse_mod @
identifier name, args, params, num, level_min, level_max;
identifier unknown, param, val, doing;
type s16;
@@
 char *parse_args(const char *name,
 			 char *args,
 			 const struct kernel_param *params,
 			 unsigned num,
 			 s16 level_min,
 			 s16 level_max,
+			 void *arg,
 			 int (*unknown)(char *param, char *val,
					const char *doing
+					, void *arg
					))
{
	...
}

@ parse_args_found @
expression R, E1, E2, E3, E4, E5, E6;
identifier func;
@@

(
	R =
	parse_args(E1, E2, E3, E4, E5, E6,
+		   NULL,
		   func);
|
	R =
	parse_args(E1, E2, E3, E4, E5, E6,
+		   NULL,
		   &func);
|
	R =
	parse_args(E1, E2, E3, E4, E5, E6,
+		   NULL,
		   NULL);
|
	parse_args(E1, E2, E3, E4, E5, E6,
+		   NULL,
		   func);
|
	parse_args(E1, E2, E3, E4, E5, E6,
+		   NULL,
		   &func);
|
	parse_args(E1, E2, E3, E4, E5, E6,
+		   NULL,
		   NULL);
)

@ parse_args_unused depends on parse_args_found @
identifier parse_args_found.func;
@@

int func(char *param, char *val, const char *unused
+		 , void *arg
		 )
{
	...
}

@ mod_unused depends on parse_args_found @
identifier parse_args_found.func;
expression A1, A2, A3;
@@

-	func(A1, A2, A3);
+	func(A1, A2, A3, NULL);

Generated-by: Coccinelle SmPL
Cc: cocci@systeme.lip6.fr
Cc: Tejun Heo <tj@kernel.org>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Felipe Contreras <felipe.contreras@gmail.com>
Cc: Ewan Milne <emilne@redhat.com>
Cc: Jean Delvare <jdelvare@suse.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Jani Nikula <jani.nikula@intel.com>
Cc: linux-kernel@vger.kernel.org
Reviewed-by: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarRusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarLuis R. Rodriguez <mcgrof@suse.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6570a9a1
...@@ -336,7 +336,7 @@ int alloc_bootmem_huge_page(struct hstate *hstate) ...@@ -336,7 +336,7 @@ int alloc_bootmem_huge_page(struct hstate *hstate)
unsigned long gpage_npages[MMU_PAGE_COUNT]; unsigned long gpage_npages[MMU_PAGE_COUNT];
static int __init do_gpage_early_setup(char *param, char *val, static int __init do_gpage_early_setup(char *param, char *val,
const char *unused) const char *unused, void *arg)
{ {
static phys_addr_t size; static phys_addr_t size;
unsigned long npages; unsigned long npages;
...@@ -385,7 +385,7 @@ void __init reserve_hugetlb_gpages(void) ...@@ -385,7 +385,7 @@ void __init reserve_hugetlb_gpages(void)
strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE); strlcpy(cmdline, boot_command_line, COMMAND_LINE_SIZE);
parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0, parse_args("hugetlb gpages", cmdline, NULL, 0, 0, 0,
&do_gpage_early_setup); NULL, &do_gpage_early_setup);
/* /*
* Walk gpage list in reverse, allocating larger page sizes first. * Walk gpage list in reverse, allocating larger page sizes first.
......
...@@ -357,8 +357,9 @@ extern char *parse_args(const char *name, ...@@ -357,8 +357,9 @@ extern char *parse_args(const char *name,
unsigned num, unsigned num,
s16 level_min, s16 level_min,
s16 level_max, s16 level_max,
void *arg,
int (*unknown)(char *param, char *val, int (*unknown)(char *param, char *val,
const char *doing)); const char *doing, void *arg));
/* Called by module remove. */ /* Called by module remove. */
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
......
...@@ -235,7 +235,8 @@ static int __init loglevel(char *str) ...@@ -235,7 +235,8 @@ static int __init loglevel(char *str)
early_param("loglevel", loglevel); early_param("loglevel", loglevel);
/* Change NUL term back to "=", to make "param" the whole string. */ /* Change NUL term back to "=", to make "param" the whole string. */
static int __init repair_env_string(char *param, char *val, const char *unused) static int __init repair_env_string(char *param, char *val,
const char *unused, void *arg)
{ {
if (val) { if (val) {
/* param=val or param="val"? */ /* param=val or param="val"? */
...@@ -252,14 +253,15 @@ static int __init repair_env_string(char *param, char *val, const char *unused) ...@@ -252,14 +253,15 @@ static int __init repair_env_string(char *param, char *val, const char *unused)
} }
/* Anything after -- gets handed straight to init. */ /* Anything after -- gets handed straight to init. */
static int __init set_init_arg(char *param, char *val, const char *unused) static int __init set_init_arg(char *param, char *val,
const char *unused, void *arg)
{ {
unsigned int i; unsigned int i;
if (panic_later) if (panic_later)
return 0; return 0;
repair_env_string(param, val, unused); repair_env_string(param, val, unused, NULL);
for (i = 0; argv_init[i]; i++) { for (i = 0; argv_init[i]; i++) {
if (i == MAX_INIT_ARGS) { if (i == MAX_INIT_ARGS) {
...@@ -276,9 +278,10 @@ static int __init set_init_arg(char *param, char *val, const char *unused) ...@@ -276,9 +278,10 @@ static int __init set_init_arg(char *param, char *val, const char *unused)
* Unknown boot options get handed to init, unless they look like * Unknown boot options get handed to init, unless they look like
* unused parameters (modprobe will find them in /proc/cmdline). * unused parameters (modprobe will find them in /proc/cmdline).
*/ */
static int __init unknown_bootoption(char *param, char *val, const char *unused) static int __init unknown_bootoption(char *param, char *val,
const char *unused, void *arg)
{ {
repair_env_string(param, val, unused); repair_env_string(param, val, unused, NULL);
/* Handle obsolete-style parameters */ /* Handle obsolete-style parameters */
if (obsolete_checksetup(param)) if (obsolete_checksetup(param))
...@@ -410,7 +413,8 @@ static noinline void __init_refok rest_init(void) ...@@ -410,7 +413,8 @@ static noinline void __init_refok rest_init(void)
} }
/* Check for early params. */ /* Check for early params. */
static int __init do_early_param(char *param, char *val, const char *unused) static int __init do_early_param(char *param, char *val,
const char *unused, void *arg)
{ {
const struct obs_kernel_param *p; const struct obs_kernel_param *p;
...@@ -429,7 +433,8 @@ static int __init do_early_param(char *param, char *val, const char *unused) ...@@ -429,7 +433,8 @@ static int __init do_early_param(char *param, char *val, const char *unused)
void __init parse_early_options(char *cmdline) void __init parse_early_options(char *cmdline)
{ {
parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param); parse_args("early options", cmdline, NULL, 0, 0, 0, NULL,
do_early_param);
} }
/* Arch code calls this early on, or if not, just before other parsing. */ /* Arch code calls this early on, or if not, just before other parsing. */
...@@ -535,10 +540,10 @@ asmlinkage __visible void __init start_kernel(void) ...@@ -535,10 +540,10 @@ asmlinkage __visible void __init start_kernel(void)
after_dashes = parse_args("Booting kernel", after_dashes = parse_args("Booting kernel",
static_command_line, __start___param, static_command_line, __start___param,
__stop___param - __start___param, __stop___param - __start___param,
-1, -1, &unknown_bootoption); -1, -1, NULL, &unknown_bootoption);
if (!IS_ERR_OR_NULL(after_dashes)) if (!IS_ERR_OR_NULL(after_dashes))
parse_args("Setting init args", after_dashes, NULL, 0, -1, -1, parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
set_init_arg); NULL, set_init_arg);
jump_label_init(); jump_label_init();
...@@ -847,7 +852,7 @@ static void __init do_initcall_level(int level) ...@@ -847,7 +852,7 @@ static void __init do_initcall_level(int level)
initcall_command_line, __start___param, initcall_command_line, __start___param,
__stop___param - __start___param, __stop___param - __start___param,
level, level, level, level,
&repair_env_string); NULL, &repair_env_string);
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
do_one_initcall(*fn); do_one_initcall(*fn);
......
...@@ -3237,7 +3237,8 @@ static int complete_formation(struct module *mod, struct load_info *info) ...@@ -3237,7 +3237,8 @@ static int complete_formation(struct module *mod, struct load_info *info)
return err; return err;
} }
static int unknown_module_param_cb(char *param, char *val, const char *modname) static int unknown_module_param_cb(char *param, char *val, const char *modname,
void *arg)
{ {
/* Check for magic 'dyndbg' arg */ /* Check for magic 'dyndbg' arg */
int ret = ddebug_dyndbg_module_param_cb(param, val, modname); int ret = ddebug_dyndbg_module_param_cb(param, val, modname);
...@@ -3342,7 +3343,8 @@ static int load_module(struct load_info *info, const char __user *uargs, ...@@ -3342,7 +3343,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
/* Module is ready to execute: parsing args may do that. */ /* Module is ready to execute: parsing args may do that. */
after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
-32768, 32767, unknown_module_param_cb); -32768, 32767, NULL,
unknown_module_param_cb);
if (IS_ERR(after_dashes)) { if (IS_ERR(after_dashes)) {
err = PTR_ERR(after_dashes); err = PTR_ERR(after_dashes);
goto bug_cleanup; goto bug_cleanup;
......
...@@ -100,8 +100,9 @@ static int parse_one(char *param, ...@@ -100,8 +100,9 @@ static int parse_one(char *param,
unsigned num_params, unsigned num_params,
s16 min_level, s16 min_level,
s16 max_level, s16 max_level,
void *arg,
int (*handle_unknown)(char *param, char *val, int (*handle_unknown)(char *param, char *val,
const char *doing)) const char *doing, void *arg))
{ {
unsigned int i; unsigned int i;
int err; int err;
...@@ -128,7 +129,7 @@ static int parse_one(char *param, ...@@ -128,7 +129,7 @@ static int parse_one(char *param,
if (handle_unknown) { if (handle_unknown) {
pr_debug("doing %s: %s='%s'\n", doing, param, val); pr_debug("doing %s: %s='%s'\n", doing, param, val);
return handle_unknown(param, val, doing); return handle_unknown(param, val, doing, arg);
} }
pr_debug("Unknown argument '%s'\n", param); pr_debug("Unknown argument '%s'\n", param);
...@@ -194,7 +195,9 @@ char *parse_args(const char *doing, ...@@ -194,7 +195,9 @@ char *parse_args(const char *doing,
unsigned num, unsigned num,
s16 min_level, s16 min_level,
s16 max_level, s16 max_level,
int (*unknown)(char *param, char *val, const char *doing)) void *arg,
int (*unknown)(char *param, char *val,
const char *doing, void *arg))
{ {
char *param, *val; char *param, *val;
...@@ -214,7 +217,7 @@ char *parse_args(const char *doing, ...@@ -214,7 +217,7 @@ char *parse_args(const char *doing,
return args; return args;
irq_was_disabled = irqs_disabled(); irq_was_disabled = irqs_disabled();
ret = parse_one(param, val, doing, params, num, ret = parse_one(param, val, doing, params, num,
min_level, max_level, unknown); min_level, max_level, arg, unknown);
if (irq_was_disabled && !irqs_disabled()) if (irq_was_disabled && !irqs_disabled())
pr_warn("%s: option '%s' enabled irq's!\n", pr_warn("%s: option '%s' enabled irq's!\n",
doing, param); doing, param);
......
...@@ -887,7 +887,7 @@ static int ddebug_dyndbg_param_cb(char *param, char *val, ...@@ -887,7 +887,7 @@ static int ddebug_dyndbg_param_cb(char *param, char *val,
/* handle both dyndbg and $module.dyndbg params at boot */ /* handle both dyndbg and $module.dyndbg params at boot */
static int ddebug_dyndbg_boot_param_cb(char *param, char *val, static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
const char *unused) const char *unused, void *arg)
{ {
vpr_info("%s=\"%s\"\n", param, val); vpr_info("%s=\"%s\"\n", param, val);
return ddebug_dyndbg_param_cb(param, val, NULL, 0); return ddebug_dyndbg_param_cb(param, val, NULL, 0);
...@@ -1028,7 +1028,7 @@ static int __init dynamic_debug_init(void) ...@@ -1028,7 +1028,7 @@ static int __init dynamic_debug_init(void)
*/ */
cmdline = kstrdup(saved_command_line, GFP_KERNEL); cmdline = kstrdup(saved_command_line, GFP_KERNEL);
parse_args("dyndbg params", cmdline, NULL, parse_args("dyndbg params", cmdline, NULL,
0, 0, 0, &ddebug_dyndbg_boot_param_cb); 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
kfree(cmdline); kfree(cmdline);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment