diff options
author | Mike Waychison <mikew@google.com> | 2011-03-11 20:43:27 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-03-14 11:40:51 -0400 |
commit | 4fc756bd9dbf6b84fbf751e3bf495277849c5db7 (patch) | |
tree | d7f71d68344385ecf2449994f1eda13fa7a5fbab | |
parent | 3295814d83c55e629abc6c2a31af1d504febb229 (diff) |
efivars: Expose efivars functionality to external drivers.
Signed-off-by: Mike Waychison <mikew@google.com>
Cc: Matt Domsch <Matt_Domsch@dell.com>,
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/firmware/efivars.c | 34 | ||||
-rw-r--r-- | include/linux/efi.h | 37 |
2 files changed, 44 insertions, 27 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index b10b7d7bd7de..ff0c373e3bbf 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c | |||
@@ -89,28 +89,6 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables"); | |||
89 | MODULE_LICENSE("GPL"); | 89 | MODULE_LICENSE("GPL"); |
90 | MODULE_VERSION(EFIVARS_VERSION); | 90 | MODULE_VERSION(EFIVARS_VERSION); |
91 | 91 | ||
92 | struct efivar_operations { | ||
93 | efi_get_variable_t *get_variable; | ||
94 | efi_get_next_variable_t *get_next_variable; | ||
95 | efi_set_variable_t *set_variable; | ||
96 | }; | ||
97 | |||
98 | struct efivars { | ||
99 | /* | ||
100 | * ->lock protects two things: | ||
101 | * 1) ->list - adds, removals, reads, writes | ||
102 | * 2) ops.[gs]et_variable() calls. | ||
103 | * It must not be held when creating sysfs entries or calling kmalloc. | ||
104 | * ops.get_next_variable() is only called from register_efivars(), | ||
105 | * which is protected by the BKL, so that path is safe. | ||
106 | */ | ||
107 | spinlock_t lock; | ||
108 | struct list_head list; | ||
109 | struct kset *kset; | ||
110 | struct bin_attribute *new_var, *del_var; | ||
111 | const struct efivar_operations *ops; | ||
112 | }; | ||
113 | |||
114 | /* | 92 | /* |
115 | * The maximum size of VariableName + Data = 1024 | 93 | * The maximum size of VariableName + Data = 1024 |
116 | * Therefore, it's reasonable to save that much | 94 | * Therefore, it's reasonable to save that much |
@@ -706,7 +684,7 @@ out_free: | |||
706 | return error; | 684 | return error; |
707 | } | 685 | } |
708 | 686 | ||
709 | static void unregister_efivars(struct efivars *efivars) | 687 | void unregister_efivars(struct efivars *efivars) |
710 | { | 688 | { |
711 | struct efivar_entry *entry, *n; | 689 | struct efivar_entry *entry, *n; |
712 | 690 | ||
@@ -724,10 +702,11 @@ static void unregister_efivars(struct efivars *efivars) | |||
724 | kfree(efivars->del_var); | 702 | kfree(efivars->del_var); |
725 | kset_unregister(efivars->kset); | 703 | kset_unregister(efivars->kset); |
726 | } | 704 | } |
705 | EXPORT_SYMBOL_GPL(unregister_efivars); | ||
727 | 706 | ||
728 | static int register_efivars(struct efivars *efivars, | 707 | int register_efivars(struct efivars *efivars, |
729 | const struct efivar_operations *ops, | 708 | const struct efivar_operations *ops, |
730 | struct kobject *parent_kobj) | 709 | struct kobject *parent_kobj) |
731 | { | 710 | { |
732 | efi_status_t status = EFI_NOT_FOUND; | 711 | efi_status_t status = EFI_NOT_FOUND; |
733 | efi_guid_t vendor_guid; | 712 | efi_guid_t vendor_guid; |
@@ -789,6 +768,7 @@ out: | |||
789 | 768 | ||
790 | return error; | 769 | return error; |
791 | } | 770 | } |
771 | EXPORT_SYMBOL_GPL(register_efivars); | ||
792 | 772 | ||
793 | static struct efivars __efivars; | 773 | static struct efivars __efivars; |
794 | static struct efivar_operations ops; | 774 | static struct efivar_operations ops; |
@@ -810,7 +790,7 @@ efivars_init(void) | |||
810 | EFIVARS_DATE); | 790 | EFIVARS_DATE); |
811 | 791 | ||
812 | if (!efi_enabled) | 792 | if (!efi_enabled) |
813 | return -ENODEV; | 793 | return 0; |
814 | 794 | ||
815 | /* For now we'll register the efi directory at /sys/firmware/efi */ | 795 | /* For now we'll register the efi directory at /sys/firmware/efi */ |
816 | efi_kobj = kobject_create_and_add("efi", firmware_kobj); | 796 | efi_kobj = kobject_create_and_add("efi", firmware_kobj); |
diff --git a/include/linux/efi.h b/include/linux/efi.h index fb737bc19a8c..33fa1203024e 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -397,4 +397,41 @@ static inline void memrange_efi_to_native(u64 *addr, u64 *npages) | |||
397 | *addr &= PAGE_MASK; | 397 | *addr &= PAGE_MASK; |
398 | } | 398 | } |
399 | 399 | ||
400 | #if defined(CONFIG_EFI_VARS) || defined(CONFIG_EFI_VARS_MODULE) | ||
401 | /* | ||
402 | * EFI Variable support. | ||
403 | * | ||
404 | * Different firmware drivers can expose their EFI-like variables using | ||
405 | * the following. | ||
406 | */ | ||
407 | |||
408 | struct efivar_operations { | ||
409 | efi_get_variable_t *get_variable; | ||
410 | efi_get_next_variable_t *get_next_variable; | ||
411 | efi_set_variable_t *set_variable; | ||
412 | }; | ||
413 | |||
414 | struct efivars { | ||
415 | /* | ||
416 | * ->lock protects two things: | ||
417 | * 1) ->list - adds, removals, reads, writes | ||
418 | * 2) ops.[gs]et_variable() calls. | ||
419 | * It must not be held when creating sysfs entries or calling kmalloc. | ||
420 | * ops.get_next_variable() is only called from register_efivars(), | ||
421 | * which is protected by the BKL, so that path is safe. | ||
422 | */ | ||
423 | spinlock_t lock; | ||
424 | struct list_head list; | ||
425 | struct kset *kset; | ||
426 | struct bin_attribute *new_var, *del_var; | ||
427 | const struct efivar_operations *ops; | ||
428 | }; | ||
429 | |||
430 | int register_efivars(struct efivars *efivars, | ||
431 | const struct efivar_operations *ops, | ||
432 | struct kobject *parent_kobj); | ||
433 | void unregister_efivars(struct efivars *efivars); | ||
434 | |||
435 | #endif /* CONFIG_EFI_VARS */ | ||
436 | |||
400 | #endif /* _LINUX_EFI_H */ | 437 | #endif /* _LINUX_EFI_H */ |