diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2014-02-19 10:35:47 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-28 18:15:56 -0500 |
commit | 6aae48ff18f2fcfb533d2b448ecae16d1de006c1 (patch) | |
tree | 1e886fe2f579ed8dea6f594219e591f7c6820d89 /drivers/misc/mei/client.c | |
parent | 4a22176aa89b8121a5160064d77244e26fe38790 (diff) |
mei: add mei_hbuf_acquire wrapper
A client has to acquire host buffer
before writing, we add lock like wrapper
to replace the code snippet
if (dev->hbuf_is_ready)
dev->hbuf_is_ready = false;
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 | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 2df0efab00a2..083179b75297 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -371,6 +371,23 @@ void mei_host_client_init(struct work_struct *work) | |||
371 | mutex_unlock(&dev->device_lock); | 371 | mutex_unlock(&dev->device_lock); |
372 | } | 372 | } |
373 | 373 | ||
374 | /** | ||
375 | * mei_hbuf_acquire: try to acquire host buffer | ||
376 | * | ||
377 | * @dev: the device structure | ||
378 | * returns true if host buffer was acquired | ||
379 | */ | ||
380 | bool mei_hbuf_acquire(struct mei_device *dev) | ||
381 | { | ||
382 | if (!dev->hbuf_is_ready) { | ||
383 | dev_dbg(&dev->pdev->dev, "hbuf is not ready\n"); | ||
384 | return false; | ||
385 | } | ||
386 | |||
387 | dev->hbuf_is_ready = false; | ||
388 | |||
389 | return true; | ||
390 | } | ||
374 | 391 | ||
375 | /** | 392 | /** |
376 | * mei_cl_disconnect - disconnect host client from the me one | 393 | * mei_cl_disconnect - disconnect host client from the me one |
@@ -402,8 +419,7 @@ int mei_cl_disconnect(struct mei_cl *cl) | |||
402 | return -ENOMEM; | 419 | return -ENOMEM; |
403 | 420 | ||
404 | cb->fop_type = MEI_FOP_CLOSE; | 421 | cb->fop_type = MEI_FOP_CLOSE; |
405 | if (dev->hbuf_is_ready) { | 422 | if (mei_hbuf_acquire(dev)) { |
406 | dev->hbuf_is_ready = false; | ||
407 | if (mei_hbm_cl_disconnect_req(dev, cl)) { | 423 | if (mei_hbm_cl_disconnect_req(dev, cl)) { |
408 | rets = -ENODEV; | 424 | rets = -ENODEV; |
409 | cl_err(dev, cl, "failed to disconnect.\n"); | 425 | cl_err(dev, cl, "failed to disconnect.\n"); |
@@ -503,9 +519,8 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) | |||
503 | 519 | ||
504 | cb->fop_type = MEI_FOP_CONNECT; | 520 | cb->fop_type = MEI_FOP_CONNECT; |
505 | 521 | ||
506 | if (dev->hbuf_is_ready && !mei_cl_is_other_connecting(cl)) { | 522 | /* run hbuf acquire last so we don't have to undo */ |
507 | dev->hbuf_is_ready = false; | 523 | if (!mei_cl_is_other_connecting(cl) && mei_hbuf_acquire(dev)) { |
508 | |||
509 | if (mei_hbm_cl_connect_req(dev, cl)) { | 524 | if (mei_hbm_cl_connect_req(dev, cl)) { |
510 | rets = -ENODEV; | 525 | rets = -ENODEV; |
511 | goto out; | 526 | goto out; |
@@ -663,8 +678,7 @@ int mei_cl_read_start(struct mei_cl *cl, size_t length) | |||
663 | goto err; | 678 | goto err; |
664 | 679 | ||
665 | cb->fop_type = MEI_FOP_READ; | 680 | cb->fop_type = MEI_FOP_READ; |
666 | if (dev->hbuf_is_ready) { | 681 | if (mei_hbuf_acquire(dev)) { |
667 | dev->hbuf_is_ready = false; | ||
668 | if (mei_hbm_cl_flow_control_req(dev, cl)) { | 682 | if (mei_hbm_cl_flow_control_req(dev, cl)) { |
669 | cl_err(dev, cl, "flow control send failed\n"); | 683 | cl_err(dev, cl, "flow control send failed\n"); |
670 | rets = -ENODEV; | 684 | rets = -ENODEV; |
@@ -799,21 +813,29 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) | |||
799 | 813 | ||
800 | 814 | ||
801 | cb->fop_type = MEI_FOP_WRITE; | 815 | cb->fop_type = MEI_FOP_WRITE; |
816 | cb->buf_idx = 0; | ||
817 | cl->writing_state = MEI_IDLE; | ||
818 | |||
819 | mei_hdr.host_addr = cl->host_client_id; | ||
820 | mei_hdr.me_addr = cl->me_client_id; | ||
821 | mei_hdr.reserved = 0; | ||
822 | mei_hdr.msg_complete = 0; | ||
823 | mei_hdr.internal = cb->internal; | ||
802 | 824 | ||
803 | rets = mei_cl_flow_ctrl_creds(cl); | 825 | rets = mei_cl_flow_ctrl_creds(cl); |
804 | if (rets < 0) | 826 | if (rets < 0) |
805 | goto err; | 827 | goto err; |
806 | 828 | ||
807 | /* Host buffer is not ready, we queue the request */ | 829 | if (rets == 0) { |
808 | if (rets == 0 || !dev->hbuf_is_ready) { | 830 | cl_dbg(dev, cl, "No flow control credentials: not sending.\n"); |
809 | cb->buf_idx = 0; | 831 | rets = buf->size; |
810 | /* unseting complete will enqueue the cb for write */ | 832 | goto out; |
811 | mei_hdr.msg_complete = 0; | 833 | } |
834 | if (!mei_hbuf_acquire(dev)) { | ||
835 | cl_dbg(dev, cl, "Cannot acquire the host buffer: not sending.\n"); | ||
812 | rets = buf->size; | 836 | rets = buf->size; |
813 | goto out; | 837 | goto out; |
814 | } | 838 | } |
815 | |||
816 | dev->hbuf_is_ready = false; | ||
817 | 839 | ||
818 | /* Check for a maximum length */ | 840 | /* Check for a maximum length */ |
819 | if (buf->size > mei_hbuf_max_len(dev)) { | 841 | if (buf->size > mei_hbuf_max_len(dev)) { |
@@ -824,12 +846,6 @@ int mei_cl_write(struct mei_cl *cl, struct mei_cl_cb *cb, bool blocking) | |||
824 | mei_hdr.msg_complete = 1; | 846 | mei_hdr.msg_complete = 1; |
825 | } | 847 | } |
826 | 848 | ||
827 | mei_hdr.host_addr = cl->host_client_id; | ||
828 | mei_hdr.me_addr = cl->me_client_id; | ||
829 | mei_hdr.reserved = 0; | ||
830 | mei_hdr.internal = cb->internal; | ||
831 | |||
832 | |||
833 | rets = mei_write_message(dev, &mei_hdr, buf->data); | 849 | rets = mei_write_message(dev, &mei_hdr, buf->data); |
834 | if (rets) | 850 | if (rets) |
835 | goto err; | 851 | goto err; |