diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2013-04-08 14:56:37 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-04-08 19:55:57 -0400 |
commit | 4234a6deb5ab04e50cfd6d72761345727bd2de21 (patch) | |
tree | 6da543ec16e78959e5a05055d4b6cee393d2ad47 /drivers/misc/mei/client.c | |
parent | 606f34ad124faeeb77830d7fdfc513084566d2ba (diff) |
mei: add mei_cl_write function
consolidate write code to a specific me client in mei_cl_write function
the function is called from mei device write handler and from
mei_cl bus send function
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei/client.c')
-rw-r--r-- | drivers/misc/mei/client.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index e14397b09187..ecadd0053ba9 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -678,6 +678,111 @@ err: | |||
678 | } | 678 | } |
679 | 679 | ||
680 | /** | 680 | /** |
681 | * mei_cl_write - submit a write cb to mei device | ||
682 | assumes device_lock is locked | ||
683 | * | ||
684 | * @cl: host client | ||
685 | * @cl: write callback with filled data | ||
686 | * | ||
687 | * returns numbe of bytes sent on success, <0 on failure. | ||
688 | */ | ||
689 | int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) | ||
690 | { | ||
691 | struct mei_device *dev; | ||
692 | struct mei_msg_data *buf; | ||
693 | struct mei_msg_hdr mei_hdr; | ||
694 | int rets; | ||
695 | |||
696 | |||
697 | if (WARN_ON(!cl || !cl->dev)) | ||
698 | return -ENODEV; | ||
699 | |||
700 | if (WARN_ON(!cb)) | ||
701 | return -EINVAL; | ||
702 | |||
703 | dev = cl->dev; | ||
704 | |||
705 | |||
706 | buf = &cb->request_buffer; | ||
707 | |||
708 | dev_dbg(&dev->pdev->dev, "mei_cl_write %d\n", buf->size); | ||
709 | |||
710 | |||
711 | cb->fop_type = MEI_FOP_WRITE; | ||
712 | |||
713 | rets = mei_cl_flow_ctrl_creds(cl); | ||
714 | if (rets < 0) | ||
715 | goto err; | ||
716 | |||
717 | /* Host buffer is not ready, we queue the request */ | ||
718 | if (rets == 0 || !dev->hbuf_is_ready) { | ||
719 | cb->buf_idx = 0; | ||
720 | /* unseting complete will enqueue the cb for write */ | ||
721 | mei_hdr.msg_complete = 0; | ||
722 | cl->writing_state = MEI_WRITING; | ||
723 | rets = buf->size; | ||
724 | goto out; | ||
725 | } | ||
726 | |||
727 | dev->hbuf_is_ready = false; | ||
728 | |||
729 | /* Check for a maximum length */ | ||
730 | if (buf->size > mei_hbuf_max_len(dev)) { | ||
731 | mei_hdr.length = mei_hbuf_max_len(dev); | ||
732 | mei_hdr.msg_complete = 0; | ||
733 | } else { | ||
734 | mei_hdr.length = buf->size; | ||
735 | mei_hdr.msg_complete = 1; | ||
736 | } | ||
737 | |||
738 | mei_hdr.host_addr = cl->host_client_id; | ||
739 | mei_hdr.me_addr = cl->me_client_id; | ||
740 | mei_hdr.reserved = 0; | ||
741 | |||
742 | dev_dbg(&dev->pdev->dev, "write " MEI_HDR_FMT "\n", | ||
743 | MEI_HDR_PRM(&mei_hdr)); | ||
744 | |||
745 | |||
746 | if (mei_write_message(dev, &mei_hdr, buf->data)) { | ||
747 | rets = -EIO; | ||
748 | goto err; | ||
749 | } | ||
750 | |||
751 | cl->writing_state = MEI_WRITING; | ||
752 | cb->buf_idx = mei_hdr.length; | ||
753 | |||
754 | rets = buf->size; | ||
755 | out: | ||
756 | if (mei_hdr.msg_complete) { | ||
757 | if (mei_cl_flow_ctrl_reduce(cl)) { | ||
758 | rets = -ENODEV; | ||
759 | goto err; | ||
760 | } | ||
761 | list_add_tail(&cb->list, &dev->write_waiting_list.list); | ||
762 | } else { | ||
763 | list_add_tail(&cb->list, &dev->write_list.list); | ||
764 | } | ||
765 | |||
766 | |||
767 | if (blocking && cl->writing_state != MEI_WRITE_COMPLETE) { | ||
768 | |||
769 | mutex_unlock(&dev->device_lock); | ||
770 | if (wait_event_interruptible(cl->tx_wait, | ||
771 | cl->writing_state == MEI_WRITE_COMPLETE)) { | ||
772 | if (signal_pending(current)) | ||
773 | rets = -EINTR; | ||
774 | else | ||
775 | rets = -ERESTARTSYS; | ||
776 | } | ||
777 | mutex_lock(&dev->device_lock); | ||
778 | } | ||
779 | err: | ||
780 | return rets; | ||
781 | } | ||
782 | |||
783 | |||
784 | |||
785 | /** | ||
681 | * mei_cl_all_disconnect - disconnect forcefully all connected clients | 786 | * mei_cl_all_disconnect - disconnect forcefully all connected clients |
682 | * | 787 | * |
683 | * @dev - mei device | 788 | * @dev - mei device |