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