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