Blame view

kernel/params.c 21.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /* Helpers for initial module or kernel cmdline parsing
     Copyright (C) 2001 Rusty Russell.
  
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.
  
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
  
      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
22
23
24
  #include <linux/moduleparam.h>
  #include <linux/kernel.h>
  #include <linux/string.h>
  #include <linux/errno.h>
  #include <linux/module.h>
  #include <linux/device.h>
  #include <linux/err.h>
4e57b6817   Tim Schmielau   [PATCH] fix missi...
25
  #include <linux/slab.h>
26d052bfc   Peter Oberparleiter   param: allow whit...
26
  #include <linux/ctype.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
31
32
  
  #if 0
  #define DEBUGP printk
  #else
  #define DEBUGP(fmt, a...)
  #endif
907b29eb4   Rusty Russell   param: locking fo...
33
34
  /* Protects all parameters, and incidentally kmalloced_param list. */
  static DEFINE_MUTEX(param_lock);
a1054322a   Rusty Russell   param: use free h...
35
36
37
38
39
  /* This just allows us to keep track of which parameters are kmalloced. */
  struct kmalloced_param {
  	struct list_head list;
  	char val[];
  };
a1054322a   Rusty Russell   param: use free h...
40
41
42
43
44
45
46
47
48
  static LIST_HEAD(kmalloced_params);
  
  static void *kmalloc_parameter(unsigned int size)
  {
  	struct kmalloced_param *p;
  
  	p = kmalloc(sizeof(*p) + size, GFP_KERNEL);
  	if (!p)
  		return NULL;
a1054322a   Rusty Russell   param: use free h...
49
  	list_add(&p->list, &kmalloced_params);
a1054322a   Rusty Russell   param: use free h...
50
51
52
53
54
55
56
  	return p->val;
  }
  
  /* Does nothing if parameter wasn't kmalloced above. */
  static void maybe_kfree_parameter(void *param)
  {
  	struct kmalloced_param *p;
a1054322a   Rusty Russell   param: use free h...
57
58
59
60
61
62
63
  	list_for_each_entry(p, &kmalloced_params, list) {
  		if (p->val == param) {
  			list_del(&p->list);
  			kfree(p);
  			break;
  		}
  	}
a1054322a   Rusty Russell   param: use free h...
64
  }
