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