diff options
| -rw-r--r-- | drivers/firmware/efivars.c | 62 |
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 | ||
| 656 | static 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 | |||
| 656 | static ssize_t efivarfs_file_write(struct file *file, | 686 | static 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, |
