aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efivars.c
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-10-16 10:58:07 -0400
committerMatt Fleming <matt.fleming@intel.com>2012-10-30 06:39:25 -0400
commit7253eaba7b179db2e07e67c5b78d5f10b332291d (patch)
treee233e80b8601446d75fe85d0f5acf9736502848e /drivers/firmware/efivars.c
parent310ad75448329f167af3c4a10e4a9de4d80058ff (diff)
efivarfs: Return an error if we fail to read a variable
Instead of always returning 0 in efivarfs_file_read(), even when we fail to successfully read the variable, convert the EFI status to something meaningful and return that to the caller. This way the user will have some hint as to why the read failed. Acked-by: Jeremy Kerr <jeremy.kerr@canonical.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware/efivars.c')
-rw-r--r--drivers/firmware/efivars.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index a93e401c20a7..277e42616f0d 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -653,6 +653,36 @@ static int efivarfs_file_open(struct inode *inode, struct file *file)
653 return 0; 653 return 0;
654} 654}
655 655
656static int efi_status_to_err(efi_status_t status)
657{
658 int err;
659
660 switch (status) {
661 case EFI_INVALID_PARAMETER:
662 err = -EINVAL;
663 break;
664 case EFI_OUT_OF_RESOURCES:
665 err = -ENOSPC;
666 break;
667 case EFI_DEVICE_ERROR:
668 err = -EIO;
669 break;
670 case EFI_WRITE_PROTECTED:
671 err = -EROFS;
672 break;
673 case EFI_SECURITY_VIOLATION:
674 err = -EACCES;
675 break;
676 case EFI_NOT_FOUND:
677 err = -ENOENT;
678 break;
679 default:
680 err = -EINVAL;
681 }
682
683 return err;
684}
685
656static ssize_t efivarfs_file_write(struct file *file, 686static ssize_t efivarfs_file_write(struct file *file,
657 const char __user *userbuf, size_t count, loff_t *ppos) 687 const char __user *userbuf, size_t count, loff_t *ppos)
658{ 688{
@@ -711,29 +741,7 @@ static ssize_t efivarfs_file_write(struct file *file,
711 spin_unlock(&efivars->lock); 741 spin_unlock(&efivars->lock);
712 kfree(data); 742 kfree(data);
713 743
714 switch (status) { 744 return efi_status_to_err(status);
715 case EFI_INVALID_PARAMETER:
716 count = -EINVAL;
717 break;
718 case EFI_OUT_OF_RESOURCES:
719 count = -ENOSPC;
720 break;
721 case EFI_DEVICE_ERROR:
722 count = -EIO;
723 break;
724 case EFI_WRITE_PROTECTED:
725 count = -EROFS;
726 break;
727 case EFI_SECURITY_VIOLATION:
728 count = -EACCES;
729 break;
730 case EFI_NOT_FOUND:
731 count = -ENOENT;
732 break;
733 default:
734 count = -EINVAL;
735 }
736 return count;
737 } 745 }
738 746
739 /* 747 /*
@@ -791,12 +799,12 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
791 spin_unlock(&efivars->lock); 799 spin_unlock(&efivars->lock);
792 800
793 if (status != EFI_BUFFER_TOO_SMALL) 801 if (status != EFI_BUFFER_TOO_SMALL)
794 return 0; 802 return efi_status_to_err(status);
795 803
796 data = kmalloc(datasize + 4, GFP_KERNEL); 804 data = kmalloc(datasize + 4, GFP_KERNEL);
797 805
798 if (!data) 806 if (!data)
799 return 0; 807 return -ENOMEM;
800 808
801 spin_lock(&efivars->lock); 809 spin_lock(&efivars->lock);
802 status = efivars->ops->get_variable(var->var.VariableName, 810 status = efivars->ops->get_variable(var->var.VariableName,
@@ -805,8 +813,10 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf,
805 (data + 4)); 813 (data + 4));
806 spin_unlock(&efivars->lock); 814 spin_unlock(&efivars->lock);
807 815
808 if (status != EFI_SUCCESS) 816 if (status != EFI_SUCCESS) {
817 size = efi_status_to_err(status);
809 goto out_free; 818 goto out_free;
819 }
810 820
811 memcpy(data, &attributes, 4); 821 memcpy(data, &attributes, 4);
812 size = simple_read_from_buffer(userbuf, count, ppos, 822 size = simple_read_from_buffer(userbuf, count, ppos,