aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-02-19 10:35:47 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-28 18:15:56 -0500
commit6aae48ff18f2fcfb533d2b448ecae16d1de006c1 (patch)
tree1e886fe2f579ed8dea6f594219e591f7c6820d89 /drivers/misc/mei
parent4a22176aa89b8121a5160064d77244e26fe38790 (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')
-rw-r--r--drivers/misc/mei/amthif.c7
-rw-r--r--drivers/misc/mei/client.c56
-rw-r--r--drivers/misc/mei/hw-me.c2
-rw-r--r--drivers/misc/mei/hw-txe.c17
-rw-r--r--drivers/misc/mei/interrupt.c6
-rw-r--r--drivers/misc/mei/mei_dev.h2
-rw-r--r--drivers/misc/mei/wd.c14
7 files changed, 57 insertions, 47 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index 61275e6e839c..e7ba8801d2b4 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -296,9 +296,8 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
296 if (ret < 0) 296 if (ret < 0)
297 return ret; 297 return ret;
298 298
299 if (ret && dev->hbuf_is_ready) { 299 if (ret && mei_hbuf_acquire(dev)) {
300 ret = 0; 300 ret = 0;
301 dev->hbuf_is_ready = false;
302 if (cb->request_buffer.size > mei_hbuf_max_len(dev)) { 301 if (cb->request_buffer.size > mei_hbuf_max_len(dev)) {
303 mei_hdr.length = mei_hbuf_max_len(dev); 302 mei_hdr.length = mei_hbuf_max_len(dev);
304 mei_hdr.msg_complete = 0; 303 mei_hdr.msg_complete = 0;
@@ -330,10 +329,6 @@ static int mei_amthif_send_cmd(struct mei_device *dev, struct mei_cl_cb *cb)
330 list_add_tail(&cb->list, &dev->write_list.list); 329 list_add_tail(&cb->list, &dev->write_list.list);
331 } 330 }
332 } else { 331 } else {
333 if (!dev->hbuf_is_ready)
334 dev_dbg(&dev->pdev->dev, "host buffer is not empty");
335
336 dev_dbg(&dev->pdev->dev, "No flow control credentials, so add iamthif cb to write list.\n");
337 list_add_tail(&cb->list, &dev->write_list.list); 332 list_add_tail(&cb->list, &dev->write_list.list);
338 } 333 }
339 return 0; 334 return 0;
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 */
380bool 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;
diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c
index 847c9e5746cb..b0c42d6182a6 100644
--- a/drivers/misc/mei/hw-me.c
+++ b/drivers/misc/mei/hw-me.c
@@ -513,6 +513,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
513 } 513 }
514 } 514 }
515 515
516 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
517
516 rets = mei_irq_write_handler(dev, &complete_list); 518 rets = mei_irq_write_handler(dev, &complete_list);
517 519
518 dev->hbuf_is_ready = mei_hbuf_is_ready(dev); 520 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
index 49a5ed376969..8f5e4be9ebc2 100644
--- a/drivers/misc/mei/hw-txe.c
+++ b/drivers/misc/mei/hw-txe.c
@@ -605,7 +605,6 @@ static int mei_txe_write(struct mei_device *dev,
605 mei_txe_input_payload_write(dev, i + 1, reg); 605 mei_txe_input_payload_write(dev, i + 1, reg);
606 } 606 }
607 607
608 dev->hbuf_is_ready = false;
609 /* Set Input-Doorbell */ 608 /* Set Input-Doorbell */
610 mei_txe_input_doorbell_set(hw); 609 mei_txe_input_doorbell_set(hw);
611 610
@@ -983,20 +982,16 @@ irqreturn_t mei_txe_irq_thread_handler(int irq, void *dev_id)
983 dev->hbuf_is_ready = true; 982 dev->hbuf_is_ready = true;
984 983
985 if (hw->aliveness && dev->hbuf_is_ready) { 984 if (hw->aliveness && dev->hbuf_is_ready) {
986 /* if SeC did not complete reading the written data by host */
987 if (!mei_txe_is_input_ready(dev)) {
988 dev_dbg(&dev->pdev->dev, "got Input Ready Int, but SEC_IPC_INPUT_STATUS_RDY is 0.\n");
989 goto end;
990 }
991 985
986 /* get the real register value */
987 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
992 rets = mei_irq_write_handler(dev, &complete_list); 988 rets = mei_irq_write_handler(dev, &complete_list);
993 if (rets) 989 if (rets && rets != -EMSGSIZE)
994 dev_err(&dev->pdev->dev, 990 dev_err(&dev->pdev->dev, "mei_irq_write_handler ret = %d.\n",
995 "mei_irq_write_handler ret = %d.\n", rets); 991 rets);
992 dev->hbuf_is_ready = mei_hbuf_is_ready(dev);
996 } 993 }
997 994
998
999
1000 mei_irq_compl_handler(dev, &complete_list); 995 mei_irq_compl_handler(dev, &complete_list);
1001 996
1002end: 997end:
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 6c4597e9b997..aed03efa72f4 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -446,10 +446,10 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
446 s32 slots; 446 s32 slots;
447 int ret; 447 int ret;
448 448
449 if (!mei_hbuf_is_ready(dev)) { 449
450 dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n"); 450 if (!mei_hbuf_acquire(dev))
451 return 0; 451 return 0;
452 } 452
453 slots = mei_hbuf_empty_slots(dev); 453 slots = mei_hbuf_empty_slots(dev);
454 if (slots <= 0) 454 if (slots <= 0)
455 return -EMSGSIZE; 455 return -EMSGSIZE;
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 030b29e1c92e..52499bc5a068 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -630,6 +630,8 @@ static inline int mei_count_full_read_slots(struct mei_device *dev)
630 return dev->ops->rdbuf_full_slots(dev); 630 return dev->ops->rdbuf_full_slots(dev);
631} 631}
632 632
633bool mei_hbuf_acquire(struct mei_device *dev);
634
633#if IS_ENABLED(CONFIG_DEBUG_FS) 635#if IS_ENABLED(CONFIG_DEBUG_FS)
634int mei_dbgfs_register(struct mei_device *dev, const char *name); 636int mei_dbgfs_register(struct mei_device *dev, const char *name);
635void mei_dbgfs_deregister(struct mei_device *dev); 637void mei_dbgfs_deregister(struct mei_device *dev);
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index 8c302829a194..afe976a18586 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -158,9 +158,8 @@ int mei_wd_stop(struct mei_device *dev)
158 if (ret < 0) 158 if (ret < 0)
159 goto out; 159 goto out;
160 160
161 if (ret && dev->hbuf_is_ready) { 161 if (ret && mei_hbuf_acquire(dev)) {
162 ret = 0; 162 ret = 0;
163 dev->hbuf_is_ready = false;
164 163
165 if (!mei_wd_send(dev)) { 164 if (!mei_wd_send(dev)) {
166 ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl); 165 ret = mei_cl_flow_ctrl_reduce(&dev->wd_cl);
@@ -265,8 +264,8 @@ static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
265 */ 264 */
266static int mei_wd_ops_ping(struct watchdog_device *wd_dev) 265static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
267{ 266{
268 int ret = 0;
269 struct mei_device *dev; 267 struct mei_device *dev;
268 int ret;
270 269
271 dev = watchdog_get_drvdata(wd_dev); 270 dev = watchdog_get_drvdata(wd_dev);
272 if (!dev) 271 if (!dev)
@@ -282,10 +281,12 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
282 281
283 dev->wd_state = MEI_WD_RUNNING; 282 dev->wd_state = MEI_WD_RUNNING;
284 283
284 ret = mei_cl_flow_ctrl_creds(&dev->wd_cl);
285 if (ret < 0)
286 goto end;
285 /* Check if we can send the ping to HW*/ 287 /* Check if we can send the ping to HW*/
286 if (dev->hbuf_is_ready && mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { 288 if (ret && mei_hbuf_acquire(dev)) {
287 289
288 dev->hbuf_is_ready = false;
289 dev_dbg(&dev->pdev->dev, "wd: sending ping\n"); 290 dev_dbg(&dev->pdev->dev, "wd: sending ping\n");
290 291
291 if (mei_wd_send(dev)) { 292 if (mei_wd_send(dev)) {
@@ -295,8 +296,7 @@ static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
295 } 296 }
296 297
297 if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) { 298 if (mei_cl_flow_ctrl_reduce(&dev->wd_cl)) {
298 dev_err(&dev->pdev->dev, 299 dev_err(&dev->pdev->dev, "wd: mei_cl_flow_ctrl_reduce() failed.\n");
299 "wd: mei_cl_flow_ctrl_reduce() failed.\n");
300 ret = -EIO; 300 ret = -EIO;
301 goto end; 301 goto end;
302 } 302 }