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