gcov-kernel: Add ARM eABI support
[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/module.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>
27
28 /* Protects all parameters, and incidentally kmalloced_param list. */
29 static DEFINE_MUTEX(param_lock);
30
31 /* This just allows us to keep track of which parameters are kmalloced. */
32 struct kmalloced_param {
33         struct list_head list;
34         char val[];
35 };
36 static LIST_HEAD(kmalloced_params);
37
38 static void *kmalloc_parameter(unsigned int size)
39 {
40         struct kmalloced_param *p;
41
42         p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
43         if (!p)
44                 return NULL;
45
46         list_add(&p->list, &kmalloced_params);
47         return p->val;
48 }
49
50 /* Does nothing if parameter wasn't kmalloced above. */
51 static void maybe_kfree_parameter(void *param)
52 {
53         struct kmalloced_param *p;
54
55         list_for_each_entry(p, &kmalloced_params, list) {
56                 if (p->val == param) {
57                         list_del(&p->list);
58                         kfree(p);
59                         break;
60                 }
61         }
62 }
63
64 static char dash2underscore(char c)
65 {
66         if (c == '-')
67                 return '_';
68         return c;
69 }
70
71 bool parameqn(const char *a, const char *b, size_t n)
72 {
73         size_t i;
74
75         for (i = 0; i < n; i++) {
76                 if (dash2underscore(a[i]) != dash2underscore(b[i]))
77                         return false;
78         }
79         return true;
80 }
81
82 bool parameq(const char *a, const char *b)
83 {
84         return parameqn(a, b, strlen(a)+1);
85 }
86
87 static int parse_one(char *param,
88                      char *val,
89                      const struct kernel_param *params,
90                      unsigned num_params,
91                      int (*handle_unknown)(char *param, char *val))
92 {
93         unsigned int i;
94         int err;
95
96         /* Find parameter */
97         for (i = 0; i < num_params; i++) {
98                 if (parameq(param, params[i].name)) {
99                         /* No one handled NULL, so do it here. */
100                         if (!val && params[i].ops->set != param_set_bool
101                             && params[i].ops->set != param_set_bint)
102                                 return -EINVAL;
103                         pr_debug("They are equal!  Calling %p\n",
104                                params[i].ops->set);
105                         mutex_lock(&param_lock);
106                         err = params[i].ops->set(val, &params[i]);
107                         mutex_unlock(&param_lock);
108                         return err;
109                 }
110         }
111
112         if (handle_unknown) {
113                 pr_debug("Unknown argument: calling %p\n", handle_unknown);
114                 return handle_unknown(param, val);
115         }
116
117         pr_debug("Unknown argument `%s'\n", param);
118         return -ENOENT;
119 }
120
121 /* You can use " around spaces, but can't escape ". */
122 /* Hyphens and underscores equivalent in parameter names. */
123 static char *next_arg(char *args, char **param, char **val)
124 {
125         unsigned int i, equals = 0;
126         int in_quote = 0, quoted = 0;
127         char *next;
128
129         if (*args == '"') {
130                 args++;
131                 in_quote = 1;
132                 quoted = 1;
133         }
134
135         for (i = 0; args[i]; i++) {
136                 if (isspace(args[i]) && !in_quote)
137                         break;
138                 if (equals == 0) {
139                         if (args[i] == '=')
140                                 equals = i;
141                 }
142                 if (args[i] == '"')
143                         in_quote = !in_quote;
144         }
145
146         *param = args;
147         if (!equals)
148                 *val = NULL;
149         else {
150                 args[equals] = '\0';
151                 *val = args + equals + 1;
152
153                 /* Don't include quotes in value. */
154                 if (**val == '"') {
155                         (*val)++;
156                         if (args[i-1] == '"')
157                                 args[i-1] = '\0';
158                 }
159                 if (quoted && args[i-1] == '"')
160                         args[i-1] = '\0';
161         }
162
163         if (args[i]) {
164                 args[i] = '\0';
165                 next = args + i + 1;
166         } else
167                 next = args + i;
168
169         /* Chew up trailing spaces. */
170         return skip_spaces(next);
171 }
172
173 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
174 int parse_args(const char *name,
175                char *args,
176                const struct kernel_param *params,
177                unsigned num,
178                int (*unknown)(char *param, char *val))
179 {
180         char *param, *val;
181
182         pr_debug("Parsing ARGS: %s\n", args);
183
184         /* Chew leading spaces */
185         args = skip_spaces(args);
186
187         while (*args) {
188                 int ret;
189                 int irq_was_disabled;
190
191                 args = next_arg(args, &param, &val);
192                 irq_was_disabled = irqs_disabled();
193                 ret = parse_one(param, val, params, num, unknown);
194                 if (irq_was_disabled && !irqs_disabled()) {
195                         printk(KERN_WARNING "parse_args(): option '%s' enabled "
196                                         "irq's!\n", param);
197                 }
198                 switch (ret) {
199                 case -ENOENT:
200                         printk(KERN_ERR "%s: Unknown parameter `%s'\n",
201                                name, param);
202                         return ret;
203                 case -ENOSPC:
204                         printk(KERN_ERR
205                                "%s: `%s' too large for parameter `%s'\n",
206                                name, val ?: "", param);
207                         return ret;
208                 case 0:
209                         break;
210                 default:
211                         printk(KERN_ERR
212                                "%s: `%s' invalid for parameter `%s'\n",
213                                name, val ?: "", param);
214                         return ret;
215                 }
216         }
217
218         /* All parsed OK. */
219         return 0;
220 }
221
222 /* Lazy bastard, eh? */
223 #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)       \
224         int param_set_##name(const char *val, const struct kernel_param *kp) \
225         {                                                               \
226                 tmptype l;                                              \
227                 int ret;                                                \
228                                                                         \
229                 ret = strtolfn(val, 0, &l);                             \
230                 if (ret < 0 || ((type)l != l))                          \
231                         return ret < 0 ? ret : -EINVAL;                 \
232                 *((type *)kp->arg) = l;                                 \
233                 return 0;                                               \
234         }                                                               \
235         int param_get_##name(char *buffer, const struct kernel_param *kp) \
236         {                                                               \
237                 return sprintf(buffer, format, *((type *)kp->arg));     \
238         }                                                               \
239         struct kernel_param_ops param_ops_##name = {                    \
240                 .set = param_set_##name,                                \
241                 .get = param_get_##name,                                \
242         };                                                              \
243         EXPORT_SYMBOL(param_set_##name);                                \
244         EXPORT_SYMBOL(param_get_##name);                                \
245         EXPORT_SYMBOL(param_ops_##name)
246
247
248 STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul);
249 STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol);
250 STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul);
251 STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol);
252 STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul);
253 STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol);
254 STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul);
255
256 int param_set_charp(const char *val, const struct kernel_param *kp)
257 {
258         if (strlen(val) > 1024) {
259                 printk(KERN_ERR "%s: string parameter too long\n",
260                        kp->name);
261                 return -ENOSPC;
262         }
263
264         maybe_kfree_parameter(*(char **)kp->arg);
265
266         /* This is a hack.  We can't kmalloc in early boot, and we
267          * don't need to; this mangled commandline is preserved. */
268         if (slab_is_available()) {
269                 *(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
270                 if (!*(char **)kp->arg)
271                         return -ENOMEM;
272                 strcpy(*(char **)kp->arg, val);
273         } else
274                 *(const char **)kp->arg = val;
275
276         return 0;
277 }
278 EXPORT_SYMBOL(param_set_charp);
279
280 int param_get_charp(char *buffer, const struct kernel_param *kp)
281 {
282         return sprintf(buffer, "%s", *((char **)kp->arg));
283 }
284 EXPORT_SYMBOL(param_get_charp);
285
286 static void param_free_charp(void *arg)
287 {
288         maybe_kfree_parameter(*((char **)arg));
289 }
290
291 struct kernel_param_ops param_ops_charp = {
292         .set = param_set_charp,
293         .get = param_get_charp,
294         .free = param_free_charp,
295 };
296 EXPORT_SYMBOL(param_ops_charp);
297
298 /* Actually could be a bool or an int, for historical reasons. */
299 int param_set_bool(const char *val, const struct kernel_param *kp)
300 {
301         bool v;
302         int ret;
303
304         /* No equals means "set"... */
305         if (!val) val = "1";
306
307         /* One of =[yYnN01] */
308         ret = strtobool(val, &v);
309         if (ret)
310                 return ret;
311
312         if (kp->flags & KPARAM_ISBOOL)
313                 *(bool *)kp->arg = v;
314         else
315                 *(int *)kp->arg = v;
316         return 0;
317 }
318 EXPORT_SYMBOL(param_set_bool);
319
320 int param_get_bool(char *buffer, const struct kernel_param *kp)
321 {
322         bool val;
323         if (kp->flags & KPARAM_ISBOOL)
324                 val = *(bool *)kp->arg;
325         else
326                 val = *(int *)kp->arg;
327
328         /* Y and N chosen as being relatively non-coder friendly */
329         return sprintf(buffer, "%c", val ? 'Y' : 'N');
330 }
331 EXPORT_SYMBOL(param_get_bool);
332
333 struct kernel_param_ops param_ops_bool = {
334         .set = param_set_bool,
335         .get = param_get_bool,
336 };
337 EXPORT_SYMBOL(param_ops_bool);
338
339 /* This one must be bool. */
340 int param_set_invbool(const char *val, const struct kernel_param *kp)
341 {
342         int ret;
343         bool boolval;
344         struct kernel_param dummy;
345
346         dummy.arg = &boolval;
347         dummy.flags = KPARAM_ISBOOL;
348         ret = param_set_bool(val, &dummy);
349         if (ret == 0)
350                 *(bool *)kp->arg = !boolval;
351         return ret;
352 }
353 EXPORT_SYMBOL(param_set_invbool);
354
355 int param_get_invbool(char *buffer, const struct kernel_param *kp)
356 {
357         return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
358 }
359 EXPORT_SYMBOL(param_get_invbool);
360
361 struct kernel_param_ops param_ops_invbool = {
362         .set = param_set_invbool,
363         .get = param_get_invbool,
364 };
365 EXPORT_SYMBOL(param_ops_invbool);
366
367 int param_set_bint(const char *val, const struct kernel_param *kp)
368 {
369         struct kernel_param boolkp;
370         bool v;
371         int ret;
372
373         /* Match bool exactly, by re-using it. */
374         boolkp = *kp;
375         boolkp.arg = &v;
376         boolkp.flags |= KPARAM_ISBOOL;
377
378         ret = param_set_bool(val, &boolkp);
379         if (ret == 0)
380                 *(int *)kp->arg = v;
381         return ret;
382 }
383 EXPORT_SYMBOL(param_set_bint);
384
385 struct kernel_param_ops param_ops_bint = {
386         .set = param_set_bint,
387         .get = param_get_int,
388 };
389 EXPORT_SYMBOL(param_ops_bint);
390
391 /* We break the rule and mangle the string. */
392 static int param_array(const char *name,
393                        const char *val,
394                        unsigned int min, unsigned int max,
395                        void *elem, int elemsize,
396                        int (*set)(const char *, const struct kernel_param *kp),
397                        u16 flags,
398                        unsigned int *num)
399 {
400         int ret;
401         struct kernel_param kp;
402         char save;
403
404         /* Get the name right for errors. */
405         kp.name = name;
406         kp.arg = elem;
407         kp.flags = flags;
408
409         *num = 0;
410         /* We expect a comma-separated list of values. */
411         do {
412                 int len;
413
414                 if (*num == max) {
415                         printk(KERN_ERR "%s: can only take %i arguments\n",
416                                name, max);
417                         return -EINVAL;
418                 }
419                 len = strcspn(val, ",");
420
421                 /* nul-terminate and parse */
422                 save = val[len];
423                 ((char *)val)[len] = '\0';
424                 BUG_ON(!mutex_is_locked(&param_lock));
425                 ret = set(val, &kp);
426
427                 if (ret != 0)
428                         return ret;
429                 kp.arg += elemsize;
430                 val += len+1;
431                 (*num)++;
432         } while (save == ',');
433
434         if (*num < min) {
435                 printk(KERN_ERR "%s: needs at least %i arguments\n",
436                        name, min);
437                 return -EINVAL;
438         }
439         return 0;
440 }
441
442 static int param_array_set(const char *val, const struct kernel_param *kp)
443 {
444         const struct kparam_array *arr = kp->arr;
445         unsigned int temp_num;
446
447         return param_array(kp->name, val, 1, arr->max, arr->elem,
448                            arr->elemsize, arr->ops->set, kp->flags,
449                            arr->num ?: &temp_num);
450 }
451
452 static int param_array_get(char *buffer, const struct kernel_param *kp)
453 {
454         int i, off, ret;
455         const struct kparam_array *arr = kp->arr;
456         struct kernel_param p;
457
458         p = *kp;
459         for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
460                 if (i)
461                         buffer[off++] = ',';
462                 p.arg = arr->elem + arr->elemsize * i;
463                 BUG_ON(!mutex_is_locked(&param_lock));
464                 ret = arr->ops->get(buffer + off, &p);
465                 if (ret < 0)
466                         return ret;
467                 off += ret;
468         }
469         buffer[off] = '\0';
470         return off;
471 }
472
473 static void param_array_free(void *arg)
474 {
475         unsigned int i;
476         const struct kparam_array *arr = arg;
477
478         if (arr->ops->free)
479                 for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
480                         arr->ops->free(arr->elem + arr->elemsize * i);
481 }
482
483 struct kernel_param_ops param_array_ops = {
484         .set = param_array_set,
485         .get = param_array_get,
486         .free = param_array_free,
487 };
488 EXPORT_SYMBOL(param_array_ops);
489
490 int param_set_copystring(const char *val, const struct kernel_param *kp)
491 {
492         const struct kparam_string *kps = kp->str;
493
494         if (strlen(val)+1 > kps->maxlen) {
495                 printk(KERN_ERR "%s: string doesn't fit in %u chars.\n",
496                        kp->name, kps->maxlen-1);
497                 return -ENOSPC;
498         }
499         strcpy(kps->string, val);
500         return 0;
501 }
502 EXPORT_SYMBOL(param_set_copystring);
503
504 int param_get_string(char *buffer, const struct kernel_param *kp)
505 {
506         const struct kparam_string *kps = kp->str;
507         return strlcpy(buffer, kps->string, kps->maxlen);
508 }
509 EXPORT_SYMBOL(param_get_string);
510
511 struct kernel_param_ops param_ops_string = {
512         .set = param_set_copystring,
513         .get = param_get_string,
514 };
515 EXPORT_SYMBOL(param_ops_string);
516
517 /* sysfs output in /sys/modules/XYZ/parameters/ */
518 #define to_module_attr(n) container_of(n, struct module_attribute, attr)
519 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
520
521 extern struct kernel_param __start___param[], __stop___param[];
522
523 struct param_attribute
524 {
525         struct module_attribute mattr;
526         const struct kernel_param *param;
527 };
528
529 struct module_param_attrs
530 {
531         unsigned int num;
532         struct attribute_group grp;
533         struct param_attribute attrs[0];
534 };
535
536 #ifdef CONFIG_SYSFS
537 #define to_param_attr(n) container_of(n, struct param_attribute, mattr)
538
539 static ssize_t param_attr_show(struct module_attribute *mattr,
540                                struct module_kobject *mk, char *buf)
541 {
542         int count;
543         struct param_attribute *attribute = to_param_attr(mattr);
544
545         if (!attribute->param->ops->get)
546                 return -EPERM;
547
548         mutex_lock(&param_lock);
549         count = attribute->param->ops->get(buf, attribute->param);
550         mutex_unlock(&param_lock);
551         if (count > 0) {
552                 strcat(buf, "\n");
553                 ++count;
554         }
555         return count;
556 }
557
558 /* sysfs always hands a nul-terminated string in buf.  We rely on that. */
559 static ssize_t param_attr_store(struct module_attribute *mattr,
560                                 struct module_kobject *km,
561                                 const char *buf, size_t len)
562 {
563         int err;
564         struct param_attribute *attribute = to_param_attr(mattr);
565
566         if (!attribute->param->ops->set)
567                 return -EPERM;
568
569         mutex_lock(&param_lock);
570         err = attribute->param->ops->set(buf, attribute->param);
571         mutex_unlock(&param_lock);
572         if (!err)
573                 return len;
574         return err;
575 }
576 #endif
577
578 #ifdef CONFIG_MODULES
579 #define __modinit
580 #else
581 #define __modinit __init
582 #endif
583
584 #ifdef CONFIG_SYSFS
585 void __kernel_param_lock(void)
586 {
587         mutex_lock(&param_lock);
588 }
589 EXPORT_SYMBOL(__kernel_param_lock);
590
591 void __kernel_param_unlock(void)
592 {
593         mutex_unlock(&param_lock);
594 }
595 EXPORT_SYMBOL(__kernel_param_unlock);
596
597 /*
598  * add_sysfs_param - add a parameter to sysfs
599  * @mk: struct module_kobject
600  * @kparam: the actual parameter definition to add to sysfs
601  * @name: name of parameter
602  *
603  * Create a kobject if for a (per-module) parameter if mp NULL, and
604  * create file in sysfs.  Returns an error on out of memory.  Always cleans up
605  * if there's an error.
606  */
607 static __modinit int add_sysfs_param(struct module_kobject *mk,
608                                      const struct kernel_param *kp,
609                                      const char *name)
610 {
611         struct module_param_attrs *new;
612         struct attribute **attrs;
613         int err, num;
614
615         /* We don't bother calling this with invisible parameters. */
616         BUG_ON(!kp->perm);
617
618         if (!mk->mp) {
619                 num = 0;
620                 attrs = NULL;
621         } else {
622                 num = mk->mp->num;
623                 attrs = mk->mp->grp.attrs;
624         }
625
626         /* Enlarge. */
627         new = krealloc(mk->mp,
628                        sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1),
629                        GFP_KERNEL);
630         if (!new) {
631                 kfree(mk->mp);
632                 err = -ENOMEM;
633                 goto fail;
634         }
635         attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL);
636         if (!attrs) {
637                 err = -ENOMEM;
638                 goto fail_free_new;
639         }
640
641         /* Sysfs wants everything zeroed. */
642         memset(new, 0, sizeof(*new));
643         memset(&new->attrs[num], 0, sizeof(new->attrs[num]));
644         memset(&attrs[num], 0, sizeof(attrs[num]));
645         new->grp.name = "parameters";
646         new->grp.attrs = attrs;
647
648         /* Tack new one on the end. */
649         sysfs_attr_init(&new->attrs[num].mattr.attr);
650         new->attrs[num].param = kp;
651         new->attrs[num].mattr.show = param_attr_show;
652         new->attrs[num].mattr.store = param_attr_store;
653         new->attrs[num].mattr.attr.name = (char *)name;
654         new->attrs[num].mattr.attr.mode = kp->perm;
655         new->num = num+1;
656
657         /* Fix up all the pointers, since krealloc can move us */
658         for (num = 0; num < new->num; num++)
659                 new->grp.attrs[num] = &new->attrs[num].mattr.attr;
660         new->grp.attrs[num] = NULL;
661
662         mk->mp = new;
663         return 0;
664
665 fail_free_new:
666         kfree(new);
667 fail:
668         mk->mp = NULL;
669         return err;
670 }
671
672 #ifdef CONFIG_MODULES
673 static void free_module_param_attrs(struct module_kobject *mk)
674 {
675         kfree(mk->mp->grp.attrs);
676         kfree(mk->mp);
677         mk->mp = NULL;
678 }
679
680 /*
681  * module_param_sysfs_setup - setup sysfs support for one module
682  * @mod: module
683  * @kparam: module parameters (array)
684  * @num_params: number of module parameters
685  *
686  * Adds sysfs entries for module parameters under
687  * /sys/module/[mod->name]/parameters/
688  */
689 int module_param_sysfs_setup(struct module *mod,
690                              const struct kernel_param *kparam,
691                              unsigned int num_params)
692 {
693         int i, err;
694         bool params = false;
695
696         for (i = 0; i < num_params; i++) {
697                 if (kparam[i].perm == 0)
698                         continue;
699                 err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
700                 if (err)
701                         return err;
702                 params = true;
703         }
704
705         if (!params)
706                 return 0;
707
708         /* Create the param group. */
709         err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
710         if (err)
711                 free_module_param_attrs(&mod->mkobj);
712         return err;
713 }
714
715 /*
716  * module_param_sysfs_remove - remove sysfs support for one module
717  * @mod: module
718  *
719  * Remove sysfs entries for module parameters and the corresponding
720  * kobject.
721  */
722 void module_param_sysfs_remove(struct module *mod)
723 {
724         if (mod->mkobj.mp) {
725                 sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
726                 /* We are positive that no one is using any param
727                  * attrs at this point.  Deallocate immediately. */
728                 free_module_param_attrs(&mod->mkobj);
729         }
730 }
731 #endif
732
733 void destroy_params(const struct kernel_param *params, unsigned num)
734 {
735         unsigned int i;
736
737         for (i = 0; i < num; i++)
738                 if (params[i].ops->free)
739                         params[i].ops->free(params[i].arg);
740 }
741
742 static struct module_kobject * __init locate_module_kobject(const char *name)
743 {
744         struct module_kobject *mk;
745         struct kobject *kobj;
746         int err;
747
748         kobj = kset_find_obj(module_kset, name);
749         if (kobj) {
750                 mk = to_module_kobject(kobj);
751         } else {
752                 mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
753                 BUG_ON(!mk);
754
755                 mk->mod = THIS_MODULE;
756                 mk->kobj.kset = module_kset;
757                 err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
758                                            "%s", name);
759 #ifdef CONFIG_MODULES
760                 if (!err)
761                         err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
762 #endif
763                 if (err) {
764                         kobject_put(&mk->kobj);
765                         printk(KERN_ERR
766                                 "Module '%s' failed add to sysfs, error number %d\n",
767                                 name, err);
768                         printk(KERN_ERR
769                                 "The system will be unstable now.\n");
770                         return NULL;
771                 }
772
773                 /* So that we hold reference in both cases. */
774                 kobject_get(&mk->kobj);
775         }
776
777         return mk;
778 }
779
780 static void __init kernel_add_sysfs_param(const char *name,
781                                           struct kernel_param *kparam,
782                                           unsigned int name_skip)
783 {
784         struct module_kobject *mk;
785         int err;
786
787         mk = locate_module_kobject(name);
788         if (!mk)
789                 return;
790
791         /* We need to remove old parameters before adding more. */
792         if (mk->mp)
793                 sysfs_remove_group(&mk->kobj, &mk->mp->grp);
794
795         /* These should not fail at boot. */
796         err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
797         BUG_ON(err);
798         err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
799         BUG_ON(err);
800         kobject_uevent(&mk->kobj, KOBJ_ADD);
801         kobject_put(&mk->kobj);
802 }
803
804 /*
805  * param_sysfs_builtin - add contents in /sys/parameters for built-in modules
806  *
807  * Add module_parameters to sysfs for "modules" built into the kernel.
808  *
809  * The "module" name (KBUILD_MODNAME) is stored before a dot, the
810  * "parameter" name is stored behind a dot in kernel_param->name. So,
811  * extract the "module" name for all built-in kernel_param-eters,
812  * and for all who have the same, call kernel_add_sysfs_param.
813  */
814 static void __init param_sysfs_builtin(void)
815 {
816         struct kernel_param *kp;
817         unsigned int name_len;
818         char modname[MODULE_NAME_LEN];
819
820         for (kp = __start___param; kp < __stop___param; kp++) {
821                 char *dot;
822
823                 if (kp->perm == 0)
824                         continue;
825
826                 dot = strchr(kp->name, '.');
827                 if (!dot) {
828                         /* This happens for core_param() */
829                         strcpy(modname, "kernel");
830                         name_len = 0;
831                 } else {
832                         name_len = dot - kp->name + 1;
833                         strlcpy(modname, kp->name, name_len);
834                 }
835                 kernel_add_sysfs_param(modname, kp, name_len);
836         }
837 }
838
839 ssize_t __modver_version_show(struct module_attribute *mattr,
840                               struct module_kobject *mk, char *buf)
841 {
842         struct module_version_attribute *vattr =
843                 container_of(mattr, struct module_version_attribute, mattr);
844
845         return sprintf(buf, "%s\n", vattr->version);
846 }
847
848 extern const struct module_version_attribute *__start___modver[];
849 extern const struct module_version_attribute *__stop___modver[];
850
851 static void __init version_sysfs_builtin(void)
852 {
853         const struct module_version_attribute **p;
854         struct module_kobject *mk;
855         int err;
856
857         for (p = __start___modver; p < __stop___modver; p++) {
858                 const struct module_version_attribute *vattr = *p;
859
860                 mk = locate_module_kobject(vattr->module_name);
861                 if (mk) {
862                         err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
863                         kobject_uevent(&mk->kobj, KOBJ_ADD);
864                         kobject_put(&mk->kobj);
865                 }
866         }
867 }
868
869 /* module-related sysfs stuff */
870
871 static ssize_t module_attr_show(struct kobject *kobj,
872                                 struct attribute *attr,
873                                 char *buf)
874 {
875         struct module_attribute *attribute;
876         struct module_kobject *mk;
877         int ret;
878
879         attribute = to_module_attr(attr);
880         mk = to_module_kobject(kobj);
881
882         if (!attribute->show)
883                 return -EIO;
884
885         ret = attribute->show(attribute, mk, buf);
886
887         return ret;
888 }
889
890 static ssize_t module_attr_store(struct kobject *kobj,
891                                 struct attribute *attr,
892                                 const char *buf, size_t len)
893 {
894         struct module_attribute *attribute;
895         struct module_kobject *mk;
896         int ret;
897
898         attribute = to_module_attr(attr);
899         mk = to_module_kobject(kobj);
900
901         if (!attribute->store)
902                 return -EIO;
903
904         ret = attribute->store(attribute, mk, buf, len);
905
906         return ret;
907 }
908
909 static const struct sysfs_ops module_sysfs_ops = {
910         .show = module_attr_show,
911         .store = module_attr_store,
912 };
913
914 static int uevent_filter(struct kset *kset, struct kobject *kobj)
915 {
916         struct kobj_type *ktype = get_ktype(kobj);
917
918         if (ktype == &module_ktype)
919                 return 1;
920         return 0;
921 }
922
923 static const struct kset_uevent_ops module_uevent_ops = {
924         .filter = uevent_filter,
925 };
926
927 struct kset *module_kset;
928 int module_sysfs_initialized;
929
930 struct kobj_type module_ktype = {
931         .sysfs_ops =    &module_sysfs_ops,
932 };
933
934 /*
935  * param_sysfs_init - wrapper for built-in params support
936  */
937 static int __init param_sysfs_init(void)
938 {
939         module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
940         if (!module_kset) {
941                 printk(KERN_WARNING "%s (%d): error creating kset\n",
942                         __FILE__, __LINE__);
943                 return -ENOMEM;
944         }
945         module_sysfs_initialized = 1;
946
947         version_sysfs_builtin();
948         param_sysfs_builtin();
949
950         return 0;
951 }
952 subsys_initcall(param_sysfs_init);
953
954 #endif /* CONFIG_SYSFS */