diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2012-10-09 10:50:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-10-24 18:35:03 -0400 |
commit | 75f0ee1559c5d51948e029041a9b722b3e3f0b83 (patch) | |
tree | 25c504ed1cca8a64d1c1b07774a617a0e3adcd4c /drivers/misc | |
parent | 33d28c9205257479be540a31b03339817cf2d62c (diff) |
mei: mei_write: revamp error path handling
1. unify common amt and regular error path and use it early in the
function
2. fix indentation
3. propagate error code directly from copy_from_user
4. print out errors using dev_err instead of dev_dbg
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/mei/main.c | 75 |
1 files changed, 27 insertions, 48 deletions
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 15de4b19caa5..8dcf59d43b0d 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -621,10 +621,26 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
621 | mutex_lock(&dev->device_lock); | 621 | mutex_lock(&dev->device_lock); |
622 | 622 | ||
623 | if (dev->dev_state != MEI_DEV_ENABLED) { | 623 | if (dev->dev_state != MEI_DEV_ENABLED) { |
624 | mutex_unlock(&dev->device_lock); | 624 | rets = -ENODEV; |
625 | return -ENODEV; | 625 | goto unlock_dev; |
626 | } | 626 | } |
627 | 627 | ||
628 | i = mei_me_cl_by_id(dev, cl->me_client_id); | ||
629 | if (i < 0) { | ||
630 | rets = -ENODEV; | ||
631 | goto unlock_dev; | ||
632 | } | ||
633 | if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { | ||
634 | rets = -EMSGSIZE; | ||
635 | goto unlock_dev; | ||
636 | } | ||
637 | |||
638 | if (cl->state != MEI_FILE_CONNECTED) { | ||
639 | rets = -ENODEV; | ||
640 | dev_err(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", | ||
641 | cl->host_client_id, cl->me_client_id); | ||
642 | goto unlock_dev; | ||
643 | } | ||
628 | if (cl == &dev->iamthif_cl) { | 644 | if (cl == &dev->iamthif_cl) { |
629 | write_cb = find_amthi_read_list_entry(dev, file); | 645 | write_cb = find_amthi_read_list_entry(dev, file); |
630 | 646 | ||
@@ -633,11 +649,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
633 | msecs_to_jiffies(IAMTHIF_READ_TIMER); | 649 | msecs_to_jiffies(IAMTHIF_READ_TIMER); |
634 | 650 | ||
635 | if (time_after(jiffies, timeout) || | 651 | if (time_after(jiffies, timeout) || |
636 | cl->reading_state == MEI_READ_COMPLETE) { | 652 | cl->reading_state == MEI_READ_COMPLETE) { |
637 | *offset = 0; | 653 | *offset = 0; |
638 | list_del(&write_cb->cb_list); | 654 | list_del(&write_cb->cb_list); |
639 | mei_free_cb_private(write_cb); | 655 | mei_free_cb_private(write_cb); |
640 | write_cb = NULL; | 656 | write_cb = NULL; |
641 | } | 657 | } |
642 | } | 658 | } |
643 | } | 659 | } |
@@ -670,8 +686,8 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
670 | 686 | ||
671 | dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); | 687 | dev_dbg(&dev->pdev->dev, "cb request size = %zd\n", length); |
672 | 688 | ||
673 | rets = -EFAULT; | 689 | rets = copy_from_user(write_cb->request_buffer.data, ubuf, length); |
674 | if (copy_from_user(write_cb->request_buffer.data, ubuf, length)) | 690 | if (rets) |
675 | goto unlock_dev; | 691 | goto unlock_dev; |
676 | 692 | ||
677 | cl->sm_state = 0; | 693 | cl->sm_state = 0; |
@@ -685,29 +701,11 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
685 | cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; | 701 | cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT; |
686 | 702 | ||
687 | if (cl == &dev->iamthif_cl) { | 703 | if (cl == &dev->iamthif_cl) { |
688 | if (dev->dev_state != MEI_DEV_ENABLED) { | ||
689 | rets = -ENODEV; | ||
690 | goto unlock_dev; | ||
691 | } | ||
692 | i = mei_me_cl_by_id(dev, dev->iamthif_cl.me_client_id); | ||
693 | if (i < 0) { | ||
694 | rets = -ENODEV; | ||
695 | goto unlock_dev; | ||
696 | } | ||
697 | if (length > dev->me_clients[i].props.max_msg_length || | ||
698 | length <= 0) { | ||
699 | rets = -EMSGSIZE; | ||
700 | goto unlock_dev; | ||
701 | } | ||
702 | rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); | 704 | rets = mei_io_cb_alloc_resp_buf(write_cb, dev->iamthif_mtu); |
703 | if (rets) | 705 | if (rets) |
704 | goto unlock_dev; | 706 | goto unlock_dev; |
705 | 707 | ||
706 | write_cb->major_file_operations = MEI_IOCTL; | 708 | write_cb->major_file_operations = MEI_IOCTL; |
707 | if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) { | ||
708 | rets = -ENODEV; | ||
709 | goto unlock_dev; | ||
710 | } | ||
711 | 709 | ||
712 | if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || | 710 | if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) || |
713 | dev->iamthif_state != MEI_IAMTHIF_IDLE) { | 711 | dev->iamthif_state != MEI_IAMTHIF_IDLE) { |
@@ -716,43 +714,24 @@ static ssize_t mei_write(struct file *file, const char __user *ubuf, | |||
716 | dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); | 714 | dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n"); |
717 | list_add_tail(&write_cb->cb_list, | 715 | list_add_tail(&write_cb->cb_list, |
718 | &dev->amthi_cmd_list.mei_cb.cb_list); | 716 | &dev->amthi_cmd_list.mei_cb.cb_list); |
719 | rets = length; | ||
720 | } else { | 717 | } else { |
721 | dev_dbg(&dev->pdev->dev, "call amthi write\n"); | 718 | dev_dbg(&dev->pdev->dev, "call amthi write\n"); |
722 | rets = amthi_write(dev, write_cb); | 719 | rets = amthi_write(dev, write_cb); |
723 | 720 | ||
724 | if (rets) { | 721 | if (rets) { |
725 | dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n", | 722 | dev_err(&dev->pdev->dev, "amthi write failed with status = %d\n", |
726 | rets); | 723 | rets); |
727 | goto unlock_dev; | 724 | goto unlock_dev; |
728 | } | 725 | } |
729 | rets = length; | ||
730 | } | 726 | } |
731 | mutex_unlock(&dev->device_lock); | 727 | mutex_unlock(&dev->device_lock); |
732 | return rets; | 728 | return length; |
733 | } | 729 | } |
734 | 730 | ||
735 | write_cb->major_file_operations = MEI_WRITE; | 731 | write_cb->major_file_operations = MEI_WRITE; |
736 | 732 | ||
737 | dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", | 733 | dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n", |
738 | cl->host_client_id, cl->me_client_id); | 734 | cl->host_client_id, cl->me_client_id); |
739 | if (cl->state != MEI_FILE_CONNECTED) { | ||
740 | rets = -ENODEV; | ||
741 | dev_dbg(&dev->pdev->dev, "host client = %d, is not connected to ME client = %d", | ||
742 | cl->host_client_id, | ||
743 | cl->me_client_id); | ||
744 | goto unlock_dev; | ||
745 | } | ||
746 | i = mei_me_cl_by_id(dev, cl->me_client_id); | ||
747 | if (i < 0) { | ||
748 | rets = -ENODEV; | ||
749 | goto unlock_dev; | ||
750 | } | ||
751 | if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { | ||
752 | rets = -EINVAL; | ||
753 | goto unlock_dev; | ||
754 | } | ||
755 | |||
756 | rets = mei_flow_ctrl_creds(dev, cl); | 735 | rets = mei_flow_ctrl_creds(dev, cl); |
757 | if (rets < 0) | 736 | if (rets < 0) |
758 | goto unlock_dev; | 737 | goto unlock_dev; |