b9e20a920   Eric Sesterhenn   [PATCH] Change da...
65
  static inline char dash2underscore(char c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  {
  	if (c == '-')
  		return '_';
  	return c;
  }
  
  static inline int parameq(const char *input, const char *paramname)
  {
  	unsigned int i;
  	for (i = 0; dash2underscore(input[i]) == paramname[i]; i++)
  		if (input[i] == '\0')
  			return 1;
  	return 0;
  }
  
  static int parse_one(char *param,
  		     char *val,
914dcaa84   Rusty Russell   param: make param...
83
  		     const struct kernel_param *params,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
  		     unsigned num_params,
  		     int (*handle_unknown)(char *param, char *val))
  {
  	unsigned int i;
907b29eb4   Rusty Russell   param: locking fo...
88
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
91
92
  
  	/* Find parameter */
  	for (i = 0; i < num_params; i++) {
  		if (parameq(param, params[i].name)) {
2e9fb9953   Rusty Russell   params: don't han...
93
  			/* Noone handled NULL, so do it here. */
9bbb9e5a3   Rusty Russell   param: use ops in...
94
  			if (!val && params[i].ops->set != param_set_bool)
2e9fb9953   Rusty Russell   params: don't han...
95
  				return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
97
  			DEBUGP("They are equal!  Calling %p
  ",
9bbb9e5a3   Rusty Russell   param: use ops in...
98
  			       params[i].ops->set);
907b29eb4   Rusty Russell   param: locking fo...
99
100
101
102
  			mutex_lock(&param_lock);
  			err = params[i].ops->set(val, &params[i]);
  			mutex_unlock(&param_lock);
  			return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  		}
  	}
  
  	if (handle_unknown) {
  		DEBUGP("Unknown argument: calling %p
  ", handle_unknown);
  		return handle_unknown(param, val);
  	}
  
  	DEBUGP("Unknown argument `%s'
  ", param);
  	return -ENOENT;
  }
  
  /* You can use " around spaces, but can't escape ". */
  /* Hyphens and underscores equivalent in parameter names. */
  static char *next_arg(char *args, char **param, char **val)
  {
  	unsigned int i, equals = 0;
  	int in_quote = 0, quoted = 0;
  	char *next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
128
129
130
  	if (*args == '"') {
  		args++;
  		in_quote = 1;
  		quoted = 1;
  	}
  
  	for (i = 0; args[i]; i++) {
26d052bfc   Peter Oberparleiter   param: allow whit...
131
  		if (isspace(args[i]) && !in_quote)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  			break;
  		if (equals == 0) {
  			if (args[i] == '=')
  				equals = i;
  		}
  		if (args[i] == '"')
  			in_quote = !in_quote;
  	}
  
  	*param = args;
  	if (!equals)
  		*val = NULL;
  	else {
  		args[equals] = '\0';
  		*val = args + equals + 1;
  
  		/* Don't include quotes in value. */
  		if (**val == '"') {
  			(*val)++;
  			if (args[i-1] == '"')
  				args[i-1] = '\0';
  		}
  		if (quoted && args[i-1] == '"')
  			args[i-1] = '\0';
  	}
  
  	if (args[i]) {
  		args[i] = '\0';
  		next = args + i + 1;
  	} else
  		next = args + i;
f36462f07   Rusty Russell   [PATCH] Ignore tr...
163
164
  
  	/* Chew up trailing spaces. */
e7d2860b6   AndrĂ© Goddard Rosa   tree-wide: conver...
165
  	return skip_spaces(next);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
168
169
170
  }
  
  /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
  int parse_args(const char *name,
  	       char *args,
914dcaa84   Rusty Russell   param: make param...
171
  	       const struct kernel_param *params,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
175
176
177
178
  	       unsigned num,
  	       int (*unknown)(char *param, char *val))
  {
  	char *param, *val;
  
  	DEBUGP("Parsing ARGS: %s
  ", args);
f36462f07   Rusty Russell   [PATCH] Ignore tr...
179
  	/* Chew leading spaces */
e7d2860b6   AndrĂ© Goddard Rosa   tree-wide: conver...
180
  	args = skip_spaces(args);
f36462f07   Rusty Russell   [PATCH] Ignore tr...
181

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
  	while (*args) {
  		int ret;
a416aba63   Ard van Breemen   [PATCH] kernelpar...
184
  		int irq_was_disabled;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
  
  		args = next_arg(args, &param, &val);
a416aba63   Ard van Breemen   [PATCH] kernelpar...
187
  		irq_was_disabled = irqs_disabled();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  		ret = parse_one(param, val, params, num, unknown);
a416aba63   Ard van Breemen   [PATCH] kernelpar...
189
190
191
192
193
  		if (irq_was_disabled && !irqs_disabled()) {
  			printk(KERN_WARNING "parse_args(): option '%s' enabled "
  					"irq's!
  ", param);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  		switch (ret) {
  		case -ENOENT:
  			printk(KERN_ERR "%s: Unknown parameter `%s'
  ",
  			       name, param);
  			return ret;
  		case -ENOSPC:
  			printk(KERN_ERR
  			       "%s: `%s' too large for parameter `%s'
  ",
  			       name, val ?: "", param);
  			return ret;
  		case 0:
  			break;
  		default:
  			printk(KERN_ERR
  			       "%s: `%s' invalid for parameter `%s'
  ",
  			       name, val ?: "", param);
  			return ret;
  		}
  	}
  
  	/* All parsed OK. */
  	return 0;
  }
  
  /* Lazy bastard, eh? */
  #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)      	\
9bbb9e5a3   Rusty Russell   param: use ops in...
223
  	int param_set_##name(const char *val, const struct kernel_param *kp) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  	{								\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  		tmptype l;						\
06b2a76d2   Yi Yang   Add new string fu...
226
  		int ret;						\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
227
  									\
06b2a76d2   Yi Yang   Add new string fu...
228
229
  		ret = strtolfn(val, 0, &l);				\
  		if (ret == -EINVAL || ((type)l != l))			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
  			return -EINVAL;					\
  		*((type *)kp->arg) = l;					\
  		return 0;						\
  	}								\
9bbb9e5a3   Rusty Russell   param: use ops in...
234
  	int param_get_##name(char *buffer, const struct kernel_param *kp) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
  	{								\
  		return sprintf(buffer, format, *((type *)kp->arg));	\
a14fe249a   Rusty Russell   param: move the E...
237
  	}								\
9bbb9e5a3   Rusty Russell   param: use ops in...
238
239
240
241
  	struct kernel_param_ops param_ops_##name = {			\
  		.set = param_set_##name,				\
  		.get = param_get_##name,				\
  	};								\
a14fe249a   Rusty Russell   param: move the E...
242
  	EXPORT_SYMBOL(param_set_##name);				\
9bbb9e5a3   Rusty Russell   param: use ops in...
243
244
  	EXPORT_SYMBOL(param_get_##name);				\
  	EXPORT_SYMBOL(param_ops_##name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245

06b2a76d2   Yi Yang   Add new string fu...
246
247
248
249
250
251
252
  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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253

9bbb9e5a3   Rusty Russell   param: use ops in...
254
  int param_set_charp(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
258
259
260
261
  	if (strlen(val) > 1024) {
  		printk(KERN_ERR "%s: string parameter too long
  ",
  		       kp->name);
  		return -ENOSPC;
  	}
a1054322a   Rusty Russell   param: use free h...
262
263
264
  	maybe_kfree_parameter(*(char **)kp->arg);
  
  	/* This is a hack.  We can't kmalloc in early boot, and we
e180a6b77   Rusty Russell   param: fix charp ...
265
266
  	 * don't need to; this mangled commandline is preserved. */
  	if (slab_is_available()) {
a1054322a   Rusty Russell   param: use free h...
267
  		*(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
d553ad864   Rusty Russell   param: fix NULL c...
268
  		if (!*(char **)kp->arg)
e180a6b77   Rusty Russell   param: fix charp ...
269
  			return -ENOMEM;
a1054322a   Rusty Russell   param: use free h...
270
  		strcpy(*(char **)kp->arg, val);
e180a6b77   Rusty Russell   param: fix charp ...
271
272
  	} else
  		*(const char **)kp->arg = val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
273
274
  	return 0;
  }
a14fe249a   Rusty Russell   param: move the E...
275
  EXPORT_SYMBOL(param_set_charp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276

9bbb9e5a3   Rusty Russell   param: use ops in...
277
  int param_get_charp(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
279
280
  {
  	return sprintf(buffer, "%s", *((char **)kp->arg));
  }
a14fe249a   Rusty Russell   param: move the E...
281
  EXPORT_SYMBOL(param_get_charp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282

a1054322a   Rusty Russell   param: use free h...
283
284
285
286
  static void param_free_charp(void *arg)
  {
  	maybe_kfree_parameter(*((char **)arg));
  }
9bbb9e5a3   Rusty Russell   param: use ops in...
287
288
289
  struct kernel_param_ops param_ops_charp = {
  	.set = param_set_charp,
  	.get = param_get_charp,
a1054322a   Rusty Russell   param: use free h...
290
  	.free = param_free_charp,
9bbb9e5a3   Rusty Russell   param: use ops in...
291
292
  };
  EXPORT_SYMBOL(param_ops_charp);
fddd52012   Rusty Russell   module_param: all...
293
  /* Actually could be a bool or an int, for historical reasons. */
9bbb9e5a3   Rusty Russell   param: use ops in...
294
  int param_set_bool(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  {
fddd52012   Rusty Russell   module_param: all...
296
  	bool v;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
300
301
302
  	/* No equals means "set"... */
  	if (!val) val = "1";
  
  	/* One of =[yYnN01] */
  	switch (val[0]) {
  	case 'y': case 'Y': case '1':
fddd52012   Rusty Russell   module_param: all...
303
304
  		v = true;
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
  	case 'n': case 'N': case '0':
fddd52012   Rusty Russell   module_param: all...
306
307
308
309
  		v = false;
  		break;
  	default:
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  	}
fddd52012   Rusty Russell   module_param: all...
311
312
313
314
315
316
  
  	if (kp->flags & KPARAM_ISBOOL)
  		*(bool *)kp->arg = v;
  	else
  		*(int *)kp->arg = v;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  }
a14fe249a   Rusty Russell   param: move the E...
318
  EXPORT_SYMBOL(param_set_bool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319

9bbb9e5a3   Rusty Russell   param: use ops in...
320
  int param_get_bool(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
  {
fddd52012   Rusty Russell   module_param: all...
322
323
324
325
326
  	bool val;
  	if (kp->flags & KPARAM_ISBOOL)
  		val = *(bool *)kp->arg;
  	else
  		val = *(int *)kp->arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  	/* Y and N chosen as being relatively non-coder friendly */
fddd52012   Rusty Russell   module_param: all...
328
  	return sprintf(buffer, "%c", val ? 'Y' : 'N');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
  }
a14fe249a   Rusty Russell   param: move the E...
330
  EXPORT_SYMBOL(param_get_bool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331

9bbb9e5a3   Rusty Russell   param: use ops in...
332
333
334
335
336
  struct kernel_param_ops param_ops_bool = {
  	.set = param_set_bool,
  	.get = param_get_bool,
  };
  EXPORT_SYMBOL(param_ops_bool);
fddd52012   Rusty Russell   module_param: all...
337
  /* This one must be bool. */
9bbb9e5a3   Rusty Russell   param: use ops in...
338
  int param_set_invbool(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  {
fddd52012   Rusty Russell   module_param: all...
340
341
  	int ret;
  	bool boolval;
22e48eaf5   Jan Beulich   constify string/a...
342
  	struct kernel_param dummy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343

22e48eaf5   Jan Beulich   constify string/a...
344
  	dummy.arg = &boolval;
fddd52012   Rusty Russell   module_param: all...
345
  	dummy.flags = KPARAM_ISBOOL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
  	ret = param_set_bool(val, &dummy);
  	if (ret == 0)
9a71af2c3   Rusty Russell   module_param: inv...
348
  		*(bool *)kp->arg = !boolval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
  	return ret;
  }
a14fe249a   Rusty Russell   param: move the E...
351
  EXPORT_SYMBOL(param_set_invbool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352

9bbb9e5a3   Rusty Russell   param: use ops in...
353
  int param_get_invbool(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
  {
9a71af2c3   Rusty Russell   module_param: inv...
355
  	return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  }
a14fe249a   Rusty Russell   param: move the E...
357
  EXPORT_SYMBOL(param_get_invbool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358

9bbb9e5a3   Rusty Russell   param: use ops in...
359
360
361
362
363
  struct kernel_param_ops param_ops_invbool = {
  	.set = param_set_invbool,
  	.get = param_get_invbool,
  };
  EXPORT_SYMBOL(param_ops_invbool);
9730b5b06   Bert Wesarg   kernel/params.c: ...
364
  /* We break the rule and mangle the string. */
9871728b7   Adrian Bunk   [PATCH] kernel/pa...
365
366
367
368
  static int param_array(const char *name,
  		       const char *val,
  		       unsigned int min, unsigned int max,
  		       void *elem, int elemsize,
9bbb9e5a3   Rusty Russell   param: use ops in...
369
  		       int (*set)(const char *, const struct kernel_param *kp),
3c7d76e37   Rusty Russell   param: fix settin...
370
  		       u16 flags,
eb38a996e   Richard Knutsson   kernel/params.c: ...
371
  		       unsigned int *num)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
373
374
375
376
377
378
379
  {
  	int ret;
  	struct kernel_param kp;
  	char save;
  
  	/* Get the name right for errors. */
  	kp.name = name;
  	kp.arg = elem;
3c7d76e37   Rusty Russell   param: fix settin...
380
  	kp.flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
381

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
  	*num = 0;
  	/* We expect a comma-separated list of values. */
  	do {
  		int len;
  
  		if (*num == max) {
  			printk(KERN_ERR "%s: can only take %i arguments
  ",
  			       name, max);
  			return -EINVAL;
  		}
  		len = strcspn(val, ",");
  
  		/* nul-terminate and parse */
  		save = val[len];
  		((char *)val)[len] = '\0';
907b29eb4   Rusty Russell   param: locking fo...
398
  		BUG_ON(!mutex_is_locked(&param_lock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  		ret = set(val, &kp);
  
  		if (ret != 0)
  			return ret;
  		kp.arg += elemsize;
  		val += len+1;
  		(*num)++;
  	} while (save == ',');
  
  	if (*num < min) {
  		printk(KERN_ERR "%s: needs at least %i arguments
  ",
  		       name, min);
  		return -EINVAL;
  	}
  	return 0;
  }
9bbb9e5a3   Rusty Russell   param: use ops in...
416
  static int param_array_set(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
417
  {
22e48eaf5   Jan Beulich   constify string/a...
418
  	const struct kparam_array *arr = kp->arr;
31143a120   Bert Wesarg   [PATCH] kernel/pa...
419
  	unsigned int temp_num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
  
  	return param_array(kp->name, val, 1, arr->max, arr->elem,
9bbb9e5a3   Rusty Russell   param: use ops in...
422
  			   arr->elemsize, arr->ops->set, kp->flags,
3c7d76e37   Rusty Russell   param: fix settin...
423
  			   arr->num ?: &temp_num);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
  }
9bbb9e5a3   Rusty Russell   param: use ops in...
425
  static int param_array_get(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
  {
  	int i, off, ret;
22e48eaf5   Jan Beulich   constify string/a...
428
  	const struct kparam_array *arr = kp->arr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
429
430
431
432
433
434
435
  	struct kernel_param p;
  
  	p = *kp;
  	for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
  		if (i)
  			buffer[off++] = ',';
  		p.arg = arr->elem + arr->elemsize * i;
907b29eb4   Rusty Russell   param: locking fo...
436
  		BUG_ON(!mutex_is_locked(&param_lock));
9bbb9e5a3   Rusty Russell   param: use ops in...
437
  		ret = arr->ops->get(buffer + off, &p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
443
444
  		if (ret < 0)
  			return ret;
  		off += ret;
  	}
  	buffer[off] = '\0';
  	return off;
  }
e6df34a44   Rusty Russell   param: add a free...
445
446
447
448
449
450
451
452
453
  static void param_array_free(void *arg)
  {
  	unsigned int i;
  	const struct kparam_array *arr = arg;
  
  	if (arr->ops->free)
  		for (i = 0; i < (arr->num ? *arr->num : arr->max); i++)
  			arr->ops->free(arr->elem + arr->elemsize * i);
  }
9bbb9e5a3   Rusty Russell   param: use ops in...
454
455
456
  struct kernel_param_ops param_array_ops = {
  	.set = param_array_set,
  	.get = param_array_get,
e6df34a44   Rusty Russell   param: add a free...
457
  	.free = param_array_free,
9bbb9e5a3   Rusty Russell   param: use ops in...
458
459
460
461
  };
  EXPORT_SYMBOL(param_array_ops);
  
  int param_set_copystring(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  {
22e48eaf5   Jan Beulich   constify string/a...
463
  	const struct kparam_string *kps = kp->str;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
467
468
469
470
471
472
473
  
  	if (strlen(val)+1 > kps->maxlen) {
  		printk(KERN_ERR "%s: string doesn't fit in %u chars.
  ",
  		       kp->name, kps->maxlen-1);
  		return -ENOSPC;
  	}
  	strcpy(kps->string, val);
  	return 0;
  }
a14fe249a   Rusty Russell   param: move the E...
474
  EXPORT_SYMBOL(param_set_copystring);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475

9bbb9e5a3   Rusty Russell   param: use ops in...
476
  int param_get_string(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
  {
22e48eaf5   Jan Beulich   constify string/a...
478
  	const struct kparam_string *kps = kp->str;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479
480
  	return strlcpy(buffer, kps->string, kps->maxlen);
  }
a14fe249a   Rusty Russell   param: move the E...
481
  EXPORT_SYMBOL(param_get_string);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482

9bbb9e5a3   Rusty Russell   param: use ops in...
483
484
485
486
487
  struct kernel_param_ops param_ops_string = {
  	.set = param_set_copystring,
  	.get = param_get_string,
  };
  EXPORT_SYMBOL(param_ops_string);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
488
  /* sysfs output in /sys/modules/XYZ/parameters/ */
350f82586   Edward Z. Yang   Remove redundant ...
489
490
  #define to_module_attr(n) container_of(n, struct module_attribute, attr)
  #define to_module_kobject(n) container_of(n, struct module_kobject, kobj)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
  
  extern struct kernel_param __start___param[], __stop___param[];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
494
495
  struct param_attribute
  {
  	struct module_attribute mattr;
9bbb9e5a3   Rusty Russell   param: use ops in...
496
  	const struct kernel_param *param;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
500
  };
  
  struct module_param_attrs
  {
9b473de87   Rusty Russell   param: Fix duplic...
501
  	unsigned int num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
504
  	struct attribute_group grp;
  	struct param_attribute attrs[0];
  };
ef665c1a0   Randy Dunlap   sysfs: fix build ...
505
  #ifdef CONFIG_SYSFS
350f82586   Edward Z. Yang   Remove redundant ...
506
  #define to_param_attr(n) container_of(n, struct param_attribute, mattr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
508
509
510
511
512
  
  static ssize_t param_attr_show(struct module_attribute *mattr,
  			       struct module *mod, char *buf)
  {
  	int count;
  	struct param_attribute *attribute = to_param_attr(mattr);
9bbb9e5a3   Rusty Russell   param: use ops in...
513
  	if (!attribute->param->ops->get)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
  		return -EPERM;
907b29eb4   Rusty Russell   param: locking fo...
515
  	mutex_lock(&param_lock);
9bbb9e5a3   Rusty Russell   param: use ops in...
516
  	count = attribute->param->ops->get(buf, attribute->param);
907b29eb4   Rusty Russell   param: locking fo...
517
  	mutex_unlock(&param_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
  	if (count > 0) {
  		strcat(buf, "
  ");
  		++count;
  	}
  	return count;
  }
  
  /* sysfs always hands a nul-terminated string in buf.  We rely on that. */
  static ssize_t param_attr_store(struct module_attribute *mattr,
  				struct module *owner,
  				const char *buf, size_t len)
  {
   	int err;
  	struct param_attribute *attribute = to_param_attr(mattr);
9bbb9e5a3   Rusty Russell   param: use ops in...
533
  	if (!attribute->param->ops->set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
  		return -EPERM;
907b29eb4   Rusty Russell   param: locking fo...
535
  	mutex_lock(&param_lock);
9bbb9e5a3   Rusty Russell   param: use ops in...
536
  	err = attribute->param->ops->set(buf, attribute->param);
907b29eb4   Rusty Russell   param: locking fo...
537
  	mutex_unlock(&param_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
539
540
541
  	if (!err)
  		return len;
  	return err;
  }
ef665c1a0   Randy Dunlap   sysfs: fix build ...
542
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
546
547
548
  
  #ifdef CONFIG_MODULES
  #define __modinit
  #else
  #define __modinit __init
  #endif
ef665c1a0   Randy Dunlap   sysfs: fix build ...
549
  #ifdef CONFIG_SYSFS
907b29eb4   Rusty Russell   param: locking fo...
550
551
552
553
554
555
556
557
558
559
560
  void __kernel_param_lock(void)
  {
  	mutex_lock(&param_lock);
  }
  EXPORT_SYMBOL(__kernel_param_lock);
  
  void __kernel_param_unlock(void)
  {
  	mutex_unlock(&param_lock);
  }
  EXPORT_SYMBOL(__kernel_param_unlock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
561
  /*
9b473de87   Rusty Russell   param: Fix duplic...
562
563
564
565
   * add_sysfs_param - add a parameter to sysfs
   * @mk: struct module_kobject
   * @kparam: the actual parameter definition to add to sysfs
   * @name: name of parameter
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
   *
9b473de87   Rusty Russell   param: Fix duplic...
567
568
569
   * Create a kobject if for a (per-module) parameter if mp NULL, and
   * create file in sysfs.  Returns an error on out of memory.  Always cleans up
   * if there's an error.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
570
   */
9b473de87   Rusty Russell   param: Fix duplic...
571
  static __modinit int add_sysfs_param(struct module_kobject *mk,
9bbb9e5a3   Rusty Russell   param: use ops in...
572
  				     const struct kernel_param *kp,
9b473de87   Rusty Russell   param: Fix duplic...
573
  				     const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
  {
9b473de87   Rusty Russell   param: Fix duplic...
575
576
577
578
579
580
581
582
583
584
585
586
587
  	struct module_param_attrs *new;
  	struct attribute **attrs;
  	int err, num;
  
  	/* We don't bother calling this with invisible parameters. */
  	BUG_ON(!kp->perm);
  
  	if (!mk->mp) {
  		num = 0;
  		attrs = NULL;
  	} else {
  		num = mk->mp->num;
  		attrs = mk->mp->grp.attrs;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
588
  	}
9b473de87   Rusty Russell   param: Fix duplic...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  	/* Enlarge. */
  	new = krealloc(mk->mp,
  		       sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1),
  		       GFP_KERNEL);
  	if (!new) {
  		kfree(mk->mp);
  		err = -ENOMEM;
  		goto fail;
  	}
  	attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL);
  	if (!attrs) {
  		err = -ENOMEM;
  		goto fail_free_new;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603

9b473de87   Rusty Russell   param: Fix duplic...
604
605
606
607
608
609
610
611
  	/* Sysfs wants everything zeroed. */
  	memset(new, 0, sizeof(*new));
  	memset(&new->attrs[num], 0, sizeof(new->attrs[num]));
  	memset(&attrs[num], 0, sizeof(attrs[num]));
  	new->grp.name = "parameters";
  	new->grp.attrs = attrs;
  
  	/* Tack new one on the end. */
a07e4156a   Eric W. Biederman   sysfs: Use sysfs_...
612
  	sysfs_attr_init(&new->attrs[num].mattr.attr);
9b473de87   Rusty Russell   param: Fix duplic...
613
614
615
616
617
618
619
620
621
622
623
624
625
626
  	new->attrs[num].param = kp;
  	new->attrs[num].mattr.show = param_attr_show;
  	new->attrs[num].mattr.store = param_attr_store;
  	new->attrs[num].mattr.attr.name = (char *)name;
  	new->attrs[num].mattr.attr.mode = kp->perm;
  	new->num = num+1;
  
  	/* Fix up all the pointers, since krealloc can move us */
  	for (num = 0; num < new->num; num++)
  		new->grp.attrs[num] = &new->attrs[num].mattr.attr;
  	new->grp.attrs[num] = NULL;
  
  	mk->mp = new;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627

9b473de87   Rusty Russell   param: Fix duplic...
628
629
630
631
632
633
  fail_free_new:
  	kfree(new);
  fail:
  	mk->mp = NULL;
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634

d2441183d   Linus Torvalds   Fix compile warni...
635
  #ifdef CONFIG_MODULES
9b473de87   Rusty Russell   param: Fix duplic...
636
637
638
639
640
  static void free_module_param_attrs(struct module_kobject *mk)
  {
  	kfree(mk->mp->grp.attrs);
  	kfree(mk->mp);
  	mk->mp = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
643
644
645
646
647
  /*
   * module_param_sysfs_setup - setup sysfs support for one module
   * @mod: module
   * @kparam: module parameters (array)
   * @num_params: number of module parameters
   *
9b473de87   Rusty Russell   param: Fix duplic...
648
649
   * Adds sysfs entries for module parameters under
   * /sys/module/[mod->name]/parameters/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
651
   */
  int module_param_sysfs_setup(struct module *mod,
9bbb9e5a3   Rusty Russell   param: use ops in...
652
  			     const struct kernel_param *kparam,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
654
  			     unsigned int num_params)
  {
9b473de87   Rusty Russell   param: Fix duplic...
655
656
657
658
659
660
661
662
663
664
665
  	int i, err;
  	bool params = false;
  
  	for (i = 0; i < num_params; i++) {
  		if (kparam[i].perm == 0)
  			continue;
  		err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name);
  		if (err)
  			return err;
  		params = true;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666

9b473de87   Rusty Russell   param: Fix duplic...
667
668
  	if (!params)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669

9b473de87   Rusty Russell   param: Fix duplic...
670
671
672
673
674
  	/* Create the param group. */
  	err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
  	if (err)
  		free_module_param_attrs(&mod->mkobj);
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
675
676
677
678
679
680
681
682
683
684
685
  }
  
  /*
   * module_param_sysfs_remove - remove sysfs support for one module
   * @mod: module
   *
   * Remove sysfs entries for module parameters and the corresponding
   * kobject.
   */
  void module_param_sysfs_remove(struct module *mod)
  {
9b473de87   Rusty Russell   param: Fix duplic...
686
687
  	if (mod->mkobj.mp) {
  		sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
689
  		/* We are positive that no one is using any param
  		 * attrs at this point.  Deallocate immediately. */
9b473de87   Rusty Russell   param: Fix duplic...
690
  		free_module_param_attrs(&mod->mkobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
693
  	}
  }
  #endif
e180a6b77   Rusty Russell   param: fix charp ...
694
695
  void destroy_params(const struct kernel_param *params, unsigned num)
  {
e6df34a44   Rusty Russell   param: add a free...
696
697
698
699
700
  	unsigned int i;
  
  	for (i = 0; i < num; i++)
  		if (params[i].ops->free)
  			params[i].ops->free(params[i].arg);
e180a6b77   Rusty Russell   param: fix charp ...
701
  }
e94965ed5   Dmitry Torokhov   module: show vers...
702
  static struct module_kobject * __init locate_module_kobject(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
  {
  	struct module_kobject *mk;
9b473de87   Rusty Russell   param: Fix duplic...
705
706
  	struct kobject *kobj;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
707

9b473de87   Rusty Russell   param: Fix duplic...
708
709
  	kobj = kset_find_obj(module_kset, name);
  	if (kobj) {
9b473de87   Rusty Russell   param: Fix duplic...
710
  		mk = to_module_kobject(kobj);
9b473de87   Rusty Russell   param: Fix duplic...
711
712
713
714
715
716
717
718
719
720
  	} else {
  		mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
  		BUG_ON(!mk);
  
  		mk->mod = THIS_MODULE;
  		mk->kobj.kset = module_kset;
  		err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL,
  					   "%s", name);
  		if (err) {
  			kobject_put(&mk->kobj);
e94965ed5   Dmitry Torokhov   module: show vers...
721
722
723
724
725
726
727
728
  			printk(KERN_ERR
  				"Module '%s' failed add to sysfs, error number %d
  ",
  				name, err);
  			printk(KERN_ERR
  				"The system will be unstable now.
  ");
  			return NULL;
9b473de87   Rusty Russell   param: Fix duplic...
729
  		}
e94965ed5   Dmitry Torokhov   module: show vers...
730
731
  
  		/* So that we hold reference in both cases. */
9b473de87   Rusty Russell   param: Fix duplic...
732
  		kobject_get(&mk->kobj);
74c5b597e   Greg Kroah-Hartman   modules: better e...
733
  	}
9b473de87   Rusty Russell   param: Fix duplic...
734

e94965ed5   Dmitry Torokhov   module: show vers...
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
  	return mk;
  }
  
  static void __init kernel_add_sysfs_param(const char *name,
  					  struct kernel_param *kparam,
  					  unsigned int name_skip)
  {
  	struct module_kobject *mk;
  	int err;
  
  	mk = locate_module_kobject(name);
  	if (!mk)
  		return;
  
  	/* We need to remove old parameters before adding more. */
  	if (mk->mp)
  		sysfs_remove_group(&mk->kobj, &mk->mp->grp);
9b473de87   Rusty Russell   param: Fix duplic...
752
753
754
755
756
  	/* These should not fail at boot. */
  	err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
  	BUG_ON(err);
  	err = sysfs_create_group(&mk->kobj, &mk->mp->grp);
  	BUG_ON(err);
f30c53a87   Kay Sievers   MODULES: add the ...
757
  	kobject_uevent(&mk->kobj, KOBJ_ADD);
9b473de87   Rusty Russell   param: Fix duplic...
758
  	kobject_put(&mk->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
760
761
762
763
764
765
766
767
768
  }
  
  /*
   * param_sysfs_builtin - add contents in /sys/parameters for built-in modules
   *
   * Add module_parameters to sysfs for "modules" built into the kernel.
   *
   * The "module" name (KBUILD_MODNAME) is stored before a dot, the
   * "parameter" name is stored behind a dot in kernel_param->name. So,
   * extract the "module" name for all built-in kernel_param-eters,
9b473de87   Rusty Russell   param: Fix duplic...
769
   * and for all who have the same, call kernel_add_sysfs_param.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
771
772
   */
  static void __init param_sysfs_builtin(void)
  {
9b473de87   Rusty Russell   param: Fix duplic...
773
774
775
  	struct kernel_param *kp;
  	unsigned int name_len;
  	char modname[MODULE_NAME_LEN];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776

9b473de87   Rusty Russell   param: Fix duplic...
777
  	for (kp = __start___param; kp < __stop___param; kp++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
  		char *dot;
9b473de87   Rusty Russell   param: Fix duplic...
779
780
  		if (kp->perm == 0)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781

730b69d22   Rusty Russell   module: check ker...
782
  		dot = strchr(kp->name, '.');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783
  		if (!dot) {
67e67ceaa   Rusty Russell   core_param() for ...
784
785
786
787
788
789
  			/* This happens for core_param() */
  			strcpy(modname, "kernel");
  			name_len = 0;
  		} else {
  			name_len = dot - kp->name + 1;
  			strlcpy(modname, kp->name, name_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
790
  		}
67e67ceaa   Rusty Russell   core_param() for ...
791
  		kernel_add_sysfs_param(modname, kp, name_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
793
  }
e94965ed5   Dmitry Torokhov   module: show vers...
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  ssize_t __modver_version_show(struct module_attribute *mattr,
  			      struct module *mod, char *buf)
  {
  	struct module_version_attribute *vattr =
  		container_of(mattr, struct module_version_attribute, mattr);
  
  	return sprintf(buf, "%s
  ", vattr->version);
  }
  
  extern struct module_version_attribute __start___modver[], __stop___modver[];
  
  static void __init version_sysfs_builtin(void)
  {
  	const struct module_version_attribute *vattr;
  	struct module_kobject *mk;
  	int err;
  
  	for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
  		mk = locate_module_kobject(vattr->module_name);
  		if (mk) {
  			err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
  			kobject_uevent(&mk->kobj, KOBJ_ADD);
  			kobject_put(&mk->kobj);
  		}
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
821
822
  
  /* module-related sysfs stuff */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824
825
826
827
828
829
830
831
832
833
834
835
  static ssize_t module_attr_show(struct kobject *kobj,
  				struct attribute *attr,
  				char *buf)
  {
  	struct module_attribute *attribute;
  	struct module_kobject *mk;
  	int ret;
  
  	attribute = to_module_attr(attr);
  	mk = to_module_kobject(kobj);
  
  	if (!attribute->show)
70f2817a4   Dmitry Torokhov   [PATCH] sysfs: (r...
836
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
  	ret = attribute->show(attribute, mk->mod, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
  	return ret;
  }
  
  static ssize_t module_attr_store(struct kobject *kobj,
  				struct attribute *attr,
  				const char *buf, size_t len)
  {
  	struct module_attribute *attribute;
  	struct module_kobject *mk;
  	int ret;
  
  	attribute = to_module_attr(attr);
  	mk = to_module_kobject(kobj);
  
  	if (!attribute->store)
70f2817a4   Dmitry Torokhov   [PATCH] sysfs: (r...
854
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  	ret = attribute->store(attribute, mk->mod, buf, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
858
  	return ret;
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
859
  static const struct sysfs_ops module_sysfs_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
862
  	.show = module_attr_show,
  	.store = module_attr_store,
  };
270a6c4ca   Kay Sievers   /sys/modules/*/ho...
863
864
865
866
867
868
869
870
  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;
  }
9cd43611c   Emese Revfy   kobject: Constify...
871
  static const struct kset_uevent_ops module_uevent_ops = {
270a6c4ca   Kay Sievers   /sys/modules/*/ho...
872
873
  	.filter = uevent_filter,
  };
7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
874
  struct kset *module_kset;
823bccfc4   Greg Kroah-Hartman   remove "struct su...
875
  int module_sysfs_initialized;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
876

7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
877
  struct kobj_type module_ktype = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
879
  	.sysfs_ops =	&module_sysfs_ops,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
880
881
882
883
884
  /*
   * param_sysfs_init - wrapper for built-in params support
   */
  static int __init param_sysfs_init(void)
  {
7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
885
886
887
888
889
890
  	module_kset = kset_create_and_add("module", &module_uevent_ops, NULL);
  	if (!module_kset) {
  		printk(KERN_WARNING "%s (%d): error creating kset
  ",
  			__FILE__, __LINE__);
  		return -ENOMEM;
d8c7649e9   Randy Dunlap   [PATCH] kernel/pa...
891
  	}
823bccfc4   Greg Kroah-Hartman   remove "struct su...
892
  	module_sysfs_initialized = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893

e94965ed5   Dmitry Torokhov   module: show vers...
894
  	version_sysfs_builtin();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
895
896
897
898
  	param_sysfs_builtin();
  
  	return 0;
  }
d10be6d1b   Mark Huang   [PATCH] module_su...
899
  subsys_initcall(param_sysfs_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900

7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
901
  #endif /* CONFIG_SYSFS */