aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMike Waychison <mikew@google.com>2011-03-11 20:43:16 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-14 11:40:50 -0400
commit76b53f7c8bfa41f94ec32d84493a691f096e89f5 (patch)
tree8871334a623c53ad993c538932ad82b12ebb47a4 /drivers/firmware
parent4142ef146aee440731de956d9f9f3170d5a238ae (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.c122
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
702static struct efivars __efivars; 702static 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
712static int __init 721static int register_efivars(struct efivars *efivars,
713efivars_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); 778out:
779 kfree(variable_name);
790 780
791out_firmware_unregister: 781 return error;
792 kobject_put(efi_kobj); 782}
793 783
794out_free: 784static 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
794static int __init
795efivars_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:
800static void __exit 827static void __exit
801efivars_exit(void) 828efivars_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