aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/efivars.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index f22bfcf2b968..b10b7d7bd7de 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -89,19 +89,26 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables");
89MODULE_LICENSE("GPL"); 89MODULE_LICENSE("GPL");
90MODULE_VERSION(EFIVARS_VERSION); 90MODULE_VERSION(EFIVARS_VERSION);
91 91
92struct 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
92struct efivars { 98struct efivars {
93 /* 99 /*
94 * ->lock protects two things: 100 * ->lock protects two things:
95 * 1) ->list - adds, removals, reads, writes 101 * 1) ->list - adds, removals, reads, writes
96 * 2) efi.[gs]et_variable() calls. 102 * 2) ops.[gs]et_variable() calls.
97 * It must not be held when creating sysfs entries or calling kmalloc. 103 * It must not be held when creating sysfs entries or calling kmalloc.
98 * efi.get_next_variable() is only called from register_efivars(), 104 * ops.get_next_variable() is only called from register_efivars(),
99 * which is protected by the BKL, so that path is safe. 105 * which is protected by the BKL, so that path is safe.
100 */ 106 */
101 spinlock_t lock; 107 spinlock_t lock;
102 struct list_head list; 108 struct list_head list;
103 struct kset *kset; 109 struct kset *kset;
104 struct bin_attribute *new_var, *del_var; 110 struct bin_attribute *new_var, *del_var;
111 const struct efivar_operations *ops;
105}; 112};
106 113
107/* 114/*
@@ -182,11 +189,11 @@ get_var_data(struct efivars *efivars, struct efi_variable *var)
182 189
183 spin_lock(&efivars->lock); 190 spin_lock(&efivars->lock);
184 var->DataSize = 1024; 191 var->DataSize = 1024;
185 status = efi.get_variable(var->VariableName, 192 status = efivars->ops->get_variable(var->VariableName,
186 &var->VendorGuid, 193 &var->VendorGuid,
187 &var->Attributes, 194 &var->Attributes,
188 &var->DataSize, 195 &var->DataSize,
189 var->Data); 196 var->Data);
190 spin_unlock(&efivars->lock); 197 spin_unlock(&efivars->lock);
191 if (status != EFI_SUCCESS) { 198 if (status != EFI_SUCCESS) {
192 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n", 199 printk(KERN_WARNING "efivars: get_variable() failed 0x%lx!\n",
@@ -299,11 +306,11 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count)
299 } 306 }
300 307
301 spin_lock(&efivars->lock); 308 spin_lock(&efivars->lock);
302 status = efi.set_variable(new_var->VariableName, 309 status = efivars->ops->set_variable(new_var->VariableName,
303 &new_var->VendorGuid, 310 &new_var->VendorGuid,
304 new_var->Attributes, 311 new_var->Attributes,
305 new_var->DataSize, 312 new_var->DataSize,
306 new_var->Data); 313 new_var->Data);
307 314
308 spin_unlock(&efivars->lock); 315 spin_unlock(&efivars->lock);
309 316
@@ -446,11 +453,11 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
446 } 453 }
447 454
448 /* now *really* create the variable via EFI */ 455 /* now *really* create the variable via EFI */
449 status = efi.set_variable(new_var->VariableName, 456 status = efivars->ops->set_variable(new_var->VariableName,
450 &new_var->VendorGuid, 457 &new_var->VendorGuid,
451 new_var->Attributes, 458 new_var->Attributes,
452 new_var->DataSize, 459 new_var->DataSize,
453 new_var->Data); 460 new_var->Data);
454 461
455 if (status != EFI_SUCCESS) { 462 if (status != EFI_SUCCESS) {
456 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 463 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
@@ -511,11 +518,11 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
511 del_var->Attributes = 0; 518 del_var->Attributes = 0;
512 del_var->DataSize = 0; 519 del_var->DataSize = 0;
513 520
514 status = efi.set_variable(del_var->VariableName, 521 status = efivars->ops->set_variable(del_var->VariableName,
515 &del_var->VendorGuid, 522 &del_var->VendorGuid,
516 del_var->Attributes, 523 del_var->Attributes,
517 del_var->DataSize, 524 del_var->DataSize,
518 del_var->Data); 525 del_var->Data);
519 526
520 if (status != EFI_SUCCESS) { 527 if (status != EFI_SUCCESS) {
521 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n", 528 printk(KERN_WARNING "efivars: set_variable() failed: status=%lx\n",
@@ -719,6 +726,7 @@ static void unregister_efivars(struct efivars *efivars)
719} 726}
720 727
721static int register_efivars(struct efivars *efivars, 728static int register_efivars(struct efivars *efivars,
729 const struct efivar_operations *ops,
722 struct kobject *parent_kobj) 730 struct kobject *parent_kobj)
723{ 731{
724 efi_status_t status = EFI_NOT_FOUND; 732 efi_status_t status = EFI_NOT_FOUND;
@@ -735,6 +743,7 @@ static int register_efivars(struct efivars *efivars,
735 743
736 spin_lock_init(&efivars->lock); 744 spin_lock_init(&efivars->lock);
737 INIT_LIST_HEAD(&efivars->list); 745 INIT_LIST_HEAD(&efivars->list);
746 efivars->ops = ops;
738 747
739 efivars->kset = kset_create_and_add("vars", NULL, parent_kobj); 748 efivars->kset = kset_create_and_add("vars", NULL, parent_kobj);
740 if (!efivars->kset) { 749 if (!efivars->kset) {
@@ -751,7 +760,7 @@ static int register_efivars(struct efivars *efivars,
751 do { 760 do {
752 variable_name_size = 1024; 761 variable_name_size = 1024;
753 762
754 status = efi.get_next_variable(&variable_name_size, 763 status = ops->get_next_variable(&variable_name_size,
755 variable_name, 764 variable_name,
756 &vendor_guid); 765 &vendor_guid);
757 switch (status) { 766 switch (status) {
@@ -782,6 +791,7 @@ out:
782} 791}
783 792
784static struct efivars __efivars; 793static struct efivars __efivars;
794static struct efivar_operations ops;
785 795
786/* 796/*
787 * For now we register the efi subsystem with the firmware subsystem 797 * For now we register the efi subsystem with the firmware subsystem
@@ -809,7 +819,10 @@ efivars_init(void)
809 return -ENOMEM; 819 return -ENOMEM;
810 } 820 }
811 821
812 error = register_efivars(&__efivars, efi_kobj); 822 ops.get_variable = efi.get_variable;
823 ops.set_variable = efi.set_variable;
824 ops.get_next_variable = efi.get_next_variable;
825 error = register_efivars(&__efivars, &ops, efi_kobj);
813 826
814 /* Don't forget the systab entry */ 827 /* Don't forget the systab entry */
815 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); 828 error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);