upgrade to linux 2.6.10-1.12_FC2
[linux-2.6.git] / kernel / params.c
1 /* Helpers for initial module or kernel cmdline parsing
2    Copyright (C) 2001 Rusty Russell.
3
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.
8
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.
13
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
17 */
18 #include <linux/config.h>
19 #include <linux/moduleparam.h>
20 #include <linux/kernel.h>
21 #include <linux/string.h>
22 #include <linux/errno.h>
23 #include <linux/module.h>
24 #include <linux/device.h>
25 #include <linux/err.h>
26
27 #if 0
28 #define DEBUGP printk
29 #else
30 #define DEBUGP(fmt, a...)
31 #endif
32
33 static inline int dash2underscore(char c)
34 {
35         if (c == '-')
36                 return '_';
37         return c;
38 }
39
40 static inline int parameq(const char *input, const char *paramname)
41 {
42         unsigned int i;
43         for (i = 0; dash2underscore(input[i]) == paramname[i]; i++)
44                 if (input[i] == '\0')
45                         return 1;
46         return 0;
47 }
48
49 static int parse_one(char *param,
50                      char *val,
51                      struct kernel_param *params, 
52                      unsigned num_params,
53                      int (*handle_unknown)(char *param, char *val))
54 {
55         unsigned int i;
56
57         /* Find parameter */
58         for (i = 0; i < num_params; i++) {
59                 if (parameq(param, params[i].name)) {
60                         DEBUGP("They are equal!  Calling %p\n",
61                                params[i].set);
62                         return params[i].set(val, &params[i]);
63                 }
64         }
65
66         if (handle_unknown) {
67                 DEBUGP("Unknown argument: calling %p\n", handle_unknown);
68                 return handle_unknown(param, val);
69         }
70
71         DEBUGP("Unknown argument `%s'\n", param);
72         return -ENOENT;
73 }
74
75 /* You can use " around spaces, but can't escape ". */
76 /* Hyphens and underscores equivalent in parameter names. */
77 static char *next_arg(char *args, char **param, char **val)
78 {
79         unsigned int i, equals = 0;
80         int in_quote = 0;
81
82         /* Chew any extra spaces */
83         while (*args == ' ') args++;
84
85         for (i = 0; args[i]; i++) {
86                 if (args[i] == ' ' && !in_quote)
87                         break;
88                 if (equals == 0) {
89                         if (args[i] == '=')
90                                 equals = i;
91                 }
92                 if (args[i] == '"')
93                         in_quote = !in_quote;
94         }
95
96         *param = args;
97         if (!equals)
98                 *val = NULL;
99         else {
100                 args[equals] = '\0';
101                 *val = args + equals + 1;
102
103                 /* Don't include quotes in value. */
104                 if (**val == '"') {
105                         (*val)++;
106                         if (args[i-1] == '"')
107                                 args[i-1] = '\0';
108                 }
109         }
110
111         if (args[i]) {
112                 args[i] = '\0';
113                 return args + i + 1;
114         } else
115                 return args + i;
116 }
117
118 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
119 int parse_args(const char *name,
120                char *args,
121                struct kernel_param *params,
122                unsigned num,
123                int (*unknown)(char *param, char *val))
124 {
125         char *param, *val;
126
127         DEBUGP("Parsing ARGS: %s\n", args);
128
129         while (*args) {
130                 int ret;
131
132                 args = next_arg(args, &param, &val);
133                 ret = parse_one(param, val, params, num, unknown);
134                 switch (ret) {
135                 case -ENOENT:
136                         printk(KERN_ERR "%s: Unknown parameter `%s'\n",
137                                name, param);
138                         return ret;
139                 case -ENOSPC:
140                         printk(KERN_ERR
141                                "%s: `%s' too large for parameter `%s'\n",
142                                name, val ?: "", param);
143                         return ret;
144                 case 0:
145                         break;
146                 default:
147                         printk(KERN_ERR
148                                "%s: `%s' invalid for parameter `%s'\n",
149                                name, val ?: "", param);
150                         return ret;
151                 }
152         }
153
154         /* All parsed OK. */
155         return 0;
156 }
157
158 /* Lazy bastard, eh? */
159 #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)       \
160         int param_set_##name(const char *val, struct kernel_param *kp)  \
161         {                                                               \
162                 char *endp;                                             \
163                 tmptype l;                                              \
164                                                                         \
165                 if (!val) return -EINVAL;                               \
166                 l = strtolfn(val, &endp, 0);                            \
167                 if (endp == val || ((type)l != l))                      \
168                         return -EINVAL;                                 \
169                 *((type *)kp->arg) = l;                                 \
170                 return 0;                                               \
171         }                                                               \
172         int param_get_##name(char *buffer, struct kernel_param *kp)     \
173         {                                                               \
174                 return sprintf(buffer, format, *((type *)kp->arg));     \
175         }
176
177 STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, simple_strtoul);
178 STANDARD_PARAM_DEF(short, short, "%hi", long, simple_strtol);
179 STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, simple_strtoul);
180 STANDARD_PARAM_DEF(int, int, "%i", long, simple_strtol);
181 STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, simple_strtoul);
182 STANDARD_PARAM_DEF(long, long, "%li", long, simple_strtol);
183 STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, simple_strtoul);
184
185 int param_set_charp(const char *val, struct kernel_param *kp)
186 {
187         if (!val) {
188                 printk(KERN_ERR "%s: string parameter expected\n",
189                        kp->name);
190                 return -EINVAL;
191         }
192
193         if (strlen(val) > 1024) {
194                 printk(KERN_ERR "%s: string parameter too long\n",
195                        kp->name);
196                 return -ENOSPC;
197         }
198
199         *(char **)kp->arg = (char *)val;
200         return 0;
201 }
202
203 int param_get_charp(char *buffer, struct kernel_param *kp)
204 {
205         return sprintf(buffer, "%s", *((char **)kp->arg));
206 }
207
208 int param_set_bool(const char *val, struct kernel_param *kp)
209 {
210         /* No equals means "set"... */
211         if (!val) val = "1";
212
213         /* One of =[yYnN01] */
214         switch (val[0]) {
215         case 'y': case 'Y': case '1':
216                 *(int *)kp->arg = 1;
217                 return 0;
218         case 'n': case 'N': case '0':
219                 *(int *)kp->arg = 0;
220                 return 0;
221         }
222         return -EINVAL;
223 }
224
225 int param_get_bool(char *buffer, struct kernel_param *kp)
226 {
227         /* Y and N chosen as being relatively non-coder friendly */
228         return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'Y' : 'N');
229 }
230
231 int param_set_invbool(const char *val, struct kernel_param *kp)
232 {
233         int boolval, ret;
234         struct kernel_param dummy = { .arg = &boolval };
235
236         ret = param_set_bool(val, &dummy);
237         if (ret == 0)
238                 *(int *)kp->arg = !boolval;
239         return ret;
240 }
241
242 int param_get_invbool(char *buffer, struct kernel_param *kp)
243 {
244         int val;
245         struct kernel_param dummy = { .arg = &val };
246
247         val = !*(int *)kp->arg;
248         return param_get_bool(buffer, &dummy);
249 }
250
251 /* We cheat here and temporarily mangle the string. */
252 int param_array(const char *name,
253                 const char *val,
254                 unsigned int min, unsigned int max,
255                 void *elem, int elemsize,
256                 int (*set)(const char *, struct kernel_param *kp),
257                 int *num)
258 {
259         int ret;
260         struct kernel_param kp;
261         char save;
262
263         /* Get the name right for errors. */
264         kp.name = name;
265         kp.arg = elem;
266
267         /* No equals sign? */
268         if (!val) {
269                 printk(KERN_ERR "%s: expects arguments\n", name);
270                 return -EINVAL;
271         }
272
273         *num = 0;
274         /* We expect a comma-separated list of values. */
275         do {
276                 int len;
277
278                 if (*num == max) {
279                         printk(KERN_ERR "%s: can only take %i arguments\n",
280                                name, max);
281                         return -EINVAL;
282                 }
283                 len = strcspn(val, ",");
284
285                 /* nul-terminate and parse */
286                 save = val[len];
287                 ((char *)val)[len] = '\0';
288                 ret = set(val, &kp);
289
290                 if (ret != 0)
291                         return ret;
292                 kp.arg += elemsize;
293                 val += len+1;
294                 (*num)++;
295         } while (save == ',');
296
297         if (*num < min) {
298                 printk(KERN_ERR "%s: needs at least %i arguments\n",
299                        name, min);
300                 return -EINVAL;
301         }
302         return 0;
303 }
304
305 int param_array_set(const char *val, struct kernel_param *kp)
306 {
307         struct kparam_array *arr = kp->arg;
308
309         return param_array(kp->name, val, 1, arr->max, arr->elem,
310                            arr->elemsize, arr->set, arr->num ?: &arr->max);
311 }
312
313 int param_array_get(char *buffer, struct kernel_param *kp)
314 {
315         int i, off, ret;
316         struct kparam_array *arr = kp->arg;
317         struct kernel_param p;
318
319         p = *kp;
320         for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
321                 if (i)
322                         buffer[off++] = ',';
323                 p.arg = arr->elem + arr->elemsize * i;
324                 ret = arr->get(buffer + off, &p);
325                 if (ret < 0)
326                         return ret;
327                 off += ret;
328         }
329         buffer[off] = '\0';
330         return off;
331 }
332
333 int param_set_copystring(const char *val, struct kernel_param *kp)
334 {
335         struct kparam_string *kps = kp->arg;
336
337         if (strlen(val)+1 > kps->maxlen) {
338                 printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
339                        kp->name, kps->maxlen-1);
340                 return -ENOSPC;
341         }
342         strcpy(kps->string, val);
343         return 0;
344 }
345
346 int param_get_string(char *buffer, struct kernel_param *kp)
347 {
348         struct kparam_string *kps = kp->arg;
349         return strlcpy(buffer, kps->string, kps->maxlen);
350 }
351
352 /* sysfs output in /sys/modules/XYZ/parameters/ */
353
354 extern struct kernel_param __start___param[], __stop___param[];
355
356 #define MAX_KBUILD_MODNAME KOBJ_NAME_LEN
357
358 struct param_attribute
359 {
360         struct attribute attr;
361         struct kernel_param *param;
362 };
363
364 struct param_kobject
365 {
366         struct kobject kobj;
367
368         unsigned int num_attributes;
369         struct param_attribute attr[0];
370 };
371
372 #define to_param_attr(n) container_of(n, struct param_attribute, attr);
373
374 static ssize_t param_attr_show(struct kobject *kobj,
375                                struct attribute *attr,
376                                char *buf)
377 {
378         int count;
379         struct param_attribute *attribute = to_param_attr(attr);
380
381         if (!attribute->param->get)
382                 return -EPERM;
383
384         count = attribute->param->get(buf, attribute->param);
385         if (count > 0) {
386                 strcat(buf, "\n");
387                 ++count;
388         }
389         return count;
390 }
391
392 /* sysfs always hands a nul-terminated string in buf.  We rely on that. */
393 static ssize_t param_attr_store(struct kobject *kobj,
394                                 struct attribute *attr,
395                                 const char *buf, size_t len)
396 {
397         int err;
398         struct param_attribute *attribute = to_param_attr(attr);
399
400         if (!attribute->param->set)
401                 return -EPERM;
402
403         err = attribute->param->set(buf, attribute->param);
404         if (!err)
405                 return len;
406         return err;
407 }
408
409
410 static struct sysfs_ops param_sysfs_ops = {
411         .show = param_attr_show,
412         .store = param_attr_store,
413 };
414
415 static void param_kobj_release(struct kobject *kobj)
416 {
417         kfree(container_of(kobj, struct param_kobject, kobj));
418 }
419
420 static struct kobj_type param_ktype = {
421         .sysfs_ops =    &param_sysfs_ops,
422         .release =      &param_kobj_release,
423 };
424
425 static struct kset param_kset = {
426         .subsys =       &module_subsys,
427         .ktype =        &param_ktype,
428 };
429
430 #ifdef CONFIG_MODULES
431 #define __modinit
432 #else
433 #define __modinit __init
434 #endif
435
436 /*
437  * param_add_attribute - actually adds an parameter to sysfs
438  * @mod: owner of parameter
439  * @pk: param_kobject the attribute shall be assigned to.
440  *      One per module, one per KBUILD_MODNAME.
441  * @kp: kernel_param to be added
442  * @skip: offset where the parameter name start in kp->name.
443  * Needed for built-in modules
444  *
445  * Fill in data into appropriate &pk->attr[], and create sysfs file.
446  */
447 static __modinit int param_add_attribute(struct module *mod,
448                                          struct param_kobject *pk,
449                                          struct kernel_param *kp,
450                                          unsigned int skip)
451 {
452         struct param_attribute *a;
453         int err;
454
455         a = &pk->attr[pk->num_attributes];
456         a->attr.name = (char *) &kp->name[skip];
457         a->attr.owner = mod;
458         a->attr.mode = kp->perm;
459         a->param = kp;
460         err = sysfs_create_file(&pk->kobj, &a->attr);
461         if (!err)
462                 pk->num_attributes++;
463         return err;
464 }
465
466 /*
467  * param_sysfs_remove - remove sysfs support for one module or KBUILD_MODNAME
468  * @pk: struct param_kobject which is to be removed
469  *
470  * Called when an error in registration occurs or a module is removed
471  * from the system.
472  */
473 static __modinit void param_sysfs_remove(struct param_kobject *pk)
474 {
475         unsigned int i;
476         for (i = 0; i < pk->num_attributes; i++)
477                 sysfs_remove_file(&pk->kobj,&pk->attr[i].attr);
478
479         /* Calls param_kobj_release */
480         kobject_unregister(&pk->kobj);
481 }
482
483
484 /*
485  * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
486  * @mk: struct module_kobject (contains parent kobject)
487  * @kparam: array of struct kernel_param, the actual parameter definitions
488  * @num_params: number of entries in array
489  * @name_skip: offset where the parameter name start in kparam[].name. Needed for built-in "modules"
490  *
491  * Create a kobject for a (per-module) group of parameters, and create files
492  * in sysfs. A pointer to the param_kobject is returned on success,
493  * NULL if there's no parameter to export, or other ERR_PTR(err).
494  */
495 static __modinit struct param_kobject *
496 param_sysfs_setup(struct module_kobject *mk,
497                   struct kernel_param *kparam,
498                   unsigned int num_params,
499                   unsigned int name_skip)
500 {
501         struct param_kobject *pk;
502         unsigned int valid_attrs = 0;
503         unsigned int i;
504         int err;
505
506         for (i=0; i<num_params; i++) {
507                 if (kparam[i].perm)
508                         valid_attrs++;
509         }
510
511         if (!valid_attrs)
512                 return NULL;
513
514         pk = kmalloc(sizeof(struct param_kobject)
515                      + sizeof(struct param_attribute) * valid_attrs,
516                      GFP_KERNEL);
517         if (!pk)
518                 return ERR_PTR(-ENOMEM);
519         memset(pk, 0, sizeof(struct param_kobject)
520                + sizeof(struct param_attribute) * valid_attrs);
521
522         err = kobject_set_name(&pk->kobj, "parameters");
523         if (err)
524                 goto out;
525
526         pk->kobj.kset = &param_kset;
527         pk->kobj.parent = &mk->kobj;
528         err = kobject_register(&pk->kobj);
529         if (err)
530                 goto out;
531
532         for (i = 0; i < num_params; i++) {
533                 if (kparam[i].perm) {
534                         err = param_add_attribute(mk->mod, pk,
535                                                   &kparam[i], name_skip);
536                         if (err)
537                                 goto out_unreg;
538                 }
539         }
540
541         return pk;
542
543 out_unreg:
544         param_sysfs_remove(pk);
545         return ERR_PTR(err);
546
547 out:
548         kfree(pk);
549         return ERR_PTR(err);
550 }
551
552
553 #ifdef CONFIG_MODULES
554
555 /*
556  * module_param_sysfs_setup - setup sysfs support for one module
557  * @mod: module
558  * @kparam: module parameters (array)
559  * @num_params: number of module parameters
560  *
561  * Adds sysfs entries for module parameters, and creates a link from
562  * /sys/module/[mod->name]/parameters to /sys/parameters/[mod->name]/
563  */
564 int module_param_sysfs_setup(struct module *mod,
565                              struct kernel_param *kparam,
566                              unsigned int num_params)
567 {
568         struct param_kobject *pk;
569
570         pk = param_sysfs_setup(mod->mkobj, kparam, num_params, 0);
571         if (IS_ERR(pk))
572                 return PTR_ERR(pk);
573
574         mod->params_kobject = pk;
575         return 0;
576 }
577
578 /*
579  * module_param_sysfs_remove - remove sysfs support for one module
580  * @mod: module
581  *
582  * Remove sysfs entries for module parameters and the corresponding
583  * kobject.
584  */
585 void module_param_sysfs_remove(struct module *mod)
586 {
587         if (mod->params_kobject) {
588                 param_sysfs_remove(mod->params_kobject);
589                 mod->params_kobject = NULL;
590         }
591 }
592 #endif
593
594 /*
595  * kernel_param_sysfs_setup - wrapper for built-in params support
596  */
597 static void __init kernel_param_sysfs_setup(const char *name,
598                                             struct kernel_param *kparam,
599                                             unsigned int num_params,
600                                             unsigned int name_skip)
601 {
602         struct module_kobject *mk;
603
604         mk = kmalloc(sizeof(struct module_kobject), GFP_KERNEL);
605         memset(mk, 0, sizeof(struct module_kobject));
606
607         mk->mod = THIS_MODULE;
608         kobj_set_kset_s(mk, module_subsys);
609         kobject_set_name(&mk->kobj, name);
610         kobject_register(&mk->kobj);
611
612         /* no need to keep the kobject if no parameter is exported */
613         if (!param_sysfs_setup(mk, kparam, num_params, name_skip))
614                 kobject_unregister(&mk->kobj);
615 }
616
617 /*
618  * param_sysfs_builtin - add contents in /sys/parameters for built-in modules
619  *
620  * Add module_parameters to sysfs for "modules" built into the kernel.
621  *
622  * The "module" name (KBUILD_MODNAME) is stored before a dot, the
623  * "parameter" name is stored behind a dot in kernel_param->name. So,
624  * extract the "module" name for all built-in kernel_param-eters,
625  * and for all who have the same, call kernel_param_sysfs_setup.
626  */
627 static void __init param_sysfs_builtin(void)
628 {
629         struct kernel_param *kp, *kp_begin = NULL;
630         unsigned int i, name_len, count = 0;
631         char modname[MAX_KBUILD_MODNAME + 1] = "";
632
633         for (i=0; i < __stop___param - __start___param; i++) {
634                 char *dot;
635
636                 kp = &__start___param[i];
637
638                 /* We do not handle args without periods. */
639                 dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME);
640                 if (!dot) {
641                         DEBUGP("couldn't find period in %s\n", kp->name);
642                         continue;
643                 }
644                 name_len = dot - kp->name;
645
646                 /* new kbuild_modname? */
647                 if (strlen(modname) != name_len
648                     || strncmp(modname, kp->name, name_len) != 0) {
649                         /* add a new kobject for previous kernel_params. */
650                         if (count)
651                                 kernel_param_sysfs_setup(modname,
652                                                          kp_begin,
653                                                          count,
654                                                          strlen(modname)+1);
655
656                         strncpy(modname, kp->name, name_len);
657                         modname[name_len] = '\0';
658                         count = 0;
659                         kp_begin = kp;
660                 }
661                 count++;
662         }
663
664         /* last kernel_params need to be registered as well */
665         if (count)
666                 kernel_param_sysfs_setup(modname, kp_begin, count,
667                                          strlen(modname)+1);
668 }
669
670
671 /* module-related sysfs stuff */
672 #ifdef CONFIG_MODULES
673
674 #define to_module_attr(n) container_of(n, struct module_attribute, attr);
675 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
676
677 static ssize_t module_attr_show(struct kobject *kobj,
678                                 struct attribute *attr,
679                                 char *buf)
680 {
681         struct module_attribute *attribute;
682         struct module_kobject *mk;
683         int ret;
684
685         attribute = to_module_attr(attr);
686         mk = to_module_kobject(kobj);
687
688         if (!attribute->show)
689                 return -EPERM;
690
691         if (!try_module_get(mk->mod))
692                 return -ENODEV;
693
694         ret = attribute->show(mk->mod, buf);
695
696         module_put(mk->mod);
697
698         return ret;
699 }
700
701 static struct sysfs_ops module_sysfs_ops = {
702         .show = module_attr_show,
703         .store = NULL,
704 };
705
706 #else
707 static struct sysfs_ops module_sysfs_ops = {
708         .show = NULL,
709         .store = NULL,
710 };
711 #endif
712
713 static void module_kobj_release(struct kobject *kobj)
714 {
715         kfree(container_of(kobj, struct module_kobject, kobj));
716 }
717
718 static struct kobj_type module_ktype = {
719         .sysfs_ops =    &module_sysfs_ops,
720         .release =      &module_kobj_release,
721 };
722
723 decl_subsys(module, &module_ktype, NULL);
724
725 /*
726  * param_sysfs_init - wrapper for built-in params support
727  */
728 static int __init param_sysfs_init(void)
729 {
730         subsystem_register(&module_subsys);
731         kobject_set_name(&param_kset.kobj, "parameters");
732         kset_init(&param_kset);
733
734         param_sysfs_builtin();
735
736         return 0;
737 }
738 __initcall(param_sysfs_init);
739
740 EXPORT_SYMBOL(param_set_byte);
741 EXPORT_SYMBOL(param_get_byte);
742 EXPORT_SYMBOL(param_set_short);
743 EXPORT_SYMBOL(param_get_short);
744 EXPORT_SYMBOL(param_set_ushort);
745 EXPORT_SYMBOL(param_get_ushort);
746 EXPORT_SYMBOL(param_set_int);
747 EXPORT_SYMBOL(param_get_int);
748 EXPORT_SYMBOL(param_set_uint);
749 EXPORT_SYMBOL(param_get_uint);
750 EXPORT_SYMBOL(param_set_long);
751 EXPORT_SYMBOL(param_get_long);
752 EXPORT_SYMBOL(param_set_ulong);
753 EXPORT_SYMBOL(param_get_ulong);
754 EXPORT_SYMBOL(param_set_charp);
755 EXPORT_SYMBOL(param_get_charp);
756 EXPORT_SYMBOL(param_set_bool);
757 EXPORT_SYMBOL(param_get_bool);
758 EXPORT_SYMBOL(param_set_invbool);
759 EXPORT_SYMBOL(param_get_invbool);
760 EXPORT_SYMBOL(param_array_set);
761 EXPORT_SYMBOL(param_array_get);
762 EXPORT_SYMBOL(param_set_copystring);
763 EXPORT_SYMBOL(param_get_string);