X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=kernel%2Fparams.c;h=afc46a23eb6d15ebfb328f242979d75998d6d4c4;hb=70eee74b70c1a8485ec5f2bafa13dbc66fab6e02;hp=fbf173215fd217bed3db643ba0676916f7085daf;hpb=dd3927105b6f65afb7dac17682172cdfb86d3f00;p=safe%2Fjmp%2Flinux-2.6 diff --git a/kernel/params.c b/kernel/params.c index fbf1732..afc46a2 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -15,7 +15,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include #include #include #include @@ -23,6 +22,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk @@ -30,7 +30,7 @@ #define DEBUGP(fmt, a...) #endif -static inline int dash2underscore(char c) +static inline char dash2underscore(char c) { if (c == '-') return '_'; @@ -80,8 +80,6 @@ static char *next_arg(char *args, char **param, char **val) int in_quote = 0, quoted = 0; char *next; - /* Chew any extra spaces */ - while (*args == ' ') args++; if (*args == '"') { args++; in_quote = 1; @@ -121,6 +119,10 @@ static char *next_arg(char *args, char **param, char **val) next = args + i + 1; } else next = args + i; + + /* Chew up trailing spaces. */ + while (*next == ' ') + next++; return next; } @@ -135,11 +137,21 @@ int parse_args(const char *name, DEBUGP("Parsing ARGS: %s\n", args); + /* Chew leading spaces */ + while (*args == ' ') + args++; + while (*args) { int ret; + int irq_was_disabled; args = next_arg(args, ¶m, &val); + irq_was_disabled = irqs_disabled(); ret = parse_one(param, val, params, num, unknown); + if (irq_was_disabled && !irqs_disabled()) { + printk(KERN_WARNING "parse_args(): option '%s' enabled " + "irq's!\n", param); + } switch (ret) { case -ENOENT: printk(KERN_ERR "%s: Unknown parameter `%s'\n", @@ -168,12 +180,12 @@ int parse_args(const char *name, #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ int param_set_##name(const char *val, struct kernel_param *kp) \ { \ - char *endp; \ tmptype l; \ + int ret; \ \ if (!val) return -EINVAL; \ - l = strtolfn(val, &endp, 0); \ - if (endp == val || ((type)l != l)) \ + ret = strtolfn(val, 0, &l); \ + if (ret == -EINVAL || ((type)l != l)) \ return -EINVAL; \ *((type *)kp->arg) = l; \ return 0; \ @@ -183,13 +195,13 @@ int parse_args(const char *name, return sprintf(buffer, format, *((type *)kp->arg)); \ } -STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, simple_strtoul); -STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol); -STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul); -STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol); -STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul); -STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol); -STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul); +STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); +STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); +STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul); +STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol); +STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul); +STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); +STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); int param_set_charp(const char *val, struct kernel_param *kp) { @@ -240,8 +252,9 @@ int param_get_bool(char *buffer, struct kernel_param *kp) int param_set_invbool(const char *val, struct kernel_param *kp) { int boolval, ret; - struct kernel_param dummy = { .arg = &boolval }; + struct kernel_param dummy; + dummy.arg = &boolval; ret = param_set_bool(val, &dummy); if (ret == 0) *(int *)kp->arg = !boolval; @@ -250,20 +263,16 @@ int param_set_invbool(const char *val, struct kernel_param *kp) int param_get_invbool(char *buffer, struct kernel_param *kp) { - int val; - struct kernel_param dummy = { .arg = &val }; - - val = !*(int *)kp->arg; - return param_get_bool(buffer, &dummy); + return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y'); } -/* We cheat here and temporarily mangle the string. */ -int param_array(const char *name, - const char *val, - unsigned int min, unsigned int max, - void *elem, int elemsize, - int (*set)(const char *, struct kernel_param *kp), - int *num) +/* We break the rule and mangle the string. */ +static int param_array(const char *name, + const char *val, + unsigned int min, unsigned int max, + void *elem, int elemsize, + int (*set)(const char *, struct kernel_param *kp), + unsigned int *num) { int ret; struct kernel_param kp; @@ -313,7 +322,7 @@ int param_array(const char *name, int param_array_set(const char *val, struct kernel_param *kp) { - struct kparam_array *arr = kp->arg; + const struct kparam_array *arr = kp->arr; unsigned int temp_num; return param_array(kp->name, val, 1, arr->max, arr->elem, @@ -323,7 +332,7 @@ int param_array_set(const char *val, struct kernel_param *kp) int param_array_get(char *buffer, struct kernel_param *kp) { int i, off, ret; - struct kparam_array *arr = kp->arg; + const struct kparam_array *arr = kp->arr; struct kernel_param p; p = *kp; @@ -342,8 +351,12 @@ int param_array_get(char *buffer, struct kernel_param *kp) int param_set_copystring(const char *val, struct kernel_param *kp) { - struct kparam_string *kps = kp->arg; + const struct kparam_string *kps = kp->str; + if (!val) { + printk(KERN_ERR "%s: missing param set value\n", kp->name); + return -EINVAL; + } if (strlen(val)+1 > kps->maxlen) { printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", kp->name, kps->maxlen-1); @@ -355,7 +368,7 @@ int param_set_copystring(const char *val, struct kernel_param *kp) int param_get_string(char *buffer, struct kernel_param *kp) { - struct kparam_string *kps = kp->arg; + const struct kparam_string *kps = kp->str; return strlcpy(buffer, kps->string, kps->maxlen); } @@ -363,8 +376,6 @@ int param_get_string(char *buffer, struct kernel_param *kp) extern struct kernel_param __start___param[], __stop___param[]; -#define MAX_KBUILD_MODNAME KOBJ_NAME_LEN - struct param_attribute { struct module_attribute mattr; @@ -377,6 +388,7 @@ struct module_param_attrs struct param_attribute attrs[0]; }; +#ifdef CONFIG_SYSFS #define to_param_attr(n) container_of(n, struct param_attribute, mattr); static ssize_t param_attr_show(struct module_attribute *mattr, @@ -412,6 +424,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, return len; return err; } +#endif #ifdef CONFIG_MODULES #define __modinit @@ -419,6 +432,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, #define __modinit __init #endif +#ifdef CONFIG_SYSFS /* * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME * @mk: struct module_kobject (contains parent kobject) @@ -456,7 +470,7 @@ param_sysfs_setup(struct module_kobject *mk, sizeof(mp->grp.attrs[0])); size[1] = (valid_attrs + 1) * sizeof(mp->grp.attrs[0]); - mp = kmalloc(size[0] + size[1], GFP_KERNEL); + mp = kzalloc(size[0] + size[1], GFP_KERNEL); if (!mp) return ERR_PTR(-ENOMEM); @@ -472,7 +486,6 @@ param_sysfs_setup(struct module_kobject *mk, pattr->mattr.show = param_attr_show; pattr->mattr.store = param_attr_store; pattr->mattr.attr.name = (char *)&kp->name[name_skip]; - pattr->mattr.attr.owner = mk->mod; pattr->mattr.attr.mode = kp->perm; *(gattr++) = &(pattr++)->mattr.attr; } @@ -486,9 +499,7 @@ param_sysfs_setup(struct module_kobject *mk, return mp; } - #ifdef CONFIG_MODULES - /* * module_param_sysfs_setup - setup sysfs support for one module * @mod: module @@ -541,20 +552,23 @@ static void __init kernel_param_sysfs_setup(const char *name, unsigned int name_skip) { struct module_kobject *mk; + int ret; mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL); BUG_ON(!mk); mk->mod = THIS_MODULE; - kobj_set_kset_s(mk, module_subsys); - kobject_set_name(&mk->kobj, name); - kobject_register(&mk->kobj); - - /* no need to keep the kobject if no parameter is exported */ - if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) { - kobject_unregister(&mk->kobj); - kfree(mk); + mk->kobj.kset = module_kset; + ret = kobject_init_and_add(&mk->kobj, &module_ktype, NULL, "%s", name); + if (ret) { + kobject_put(&mk->kobj); + printk(KERN_ERR "Module '%s' failed to be added to sysfs, " + "error number %d\n", name, ret); + printk(KERN_ERR "The system will be unstable now.\n"); + return; } + param_sysfs_setup(mk, kparam, num_params, name_skip); + kobject_uevent(&mk->kobj, KOBJ_ADD); } /* @@ -571,17 +585,20 @@ static void __init param_sysfs_builtin(void) { struct kernel_param *kp, *kp_begin = NULL; unsigned int i, name_len, count = 0; - char modname[MAX_KBUILD_MODNAME + 1] = ""; + char modname[MODULE_NAME_LEN + 1] = ""; for (i=0; i < __stop___param - __start___param; i++) { char *dot; + size_t max_name_len; kp = &__start___param[i]; + max_name_len = + min_t(size_t, MODULE_NAME_LEN, strlen(kp->name)); - /* We do not handle args without periods. */ - dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME); + dot = memchr(kp->name, '.', max_name_len); if (!dot) { - DEBUGP("couldn't find period in %s\n", kp->name); + DEBUGP("couldn't find period in first %d characters " + "of %s\n", MODULE_NAME_LEN, kp->name); continue; } name_len = dot - kp->name; @@ -612,7 +629,6 @@ static void __init param_sysfs_builtin(void) /* module-related sysfs stuff */ -#ifdef CONFIG_MODULES #define to_module_attr(n) container_of(n, struct module_attribute, attr); #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); @@ -631,13 +647,8 @@ static ssize_t module_attr_show(struct kobject *kobj, if (!attribute->show) return -EIO; - if (!try_module_get(mk->mod)) - return -ENODEV; - ret = attribute->show(attribute, mk->mod, buf); - module_put(mk->mod); - return ret; } @@ -655,13 +666,8 @@ static ssize_t module_attr_store(struct kobject *kobj, if (!attribute->store) return -EIO; - if (!try_module_get(mk->mod)) - return -ENODEV; - ret = attribute->store(attribute, mk->mod, buf, len); - module_put(mk->mod); - return ret; } @@ -670,31 +676,46 @@ static struct sysfs_ops module_sysfs_ops = { .store = module_attr_store, }; -#else -static struct sysfs_ops module_sysfs_ops = { - .show = NULL, - .store = NULL, +static int uevent_filter(struct kset *kset, struct kobject *kobj) +{ + struct kobj_type *ktype = get_ktype(kobj); + + if (ktype == &module_ktype) + return 1; + return 0; +} + +static struct kset_uevent_ops module_uevent_ops = { + .filter = uevent_filter, }; -#endif -static struct kobj_type module_ktype = { +struct kset *module_kset; +int module_sysfs_initialized; + +struct kobj_type module_ktype = { .sysfs_ops = &module_sysfs_ops, }; -decl_subsys(module, &module_ktype, NULL); - /* * param_sysfs_init - wrapper for built-in params support */ static int __init param_sysfs_init(void) { - subsystem_register(&module_subsys); + module_kset = kset_create_and_add("module", &module_uevent_ops, NULL); + if (!module_kset) { + printk(KERN_WARNING "%s (%d): error creating kset\n", + __FILE__, __LINE__); + return -ENOMEM; + } + module_sysfs_initialized = 1; param_sysfs_builtin(); return 0; } -__initcall(param_sysfs_init); +subsys_initcall(param_sysfs_init); + +#endif /* CONFIG_SYSFS */ EXPORT_SYMBOL(param_set_byte); EXPORT_SYMBOL(param_get_byte);