1 /* Helpers for initial module or kernel cmdline parsing
2 Copyright (C) 2001 Rusty Russell.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #include <linux/moduleparam.h>
19 #include <linux/kernel.h>
20 #include <linux/string.h>
21 #include <linux/errno.h>
22 #include <linux/module.h>
23 #include <linux/device.h>
24 #include <linux/err.h>
25 #include <linux/slab.h>
26 #include <linux/ctype.h>
31 #define DEBUGP(fmt, a...)
34 static inline char dash2underscore(char c
)
41 static inline int parameq(const char *input
, const char *paramname
)
44 for (i
= 0; dash2underscore(input
[i
]) == paramname
[i
]; i
++)
50 static int parse_one(char *param
,
52 struct kernel_param
*params
,
54 int (*handle_unknown
)(char *param
, char *val
))
59 for (i
= 0; i
< num_params
; i
++) {
60 if (parameq(param
, params
[i
].name
)) {
61 /* Noone handled NULL, so do it here. */
62 if (!val
&& params
[i
].ops
->set
!= param_set_bool
)
64 DEBUGP("They are equal! Calling %p\n",
66 return params
[i
].ops
->set(val
, ¶ms
[i
]);
71 DEBUGP("Unknown argument: calling %p\n", handle_unknown
);
72 return handle_unknown(param
, val
);
75 DEBUGP("Unknown argument `%s'\n", param
);
79 /* You can use " around spaces, but can't escape ". */
80 /* Hyphens and underscores equivalent in parameter names. */
81 static char *next_arg(char *args
, char **param
, char **val
)
83 unsigned int i
, equals
= 0;
84 int in_quote
= 0, quoted
= 0;
93 for (i
= 0; args
[i
]; i
++) {
94 if (isspace(args
[i
]) && !in_quote
)
101 in_quote
= !in_quote
;
109 *val
= args
+ equals
+ 1;
111 /* Don't include quotes in value. */
114 if (args
[i
-1] == '"')
117 if (quoted
&& args
[i
-1] == '"')
127 /* Chew up trailing spaces. */
128 return skip_spaces(next
);
131 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
132 int parse_args(const char *name
,
134 struct kernel_param
*params
,
136 int (*unknown
)(char *param
, char *val
))
140 DEBUGP("Parsing ARGS: %s\n", args
);
142 /* Chew leading spaces */
143 args
= skip_spaces(args
);
147 int irq_was_disabled
;
149 args
= next_arg(args
, ¶m
, &val
);
150 irq_was_disabled
= irqs_disabled();
151 ret
= parse_one(param
, val
, params
, num
, unknown
);
152 if (irq_was_disabled
&& !irqs_disabled()) {
153 printk(KERN_WARNING
"parse_args(): option '%s' enabled "
158 printk(KERN_ERR
"%s: Unknown parameter `%s'\n",
163 "%s: `%s' too large for parameter `%s'\n",
164 name
, val
?: "", param
);
170 "%s: `%s' invalid for parameter `%s'\n",
171 name
, val
?: "", param
);
180 /* Lazy bastard, eh? */
181 #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \
182 int param_set_##name(const char *val, const struct kernel_param *kp) \
187 ret = strtolfn(val, 0, &l); \
188 if (ret == -EINVAL || ((type)l != l)) \
190 *((type *)kp->arg) = l; \
193 int param_get_##name(char *buffer, const struct kernel_param *kp) \
195 return sprintf(buffer, format, *((type *)kp->arg)); \
197 struct kernel_param_ops param_ops_##name = { \
198 .set = param_set_##name, \
199 .get = param_get_##name, \
201 EXPORT_SYMBOL(param_set_##name); \
202 EXPORT_SYMBOL(param_get_##name); \
203 EXPORT_SYMBOL(param_ops_##name)
206 STANDARD_PARAM_DEF(byte
, unsigned char, "%c", unsigned long, strict_strtoul
);
207 STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol
);
208 STANDARD_PARAM_DEF(ushort
, unsigned short, "%hu", unsigned long, strict_strtoul
);
209 STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol
);
210 STANDARD_PARAM_DEF(uint
, unsigned int, "%u", unsigned long, strict_strtoul
);
211 STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol
);
212 STANDARD_PARAM_DEF(ulong
, unsigned long, "%lu", unsigned long, strict_strtoul
);
214 int param_set_charp(const char *val
, const struct kernel_param
*kp
)
216 if (strlen(val
) > 1024) {
217 printk(KERN_ERR
"%s: string parameter too long\n",
222 /* This is a hack. We can't need to strdup in early boot, and we
223 * don't need to; this mangled commandline is preserved. */
224 if (slab_is_available()) {
225 *(char **)kp
->arg
= kstrdup(val
, GFP_KERNEL
);
226 if (!*(char **)kp
->arg
)
229 *(const char **)kp
->arg
= val
;
233 EXPORT_SYMBOL(param_set_charp
);
235 int param_get_charp(char *buffer
, const struct kernel_param
*kp
)
237 return sprintf(buffer
, "%s", *((char **)kp
->arg
));
239 EXPORT_SYMBOL(param_get_charp
);
241 struct kernel_param_ops param_ops_charp
= {
242 .set
= param_set_charp
,
243 .get
= param_get_charp
,
245 EXPORT_SYMBOL(param_ops_charp
);
247 /* Actually could be a bool or an int, for historical reasons. */
248 int param_set_bool(const char *val
, const struct kernel_param
*kp
)
252 /* No equals means "set"... */
255 /* One of =[yYnN01] */
257 case 'y': case 'Y': case '1':
260 case 'n': case 'N': case '0':
267 if (kp
->flags
& KPARAM_ISBOOL
)
268 *(bool *)kp
->arg
= v
;
273 EXPORT_SYMBOL(param_set_bool
);
275 int param_get_bool(char *buffer
, const struct kernel_param
*kp
)
278 if (kp
->flags
& KPARAM_ISBOOL
)
279 val
= *(bool *)kp
->arg
;
281 val
= *(int *)kp
->arg
;
283 /* Y and N chosen as being relatively non-coder friendly */
284 return sprintf(buffer
, "%c", val
? 'Y' : 'N');
286 EXPORT_SYMBOL(param_get_bool
);
288 struct kernel_param_ops param_ops_bool
= {
289 .set
= param_set_bool
,
290 .get
= param_get_bool
,
292 EXPORT_SYMBOL(param_ops_bool
);
294 /* This one must be bool. */
295 int param_set_invbool(const char *val
, const struct kernel_param
*kp
)
299 struct kernel_param dummy
;
301 dummy
.arg
= &boolval
;
302 dummy
.flags
= KPARAM_ISBOOL
;
303 ret
= param_set_bool(val
, &dummy
);
305 *(bool *)kp
->arg
= !boolval
;
308 EXPORT_SYMBOL(param_set_invbool
);
310 int param_get_invbool(char *buffer
, const struct kernel_param
*kp
)
312 return sprintf(buffer
, "%c", (*(bool *)kp
->arg
) ? 'N' : 'Y');
314 EXPORT_SYMBOL(param_get_invbool
);
316 struct kernel_param_ops param_ops_invbool
= {
317 .set
= param_set_invbool
,
318 .get
= param_get_invbool
,
320 EXPORT_SYMBOL(param_ops_invbool
);
322 /* We break the rule and mangle the string. */
323 static int param_array(const char *name
,
325 unsigned int min
, unsigned int max
,
326 void *elem
, int elemsize
,
327 int (*set
)(const char *, const struct kernel_param
*kp
),
332 struct kernel_param kp
;
335 /* Get the name right for errors. */
341 /* We expect a comma-separated list of values. */
346 printk(KERN_ERR
"%s: can only take %i arguments\n",
350 len
= strcspn(val
, ",");
352 /* nul-terminate and parse */
354 ((char *)val
)[len
] = '\0';
362 } while (save
== ',');
365 printk(KERN_ERR
"%s: needs at least %i arguments\n",
372 static int param_array_set(const char *val
, const struct kernel_param
*kp
)
374 const struct kparam_array
*arr
= kp
->arr
;
375 unsigned int temp_num
;
377 return param_array(kp
->name
, val
, 1, arr
->max
, arr
->elem
,
378 arr
->elemsize
, arr
->ops
->set
, kp
->flags
,
379 arr
->num
?: &temp_num
);
382 static int param_array_get(char *buffer
, const struct kernel_param
*kp
)
385 const struct kparam_array
*arr
= kp
->arr
;
386 struct kernel_param p
;
389 for (i
= off
= 0; i
< (arr
->num
? *arr
->num
: arr
->max
); i
++) {
392 p
.arg
= arr
->elem
+ arr
->elemsize
* i
;
393 ret
= arr
->ops
->get(buffer
+ off
, &p
);
402 struct kernel_param_ops param_array_ops
= {
403 .set
= param_array_set
,
404 .get
= param_array_get
,
406 EXPORT_SYMBOL(param_array_ops
);
408 int param_set_copystring(const char *val
, const struct kernel_param
*kp
)
410 const struct kparam_string
*kps
= kp
->str
;
412 if (strlen(val
)+1 > kps
->maxlen
) {
413 printk(KERN_ERR
"%s: string doesn't fit in %u chars.\n",
414 kp
->name
, kps
->maxlen
-1);
417 strcpy(kps
->string
, val
);
420 EXPORT_SYMBOL(param_set_copystring
);
422 int param_get_string(char *buffer
, const struct kernel_param
*kp
)
424 const struct kparam_string
*kps
= kp
->str
;
425 return strlcpy(buffer
, kps
->string
, kps
->maxlen
);
427 EXPORT_SYMBOL(param_get_string
);
429 struct kernel_param_ops param_ops_string
= {
430 .set
= param_set_copystring
,
431 .get
= param_get_string
,
433 EXPORT_SYMBOL(param_ops_string
);
435 /* sysfs output in /sys/modules/XYZ/parameters/ */
436 #define to_module_attr(n) container_of(n, struct module_attribute, attr)
437 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
439 extern struct kernel_param __start___param
[], __stop___param
[];
441 struct param_attribute
443 struct module_attribute mattr
;
444 const struct kernel_param
*param
;
447 struct module_param_attrs
450 struct attribute_group grp
;
451 struct param_attribute attrs
[0];
455 #define to_param_attr(n) container_of(n, struct param_attribute, mattr)
457 static ssize_t
param_attr_show(struct module_attribute
*mattr
,
458 struct module
*mod
, char *buf
)
461 struct param_attribute
*attribute
= to_param_attr(mattr
);
463 if (!attribute
->param
->ops
->get
)
466 count
= attribute
->param
->ops
->get(buf
, attribute
->param
);
474 /* sysfs always hands a nul-terminated string in buf. We rely on that. */
475 static ssize_t
param_attr_store(struct module_attribute
*mattr
,
476 struct module
*owner
,
477 const char *buf
, size_t len
)
480 struct param_attribute
*attribute
= to_param_attr(mattr
);
482 if (!attribute
->param
->ops
->set
)
485 err
= attribute
->param
->ops
->set(buf
, attribute
->param
);
492 #ifdef CONFIG_MODULES
495 #define __modinit __init
500 * add_sysfs_param - add a parameter to sysfs
501 * @mk: struct module_kobject
502 * @kparam: the actual parameter definition to add to sysfs
503 * @name: name of parameter
505 * Create a kobject if for a (per-module) parameter if mp NULL, and
506 * create file in sysfs. Returns an error on out of memory. Always cleans up
507 * if there's an error.
509 static __modinit
int add_sysfs_param(struct module_kobject
*mk
,
510 const struct kernel_param
*kp
,
513 struct module_param_attrs
*new;
514 struct attribute
**attrs
;
517 /* We don't bother calling this with invisible parameters. */
525 attrs
= mk
->mp
->grp
.attrs
;
529 new = krealloc(mk
->mp
,
530 sizeof(*mk
->mp
) + sizeof(mk
->mp
->attrs
[0]) * (num
+1),
537 attrs
= krealloc(attrs
, sizeof(new->grp
.attrs
[0])*(num
+2), GFP_KERNEL
);
543 /* Sysfs wants everything zeroed. */
544 memset(new, 0, sizeof(*new));
545 memset(&new->attrs
[num
], 0, sizeof(new->attrs
[num
]));
546 memset(&attrs
[num
], 0, sizeof(attrs
[num
]));
547 new->grp
.name
= "parameters";
548 new->grp
.attrs
= attrs
;
550 /* Tack new one on the end. */
551 sysfs_attr_init(&new->attrs
[num
].mattr
.attr
);
552 new->attrs
[num
].param
= kp
;
553 new->attrs
[num
].mattr
.show
= param_attr_show
;
554 new->attrs
[num
].mattr
.store
= param_attr_store
;
555 new->attrs
[num
].mattr
.attr
.name
= (char *)name
;
556 new->attrs
[num
].mattr
.attr
.mode
= kp
->perm
;
559 /* Fix up all the pointers, since krealloc can move us */
560 for (num
= 0; num
< new->num
; num
++)
561 new->grp
.attrs
[num
] = &new->attrs
[num
].mattr
.attr
;
562 new->grp
.attrs
[num
] = NULL
;
574 #ifdef CONFIG_MODULES
575 static void free_module_param_attrs(struct module_kobject
*mk
)
577 kfree(mk
->mp
->grp
.attrs
);
583 * module_param_sysfs_setup - setup sysfs support for one module
585 * @kparam: module parameters (array)
586 * @num_params: number of module parameters
588 * Adds sysfs entries for module parameters under
589 * /sys/module/[mod->name]/parameters/
591 int module_param_sysfs_setup(struct module
*mod
,
592 const struct kernel_param
*kparam
,
593 unsigned int num_params
)
598 for (i
= 0; i
< num_params
; i
++) {
599 if (kparam
[i
].perm
== 0)
601 err
= add_sysfs_param(&mod
->mkobj
, &kparam
[i
], kparam
[i
].name
);
610 /* Create the param group. */
611 err
= sysfs_create_group(&mod
->mkobj
.kobj
, &mod
->mkobj
.mp
->grp
);
613 free_module_param_attrs(&mod
->mkobj
);
618 * module_param_sysfs_remove - remove sysfs support for one module
621 * Remove sysfs entries for module parameters and the corresponding
624 void module_param_sysfs_remove(struct module
*mod
)
627 sysfs_remove_group(&mod
->mkobj
.kobj
, &mod
->mkobj
.mp
->grp
);
628 /* We are positive that no one is using any param
629 * attrs at this point. Deallocate immediately. */
630 free_module_param_attrs(&mod
->mkobj
);
635 void destroy_params(const struct kernel_param
*params
, unsigned num
)
637 /* FIXME: This should free kmalloced charp parameters. It doesn't. */
640 static void __init
kernel_add_sysfs_param(const char *name
,
641 struct kernel_param
*kparam
,
642 unsigned int name_skip
)
644 struct module_kobject
*mk
;
645 struct kobject
*kobj
;
648 kobj
= kset_find_obj(module_kset
, name
);
650 /* We already have one. Remove params so we can add more. */
651 mk
= to_module_kobject(kobj
);
652 /* We need to remove it before adding parameters. */
653 sysfs_remove_group(&mk
->kobj
, &mk
->mp
->grp
);
655 mk
= kzalloc(sizeof(struct module_kobject
), GFP_KERNEL
);
658 mk
->mod
= THIS_MODULE
;
659 mk
->kobj
.kset
= module_kset
;
660 err
= kobject_init_and_add(&mk
->kobj
, &module_ktype
, NULL
,
663 kobject_put(&mk
->kobj
);
664 printk(KERN_ERR
"Module '%s' failed add to sysfs, "
665 "error number %d\n", name
, err
);
666 printk(KERN_ERR
"The system will be unstable now.\n");
669 /* So that exit path is even. */
670 kobject_get(&mk
->kobj
);
673 /* These should not fail at boot. */
674 err
= add_sysfs_param(mk
, kparam
, kparam
->name
+ name_skip
);
676 err
= sysfs_create_group(&mk
->kobj
, &mk
->mp
->grp
);
678 kobject_uevent(&mk
->kobj
, KOBJ_ADD
);
679 kobject_put(&mk
->kobj
);
683 * param_sysfs_builtin - add contents in /sys/parameters for built-in modules
685 * Add module_parameters to sysfs for "modules" built into the kernel.
687 * The "module" name (KBUILD_MODNAME) is stored before a dot, the
688 * "parameter" name is stored behind a dot in kernel_param->name. So,
689 * extract the "module" name for all built-in kernel_param-eters,
690 * and for all who have the same, call kernel_add_sysfs_param.
692 static void __init
param_sysfs_builtin(void)
694 struct kernel_param
*kp
;
695 unsigned int name_len
;
696 char modname
[MODULE_NAME_LEN
];
698 for (kp
= __start___param
; kp
< __stop___param
; kp
++) {
704 dot
= strchr(kp
->name
, '.');
706 /* This happens for core_param() */
707 strcpy(modname
, "kernel");
710 name_len
= dot
- kp
->name
+ 1;
711 strlcpy(modname
, kp
->name
, name_len
);
713 kernel_add_sysfs_param(modname
, kp
, name_len
);
718 /* module-related sysfs stuff */
720 static ssize_t
module_attr_show(struct kobject
*kobj
,
721 struct attribute
*attr
,
724 struct module_attribute
*attribute
;
725 struct module_kobject
*mk
;
728 attribute
= to_module_attr(attr
);
729 mk
= to_module_kobject(kobj
);
731 if (!attribute
->show
)
734 ret
= attribute
->show(attribute
, mk
->mod
, buf
);
739 static ssize_t
module_attr_store(struct kobject
*kobj
,
740 struct attribute
*attr
,
741 const char *buf
, size_t len
)
743 struct module_attribute
*attribute
;
744 struct module_kobject
*mk
;
747 attribute
= to_module_attr(attr
);
748 mk
= to_module_kobject(kobj
);
750 if (!attribute
->store
)
753 ret
= attribute
->store(attribute
, mk
->mod
, buf
, len
);
758 static const struct sysfs_ops module_sysfs_ops
= {
759 .show
= module_attr_show
,
760 .store
= module_attr_store
,
763 static int uevent_filter(struct kset
*kset
, struct kobject
*kobj
)
765 struct kobj_type
*ktype
= get_ktype(kobj
);
767 if (ktype
== &module_ktype
)
772 static const struct kset_uevent_ops module_uevent_ops
= {
773 .filter
= uevent_filter
,
776 struct kset
*module_kset
;
777 int module_sysfs_initialized
;
779 struct kobj_type module_ktype
= {
780 .sysfs_ops
= &module_sysfs_ops
,
784 * param_sysfs_init - wrapper for built-in params support
786 static int __init
param_sysfs_init(void)
788 module_kset
= kset_create_and_add("module", &module_uevent_ops
, NULL
);
790 printk(KERN_WARNING
"%s (%d): error creating kset\n",
794 module_sysfs_initialized
= 1;
796 param_sysfs_builtin();
800 subsys_initcall(param_sysfs_init
);
802 #endif /* CONFIG_SYSFS */