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