Blame view

kernel/params.c 21.5 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
  */
72a59aaad   Paul Gortmaker   kernel: params.c ...
18
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
  #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
  }
b1e4d20cb   Michal Schmidt   params: make dash...
65
  static char dash2underscore(char c)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
  {
  	if (c == '-')
  		return '_';
  	return c;
  }
b1e4d20cb   Michal Schmidt   params: make dash...
71
  bool parameqn(const char *a, const char *b, size_t n)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
  {
b1e4d20cb   Michal Schmidt   params: make dash...
73
74
75
76
77
78
79
80
81
82
83
84
  	size_t i;
  
  	for (i = 0; i < n; i++) {
  		if (dash2underscore(a[i]) != dash2underscore(b[i]))
  			return false;
  	}
  	return true;
  }
  
  bool parameq(const char *a, const char *b)
  {
  	return parameqn(a, b, strlen(a)+1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
86
87
88
  }
  
  static int parse_one(char *param,
  		     char *val,
914dcaa84   Rusty Russell   param: make param...
89
  		     const struct kernel_param *params,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
91
92
93
  		     unsigned num_params,
  		     int (*handle_unknown)(char *param, char *val))
  {
  	unsigned int i;
907b29eb4   Rusty Russell   param: locking fo...
94
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
97
98
  
  	/* Find parameter */
  	for (i = 0; i < num_params; i++) {
  		if (parameq(param, params[i].name)) {
25985edce   Lucas De Marchi   Fix common misspe...
99
  			/* No one handled NULL, so do it here. */
9bbb9e5a3   Rusty Russell   param: use ops in...
100
  			if (!val && params[i].ops->set != param_set_bool)
2e9fb9953   Rusty Russell   params: don't han...
101
  				return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
  			DEBUGP("They are equal!  Calling %p
  ",
9bbb9e5a3   Rusty Russell   param: use ops in...
104
  			       params[i].ops->set);
907b29eb4   Rusty Russell   param: locking fo...
105
106
107
108
  			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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
  		}
  	}
  
  	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
130
131
132
133
134
135
136
  	if (*args == '"') {
  		args++;
  		in_quote = 1;
  		quoted = 1;
  	}
  
  	for (i = 0; args[i]; i++) {
26d052bfc   Peter Oberparleiter   param: allow whit...
137
  		if (isspace(args[i]) && !in_quote)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
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
163
164
165
166
167
168
  			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...
169
170
  
  	/* Chew up trailing spaces. */
e7d2860b6   AndrĂ© Goddard Rosa   tree-wide: conver...
171
  	return skip_spaces(next);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
175
176
  }
  
  /* Args looks like "foo=bar,bar2 baz=fuz wiz". */
  int parse_args(const char *name,
  	       char *args,
914dcaa84   Rusty Russell   param: make param...
177
  	       const struct kernel_param *params,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
182
183
184
  	       unsigned num,
  	       int (*unknown)(char *param, char *val))
  {
  	char *param, *val;
  
  	DEBUGP("Parsing ARGS: %s
  ", args);
f36462f07   Rusty Russell   [PATCH] Ignore tr...
185
  	/* Chew leading spaces */
e7d2860b6   AndrĂ© Goddard Rosa   tree-wide: conver...
186
  	args = skip_spaces(args);
f36462f07   Rusty Russell   [PATCH] Ignore tr...
187

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
  	while (*args) {
  		int ret;
a416aba63   Ard van Breemen   [PATCH] kernelpar...
190
  		int irq_was_disabled;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
  
  		args = next_arg(args, &param, &val);
a416aba63   Ard van Breemen   [PATCH] kernelpar...
193
  		irq_was_disabled = irqs_disabled();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
194
  		ret = parse_one(param, val, params, num, unknown);
a416aba63   Ard van Breemen   [PATCH] kernelpar...
195
196
197
198
199
  		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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  		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...
229
  	int param_set_##name(const char *val, const struct kernel_param *kp) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
  	{								\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
  		tmptype l;						\
06b2a76d2   Yi Yang   Add new string fu...
232
  		int ret;						\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
  									\
06b2a76d2   Yi Yang   Add new string fu...
234
  		ret = strtolfn(val, 0, &l);				\
81c741365   Satoru Moriya   param: fix return...
235
236
  		if (ret < 0 || ((type)l != l))				\
  			return ret < 0 ? ret : -EINVAL;			\
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
239
  		*((type *)kp->arg) = l;					\
  		return 0;						\
  	}								\
9bbb9e5a3   Rusty Russell   param: use ops in...
240
  	int param_get_##name(char *buffer, const struct kernel_param *kp) \
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
  	{								\
  		return sprintf(buffer, format, *((type *)kp->arg));	\
a14fe249a   Rusty Russell   param: move the E...
243
  	}								\
9bbb9e5a3   Rusty Russell   param: use ops in...
244
245
246
247
  	struct kernel_param_ops param_ops_##name = {			\
  		.set = param_set_##name,				\
  		.get = param_get_##name,				\
  	};								\
a14fe249a   Rusty Russell   param: move the E...
248
  	EXPORT_SYMBOL(param_set_##name);				\
9bbb9e5a3   Rusty Russell   param: use ops in...
249
250
  	EXPORT_SYMBOL(param_get_##name);				\
  	EXPORT_SYMBOL(param_ops_##name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251

06b2a76d2   Yi Yang   Add new string fu...
252
253
254
255
256
257
258
  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
259

9bbb9e5a3   Rusty Russell   param: use ops in...
260
  int param_set_charp(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
  	if (strlen(val) > 1024) {
  		printk(KERN_ERR "%s: string parameter too long
  ",
  		       kp->name);
  		return -ENOSPC;
  	}
a1054322a   Rusty Russell   param: use free h...
268
269
270
  	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 ...
271
272
  	 * don't need to; this mangled commandline is preserved. */
  	if (slab_is_available()) {
a1054322a   Rusty Russell   param: use free h...
273
  		*(char **)kp->arg = kmalloc_parameter(strlen(val)+1);
d553ad864   Rusty Russell   param: fix NULL c...
274
  		if (!*(char **)kp->arg)
e180a6b77   Rusty Russell   param: fix charp ...
275
  			return -ENOMEM;
a1054322a   Rusty Russell   param: use free h...
276
  		strcpy(*(char **)kp->arg, val);
e180a6b77   Rusty Russell   param: fix charp ...
277
278
  	} else
  		*(const char **)kp->arg = val;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
280
  	return 0;
  }
a14fe249a   Rusty Russell   param: move the E...
281
  EXPORT_SYMBOL(param_set_charp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282

9bbb9e5a3   Rusty Russell   param: use ops in...
283
  int param_get_charp(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
  {
  	return sprintf(buffer, "%s", *((char **)kp->arg));
  }
a14fe249a   Rusty Russell   param: move the E...
287
  EXPORT_SYMBOL(param_get_charp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288

a1054322a   Rusty Russell   param: use free h...
289
290
291
292
  static void param_free_charp(void *arg)
  {
  	maybe_kfree_parameter(*((char **)arg));
  }
9bbb9e5a3   Rusty Russell   param: use ops in...
293
294
295
  struct kernel_param_ops param_ops_charp = {
  	.set = param_set_charp,
  	.get = param_get_charp,
a1054322a   Rusty Russell   param: use free h...
296
  	.free = param_free_charp,
9bbb9e5a3   Rusty Russell   param: use ops in...
297
298
  };
  EXPORT_SYMBOL(param_ops_charp);
fddd52012   Rusty Russell   module_param: all...
299
  /* Actually could be a bool or an int, for historical reasons. */
9bbb9e5a3   Rusty Russell   param: use ops in...
300
  int param_set_bool(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  {
fddd52012   Rusty Russell   module_param: all...
302
  	bool v;
f721a465c   Jonathan Cameron   params.c: Use new...
303
  	int ret;
fddd52012   Rusty Russell   module_param: all...
304

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
305
306
307
308
  	/* No equals means "set"... */
  	if (!val) val = "1";
  
  	/* One of =[yYnN01] */
f721a465c   Jonathan Cameron   params.c: Use new...
309
310
311
  	ret = strtobool(val, &v);
  	if (ret)
  		return ret;
fddd52012   Rusty Russell   module_param: all...
312
313
314
315
316
317
  
  	if (kp->flags & KPARAM_ISBOOL)
  		*(bool *)kp->arg = v;
  	else
  		*(int *)kp->arg = v;
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
  }
a14fe249a   Rusty Russell   param: move the E...
319
  EXPORT_SYMBOL(param_set_bool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320

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

9bbb9e5a3   Rusty Russell   param: use ops in...
333
334
335
336
337
  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...
338
  /* This one must be bool. */
9bbb9e5a3   Rusty Russell   param: use ops in...
339
  int param_set_invbool(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
  {
fddd52012   Rusty Russell   module_param: all...
341
342
  	int ret;
  	bool boolval;
22e48eaf5   Jan Beulich   constify string/a...
343
  	struct kernel_param dummy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344

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

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

9bbb9e5a3   Rusty Russell   param: use ops in...
360
361
362
363
364
  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: ...
365
  /* We break the rule and mangle the string. */
9871728b7   Adrian Bunk   [PATCH] kernel/pa...
366
367
368
369
  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...
370
  		       int (*set)(const char *, const struct kernel_param *kp),
3c7d76e37   Rusty Russell   param: fix settin...
371
  		       u16 flags,
eb38a996e   Richard Knutsson   kernel/params.c: ...
372
  		       unsigned int *num)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
375
376
377
378
379
380
  {
  	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...
381
  	kp.flags = flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
  	*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...
399
  		BUG_ON(!mutex_is_locked(&param_lock));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  		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...
417
  static int param_array_set(const char *val, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
  {
22e48eaf5   Jan Beulich   constify string/a...
419
  	const struct kparam_array *arr = kp->arr;
31143a120   Bert Wesarg   [PATCH] kernel/pa...
420
  	unsigned int temp_num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
422
  
  	return param_array(kp->name, val, 1, arr->max, arr->elem,
9bbb9e5a3   Rusty Russell   param: use ops in...
423
  			   arr->elemsize, arr->ops->set, kp->flags,
3c7d76e37   Rusty Russell   param: fix settin...
424
  			   arr->num ?: &temp_num);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
  }
9bbb9e5a3   Rusty Russell   param: use ops in...
426
  static int param_array_get(char *buffer, const struct kernel_param *kp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
  {
  	int i, off, ret;
22e48eaf5   Jan Beulich   constify string/a...
429
  	const struct kparam_array *arr = kp->arr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
431
432
433
434
435
436
  	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...
437
  		BUG_ON(!mutex_is_locked(&param_lock));
9bbb9e5a3   Rusty Russell   param: use ops in...
438
  		ret = arr->ops->get(buffer + off, &p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
439
440
441
442
443
444
445
  		if (ret < 0)
  			return ret;
  		off += ret;
  	}
  	buffer[off] = '\0';
  	return off;
  }
e6df34a44   Rusty Russell   param: add a free...
446
447
448
449
450
451
452
453
454
  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...
455
456
457
  struct kernel_param_ops param_array_ops = {
  	.set = param_array_set,
  	.get = param_array_get,
e6df34a44   Rusty Russell   param: add a free...
458
  	.free = param_array_free,
9bbb9e5a3   Rusty Russell   param: use ops in...
459
460
461
462
  };
  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
463
  {
22e48eaf5   Jan Beulich   constify string/a...
464
  	const struct kparam_string *kps = kp->str;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
468
469
470
471
472
473
474
  
  	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...
475
  EXPORT_SYMBOL(param_set_copystring);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
476

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

9bbb9e5a3   Rusty Russell   param: use ops in...
484
485
486
487
488
  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
489
  /* sysfs output in /sys/modules/XYZ/parameters/ */
350f82586   Edward Z. Yang   Remove redundant ...
490
491
  #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
492
493
  
  extern struct kernel_param __start___param[], __stop___param[];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
  struct param_attribute
  {
  	struct module_attribute mattr;
9bbb9e5a3   Rusty Russell   param: use ops in...
497
  	const struct kernel_param *param;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
500
501
  };
  
  struct module_param_attrs
  {
9b473de87   Rusty Russell   param: Fix duplic...
502
  	unsigned int num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503
504
505
  	struct attribute_group grp;
  	struct param_attribute attrs[0];
  };
ef665c1a0   Randy Dunlap   sysfs: fix build ...
506
  #ifdef CONFIG_SYSFS
350f82586   Edward Z. Yang   Remove redundant ...
507
  #define to_param_attr(n) container_of(n, struct param_attribute, mattr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
509
  
  static ssize_t param_attr_show(struct module_attribute *mattr,
4befb026c   Kay Sievers   module: change at...
510
  			       struct module_kobject *mk, char *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
512
513
  {
  	int count;
  	struct param_attribute *attribute = to_param_attr(mattr);
9bbb9e5a3   Rusty Russell   param: use ops in...
514
  	if (!attribute->param->ops->get)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515
  		return -EPERM;
907b29eb4   Rusty Russell   param: locking fo...
516
  	mutex_lock(&param_lock);
9bbb9e5a3   Rusty Russell   param: use ops in...
517
  	count = attribute->param->ops->get(buf, attribute->param);
907b29eb4   Rusty Russell   param: locking fo...
518
  	mutex_unlock(&param_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519
520
521
522
523
524
525
526
527
528
  	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,
4befb026c   Kay Sievers   module: change at...
529
  				struct module_kobject *km,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
531
532
533
  				const char *buf, size_t len)
  {
   	int err;
  	struct param_attribute *attribute = to_param_attr(mattr);
9bbb9e5a3   Rusty Russell   param: use ops in...
534
  	if (!attribute->param->ops->set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
535
  		return -EPERM;
907b29eb4   Rusty Russell   param: locking fo...
536
  	mutex_lock(&param_lock);
9bbb9e5a3   Rusty Russell   param: use ops in...
537
  	err = attribute->param->ops->set(buf, attribute->param);
907b29eb4   Rusty Russell   param: locking fo...
538
  	mutex_unlock(&param_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
541
542
  	if (!err)
  		return len;
  	return err;
  }
ef665c1a0   Randy Dunlap   sysfs: fix build ...
543
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
545
546
547
548
549
  
  #ifdef CONFIG_MODULES
  #define __modinit
  #else
  #define __modinit __init
  #endif
ef665c1a0   Randy Dunlap   sysfs: fix build ...
550
  #ifdef CONFIG_SYSFS
907b29eb4   Rusty Russell   param: locking fo...
551
552
553
554
555
556
557
558
559
560
561
  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
562
  /*
9b473de87   Rusty Russell   param: Fix duplic...
563
564
565
566
   * 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
567
   *
9b473de87   Rusty Russell   param: Fix duplic...
568
569
570
   * 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
571
   */
9b473de87   Rusty Russell   param: Fix duplic...
572
  static __modinit int add_sysfs_param(struct module_kobject *mk,
9bbb9e5a3   Rusty Russell   param: use ops in...
573
  				     const struct kernel_param *kp,
9b473de87   Rusty Russell   param: Fix duplic...
574
  				     const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  {
9b473de87   Rusty Russell   param: Fix duplic...
576
577
578
579
580
581
582
583
584
585
586
587
588
  	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
589
  	}
9b473de87   Rusty Russell   param: Fix duplic...
590
591
592
593
594
595
596
597
598
599
600
601
602
603
  	/* 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
604

9b473de87   Rusty Russell   param: Fix duplic...
605
606
607
608
609
610
611
612
  	/* 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_...
613
  	sysfs_attr_init(&new->attrs[num].mattr.attr);
9b473de87   Rusty Russell   param: Fix duplic...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
  	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
628

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

d2441183d   Linus Torvalds   Fix compile warni...
636
  #ifdef CONFIG_MODULES
9b473de87   Rusty Russell   param: Fix duplic...
637
638
639
640
641
  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
642
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
644
645
646
647
648
  /*
   * 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...
649
650
   * Adds sysfs entries for module parameters under
   * /sys/module/[mod->name]/parameters/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
651
652
   */
  int module_param_sysfs_setup(struct module *mod,
9bbb9e5a3   Rusty Russell   param: use ops in...
653
  			     const struct kernel_param *kparam,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
  			     unsigned int num_params)
  {
9b473de87   Rusty Russell   param: Fix duplic...
656
657
658
659
660
661
662
663
664
665
666
  	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
667

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

9b473de87   Rusty Russell   param: Fix duplic...
671
672
673
674
675
  	/* 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
676
677
678
679
680
681
682
683
684
685
686
  }
  
  /*
   * 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...
687
688
  	if (mod->mkobj.mp) {
  		sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
689
690
  		/* We are positive that no one is using any param
  		 * attrs at this point.  Deallocate immediately. */
9b473de87   Rusty Russell   param: Fix duplic...
691
  		free_module_param_attrs(&mod->mkobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
693
694
  	}
  }
  #endif
e180a6b77   Rusty Russell   param: fix charp ...
695
696
  void destroy_params(const struct kernel_param *params, unsigned num)
  {
e6df34a44   Rusty Russell   param: add a free...
697
698
699
700
701
  	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 ...
702
  }
e94965ed5   Dmitry Torokhov   module: show vers...
703
  static struct module_kobject * __init locate_module_kobject(const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
  {
  	struct module_kobject *mk;
9b473de87   Rusty Russell   param: Fix duplic...
706
707
  	struct kobject *kobj;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708

9b473de87   Rusty Russell   param: Fix duplic...
709
710
  	kobj = kset_find_obj(module_kset, name);
  	if (kobj) {
9b473de87   Rusty Russell   param: Fix duplic...
711
  		mk = to_module_kobject(kobj);
9b473de87   Rusty Russell   param: Fix duplic...
712
713
714
715
716
717
718
719
  	} 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);
88bfa3247   Kay Sievers   module: add /sys/...
720
721
722
723
  #ifdef CONFIG_MODULES
  		if (!err)
  			err = sysfs_create_file(&mk->kobj, &module_uevent.attr);
  #endif
9b473de87   Rusty Russell   param: Fix duplic...
724
725
  		if (err) {
  			kobject_put(&mk->kobj);
e94965ed5   Dmitry Torokhov   module: show vers...
726
727
728
729
730
731
732
733
  			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...
734
  		}
e94965ed5   Dmitry Torokhov   module: show vers...
735
736
  
  		/* So that we hold reference in both cases. */
9b473de87   Rusty Russell   param: Fix duplic...
737
  		kobject_get(&mk->kobj);
74c5b597e   Greg Kroah-Hartman   modules: better e...
738
  	}
9b473de87   Rusty Russell   param: Fix duplic...
739

e94965ed5   Dmitry Torokhov   module: show vers...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
  	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...
757
758
759
760
761
  	/* 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 ...
762
  	kobject_uevent(&mk->kobj, KOBJ_ADD);
9b473de87   Rusty Russell   param: Fix duplic...
763
  	kobject_put(&mk->kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
765
766
767
768
769
770
771
772
773
  }
  
  /*
   * 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...
774
   * and for all who have the same, call kernel_add_sysfs_param.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
776
777
   */
  static void __init param_sysfs_builtin(void)
  {
9b473de87   Rusty Russell   param: Fix duplic...
778
779
780
  	struct kernel_param *kp;
  	unsigned int name_len;
  	char modname[MODULE_NAME_LEN];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781

9b473de87   Rusty Russell   param: Fix duplic...
782
  	for (kp = __start___param; kp < __stop___param; kp++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
783
  		char *dot;
9b473de87   Rusty Russell   param: Fix duplic...
784
785
  		if (kp->perm == 0)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786

730b69d22   Rusty Russell   module: check ker...
787
  		dot = strchr(kp->name, '.');
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
788
  		if (!dot) {
67e67ceaa   Rusty Russell   core_param() for ...
789
790
791
792
793
794
  			/* 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
795
  		}
67e67ceaa   Rusty Russell   core_param() for ...
796
  		kernel_add_sysfs_param(modname, kp, name_len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
797
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
  }
e94965ed5   Dmitry Torokhov   module: show vers...
799
  ssize_t __modver_version_show(struct module_attribute *mattr,
4befb026c   Kay Sievers   module: change at...
800
  			      struct module_kobject *mk, char *buf)
e94965ed5   Dmitry Torokhov   module: show vers...
801
802
803
804
805
806
807
  {
  	struct module_version_attribute *vattr =
  		container_of(mattr, struct module_version_attribute, mattr);
  
  	return sprintf(buf, "%s
  ", vattr->version);
  }
b4bc84280   Dmitry Torokhov   module: deal with...
808
809
  extern const struct module_version_attribute *__start___modver[];
  extern const struct module_version_attribute *__stop___modver[];
e94965ed5   Dmitry Torokhov   module: show vers...
810
811
812
  
  static void __init version_sysfs_builtin(void)
  {
b4bc84280   Dmitry Torokhov   module: deal with...
813
  	const struct module_version_attribute **p;
e94965ed5   Dmitry Torokhov   module: show vers...
814
815
  	struct module_kobject *mk;
  	int err;
b4bc84280   Dmitry Torokhov   module: deal with...
816
817
  	for (p = __start___modver; p < __stop___modver; p++) {
  		const struct module_version_attribute *vattr = *p;
e94965ed5   Dmitry Torokhov   module: show vers...
818
819
820
821
822
823
824
825
  		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
826
827
  
  /* module-related sysfs stuff */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
831
832
833
834
835
836
837
838
839
840
  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...
841
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842

4befb026c   Kay Sievers   module: change at...
843
  	ret = attribute->show(attribute, mk, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
844

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
  	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...
860
  		return -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861

4befb026c   Kay Sievers   module: change at...
862
  	ret = attribute->store(attribute, mk, buf, len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
865
  	return ret;
  }
52cf25d0a   Emese Revfy   Driver core: Cons...
866
  static const struct sysfs_ops module_sysfs_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
868
869
  	.show = module_attr_show,
  	.store = module_attr_store,
  };
270a6c4ca   Kay Sievers   /sys/modules/*/ho...
870
871
872
873
874
875
876
877
  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...
878
  static const struct kset_uevent_ops module_uevent_ops = {
270a6c4ca   Kay Sievers   /sys/modules/*/ho...
879
880
  	.filter = uevent_filter,
  };
7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
881
  struct kset *module_kset;
823bccfc4   Greg Kroah-Hartman   remove "struct su...
882
  int module_sysfs_initialized;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
883

7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
884
  struct kobj_type module_ktype = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
886
  	.sysfs_ops =	&module_sysfs_ops,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
888
889
890
891
  /*
   * param_sysfs_init - wrapper for built-in params support
   */
  static int __init param_sysfs_init(void)
  {
7405c1e15   Greg Kroah-Hartman   kset: convert /sy...
892
893
894
895
896
897
  	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...
898
  	}
823bccfc4   Greg Kroah-Hartman   remove "struct su...
899
  	module_sysfs_initialized = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
900

e94965ed5   Dmitry Torokhov   module: show vers...
901
  	version_sysfs_builtin();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
904
905
  	param_sysfs_builtin();
  
  	return 0;
  }
d10be6d1b   Mark Huang   [PATCH] module_su...
906
  subsys_initcall(param_sysfs_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
907

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