diff options
Diffstat (limited to 'drivers/firmware/efivars.c')
-rw-r--r-- | drivers/firmware/efivars.c | 130 |
1 files changed, 57 insertions, 73 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 858a7b95933b..f4f709d1370b 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -129,13 +129,6 @@ struct efivar_attribute { | |||
129 | }; | 129 | }; |
130 | 130 | ||
131 | 131 | ||
132 | #define EFI_ATTR(_name, _mode, _show, _store) \ | ||
133 | struct subsys_attribute efi_attr_##_name = { \ | ||
134 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | ||
135 | .show = _show, \ | ||
136 | .store = _store, \ | ||
137 | }; | ||
138 | |||
139 | #define EFIVAR_ATTR(_name, _mode, _show, _store) \ | 132 | #define EFIVAR_ATTR(_name, _mode, _show, _store) \ |
140 | struct efivar_attribute efivar_attr_##_name = { \ | 133 | struct efivar_attribute efivar_attr_##_name = { \ |
141 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | 134 | .attr = {.name = __stringify(_name), .mode = _mode}, \ |
@@ -143,13 +136,6 @@ struct efivar_attribute efivar_attr_##_name = { \ | |||
143 | .store = _store, \ | 136 | .store = _store, \ |
144 | }; | 137 | }; |
145 | 138 | ||
146 | #define VAR_SUBSYS_ATTR(_name, _mode, _show, _store) \ | ||
147 | struct subsys_attribute var_subsys_attr_##_name = { \ | ||
148 | .attr = {.name = __stringify(_name), .mode = _mode}, \ | ||
149 | .show = _show, \ | ||
150 | .store = _store, \ | ||
151 | }; | ||
152 | |||
153 | #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr) | 139 | #define to_efivar_attr(_attr) container_of(_attr, struct efivar_attribute, attr) |
154 | #define to_efivar_entry(obj) container_of(obj, struct efivar_entry, kobj) | 140 | #define to_efivar_entry(obj) container_of(obj, struct efivar_entry, kobj) |
155 | 141 | ||
@@ -408,21 +394,16 @@ static struct kobj_type efivar_ktype = { | |||
408 | .default_attrs = def_attrs, | 394 | .default_attrs = def_attrs, |
409 | }; | 395 | }; |
410 | 396 | ||
411 | static ssize_t | ||
412 | dummy(struct kset *kset, char *buf) | ||
413 | { | ||
414 | return -ENODEV; | ||
415 | } | ||
416 | |||
417 | static inline void | 397 | static inline void |
418 | efivar_unregister(struct efivar_entry *var) | 398 | efivar_unregister(struct efivar_entry *var) |
419 | { | 399 | { |
420 | kobject_unregister(&var->kobj); | 400 | kobject_put(&var->kobj); |
421 | } | 401 | } |
422 | 402 | ||
423 | 403 | ||
424 | static ssize_t | 404 | static ssize_t efivar_create(struct kobject *kobj, |
425 | efivar_create(struct kset *kset, const char *buf, size_t count) | 405 | struct bin_attribute *bin_attr, |
406 | char *buf, loff_t pos, size_t count) | ||
426 | { | 407 | { |
427 | struct efi_variable *new_var = (struct efi_variable *)buf; | 408 | struct efi_variable *new_var = (struct efi_variable *)buf; |
428 | struct efivar_entry *search_efivar, *n; | 409 | struct efivar_entry *search_efivar, *n; |
@@ -479,8 +460,9 @@ efivar_create(struct kset *kset, const char *buf, size_t count) | |||
479 | return count; | 460 | return count; |
480 | } | 461 | } |
481 | 462 | ||
482 | static ssize_t | 463 | static ssize_t efivar_delete(struct kobject *kobj, |
483 | efivar_delete(struct kset *kset, const char *buf, size_t count) | 464 | struct bin_attribute *bin_attr, |
465 | char *buf, loff_t pos, size_t count) | ||
484 | { | 466 | { |
485 | struct efi_variable *del_var = (struct efi_variable *)buf; | 467 | struct efi_variable *del_var = (struct efi_variable *)buf; |
486 | struct efivar_entry *search_efivar, *n; | 468 | struct efivar_entry *search_efivar, *n; |
@@ -537,25 +519,26 @@ efivar_delete(struct kset *kset, const char *buf, size_t count) | |||
537 | return count; | 519 | return count; |
538 | } | 520 | } |
539 | 521 | ||
540 | static VAR_SUBSYS_ATTR(new_var, 0200, dummy, efivar_create); | 522 | static struct bin_attribute var_subsys_attr_new_var = { |
541 | static VAR_SUBSYS_ATTR(del_var, 0200, dummy, efivar_delete); | 523 | .attr = {.name = "new_var", .mode = 0200}, |
524 | .write = efivar_create, | ||
525 | }; | ||
542 | 526 | ||
543 | static struct subsys_attribute *var_subsys_attrs[] = { | 527 | static struct bin_attribute var_subsys_attr_del_var = { |
544 | &var_subsys_attr_new_var, | 528 | .attr = {.name = "del_var", .mode = 0200}, |
545 | &var_subsys_attr_del_var, | 529 | .write = efivar_delete, |
546 | NULL, | ||
547 | }; | 530 | }; |
548 | 531 | ||
549 | /* | 532 | /* |
550 | * Let's not leave out systab information that snuck into | 533 | * Let's not leave out systab information that snuck into |
551 | * the efivars driver | 534 | * the efivars driver |
552 | */ | 535 | */ |
553 | static ssize_t | 536 | static ssize_t systab_show(struct kobject *kobj, |
554 | systab_read(struct kset *kset, char *buf) | 537 | struct kobj_attribute *attr, char *buf) |
555 | { | 538 | { |
556 | char *str = buf; | 539 | char *str = buf; |
557 | 540 | ||
558 | if (!kset || !buf) | 541 | if (!kobj || !buf) |
559 | return -EINVAL; | 542 | return -EINVAL; |
560 | 543 | ||
561 | if (efi.mps != EFI_INVALID_TABLE_ADDR) | 544 | if (efi.mps != EFI_INVALID_TABLE_ADDR) |
@@ -576,15 +559,21 @@ systab_read(struct kset *kset, char *buf) | |||
576 | return str - buf; | 559 | return str - buf; |
577 | } | 560 | } |
578 | 561 | ||
579 | static EFI_ATTR(systab, 0400, systab_read, NULL); | 562 | static struct kobj_attribute efi_attr_systab = |
563 | __ATTR(systab, 0400, systab_show, NULL); | ||
580 | 564 | ||
581 | static struct subsys_attribute *efi_subsys_attrs[] = { | 565 | static struct attribute *efi_subsys_attrs[] = { |
582 | &efi_attr_systab, | 566 | &efi_attr_systab.attr, |
583 | NULL, /* maybe more in the future? */ | 567 | NULL, /* maybe more in the future? */ |
584 | }; | 568 | }; |
585 | 569 | ||
586 | static decl_subsys(vars, &efivar_ktype, NULL); | 570 | static struct attribute_group efi_subsys_attr_group = { |
587 | static decl_subsys(efi, NULL, NULL); | 571 | .attrs = efi_subsys_attrs, |
572 | }; | ||
573 | |||
574 | |||
575 | static struct kset *vars_kset; | ||
576 | static struct kobject *efi_kobj; | ||
588 | 577 | ||
589 | /* | 578 | /* |
590 | * efivar_create_sysfs_entry() | 579 | * efivar_create_sysfs_entry() |
@@ -628,15 +617,16 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, | |||
628 | *(short_name + strlen(short_name)) = '-'; | 617 | *(short_name + strlen(short_name)) = '-'; |
629 | efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); | 618 | efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); |
630 | 619 | ||
631 | kobject_set_name(&new_efivar->kobj, "%s", short_name); | 620 | new_efivar->kobj.kset = vars_kset; |
632 | kobj_set_kset_s(new_efivar, vars_subsys); | 621 | i = kobject_init_and_add(&new_efivar->kobj, &efivar_ktype, NULL, |
633 | i = kobject_register(&new_efivar->kobj); | 622 | "%s", short_name); |
634 | if (i) { | 623 | if (i) { |
635 | kfree(short_name); | 624 | kfree(short_name); |
636 | kfree(new_efivar); | 625 | kfree(new_efivar); |
637 | return 1; | 626 | return 1; |
638 | } | 627 | } |
639 | 628 | ||
629 | kobject_uevent(&new_efivar->kobj, KOBJ_ADD); | ||
640 | kfree(short_name); | 630 | kfree(short_name); |
641 | short_name = NULL; | 631 | short_name = NULL; |
642 | 632 | ||
@@ -660,9 +650,8 @@ efivars_init(void) | |||
660 | efi_status_t status = EFI_NOT_FOUND; | 650 | efi_status_t status = EFI_NOT_FOUND; |
661 | efi_guid_t vendor_guid; | 651 | efi_guid_t vendor_guid; |
662 | efi_char16_t *variable_name; | 652 | efi_char16_t *variable_name; |
663 | struct subsys_attribute *attr; | ||
664 | unsigned long variable_name_size = 1024; | 653 | unsigned long variable_name_size = 1024; |
665 | int i, error = 0; | 654 | int error = 0; |
666 | 655 | ||
667 | if (!efi_enabled) | 656 | if (!efi_enabled) |
668 | return -ENODEV; | 657 | return -ENODEV; |
@@ -676,23 +665,18 @@ efivars_init(void) | |||
676 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, | 665 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, |
677 | EFIVARS_DATE); | 666 | EFIVARS_DATE); |
678 | 667 | ||
679 | /* | 668 | /* For now we'll register the efi directory at /sys/firmware/efi */ |
680 | * For now we'll register the efi subsys within this driver | 669 | efi_kobj = kobject_create_and_add("efi", firmware_kobj); |
681 | */ | 670 | if (!efi_kobj) { |
682 | 671 | printk(KERN_ERR "efivars: Firmware registration failed.\n"); | |
683 | error = firmware_register(&efi_subsys); | 672 | error = -ENOMEM; |
684 | |||
685 | if (error) { | ||
686 | printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error); | ||
687 | goto out_free; | 673 | goto out_free; |
688 | } | 674 | } |
689 | 675 | ||
690 | kobj_set_kset_s(&vars_subsys, efi_subsys); | 676 | vars_kset = kset_create_and_add("vars", NULL, efi_kobj); |
691 | 677 | if (!vars_kset) { | |
692 | error = subsystem_register(&vars_subsys); | 678 | printk(KERN_ERR "efivars: Subsystem registration failed.\n"); |
693 | 679 | error = -ENOMEM; | |
694 | if (error) { | ||
695 | printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error); | ||
696 | goto out_firmware_unregister; | 680 | goto out_firmware_unregister; |
697 | } | 681 | } |
698 | 682 | ||
@@ -727,28 +711,28 @@ efivars_init(void) | |||
727 | * Now add attributes to allow creation of new vars | 711 | * Now add attributes to allow creation of new vars |
728 | * and deletion of existing ones... | 712 | * and deletion of existing ones... |
729 | */ | 713 | */ |
730 | 714 | error = sysfs_create_bin_file(&vars_kset->kobj, | |
731 | for (i = 0; (attr = var_subsys_attrs[i]) && !error; i++) { | 715 | &var_subsys_attr_new_var); |
732 | if (attr->show && attr->store) | 716 | if (error) |
733 | error = subsys_create_file(&vars_subsys, attr); | 717 | printk(KERN_ERR "efivars: unable to create new_var sysfs file" |
734 | } | 718 | " due to error %d\n", error); |
719 | error = sysfs_create_bin_file(&vars_kset->kobj, | ||
720 | &var_subsys_attr_del_var); | ||
721 | if (error) | ||
722 | printk(KERN_ERR "efivars: unable to create del_var sysfs file" | ||
723 | " due to error %d\n", error); | ||
735 | 724 | ||
736 | /* Don't forget the systab entry */ | 725 | /* Don't forget the systab entry */ |
737 | 726 | error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); | |
738 | for (i = 0; (attr = efi_subsys_attrs[i]) && !error; i++) { | ||
739 | if (attr->show) | ||
740 | error = subsys_create_file(&efi_subsys, attr); | ||
741 | } | ||
742 | |||
743 | if (error) | 727 | if (error) |
744 | printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); | 728 | printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); |
745 | else | 729 | else |
746 | goto out_free; | 730 | goto out_free; |
747 | 731 | ||
748 | subsystem_unregister(&vars_subsys); | 732 | kset_unregister(vars_kset); |
749 | 733 | ||
750 | out_firmware_unregister: | 734 | out_firmware_unregister: |
751 | firmware_unregister(&efi_subsys); | 735 | kobject_put(efi_kobj); |
752 | 736 | ||
753 | out_free: | 737 | out_free: |
754 | kfree(variable_name); | 738 | kfree(variable_name); |
@@ -768,8 +752,8 @@ efivars_exit(void) | |||
768 | efivar_unregister(entry); | 752 | efivar_unregister(entry); |
769 | } | 753 | } |
770 | 754 | ||
771 | subsystem_unregister(&vars_subsys); | 755 | kset_unregister(vars_kset); |
772 | firmware_unregister(&efi_subsys); | 756 | kobject_put(efi_kobj); |
773 | } | 757 | } |
774 | 758 | ||
775 | module_init(efivars_init); | 759 | module_init(efivars_init); |