X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=kernel%2Fparams.c;h=42fe5e6126c0948e5b6859f5fcc75ebb71e2b039;hb=cc5d207c85b9a6fafebe2856ead0a9360978c8cd;hp=9de637a5c8bc920df2875910d29aba8dc0b4e3bb;hpb=9871728b756646e0d758a966ba00f2c0ff812817;p=safe%2Fjmp%2Flinux-2.6 diff --git a/kernel/params.c b/kernel/params.c index 9de637a..42fe5e6 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 @@ -31,7 +30,7 @@ #define DEBUGP(fmt, a...) #endif -static inline int dash2underscore(char c) +static inline char dash2underscore(char c) { if (c == '-') return '_'; @@ -144,9 +143,15 @@ int parse_args(const char *name, 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", @@ -247,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; @@ -257,14 +263,10 @@ 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. */ +/* We break the rule and mangle the string. */ static int param_array(const char *name, const char *val, unsigned int min, unsigned int max, @@ -320,7 +322,7 @@ static 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, @@ -330,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; @@ -349,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); @@ -362,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); } @@ -370,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; @@ -384,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, @@ -419,6 +424,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, return len; return err; } +#endif #ifdef CONFIG_MODULES #define __modinit @@ -426,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) @@ -463,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); @@ -479,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; } @@ -493,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 @@ -548,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); } /* @@ -578,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; @@ -619,7 +629,6 @@ static void __init param_sysfs_builtin(void) /* module-related sysfs stuff */ -#ifdef CONFIG_SYSFS #define to_module_attr(n) container_of(n, struct module_attribute, attr); #define to_module_kobject(n) container_of(n, struct module_kobject, kobj); @@ -667,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);