X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Ffirmware%2Fefivars.c;h=9b7e4d52ffd474ef9f745b9d36c5db13ad172e2e;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=4f92849567aa78053ce1ef04f495d2020e941168;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 4f9284956..9b7e4d52f 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -65,11 +65,11 @@ * v0.01 release to linux-ia64@linuxia64.org */ +#include #include #include #include #include -#include /* for capable() */ #include #include #include @@ -97,7 +97,7 @@ MODULE_VERSION(EFIVARS_VERSION); * efi.get_next_variable() is only called from efivars_init(), * which is protected by the BKL, so that path is safe. */ -static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(efivars_lock); static LIST_HEAD(efivar_list); /* @@ -352,7 +352,7 @@ static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr, { struct efivar_entry *var = to_efivar_entry(kobj); struct efivar_attribute *efivar_attr = to_efivar_attr(attr); - ssize_t ret = 0; + ssize_t ret = -EIO; if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -368,7 +368,7 @@ static ssize_t efivar_attr_store(struct kobject *kobj, struct attribute *attr, { struct efivar_entry *var = to_efivar_entry(kobj); struct efivar_attribute *efivar_attr = to_efivar_attr(attr); - ssize_t ret = 0; + ssize_t ret = -EIO; if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -568,20 +568,20 @@ systab_read(struct subsystem *entry, char *buf) if (!entry || !buf) return -EINVAL; - if (efi.mps) - str += sprintf(str, "MPS=0x%lx\n", __pa(efi.mps)); - if (efi.acpi20) - str += sprintf(str, "ACPI20=0x%lx\n", __pa(efi.acpi20)); - if (efi.acpi) - str += sprintf(str, "ACPI=0x%lx\n", __pa(efi.acpi)); - if (efi.smbios) - str += sprintf(str, "SMBIOS=0x%lx\n", __pa(efi.smbios)); - if (efi.hcdp) - str += sprintf(str, "HCDP=0x%lx\n", __pa(efi.hcdp)); - if (efi.boot_info) - str += sprintf(str, "BOOTINFO=0x%lx\n", __pa(efi.boot_info)); - if (efi.uga) - str += sprintf(str, "UGA=0x%lx\n", __pa(efi.uga)); + if (efi.mps != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "MPS=0x%lx\n", efi.mps); + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20); + if (efi.acpi != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "ACPI=0x%lx\n", efi.acpi); + if (efi.smbios != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios); + if (efi.hcdp != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp); + if (efi.boot_info != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info); + if (efi.uga != EFI_INVALID_TABLE_ADDR) + str += sprintf(str, "UGA=0x%lx\n", efi.uga); return str - buf; } @@ -614,16 +614,14 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, char *short_name; struct efivar_entry *new_efivar; - short_name = kmalloc(short_name_size + 1, GFP_KERNEL); - new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL); + short_name = kzalloc(short_name_size + 1, GFP_KERNEL); + new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); if (!short_name || !new_efivar) { - if (short_name) kfree(short_name); - if (new_efivar) kfree(new_efivar); + kfree(short_name); + kfree(new_efivar); return 1; } - memset(short_name, 0, short_name_size+1); - memset(new_efivar, 0, sizeof(struct efivar_entry)); memcpy(new_efivar->var.VariableName, variable_name, variable_name_size); @@ -640,11 +638,12 @@ efivar_create_sysfs_entry(unsigned long variable_name_size, *(short_name + strlen(short_name)) = '-'; efi_guid_unparse(vendor_guid, short_name + strlen(short_name)); - kobject_set_name(&new_efivar->kobj, short_name); + kobject_set_name(&new_efivar->kobj, "%s", short_name); kobj_set_kset_s(new_efivar, vars_subsys); kobject_register(&new_efivar->kobj); - kfree(short_name); short_name = NULL; + kfree(short_name); + short_name = NULL; spin_lock(&efivars_lock); list_add(&new_efivar->list, &efivar_list); @@ -665,14 +664,20 @@ efivars_init(void) { efi_status_t status = EFI_NOT_FOUND; efi_guid_t vendor_guid; - efi_char16_t *variable_name = kmalloc(1024, GFP_KERNEL); + efi_char16_t *variable_name; struct subsys_attribute *attr; unsigned long variable_name_size = 1024; - int i, rc = 0, error = 0; + int i, error = 0; if (!efi_enabled) return -ENODEV; + variable_name = kzalloc(variable_name_size, GFP_KERNEL); + if (!variable_name) { + printk(KERN_ERR "efivars: Memory allocation failed.\n"); + return -ENOMEM; + } + printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, EFIVARS_DATE); @@ -680,21 +685,27 @@ efivars_init(void) * For now we'll register the efi subsys within this driver */ - rc = firmware_register(&efi_subsys); + error = firmware_register(&efi_subsys); - if (rc) - return rc; + if (error) { + printk(KERN_ERR "efivars: Firmware registration failed with error %d.\n", error); + goto out_free; + } kset_set_kset_s(&vars_subsys, efi_subsys); - subsystem_register(&vars_subsys); + + error = subsystem_register(&vars_subsys); + + if (error) { + printk(KERN_ERR "efivars: Subsystem registration failed with error %d.\n", error); + goto out_firmware_unregister; + } /* * Per EFI spec, the maximum storage allocated for both * the variable name and variable data is 1024 bytes. */ - memset(variable_name, 0, 1024); - do { variable_name_size = 1024; @@ -734,8 +745,20 @@ efivars_init(void) error = subsys_create_file(&efi_subsys, attr); } + if (error) + printk(KERN_ERR "efivars: Sysfs attribute export failed with error %d.\n", error); + else + goto out_free; + + subsystem_unregister(&vars_subsys); + +out_firmware_unregister: + firmware_unregister(&efi_subsys); + +out_free: kfree(variable_name); - return 0; + + return error; } static void __exit