aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei/client.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2013-04-08 14:56:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-04-08 19:55:57 -0400
commit4234a6deb5ab04e50cfd6d72761345727bd2de21 (patch)
tree6da543ec16e78959e5a05055d4b6cee393d2ad47 /drivers/misc/mei/client.c
parent606f34ad124faeeb77830d7fdfc513084566d2ba (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.c105
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 */
689int 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;
755out:
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 }
779err:
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