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