diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-12 01:04:12 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2010-08-11 09:34:13 -0400 |
commit | 9bbb9e5a33109b2832e2e63dcc7a132924ab374b (patch) | |
tree | 87270ed3a61d0d0e654a61c8d44504cdef330192 /kernel | |
parent | a14fe249a8f74269c9e636bcbaa78f5bdb354ce3 (diff) |
param: use ops in struct kernel_param, rather than get and set fns directly
This is more kernel-ish, saves some space, and also allows us to
expand the ops without breaking all the callers who are happy for the
new members to be NULL.
The few places which defined their own param types are changed to the
new scheme (more which crept in recently fixed in following patches).
Since we're touching them anyway, we change get() and set() to take a
const struct kernel_param (which they really are). This causes some
harmless warnings until we fix them (in following patches).
To reduce churn, module_param_call creates the ops struct so the callers
don't have to change (and casts the functions to reduce warnings).
The modern version which takes an ops struct is called module_param_cb.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Tested-by: Phil Carmody <ext-phil.2.carmody@nokia.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Ville Syrjala <syrjala@sci.fi>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Alessandro Rubini <rubini@ipvvis.unipv.it>
Cc: Michal Januszewski <spock@gentoo.org>
Cc: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Neil Brown <neilb@suse.de>
Cc: linux-kernel@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-fbdev-devel@lists.sourceforge.net
Cc: linux-nfs@vger.kernel.org
Cc: netdev@vger.kernel.org
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/params.c | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/kernel/params.c b/kernel/params.c index 3e78fdb445e7..a550698ae02d 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -59,11 +59,11 @@ static int parse_one(char *param, | |||
59 | for (i = 0; i < num_params; i++) { | 59 | for (i = 0; i < num_params; i++) { |
60 | if (parameq(param, params[i].name)) { | 60 | if (parameq(param, params[i].name)) { |
61 | /* Noone handled NULL, so do it here. */ | 61 | /* Noone handled NULL, so do it here. */ |
62 | if (!val && params[i].set != param_set_bool) | 62 | if (!val && params[i].ops->set != param_set_bool) |
63 | return -EINVAL; | 63 | return -EINVAL; |
64 | DEBUGP("They are equal! Calling %p\n", | 64 | DEBUGP("They are equal! Calling %p\n", |
65 | params[i].set); | 65 | params[i].ops->set); |
66 | return params[i].set(val, ¶ms[i]); | 66 | return params[i].ops->set(val, ¶ms[i]); |
67 | } | 67 | } |
68 | } | 68 | } |
69 | 69 | ||
@@ -179,7 +179,7 @@ int parse_args(const char *name, | |||
179 | 179 | ||
180 | /* Lazy bastard, eh? */ | 180 | /* Lazy bastard, eh? */ |
181 | #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ | 181 | #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ |
182 | int param_set_##name(const char *val, struct kernel_param *kp) \ | 182 | int param_set_##name(const char *val, const struct kernel_param *kp) \ |
183 | { \ | 183 | { \ |
184 | tmptype l; \ | 184 | tmptype l; \ |
185 | int ret; \ | 185 | int ret; \ |
@@ -190,12 +190,18 @@ int parse_args(const char *name, | |||
190 | *((type *)kp->arg) = l; \ | 190 | *((type *)kp->arg) = l; \ |
191 | return 0; \ | 191 | return 0; \ |
192 | } \ | 192 | } \ |
193 | int param_get_##name(char *buffer, struct kernel_param *kp) \ | 193 | int param_get_##name(char *buffer, const struct kernel_param *kp) \ |
194 | { \ | 194 | { \ |
195 | return sprintf(buffer, format, *((type *)kp->arg)); \ | 195 | return sprintf(buffer, format, *((type *)kp->arg)); \ |
196 | } \ | 196 | } \ |
197 | struct kernel_param_ops param_ops_##name = { \ | ||
198 | .set = param_set_##name, \ | ||
199 | .get = param_get_##name, \ | ||
200 | }; \ | ||
197 | EXPORT_SYMBOL(param_set_##name); \ | 201 | EXPORT_SYMBOL(param_set_##name); \ |
198 | EXPORT_SYMBOL(param_get_##name) | 202 | EXPORT_SYMBOL(param_get_##name); \ |
203 | EXPORT_SYMBOL(param_ops_##name) | ||
204 | |||
199 | 205 | ||
200 | STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); | 206 | STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); |
201 | STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); | 207 | STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); |
@@ -205,7 +211,7 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul); | |||
205 | STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); | 211 | STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); |
206 | STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); | 212 | STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); |
207 | 213 | ||
208 | int param_set_charp(const char *val, struct kernel_param *kp) | 214 | int param_set_charp(const char *val, const struct kernel_param *kp) |
209 | { | 215 | { |
210 | if (strlen(val) > 1024) { | 216 | if (strlen(val) > 1024) { |
211 | printk(KERN_ERR "%s: string parameter too long\n", | 217 | printk(KERN_ERR "%s: string parameter too long\n", |
@@ -226,14 +232,20 @@ int param_set_charp(const char *val, struct kernel_param *kp) | |||
226 | } | 232 | } |
227 | EXPORT_SYMBOL(param_set_charp); | 233 | EXPORT_SYMBOL(param_set_charp); |
228 | 234 | ||
229 | int param_get_charp(char *buffer, struct kernel_param *kp) | 235 | int param_get_charp(char *buffer, const struct kernel_param *kp) |
230 | { | 236 | { |
231 | return sprintf(buffer, "%s", *((char **)kp->arg)); | 237 | return sprintf(buffer, "%s", *((char **)kp->arg)); |
232 | } | 238 | } |
233 | EXPORT_SYMBOL(param_get_charp); | 239 | EXPORT_SYMBOL(param_get_charp); |
234 | 240 | ||
241 | struct kernel_param_ops param_ops_charp = { | ||
242 | .set = param_set_charp, | ||
243 | .get = param_get_charp, | ||
244 | }; | ||
245 | EXPORT_SYMBOL(param_ops_charp); | ||
246 | |||
235 | /* Actually could be a bool or an int, for historical reasons. */ | 247 | /* Actually could be a bool or an int, for historical reasons. */ |
236 | int param_set_bool(const char *val, struct kernel_param *kp) | 248 | int param_set_bool(const char *val, const struct kernel_param *kp) |
237 | { | 249 | { |
238 | bool v; | 250 | bool v; |
239 | 251 | ||
@@ -260,7 +272,7 @@ int param_set_bool(const char *val, struct kernel_param *kp) | |||
260 | } | 272 | } |
261 | EXPORT_SYMBOL(param_set_bool); | 273 | EXPORT_SYMBOL(param_set_bool); |
262 | 274 | ||
263 | int param_get_bool(char *buffer, struct kernel_param *kp) | 275 | int param_get_bool(char *buffer, const struct kernel_param *kp) |
264 | { | 276 | { |
265 | bool val; | 277 | bool val; |
266 | if (kp->flags & KPARAM_ISBOOL) | 278 | if (kp->flags & KPARAM_ISBOOL) |
@@ -273,8 +285,14 @@ int param_get_bool(char *buffer, struct kernel_param *kp) | |||
273 | } | 285 | } |
274 | EXPORT_SYMBOL(param_get_bool); | 286 | EXPORT_SYMBOL(param_get_bool); |
275 | 287 | ||
288 | struct kernel_param_ops param_ops_bool = { | ||
289 | .set = param_set_bool, | ||
290 | .get = param_get_bool, | ||
291 | }; | ||
292 | EXPORT_SYMBOL(param_ops_bool); | ||
293 | |||
276 | /* This one must be bool. */ | 294 | /* This one must be bool. */ |
277 | int param_set_invbool(const char *val, struct kernel_param *kp) | 295 | int param_set_invbool(const char *val, const struct kernel_param *kp) |
278 | { | 296 | { |
279 | int ret; | 297 | int ret; |
280 | bool boolval; | 298 | bool boolval; |
@@ -289,18 +307,24 @@ int param_set_invbool(const char *val, struct kernel_param *kp) | |||
289 | } | 307 | } |
290 | EXPORT_SYMBOL(param_set_invbool); | 308 | EXPORT_SYMBOL(param_set_invbool); |
291 | 309 | ||
292 | int param_get_invbool(char *buffer, struct kernel_param *kp) | 310 | int param_get_invbool(char *buffer, const struct kernel_param *kp) |
293 | { | 311 | { |
294 | return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); | 312 | return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); |
295 | } | 313 | } |
296 | EXPORT_SYMBOL(param_get_invbool); | 314 | EXPORT_SYMBOL(param_get_invbool); |
297 | 315 | ||
316 | struct kernel_param_ops param_ops_invbool = { | ||
317 | .set = param_set_invbool, | ||
318 | .get = param_get_invbool, | ||
319 | }; | ||
320 | EXPORT_SYMBOL(param_ops_invbool); | ||
321 | |||
298 | /* We break the rule and mangle the string. */ | 322 | /* We break the rule and mangle the string. */ |
299 | static int param_array(const char *name, | 323 | static int param_array(const char *name, |
300 | const char *val, | 324 | const char *val, |
301 | unsigned int min, unsigned int max, | 325 | unsigned int min, unsigned int max, |
302 | void *elem, int elemsize, | 326 | void *elem, int elemsize, |
303 | int (*set)(const char *, struct kernel_param *kp), | 327 | int (*set)(const char *, const struct kernel_param *kp), |
304 | u16 flags, | 328 | u16 flags, |
305 | unsigned int *num) | 329 | unsigned int *num) |
306 | { | 330 | { |
@@ -345,18 +369,17 @@ static int param_array(const char *name, | |||
345 | return 0; | 369 | return 0; |
346 | } | 370 | } |
347 | 371 | ||
348 | int param_array_set(const char *val, struct kernel_param *kp) | 372 | static int param_array_set(const char *val, const struct kernel_param *kp) |
349 | { | 373 | { |
350 | const struct kparam_array *arr = kp->arr; | 374 | const struct kparam_array *arr = kp->arr; |
351 | unsigned int temp_num; | 375 | unsigned int temp_num; |
352 | 376 | ||
353 | return param_array(kp->name, val, 1, arr->max, arr->elem, | 377 | return param_array(kp->name, val, 1, arr->max, arr->elem, |
354 | arr->elemsize, arr->set, kp->flags, | 378 | arr->elemsize, arr->ops->set, kp->flags, |
355 | arr->num ?: &temp_num); | 379 | arr->num ?: &temp_num); |
356 | } | 380 | } |
357 | EXPORT_SYMBOL(param_array_set); | ||
358 | 381 | ||
359 | int param_array_get(char *buffer, struct kernel_param *kp) | 382 | static int param_array_get(char *buffer, const struct kernel_param *kp) |
360 | { | 383 | { |
361 | int i, off, ret; | 384 | int i, off, ret; |
362 | const struct kparam_array *arr = kp->arr; | 385 | const struct kparam_array *arr = kp->arr; |
@@ -367,7 +390,7 @@ int param_array_get(char *buffer, struct kernel_param *kp) | |||
367 | if (i) | 390 | if (i) |
368 | buffer[off++] = ','; | 391 | buffer[off++] = ','; |
369 | p.arg = arr->elem + arr->elemsize * i; | 392 | p.arg = arr->elem + arr->elemsize * i; |
370 | ret = arr->get(buffer + off, &p); | 393 | ret = arr->ops->get(buffer + off, &p); |
371 | if (ret < 0) | 394 | if (ret < 0) |
372 | return ret; | 395 | return ret; |
373 | off += ret; | 396 | off += ret; |
@@ -375,9 +398,14 @@ int param_array_get(char *buffer, struct kernel_param *kp) | |||
375 | buffer[off] = '\0'; | 398 | buffer[off] = '\0'; |
376 | return off; | 399 | return off; |
377 | } | 400 | } |
378 | EXPORT_SYMBOL(param_array_get); | ||
379 | 401 | ||
380 | int param_set_copystring(const char *val, struct kernel_param *kp) | 402 | struct kernel_param_ops param_array_ops = { |
403 | .set = param_array_set, | ||
404 | .get = param_array_get, | ||
405 | }; | ||
406 | EXPORT_SYMBOL(param_array_ops); | ||
407 | |||
408 | int param_set_copystring(const char *val, const struct kernel_param *kp) | ||
381 | { | 409 | { |
382 | const struct kparam_string *kps = kp->str; | 410 | const struct kparam_string *kps = kp->str; |
383 | 411 | ||
@@ -391,13 +419,19 @@ int param_set_copystring(const char *val, struct kernel_param *kp) | |||
391 | } | 419 | } |
392 | EXPORT_SYMBOL(param_set_copystring); | 420 | EXPORT_SYMBOL(param_set_copystring); |
393 | 421 | ||
394 | int param_get_string(char *buffer, struct kernel_param *kp) | 422 | int param_get_string(char *buffer, const struct kernel_param *kp) |
395 | { | 423 | { |
396 | const struct kparam_string *kps = kp->str; | 424 | const struct kparam_string *kps = kp->str; |
397 | return strlcpy(buffer, kps->string, kps->maxlen); | 425 | return strlcpy(buffer, kps->string, kps->maxlen); |
398 | } | 426 | } |
399 | EXPORT_SYMBOL(param_get_string); | 427 | EXPORT_SYMBOL(param_get_string); |
400 | 428 | ||
429 | struct kernel_param_ops param_ops_string = { | ||
430 | .set = param_set_copystring, | ||
431 | .get = param_get_string, | ||
432 | }; | ||
433 | EXPORT_SYMBOL(param_ops_string); | ||
434 | |||
401 | /* sysfs output in /sys/modules/XYZ/parameters/ */ | 435 | /* sysfs output in /sys/modules/XYZ/parameters/ */ |
402 | #define to_module_attr(n) container_of(n, struct module_attribute, attr) | 436 | #define to_module_attr(n) container_of(n, struct module_attribute, attr) |
403 | #define to_module_kobject(n) container_of(n, struct module_kobject, kobj) | 437 | #define to_module_kobject(n) container_of(n, struct module_kobject, kobj) |
@@ -407,7 +441,7 @@ extern struct kernel_param __start___param[], __stop___param[]; | |||
407 | struct param_attribute | 441 | struct param_attribute |
408 | { | 442 | { |
409 | struct module_attribute mattr; | 443 | struct module_attribute mattr; |
410 | struct kernel_param *param; | 444 | const struct kernel_param *param; |
411 | }; | 445 | }; |
412 | 446 | ||
413 | struct module_param_attrs | 447 | struct module_param_attrs |
@@ -426,10 +460,10 @@ static ssize_t param_attr_show(struct module_attribute *mattr, | |||
426 | int count; | 460 | int count; |
427 | struct param_attribute *attribute = to_param_attr(mattr); | 461 | struct param_attribute *attribute = to_param_attr(mattr); |
428 | 462 | ||
429 | if (!attribute->param->get) | 463 | if (!attribute->param->ops->get) |
430 | return -EPERM; | 464 | return -EPERM; |
431 | 465 | ||
432 | count = attribute->param->get(buf, attribute->param); | 466 | count = attribute->param->ops->get(buf, attribute->param); |
433 | if (count > 0) { | 467 | if (count > 0) { |
434 | strcat(buf, "\n"); | 468 | strcat(buf, "\n"); |
435 | ++count; | 469 | ++count; |
@@ -445,10 +479,10 @@ static ssize_t param_attr_store(struct module_attribute *mattr, | |||
445 | int err; | 479 | int err; |
446 | struct param_attribute *attribute = to_param_attr(mattr); | 480 | struct param_attribute *attribute = to_param_attr(mattr); |
447 | 481 | ||
448 | if (!attribute->param->set) | 482 | if (!attribute->param->ops->set) |
449 | return -EPERM; | 483 | return -EPERM; |
450 | 484 | ||
451 | err = attribute->param->set(buf, attribute->param); | 485 | err = attribute->param->ops->set(buf, attribute->param); |
452 | if (!err) | 486 | if (!err) |
453 | return len; | 487 | return len; |
454 | return err; | 488 | return err; |
@@ -473,7 +507,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr, | |||
473 | * if there's an error. | 507 | * if there's an error. |
474 | */ | 508 | */ |
475 | static __modinit int add_sysfs_param(struct module_kobject *mk, | 509 | static __modinit int add_sysfs_param(struct module_kobject *mk, |
476 | struct kernel_param *kp, | 510 | const struct kernel_param *kp, |
477 | const char *name) | 511 | const char *name) |
478 | { | 512 | { |
479 | struct module_param_attrs *new; | 513 | struct module_param_attrs *new; |
@@ -555,7 +589,7 @@ static void free_module_param_attrs(struct module_kobject *mk) | |||
555 | * /sys/module/[mod->name]/parameters/ | 589 | * /sys/module/[mod->name]/parameters/ |
556 | */ | 590 | */ |
557 | int module_param_sysfs_setup(struct module *mod, | 591 | int module_param_sysfs_setup(struct module *mod, |
558 | struct kernel_param *kparam, | 592 | const struct kernel_param *kparam, |
559 | unsigned int num_params) | 593 | unsigned int num_params) |
560 | { | 594 | { |
561 | int i, err; | 595 | int i, err; |