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(mk->mp); 617 err = -ENOMEM; 618 goto fail; 619 } 620 attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL); 621 if (!attrs) { 622 err = -ENOMEM; 623 goto fail_free_new; 624 } 625 626 /* Sysfs wants everything zeroed. */ 627 memset(new, 0, sizeof(*new)); 628 memset(&new->attrs[num], 0, sizeof(new->attrs[num])); 629 memset(&attrs[num], 0, sizeof(attrs[num])); 630 new->grp.name = "parameters"; 631 new->grp.attrs = attrs; 632 633 /* Tack new one on the end. */ 634 sysfs_attr_init(&new->attrs[num].mattr.attr); 635 new->attrs[num].param = kp; 636 new->attrs[num].mattr.show = param_attr_show; 637 new->attrs[num].mattr.store = param_attr_store; 638 new->attrs[num].mattr.attr.name = (char *)name; 639 new->attrs[num].mattr.attr.mode = kp->perm; 640 new->num = num+1; 641 642 /* Fix up all the pointers, since krealloc can move us */ 643 for (num = 0; num < new->num; num++) 644 new->grp.attrs[num] = &new->attrs[num].mattr.attr; 645 new->grp.attrs[num] = NULL; 646 647 mk->mp = new; 648 return 0; 649 650 fail_free_new: 651 kfree(new); 652 fail: 653 mk->mp = NULL; 654 return err; 655 } 656 657 #ifdef CONFIG_MODULES 658 static void free_module_param_attrs(struct module_kobject *mk) 659 { 660 kfree(mk->mp->grp.attrs); 661 kfree(mk->mp); 662 mk->mp = NULL; 663 } 664 665 /* 666 * module_param_sysfs_setup - setup sysfs support for one module 667 * @mod: module 668 * @kparam: module parameters (array) 669 * @num_params: number of module parameters 670 * 671 * Adds sysfs entries for module parameters under 672 * /sys/module/[mod->name]/parameters/ 673 */ 674 int module_param_sysfs_setup(struct module *mod, 675 const struct kernel_param *kparam, 676 unsigned int num_params) 677 { 678 int i, err; 679 bool params = false; 680 681 for (i = 0; i < num_params; i++) { 682 if (kparam[i].perm == 0) 683 continue; 684 err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name); 685 if (err) 686 return err; 687 params = true; 688 } 689 690 if (!params) 691 return 0; 692 693 /* Create the param group. */ 694 err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp); 695 if (err) 696 free_module_param_attrs(&mod->mkobj); 697 return err; 698 } 699 700 /* 701 * module_param_sysfs_remove - remove sysfs support for one module 702 * @mod: module 703 * 704 * Remove sysfs entries for module parameters and the corresponding 705 * kobject. 706 */ 707 void module_param_sysfs_remove(struct module *mod) 708 { 709 if (mod->mkobj.mp) { 710 sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp); 711 /* We are positive that no one is using any param 712 * attrs at this point. Deallocate immediately. */ 713 free_module_param_attrs(&mod->mkobj); 714 } 715 } 716 #endif 717 718 void destroy_params(const struct kernel_param *params, unsigned num) 719 { 720 unsigned int i; 721 722 for (i = 0; i < num; i++) 723 if (params[i].ops->free) 724 params[i].ops->free(params[i].arg); 725 } 726 727 static struct module_kobject * __init locate_module_kobject(const char *name) 728 { 729 struct module_kobject *mk; 730 struct kobject *kobj; 731 int err; 732 733 kobj = kset_find_obj(module_kset, name); 734 if (kobj) { 735 mk = to_module_kobject(kobj); 736 } else { 737 mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL); 738 BUG_ON(!mk); 739 740 mk->mod = THIS_MODULE; 741 mk->kobj.kset = module_kset; 742 err = kobject_init_and_add(&mk->kobj, &module_ktype, NULL, 743 "%s", name); 744 #ifdef CONFIG_MODULES 745 if (!err) 746 err = sysfs_create_file(&mk->kobj, &module_uevent.attr); 747 #endif 748 if (err) { 749 kobject_put(&mk->kobj); 750 pr_crit("Adding module '%s' to sysfs failed (%d), the system may be unstable.\n", 751 name, err); 752 return NULL; 753 } 754 755 /* So that we hold reference in both cases. */ 756 kobject_get(&mk->kobj); 757 } 758 759 return mk; 760 } 761 762 static void __init kernel_add_sysfs_param(const char *name, 763 struct kernel_param *kparam, 764 unsigned int name_skip) 765 { 766 struct module_kobject *mk; 767 int err; 768 769 mk = locate_module_kobject(name); 770 if (!mk) 771 return; 772 773 /* We need to remove old parameters before adding more. */ 774 if (mk->mp) 775 sysfs_remove_group(&mk->kobj, &mk->mp->grp); 776 777 /* These should not fail at boot. */ 778 err = add_sysfs_param(mk, kparam, kparam->name + name_skip); 779 BUG_ON(err); 780 err = sysfs_create_group(&mk->kobj, &mk->mp->grp); 781 BUG_ON(err); 782 kobject_uevent(&mk->kobj, KOBJ_ADD); 783 kobject_put(&mk->kobj); 784 } 785 786 /* 787 * param_sysfs_builtin - add contents in /sys/parameters for built-in modules 788 * 789 * Add module_parameters to sysfs for "modules" built into the kernel. 790 * 791 * The "module" name (KBUILD_MODNAME) is stored before a dot, the 792 * "parameter" name is stored behind a dot in kernel_param->name. So, 793 * extract the "module" name for all built-in kernel_param-eters, 794 * and for all who have the same, call kernel_add_sysfs_param. 795 */ 796 static void __init param_sysfs_builtin(void) 797 { 798 struct kernel_param *kp; 799 unsigned int name_len; 800 char modname[MODULE_NAME_LEN]; 801 802 for (kp = __start___param; kp < __stop___param; kp++) { 803 char *dot; 804 805 if (kp->perm == 0) 806 continue; 807 808 dot = strchr(kp->name, '.'); 809 if (!dot) { 810 /* This happens for core_param() */ 811 strcpy(modname, "kernel"); 812 name_len = 0; 813 } else { 814 name_len = dot - kp->name + 1; 815 strlcpy(modname, kp->name, name_len); 816 } 817 kernel_add_sysfs_param(modname, kp, name_len); 818 } 819 } 820 821 ssize_t __modver_version_show(struct module_attribute *mattr, 822 struct module_kobject *mk, char *buf) 823 { 824 struct module_version_attribute *vattr = 825 container_of(mattr, struct module_version_attribute, mattr); 826 827 return sprintf(buf, "%s\n", vattr->version); 828 } 829 830 extern const struct module_version_attribute *__start___modver[]; 831 extern const struct module_version_attribute *__stop___modver[]; 832 833 static void __init version_sysfs_builtin(void) 834 { 835 const struct module_version_attribute **p; 836 struct module_kobject *mk; 837 int err; 838 839 for (p = __start___modver; p < __stop___modver; p++) { 840 const struct module_version_attribute *vattr = *p; 841 842 mk = locate_module_kobject(vattr->module_name); 843 if (mk) { 844 err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr); 845 kobject_uevent(&mk->kobj, KOBJ_ADD); 846 kobject_put(&mk->kobj); 847 } 848 } 849 } 850 851 /* module-related sysfs stuff */ 852 853 static ssize_t module_attr_show(struct kobject *kobj, 854 struct attribute *attr, 855 char *buf) 856 { 857 struct module_attribute *attribute; 858 struct module_kobject *mk; 859 int ret; 860 861 attribute = to_module_attr(attr); 862 mk = to_module_kobject(kobj); 863 864 if (!attribute->show) 865 return -EIO; 866 867 ret = attribute->show(attribute, mk, buf); 868 869 return ret; 870 } 871 872 static ssize_t module_attr_store(struct kobject *kobj, 873 struct attribute *attr, 874 const char *buf, size_t len) 875 { 876 struct module_attribute *attribute; 877 struct module_kobject *mk; 878 int ret; 879 880 attribute = to_module_attr(attr); 881 mk = to_module_kobject(kobj); 882 883 if (!attribute->store) 884 return -EIO; 885 886 ret = attribute->store(attribute, mk, buf, len); 887 888 return ret; 889 } 890 891 static const struct sysfs_ops module_sysfs_ops = { 892 .show = module_attr_show, 893 .store = module_attr_store, 894 }; 895 896 static int uevent_filter(struct kset *kset, struct kobject *kobj) 897 { 898 struct kobj_type *ktype = get_ktype(kobj); 899 900 if (ktype == &module_ktype) 901 return 1; 902 return 0; 903 } 904 905 static const struct kset_uevent_ops module_uevent_ops = { 906 .filter = uevent_filter, 907 }; 908 909 struct kset *module_kset; 910 int module_sysfs_initialized; 911 912 struct kobj_type module_ktype = { 913 .sysfs_ops = &module_sysfs_ops, 914 }; 915 916 /* 917 * param_sysfs_init - wrapper for built-in params support 918 */ 919 static int __init param_sysfs_init(void) 920 { 921 module_kset = kset_create_and_add("module", &module_uevent_ops, NULL); 922 if (!module_kset) { 923 printk(KERN_WARNING "%s (%d): error creating kset\n", 924 __FILE__, __LINE__); 925 return -ENOMEM; 926 } 927 module_sysfs_initialized = 1; 928 929 version_sysfs_builtin(); 930 param_sysfs_builtin(); 931 932 return 0; 933 } 934 subsys_initcall(param_sysfs_init); 935 936 #endif /* CONFIG_SYSFS */ 937