diff options
author | Mike Waychison <mikew@google.com> | 2011-03-11 20:43:16 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-03-14 11:40:50 -0400 |
commit | 76b53f7c8bfa41f94ec32d84493a691f096e89f5 (patch) | |
tree | 8871334a623c53ad993c538932ad82b12ebb47a4 /drivers/firmware | |
parent | 4142ef146aee440731de956d9f9f3170d5a238ae (diff) |
efivars: Split out variable registration
In anticipation of re-using the variable facilities in efivars from
elsewhere, split out the registration and unregistration of struct
efivars from the rest of the EFI specific sysfs code.
Signed-off-by: Mike Waychison <mikew@google.com>
Cc: Matt Domsch <Matt_Domsch@dell.com>,
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efivars.c | 122 |
1 files changed, 67 insertions, 55 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 5633018c34af..f22bfcf2b968 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -95,7 +95,7 @@ struct efivars { | |||
95 | * 1) ->list - adds, removals, reads, writes | 95 | * 1) ->list - adds, removals, reads, writes |
96 | * 2) efi.[gs]et_variable() calls. | 96 | * 2) efi.[gs]et_variable() calls. |
97 | * It must not be held when creating sysfs entries or calling kmalloc. | 97 | * It must not be held when creating sysfs entries or calling kmalloc. |
98 | * efi.get_next_variable() is only called from efivars_init(), | 98 | * efi.get_next_variable() is only called from register_efivars(), |
99 | * which is protected by the BKL, so that path is safe. | 99 | * which is protected by the BKL, so that path is safe. |
100 | */ | 100 | */ |
101 | spinlock_t lock; | 101 | spinlock_t lock; |
@@ -699,54 +699,48 @@ out_free: | |||
699 | return error; | 699 | return error; |
700 | } | 700 | } |
701 | 701 | ||
702 | static struct efivars __efivars; | 702 | static void unregister_efivars(struct efivars *efivars) |
703 | { | ||
704 | struct efivar_entry *entry, *n; | ||
703 | 705 | ||
704 | /* | 706 | list_for_each_entry_safe(entry, n, &efivars->list, list) { |
705 | * For now we register the efi subsystem with the firmware subsystem | 707 | spin_lock(&efivars->lock); |
706 | * and the vars subsystem with the efi subsystem. In the future, it | 708 | list_del(&entry->list); |
707 | * might make sense to split off the efi subsystem into its own | 709 | spin_unlock(&efivars->lock); |
708 | * driver, but for now only efivars will register with it, so just | 710 | efivar_unregister(entry); |
709 | * include it here. | 711 | } |
710 | */ | 712 | if (efivars->new_var) |
713 | sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var); | ||
714 | if (efivars->del_var) | ||
715 | sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); | ||
716 | kfree(efivars->new_var); | ||
717 | kfree(efivars->del_var); | ||
718 | kset_unregister(efivars->kset); | ||
719 | } | ||
711 | 720 | ||
712 | static int __init | 721 | static int register_efivars(struct efivars *efivars, |
713 | efivars_init(void) | 722 | struct kobject *parent_kobj) |
714 | { | 723 | { |
715 | efi_status_t status = EFI_NOT_FOUND; | 724 | efi_status_t status = EFI_NOT_FOUND; |
716 | efi_guid_t vendor_guid; | 725 | efi_guid_t vendor_guid; |
717 | efi_char16_t *variable_name; | 726 | efi_char16_t *variable_name; |
718 | unsigned long variable_name_size = 1024; | 727 | unsigned long variable_name_size = 1024; |
719 | struct efivars *efivars = &__efivars; | ||
720 | int error = 0; | 728 | int error = 0; |
721 | 729 | ||
722 | if (!efi_enabled) | ||
723 | return -ENODEV; | ||
724 | |||
725 | variable_name = kzalloc(variable_name_size, GFP_KERNEL); | 730 | variable_name = kzalloc(variable_name_size, GFP_KERNEL); |
726 | if (!variable_name) { | 731 | if (!variable_name) { |
727 | printk(KERN_ERR "efivars: Memory allocation failed.\n"); | 732 | printk(KERN_ERR "efivars: Memory allocation failed.\n"); |
728 | return -ENOMEM; | 733 | return -ENOMEM; |
729 | } | 734 | } |
730 | 735 | ||
731 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, | ||
732 | EFIVARS_DATE); | ||
733 | |||
734 | /* For now we'll register the efi directory at /sys/firmware/efi */ | ||
735 | efi_kobj = kobject_create_and_add("efi", firmware_kobj); | ||
736 | if (!efi_kobj) { | ||
737 | printk(KERN_ERR "efivars: Firmware registration failed.\n"); | ||
738 | error = -ENOMEM; | ||
739 | goto out_free; | ||
740 | } | ||
741 | |||
742 | spin_lock_init(&efivars->lock); | 736 | spin_lock_init(&efivars->lock); |
743 | INIT_LIST_HEAD(&efivars->list); | 737 | INIT_LIST_HEAD(&efivars->list); |
744 | 738 | ||
745 | efivars->kset = kset_create_and_add("vars", NULL, efi_kobj); | 739 | efivars->kset = kset_create_and_add("vars", NULL, parent_kobj); |
746 | if (!efivars->kset) { | 740 | if (!efivars->kset) { |
747 | printk(KERN_ERR "efivars: Subsystem registration failed.\n"); | 741 | printk(KERN_ERR "efivars: Subsystem registration failed.\n"); |
748 | error = -ENOMEM; | 742 | error = -ENOMEM; |
749 | goto out_firmware_unregister; | 743 | goto out; |
750 | } | 744 | } |
751 | 745 | ||
752 | /* | 746 | /* |
@@ -778,21 +772,54 @@ efivars_init(void) | |||
778 | } while (status != EFI_NOT_FOUND); | 772 | } while (status != EFI_NOT_FOUND); |
779 | 773 | ||
780 | error = create_efivars_bin_attributes(efivars); | 774 | error = create_efivars_bin_attributes(efivars); |
781 | |||
782 | /* Don't forget the systab entry */ | ||
783 | error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); | ||
784 | if (error) | 775 | if (error) |
785 | printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); | 776 | unregister_efivars(efivars); |
786 | else | ||
787 | goto out_free; | ||
788 | 777 | ||
789 | kset_unregister(efivars->kset); | 778 | out: |
779 | kfree(variable_name); | ||
790 | 780 | ||
791 | out_firmware_unregister: | 781 | return error; |
792 | kobject_put(efi_kobj); | 782 | } |
793 | 783 | ||
794 | out_free: | 784 | static struct efivars __efivars; |
795 | kfree(variable_name); | 785 | |
786 | /* | ||
787 | * For now we register the efi subsystem with the firmware subsystem | ||
788 | * and the vars subsystem with the efi subsystem. In the future, it | ||
789 | * might make sense to split off the efi subsystem into its own | ||
790 | * driver, but for now only efivars will register with it, so just | ||
791 | * include it here. | ||
792 | */ | ||
793 | |||
794 | static int __init | ||
795 | efivars_init(void) | ||
796 | { | ||
797 | int error = 0; | ||
798 | |||
799 | printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, | ||
800 | EFIVARS_DATE); | ||
801 | |||
802 | if (!efi_enabled) | ||
803 | return -ENODEV; | ||
804 | |||
805 | /* For now we'll register the efi directory at /sys/firmware/efi */ | ||
806 | efi_kobj = kobject_create_and_add("efi", firmware_kobj); | ||
807 | if (!efi_kobj) { | ||
808 | printk(KERN_ERR "efivars: Firmware registration failed.\n"); | ||
809 | return -ENOMEM; | ||
810 | } | ||
811 | |||
812 | error = register_efivars(&__efivars, efi_kobj); | ||
813 | |||
814 | /* Don't forget the systab entry */ | ||
815 | error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); | ||
816 | if (error) { | ||
817 | printk(KERN_ERR | ||
818 | "efivars: Sysfs attribute export failed with error %d.\n", | ||
819 | error); | ||
820 | unregister_efivars(&__efivars); | ||
821 | kobject_put(efi_kobj); | ||
822 | } | ||
796 | 823 | ||
797 | return error; | 824 | return error; |
798 | } | 825 | } |
@@ -800,22 +827,7 @@ out_free: | |||
800 | static void __exit | 827 | static void __exit |
801 | efivars_exit(void) | 828 | efivars_exit(void) |
802 | { | 829 | { |
803 | struct efivars *efivars = &__efivars; | 830 | unregister_efivars(&__efivars); |
804 | struct efivar_entry *entry, *n; | ||
805 | |||
806 | list_for_each_entry_safe(entry, n, &efivars->list, list) { | ||
807 | spin_lock(&efivars->lock); | ||
808 | list_del(&entry->list); | ||
809 | spin_unlock(&efivars->lock); | ||
810 | efivar_unregister(entry); | ||
811 | } | ||
812 | if (efivars->new_var) | ||
813 | sysfs_remove_bin_file(&efivars->kset->kobj, efivars->new_var); | ||
814 | if (efivars->del_var) | ||
815 | sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); | ||
816 | kfree(efivars->new_var); | ||
817 | kfree(efivars->del_var); | ||
818 | kset_unregister(efivars->kset); | ||
819 | kobject_put(efi_kobj); | 831 | kobject_put(efi_kobj); |
820 | } | 832 | } |
821 | 833 | ||