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 struct kernel_param *params, 89 unsigned num_params, 90 s16 min_level, 91 s16 max_level, 92 int (*handle_unknown)(char *param, char *val)) 93 { 94 unsigned int i; 95 int err; 96 97 /* Find parameter */ 98 for (i = 0; i < num_params; i++) { 99 if (parameq(param, params[i].name)) { 100 if (params[i].level < min_level 101 || params[i].level > max_level) 102 return 0; 103 /* No one handled NULL, so do it here. */ 104 if (!val && params[i].ops->set != param_set_bool 105 && params[i].ops->set != param_set_bint) 106 return -EINVAL; 107 pr_debug("They are equal! Calling %p\n", 108 params[i].ops->set); 109 mutex_lock(¶m_lock); 110 err = params[i].ops->set(val, ¶ms[i]); 111 mutex_unlock(¶m_lock); 112 return err; 113 } 114 } 115 116 if (handle_unknown) { 117 pr_debug("Unknown argument: calling %p\n", handle_unknown); 118 return handle_unknown(param, val); 119 } 120 121 pr_debug("Unknown argument `%s'\n", param); 122 return -ENOENT; 123 } 124 125 /* You can use " around spaces, but can't escape ". */ 126 /* Hyphens and underscores equivalent in parameter names. */ 127 static char *next_arg(char *args, char **param, char **val) 128 { 129 unsigned int i, equals = 0; 130 int in_quote = 0, quoted = 0; 131 char *next; 132 133 if (*args == '"') { 134 args++; 135 in_quote = 1; 136 quoted = 1; 137 } 138 139 for (i = 0; args[i]; i++) { 140 if (isspace(args[i]) && !in_quote) 141 break; 142 if (equals == 0) { 143 if (args[i] == '=') 144 equals = i; 145 } 146 if (args[i] == '"') 147 in_quote = !in_quote; 148 } 149 150 *param = args; 151 if (!equals) 152 *val = NULL; 153 else { 154 args[equals] = '\0'; 155 *val = args + equals + 1; 156 157 /* Don't include quotes in value. */ 158 if (**val == '"') { 159 (*val)++; 160 if (args[i-1] == '"') 161 args[i-1] = '\0'; 162 } 163 if (quoted && args[i-1] == '"') 164 args[i-1] = '\0'; 165 } 166 167 if (args[i]) { 168 args[i] = '\0'; 169 next = args + i + 1; 170 } else 171 next = args + i; 172 173 /* Chew up trailing spaces. */ 174 return skip_spaces(next); 175 } 176 177 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ 178 int parse_args(const char *name, 179 char *args, 180 const struct kernel_param *params, 181 unsigned num, 182 s16 min_level, 183 s16 max_level, 184 int (*unknown)(char *param, char *val)) 185 { 186 char *param, *val; 187 188 pr_debug("Parsing ARGS: %s\n", args); 189 190 /* Chew leading spaces */ 191 args = skip_spaces(args); 192 193 while (*args) { 194 int ret; 195 int irq_was_disabled; 196 197 args = next_arg(args, ¶m, &val); 198 irq_was_disabled = irqs_disabled(); 199 ret = parse_one(param, val, params, num, 200 min_level, max_level, unknown); 201 if (irq_was_disabled && !irqs_disabled()) { 202 printk(KERN_WARNING "parse_args(): option '%s' enabled " 203 "irq's!\n", param); 204 } 205 switch (ret) { 206 case -ENOENT: 207 printk(KERN_ERR "%s: Unknown parameter `%s'\n", 208 name, param); 209 return ret; 210 case -ENOSPC: 211 printk(KERN_ERR 212 "%s: `%s' too large for parameter `%s'\n", 213 name, val ?: "", param); 214 return ret; 215 case 0: 216 break; 217 default: 218 printk(KERN_ERR 219 "%s: `%s' invalid for parameter `%s'\n", 220 name, 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 printk(KERN_ERR "%s: string parameter too long\n", 267 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 sprintf(buffer, "%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 .set = param_set_bool, 325 .get = param_get_bool, 326 }; 327 EXPORT_SYMBOL(param_ops_bool); 328 329 /* This one must be bool. */ 330 int param_set_invbool(const char *val, const struct kernel_param *kp) 331 { 332 int ret; 333 bool boolval; 334 struct kernel_param dummy; 335 336 dummy.arg = &boolval; 337 ret = param_set_bool(val, &dummy); 338 if (ret == 0) 339 *(bool *)kp->arg = !boolval; 340 return ret; 341 } 342 EXPORT_SYMBOL(param_set_invbool); 343 344 int param_get_invbool(char *buffer, const struct kernel_param *kp) 345 { 346 return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); 347 } 348 EXPORT_SYMBOL(param_get_invbool); 349 350 struct kernel_param_ops param_ops_invbool = { 351 .set = param_set_invbool, 352 .get = param_get_invbool, 353 }; 354 EXPORT_SYMBOL(param_ops_invbool); 355 356 int param_set_bint(const char *val, const struct kernel_param *kp) 357 { 358 struct kernel_param boolkp; 359 bool v; 360 int ret; 361 362 /* Match bool exactly, by re-using it. */ 363 boolkp = *kp; 364 boolkp.arg = &v; 365 366 ret = param_set_bool(val, &boolkp); 367 if (ret == 0) 368 *(int *)kp->arg = v; 369 return ret; 370 } 371 EXPORT_SYMBOL(param_set_bint); 372 373 struct kernel_param_ops param_ops_bint = { 374 .set = param_set_bint, 375 .get = param_get_int, 376 }; 377 EXPORT_SYMBOL(param_ops_bint); 378 379 /* We break the rule and mangle the string. */ 380 static int param_array(const char *name, 381 const char *val, 382 unsigned int min, unsigned int max, 383 void *elem, int elemsize, 384 int (*set)(const char *, const struct kernel_param *kp), 385 s16 level, 386 unsigned int *num) 387 { 388 int ret; 389 struct kernel_param kp; 390 char save; 391 392 /* Get the name right for errors. */ 393 kp.name = name; 394 kp.arg = elem; 395 kp.level = level; 396 397 *num = 0; 398 /* We expect a comma-separated list of values. */ 399 do { 400 int len; 401 402 if (*num == max) { 403 printk(KERN_ERR "%s: can only take %i arguments\n", 404 name, max); 405 return -EINVAL; 406 } 407 len = strcspn(val, ","); 408 409 /* nul-terminate and parse */ 410 save = val[len]; 411 ((char *)val)[len] = '\0'; 412 BUG_ON(!mutex_is_locked(¶m_lock)); 413 ret = set(val, &kp); 414 415 if (ret != 0) 416 return ret; 417 kp.arg += elemsize; 418 val += len+1; 419 (*num)++; 420 } while (save == ','); 421 422 if (*num < min) { 423 printk(KERN_ERR "%s: needs at least %i arguments\n", 424 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 printk(KERN_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(mk->mp); 620 err = -ENOMEM; 621 goto fail; 622 } 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 printk(KERN_ERR 754 "Module '%s' failed add to sysfs, error number %d\n", 755 name, err); 756 printk(KERN_ERR 757 "The system will be unstable now.\n"); 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 contents in /sys/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 sprintf(buf, "%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 struct kobj_type module_ktype = { 919 .sysfs_ops = &module_sysfs_ops, 920 }; 921 922 /* 923 * param_sysfs_init - wrapper for built-in params support 924 */ 925 static int __init param_sysfs_init(void) 926 { 927 module_kset = kset_create_and_add("module", &module_uevent_ops, NULL); 928 if (!module_kset) { 929 printk(KERN_WARNING "%s (%d): error creating kset\n", 930 __FILE__, __LINE__); 931 return -ENOMEM; 932 } 933 module_sysfs_initialized = 1; 934 935 version_sysfs_builtin(); 936 param_sysfs_builtin(); 937 938 return 0; 939 } 940 subsys_initcall(param_sysfs_init); 941 942 #endif /* CONFIG_SYSFS */ 943