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/moduleparam.h> 19 #include <linux/kernel.h> 20 #include <linux/string.h> 21 #include <linux/errno.h> 22 #include <linux/module.h> 23 #include <linux/device.h> 24 #include <linux/err.h> 25 #include <linux/slab.h> 26 #include <linux/ctype.h> 27 28 #if 0 29 #define DEBUGP printk 30 #else 31 #define DEBUGP(fmt, a...) 32 #endif 33 34 /* Protects all parameters, and incidentally kmalloced_param list. */ 35 static DEFINE_MUTEX(param_lock); 36 37 /* This just allows us to keep track of which parameters are kmalloced. */ 38 struct kmalloced_param { 39 struct list_head list; 40 char val[]; 41 }; 42 static LIST_HEAD(kmalloced_params); 43 44 static void *kmalloc_parameter(unsigned int size) 45 { 46 struct kmalloced_param *p; 47 48 p = kmalloc(sizeof(*p) + size, GFP_KERNEL); 49 if (!p) 50 return NULL; 51 52 list_add(&p->list, &kmalloced_params); 53 return p->val; 54 } 55 56 /* Does nothing if parameter wasn't kmalloced above. */ 57 static void maybe_kfree_parameter(void *param) 58 { 59 struct kmalloced_param *p; 60 61 list_for_each_entry(p, &kmalloced_params, list) { 62 if (p->val == param) { 63 list_del(&p->list); 64 kfree(p); 65 break; 66 } 67 } 68 } 69 70 static inline char dash2underscore(char c) 71 { 72 if (c == '-') 73 return '_'; 74 return c; 75 } 76 77 static inline int parameq(const char *input, const char *paramname) 78 { 79 unsigned int i; 80 for (i = 0; dash2underscore(input[i]) == paramname[i]; i++) 81 if (input[i] == '\0') 82 return 1; 83 return 0; 84 } 85 86 static int parse_one(char *param, 87 char *val, 88 const struct kernel_param *params, 89 unsigned num_params, 90 int (*handle_unknown)(char *param, char *val)) 91 { 92 unsigned int i; 93 int err; 94 95 /* Find parameter */ 96 for (i = 0; i < num_params; i++) { 97 if (parameq(param, params[i].name)) { 98 /* Noone handled NULL, so do it here. */ 99 if (!val && params[i].ops->set != param_set_bool) 100 return -EINVAL; 101 DEBUGP("They are equal! Calling %p\n", 102 params[i].ops->set); 103 mutex_lock(¶m_lock); 104 err = params[i].ops->set(val, ¶ms[i]); 105 mutex_unlock(¶m_lock); 106 return err; 107 } 108 } 109 110 if (handle_unknown) { 111 DEBUGP("Unknown argument: calling %p\n", handle_unknown); 112 return handle_unknown(param, val); 113 } 114 115 DEBUGP("Unknown argument `%s'\n", param); 116 return -ENOENT; 117 } 118 119 /* You can use " around spaces, but can't escape ". */ 120 /* Hyphens and underscores equivalent in parameter names. */ 121 static char *next_arg(char *args, char **param, char **val) 122 { 123 unsigned int i, equals = 0; 124 int in_quote = 0, quoted = 0; 125 char *next; 126 127 if (*args == '"') { 128 args++; 129 in_quote = 1; 130 quoted = 1; 131 } 132 133 for (i = 0; args[i]; i++) { 134 if (isspace(args[i]) && !in_quote) 135 break; 136 if (equals == 0) { 137 if (args[i] == '=') 138 equals = i; 139 } 140 if (args[i] == '"') 141 in_quote = !in_quote; 142 } 143 144 *param = args; 145 if (!equals) 146 *val = NULL; 147 else { 148 args[equals] = '\0'; 149 *val = args + equals + 1; 150 151 /* Don't include quotes in value. */ 152 if (**val == '"') { 153 (*val)++; 154 if (args[i-1] == '"') 155 args[i-1] = '\0'; 156 } 157 if (quoted && args[i-1] == '"') 158 args[i-1] = '\0'; 159 } 160 161 if (args[i]) { 162 args[i] = '\0'; 163 next = args + i + 1; 164 } else 165 next = args + i; 166 167 /* Chew up trailing spaces. */ 168 return skip_spaces(next); 169 } 170 171 /* Args looks like "foo=bar,bar2 baz=fuz wiz". */ 172 int parse_args(const char *name, 173 char *args, 174 const struct kernel_param *params, 175 unsigned num, 176 int (*unknown)(char *param, char *val)) 177 { 178 char *param, *val; 179 180 DEBUGP("Parsing ARGS: %s\n", args); 181 182 /* Chew leading spaces */ 183 args = skip_spaces(args); 184 185 while (*args) { 186 int ret; 187 int irq_was_disabled; 188 189 args = next_arg(args, ¶m, &val); 190 irq_was_disabled = irqs_disabled(); 191 ret = parse_one(param, val, params, num, unknown); 192 if (irq_was_disabled && !irqs_disabled()) { 193 printk(KERN_WARNING "parse_args(): option '%s' enabled " 194 "irq's!\n", param); 195 } 196 switch (ret) { 197 case -ENOENT: 198 printk(KERN_ERR "%s: Unknown parameter `%s'\n", 199 name, param); 200 return ret; 201 case -ENOSPC: 202 printk(KERN_ERR 203 "%s: `%s' too large for parameter `%s'\n", 204 name, val ?: "", param); 205 return ret; 206 case 0: 207 break; 208 default: 209 printk(KERN_ERR 210 "%s: `%s' invalid for parameter `%s'\n", 211 name, val ?: "", param); 212 return ret; 213 } 214 } 215 216 /* All parsed OK. */ 217 return 0; 218 } 219 220 /* Lazy bastard, eh? */ 221 #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn) \ 222 int param_set_##name(const char *val, const struct kernel_param *kp) \ 223 { \ 224 tmptype l; \ 225 int ret; \ 226 \ 227 ret = strtolfn(val, 0, &l); \ 228 if (ret == -EINVAL || ((type)l != l)) \ 229 return -EINVAL; \ 230 *((type *)kp->arg) = l; \ 231 return 0; \ 232 } \ 233 int param_get_##name(char *buffer, const struct kernel_param *kp) \ 234 { \ 235 return sprintf(buffer, format, *((type *)kp->arg)); \ 236 } \ 237 struct kernel_param_ops param_ops_##name = { \ 238 .set = param_set_##name, \ 239 .get = param_get_##name, \ 240 }; \ 241 EXPORT_SYMBOL(param_set_##name); \ 242 EXPORT_SYMBOL(param_get_##name); \ 243 EXPORT_SYMBOL(param_ops_##name) 244 245 246 STANDARD_PARAM_DEF(byte, unsigned char, "%c", unsigned long, strict_strtoul); 247 STANDARD_PARAM_DEF(short, short, "%hi", long, strict_strtol); 248 STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", unsigned long, strict_strtoul); 249 STANDARD_PARAM_DEF(int, int, "%i", long, strict_strtol); 250 STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul); 251 STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol); 252 STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul); 253 254 int param_set_charp(const char *val, const struct kernel_param *kp) 255 { 256 if (strlen(val) > 1024) { 257 printk(KERN_ERR "%s: string parameter too long\n", 258 kp->name); 259 return -ENOSPC; 260 } 261 262 maybe_kfree_parameter(*(char **)kp->arg); 263 264 /* This is a hack. We can't kmalloc in early boot, and we 265 * don't need to; this mangled commandline is preserved. */ 266 if (slab_is_available()) { 267 *(char **)kp->arg = kmalloc_parameter(strlen(val)+1); 268 if (!*(char **)kp->arg) 269 return -ENOMEM; 270 strcpy(*(char **)kp->arg, val); 271 } else 272 *(const char **)kp->arg = val; 273 274 return 0; 275 } 276 EXPORT_SYMBOL(param_set_charp); 277 278 int param_get_charp(char *buffer, const struct kernel_param *kp) 279 { 280 return sprintf(buffer, "%s", *((char **)kp->arg)); 281 } 282 EXPORT_SYMBOL(param_get_charp); 283 284 static void param_free_charp(void *arg) 285 { 286 maybe_kfree_parameter(*((char **)arg)); 287 } 288 289 struct kernel_param_ops param_ops_charp = { 290 .set = param_set_charp, 291 .get = param_get_charp, 292 .free = param_free_charp, 293 }; 294 EXPORT_SYMBOL(param_ops_charp); 295 296 /* Actually could be a bool or an int, for historical reasons. */ 297 int param_set_bool(const char *val, const struct kernel_param *kp) 298 { 299 bool v; 300 301 /* No equals means "set"... */ 302 if (!val) val = "1"; 303 304 /* One of =[yYnN01] */ 305 switch (val[0]) { 306 case 'y': case 'Y': case '1': 307 v = true; 308 break; 309 case 'n': case 'N': case '0': 310 v = false; 311 break; 312 default: 313 return -EINVAL; 314 } 315 316 if (kp->flags & KPARAM_ISBOOL) 317 *(bool *)kp->arg = v; 318 else 319 *(int *)kp->arg = v; 320 return 0; 321 } 322 EXPORT_SYMBOL(param_set_bool); 323 324 int param_get_bool(char *buffer, const struct kernel_param *kp) 325 { 326 bool val; 327 if (kp->flags & KPARAM_ISBOOL) 328 val = *(bool *)kp->arg; 329 else 330 val = *(int *)kp->arg; 331 332 /* Y and N chosen as being relatively non-coder friendly */ 333 return sprintf(buffer, "%c", val ? 'Y' : 'N'); 334 } 335 EXPORT_SYMBOL(param_get_bool); 336 337 struct kernel_param_ops param_ops_bool = { 338 .set = param_set_bool, 339 .get = param_get_bool, 340 }; 341 EXPORT_SYMBOL(param_ops_bool); 342 343 /* This one must be bool. */ 344 int param_set_invbool(const char *val, const struct kernel_param *kp) 345 { 346 int ret; 347 bool boolval; 348 struct kernel_param dummy; 349 350 dummy.arg = &boolval; 351 dummy.flags = KPARAM_ISBOOL; 352 ret = param_set_bool(val, &dummy); 353 if (ret == 0) 354 *(bool *)kp->arg = !boolval; 355 return ret; 356 } 357 EXPORT_SYMBOL(param_set_invbool); 358 359 int param_get_invbool(char *buffer, const struct kernel_param *kp) 360 { 361 return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y'); 362 } 363 EXPORT_SYMBOL(param_get_invbool); 364 365 struct kernel_param_ops param_ops_invbool = { 366 .set = param_set_invbool, 367 .get = param_get_invbool, 368 }; 369 EXPORT_SYMBOL(param_ops_invbool); 370 371 /* We break the rule and mangle the string. */ 372 static int param_array(const char *name, 373 const char *val, 374 unsigned int min, unsigned int max, 375 void *elem, int elemsize, 376 int (*set)(const char *, const struct kernel_param *kp), 377 u16 flags, 378 unsigned int *num) 379 { 380 int ret; 381 struct kernel_param kp; 382 char save; 383 384 /* Get the name right for errors. */ 385 kp.name = name; 386 kp.arg = elem; 387 kp.flags = flags; 388 389 *num = 0; 390 /* We expect a comma-separated list of values. */ 391 do { 392 int len; 393 394 if (*num == max) { 395 printk(KERN_ERR "%s: can only take %i arguments\n", 396 name, max); 397 return -EINVAL; 398 } 399 len = strcspn(val, ","); 400 401 /* nul-terminate and parse */ 402 save = val[len]; 403 ((char *)val)[len] = '\0'; 404 BUG_ON(!mutex_is_locked(¶m_lock)); 405 ret = set(val, &kp); 406 407 if (ret != 0) 408 return ret; 409 kp.arg += elemsize; 410 val += len+1; 411 (*num)++; 412 } while (save == ','); 413 414 if (*num < min) { 415 printk(KERN_ERR "%s: needs at least %i arguments\n", 416 name, min); 417 return -EINVAL; 418 } 419 return 0; 420 } 421 422 static int param_array_set(const char *val, const struct kernel_param *kp) 423 { 424 const struct kparam_array *arr = kp->arr; 425 unsigned int temp_num; 426 427 return param_array(kp->name, val, 1, arr->max, arr->elem, 428 arr->elemsize, arr->ops->set, kp->flags, 429 arr->num ?: &temp_num); 430 } 431 432 static int param_array_get(char *buffer, const struct kernel_param *kp) 433 { 434 int i, off, ret; 435 const struct kparam_array *arr = kp->arr; 436 struct kernel_param p; 437 438 p = *kp; 439 for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) { 440 if (i) 441 buffer[off++] = ','; 442 p.arg = arr->elem + arr->elemsize * i; 443 BUG_ON(!mutex_is_locked(¶m_lock)); 444 ret = arr->ops->get(buffer + off, &p); 445 if (ret < 0) 446 return ret; 447 off += ret; 448 } 449 buffer[off] = '\0'; 450 return off; 451 } 452 453 static void param_array_free(void *arg) 454 { 455 unsigned int i; 456 const struct kparam_array *arr = arg; 457 458 if (arr->ops->free) 459 for (i = 0; i < (arr->num ? *arr->num : arr->max); i++) 460 arr->ops->free(arr->elem + arr->elemsize * i); 461 } 462 463 struct kernel_param_ops param_array_ops = { 464 .set = param_array_set, 465 .get = param_array_get, 466 .free = param_array_free, 467 }; 468 EXPORT_SYMBOL(param_array_ops); 469 470 int param_set_copystring(const char *val, const struct kernel_param *kp) 471 { 472 const struct kparam_string *kps = kp->str; 473 474 if (strlen(val)+1 > kps->maxlen) { 475 printk(KERN_ERR "%s: string doesn't fit in %u chars.\n", 476 kp->name, kps->maxlen-1); 477 return -ENOSPC; 478 } 479 strcpy(kps->string, val); 480 return 0; 481 } 482 EXPORT_SYMBOL(param_set_copystring); 483 484 int param_get_string(char *buffer, const struct kernel_param *kp) 485 { 486 const struct kparam_string *kps = kp->str; 487 return strlcpy(buffer, kps->string, kps->maxlen); 488 } 489 EXPORT_SYMBOL(param_get_string); 490 491 struct kernel_param_ops param_ops_string = { 492 .set = param_set_copystring, 493 .get = param_get_string, 494 }; 495 EXPORT_SYMBOL(param_ops_string); 496 497 /* sysfs output in /sys/modules/XYZ/parameters/ */ 498 #define to_module_attr(n) container_of(n, struct module_attribute, attr) 499 #define to_module_kobject(n) container_of(n, struct module_kobject, kobj) 500 501 extern struct kernel_param __start___param[], __stop___param[]; 502 503 struct param_attribute 504 { 505 struct module_attribute mattr; 506 const struct kernel_param *param; 507 }; 508 509 struct module_param_attrs 510 { 511 unsigned int num; 512 struct attribute_group grp; 513 struct param_attribute attrs[0]; 514 }; 515 516 #ifdef CONFIG_SYSFS 517 #define to_param_attr(n) container_of(n, struct param_attribute, mattr) 518 519 static ssize_t param_attr_show(struct module_attribute *mattr, 520 struct module *mod, char *buf) 521 { 522 int count; 523 struct param_attribute *attribute = to_param_attr(mattr); 524 525 if (!attribute->param->ops->get) 526 return -EPERM; 527 528 mutex_lock(¶m_lock); 529 count = attribute->param->ops->get(buf, attribute->param); 530 mutex_unlock(¶m_lock); 531 if (count > 0) { 532 strcat(buf, "\n"); 533 ++count; 534 } 535 return count; 536 } 537 538 /* sysfs always hands a nul-terminated string in buf. We rely on that. */ 539 static ssize_t param_attr_store(struct module_attribute *mattr, 540 struct module *owner, 541 const char *buf, size_t len) 542 { 543 int err; 544 struct param_attribute *attribute = to_param_attr(mattr); 545 546 if (!attribute->param->ops->set) 547 return -EPERM; 548 549 mutex_lock(¶m_lock); 550 err = attribute->param->ops->set(buf, attribute->param); 551 mutex_unlock(¶m_lock); 552 if (!err) 553 return len; 554 return err; 555 } 556 #endif 557 558 #ifdef CONFIG_MODULES 559 #define __modinit 560 #else 561 #define __modinit __init 562 #endif 563 564 #ifdef CONFIG_SYSFS 565 void __kernel_param_lock(void) 566 { 567 mutex_lock(¶m_lock); 568 } 569 EXPORT_SYMBOL(__kernel_param_lock); 570 571 void __kernel_param_unlock(void) 572 { 573 mutex_unlock(¶m_lock); 574 } 575 EXPORT_SYMBOL(__kernel_param_unlock); 576 577 /* 578 * add_sysfs_param - add a parameter to sysfs 579 * @mk: struct module_kobject 580 * @kparam: the actual parameter definition to add to sysfs 581 * @name: name of parameter 582 * 583 * Create a kobject if for a (per-module) parameter if mp NULL, and 584 * create file in sysfs. Returns an error on out of memory. Always cleans up 585 * if there's an error. 586 */ 587 static __modinit int add_sysfs_param(struct module_kobject *mk, 588 const struct kernel_param *kp, 589 const char *name) 590 { 591 struct module_param_attrs *new; 592 struct attribute **attrs; 593 int err, num; 594 595 /* We don't bother calling this with invisible parameters. */ 596 BUG_ON(!kp->perm); 597 598 if (!mk->mp) { 599 num = 0; 600 attrs = NULL; 601 } else { 602 num = mk->mp->num; 603 attrs = mk->mp->grp.attrs; 604 } 605 606 /* Enlarge. */ 607 new = krealloc(mk->mp, 608 sizeof(*mk->mp) + sizeof(mk->mp->attrs[0]) * (num+1), 609 GFP_KERNEL); 610 if (!new) { 611 kfree(mk->mp); 612 err = -ENOMEM; 613 goto fail; 614 } 615 attrs = krealloc(attrs, sizeof(new->grp.attrs[0])*(num+2), GFP_KERNEL); 616 if (!attrs) { 617 err = -ENOMEM; 618 goto fail_free_new; 619 } 620 621 /* Sysfs wants everything zeroed. */ 622 memset(new, 0, sizeof(*new)); 623 memset(&new->attrs[num], 0, sizeof(new->attrs[num])); 624 memset(&attrs[num], 0, sizeof(attrs[num])); 625 new->grp.name = "parameters"; 626 new->grp.attrs = attrs; 627 628 /* Tack new one on the end. */ 629 sysfs_attr_init(&new->attrs[num].mattr.attr); 630 new->attrs[num].param = kp; 631 new->attrs[num].mattr.show = param_attr_show; 632 new->attrs[num].mattr.store = param_attr_store; 633 new->attrs[num].mattr.attr.name = (char *)name; 634 new->attrs[num].mattr.attr.mode = kp->perm; 635 new->num = num+1; 636 637 /* Fix up all the pointers, since krealloc can move us */ 638 for (num = 0; num < new->num; num++) 639 new->grp.attrs[num] = &new->attrs[num].mattr.attr; 640 new->grp.attrs[num] = NULL; 641 642 mk->mp = new; 643 return 0; 644 645 fail_free_new: 646 kfree(new); 647 fail: 648 mk->mp = NULL; 649 return err; 650 } 651 652 #ifdef CONFIG_MODULES 653 static void free_module_param_attrs(struct module_kobject *mk) 654 { 655 kfree(mk->mp->grp.attrs); 656 kfree(mk->mp); 657 mk->mp = NULL; 658 } 659 660 /* 661 * module_param_sysfs_setup - setup sysfs support for one module 662 * @mod: module 663 * @kparam: module parameters (array) 664 * @num_params: number of module parameters 665 * 666 * Adds sysfs entries for module parameters under 667 * /sys/module/[mod->name]/parameters/ 668 */ 669 int module_param_sysfs_setup(struct module *mod, 670 const struct kernel_param *kparam, 671 unsigned int num_params) 672 { 673 int i, err; 674 bool params = false; 675 676 for (i = 0; i < num_params; i++) { 677 if (kparam[i].perm == 0) 678 continue; 679 err = add_sysfs_param(&mod->mkobj, &kparam[i], kparam[i].name); 680 if (err) 681 return err; 682 params = true; 683 } 684 685 if (!params) 686 return 0; 687 688 /* Create the param group. */ 689 err = sysfs_create_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp); 690 if (err) 691 free_module_param_attrs(&mod->mkobj); 692 return err; 693 } 694 695 /* 696 * module_param_sysfs_remove - remove sysfs support for one module 697 * @mod: module 698 * 699 * Remove sysfs entries for module parameters and the corresponding 700 * kobject. 701 */ 702 void module_param_sysfs_remove(struct module *mod) 703 { 704 if (mod->mkobj.mp) { 705 sysfs_remove_group(&mod->mkobj.kobj, &mod->mkobj.mp->grp); 706 /* We are positive that no one is using any param 707 * attrs at this point. Deallocate immediately. */ 708 free_module_param_attrs(&mod->mkobj); 709 } 710 } 711 #endif 712 713 void destroy_params(const struct kernel_param *params, unsigned num) 714 { 715 unsigned int i; 716 717 for (i = 0; i < num; i++) 718 if (params[i].ops->free) 719 params[i].ops->free(params[i].arg); 720 } 721 722 static void __init kernel_add_sysfs_param(const char *name, 723 struct kernel_param *kparam, 724 unsigned int name_skip) 725 { 726 struct module_kobject *mk; 727 struct kobject *kobj; 728 int err; 729 730 kobj = kset_find_obj(module_kset, name); 731 if (kobj) { 732 /* We already have one. Remove params so we can add more. */ 733 mk = to_module_kobject(kobj); 734 /* We need to remove it before adding parameters. */ 735 sysfs_remove_group(&mk->kobj, &mk->mp->grp); 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 if (err) { 745 kobject_put(&mk->kobj); 746 printk(KERN_ERR "Module '%s' failed add to sysfs, " 747 "error number %d\n", name, err); 748 printk(KERN_ERR "The system will be unstable now.\n"); 749 return; 750 } 751 /* So that exit path is even. */ 752 kobject_get(&mk->kobj); 753 } 754 755 /* These should not fail at boot. */ 756 err = add_sysfs_param(mk, kparam, kparam->name + name_skip); 757 BUG_ON(err); 758 err = sysfs_create_group(&mk->kobj, &mk->mp->grp); 759 BUG_ON(err); 760 kobject_uevent(&mk->kobj, KOBJ_ADD); 761 kobject_put(&mk->kobj); 762 } 763 764 /* 765 * param_sysfs_builtin - add contents in /sys/parameters for built-in modules 766 * 767 * Add module_parameters to sysfs for "modules" built into the kernel. 768 * 769 * The "module" name (KBUILD_MODNAME) is stored before a dot, the 770 * "parameter" name is stored behind a dot in kernel_param->name. So, 771 * extract the "module" name for all built-in kernel_param-eters, 772 * and for all who have the same, call kernel_add_sysfs_param. 773 */ 774 static void __init param_sysfs_builtin(void) 775 { 776 struct kernel_param *kp; 777 unsigned int name_len; 778 char modname[MODULE_NAME_LEN]; 779 780 for (kp = __start___param; kp < __stop___param; kp++) { 781 char *dot; 782 783 if (kp->perm == 0) 784 continue; 785 786 dot = strchr(kp->name, '.'); 787 if (!dot) { 788 /* This happens for core_param() */ 789 strcpy(modname, "kernel"); 790 name_len = 0; 791 } else { 792 name_len = dot - kp->name + 1; 793 strlcpy(modname, kp->name, name_len); 794 } 795 kernel_add_sysfs_param(modname, kp, name_len); 796 } 797 } 798 799 800 /* module-related sysfs stuff */ 801 802 static ssize_t module_attr_show(struct kobject *kobj, 803 struct attribute *attr, 804 char *buf) 805 { 806 struct module_attribute *attribute; 807 struct module_kobject *mk; 808 int ret; 809 810 attribute = to_module_attr(attr); 811 mk = to_module_kobject(kobj); 812 813 if (!attribute->show) 814 return -EIO; 815 816 ret = attribute->show(attribute, mk->mod, buf); 817 818 return ret; 819 } 820 821 static ssize_t module_attr_store(struct kobject *kobj, 822 struct attribute *attr, 823 const char *buf, size_t len) 824 { 825 struct module_attribute *attribute; 826 struct module_kobject *mk; 827 int ret; 828 829 attribute = to_module_attr(attr); 830 mk = to_module_kobject(kobj); 831 832 if (!attribute->store) 833 return -EIO; 834 835 ret = attribute->store(attribute, mk->mod, buf, len); 836 837 return ret; 838 } 839 840 static const struct sysfs_ops module_sysfs_ops = { 841 .show = module_attr_show, 842 .store = module_attr_store, 843 }; 844 845 static int uevent_filter(struct kset *kset, struct kobject *kobj) 846 { 847 struct kobj_type *ktype = get_ktype(kobj); 848 849 if (ktype == &module_ktype) 850 return 1; 851 return 0; 852 } 853 854 static const struct kset_uevent_ops module_uevent_ops = { 855 .filter = uevent_filter, 856 }; 857 858 struct kset *module_kset; 859 int module_sysfs_initialized; 860 861 struct kobj_type module_ktype = { 862 .sysfs_ops = &module_sysfs_ops, 863 }; 864 865 /* 866 * param_sysfs_init - wrapper for built-in params support 867 */ 868 static int __init param_sysfs_init(void) 869 { 870 module_kset = kset_create_and_add("module", &module_uevent_ops, NULL); 871 if (!module_kset) { 872 printk(KERN_WARNING "%s (%d): error creating kset\n", 873 __FILE__, __LINE__); 874 return -ENOMEM; 875 } 876 module_sysfs_initialized = 1; 877 878 param_sysfs_builtin(); 879 880 return 0; 881 } 882 subsys_initcall(param_sysfs_init); 883 884 #endif /* CONFIG_SYSFS */ 885