aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mei
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-02-17 08:13:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-18 13:05:07 -0500
commit64092858acfd995fae0def466126692423c30828 (patch)
tree6ec7408d1a8705e170d7aa668901f46b1eb4701b /drivers/misc/mei
parent285e2996655b7bbfb5eb83076a7d7e6f03e2f5c2 (diff)
mei: wd and amthif use mei_cl_ api for dis/connection
Connect wd and amthif through regular mei_cl_connect API as there is no reason to connect in asynchronous mode. Also use mei_cl_is_connected in order to protect flows instead of depending on wd_pending and amthif_timer Now we can remove all the special handling in hbm layer Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mei')
-rw-r--r--drivers/misc/mei/amthif.c13
-rw-r--r--drivers/misc/mei/hbm.c89
-rw-r--r--drivers/misc/mei/interrupt.c5
-rw-r--r--drivers/misc/mei/mei_dev.h2
-rw-r--r--drivers/misc/mei/wd.c37
5 files changed, 66 insertions, 80 deletions
diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
index f88cb26364f5..c0fc23f16496 100644
--- a/drivers/misc/mei/amthif.c
+++ b/drivers/misc/mei/amthif.c
@@ -115,14 +115,11 @@ int mei_amthif_host_init(struct mei_device *dev)
115 115
116 cl->state = MEI_FILE_CONNECTING; 116 cl->state = MEI_FILE_CONNECTING;
117 117
118 if (mei_hbm_cl_connect_req(dev, cl)) { 118 ret = mei_cl_connect(cl, NULL);
119 dev_dbg(&dev->pdev->dev, "amthif: Failed to connect to ME client\n"); 119
120 cl->state = MEI_FILE_DISCONNECTED; 120 dev->iamthif_state = MEI_IAMTHIF_IDLE;
121 cl->host_client_id = 0; 121
122 } else { 122 return ret;
123 cl->timer_count = MEI_CONNECT_TIMEOUT;
124 }
125 return 0;
126} 123}
127 124
128/** 125/**
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
index d360e9a5a1a5..46743e2349b1 100644
--- a/drivers/misc/mei/hbm.c
+++ b/drivers/misc/mei/hbm.c
@@ -134,30 +134,6 @@ bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
134 134
135 135
136/** 136/**
137 * is_treat_specially_client - checks if the message belongs
138 * to the file private data.
139 *
140 * @cl: private data of the file object
141 * @rs: connect response bus message
142 *
143 */
144static bool is_treat_specially_client(struct mei_cl *cl,
145 struct hbm_client_connect_response *rs)
146{
147 if (mei_hbm_cl_addr_equal(cl, rs)) {
148 if (rs->status == MEI_CL_CONN_SUCCESS)
149 cl->state = MEI_FILE_CONNECTED;
150 else
151 cl->state = MEI_FILE_DISCONNECTED;
152 cl->status = mei_cl_conn_status_to_errno(rs->status);
153 cl->timer_count = 0;
154
155 return true;
156 }
157 return false;
158}
159
160/**
161 * mei_hbm_idle - set hbm to idle state 137 * mei_hbm_idle - set hbm to idle state
162 * 138 *
163 * @dev: the device structure 139 * @dev: the device structure
@@ -467,22 +443,22 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
467 struct hbm_client_connect_response *rs) 443 struct hbm_client_connect_response *rs)
468{ 444{
469 struct mei_cl *cl; 445 struct mei_cl *cl;
470 struct mei_cl_cb *pos = NULL, *next = NULL; 446 struct mei_cl_cb *cb, *next;
471 447
472 dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", 448 dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n",
473 rs->me_addr, rs->host_addr, rs->status); 449 rs->me_addr, rs->host_addr, rs->status);
474 450
475 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) { 451 list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) {
476 cl = pos->cl; 452 cl = cb->cl;
477 453
478 if (!cl) { 454 /* this should not happen */
479 list_del(&pos->list); 455 if (WARN_ON(!cl)) {
456 list_del(&cb->list);
480 return; 457 return;
481 } 458 }
482 459
483 dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
484 if (mei_hbm_cl_addr_equal(cl, rs)) { 460 if (mei_hbm_cl_addr_equal(cl, rs)) {
485 list_del(&pos->list); 461 list_del(&cb->list);
486 if (rs->status == MEI_CL_DISCONN_SUCCESS) 462 if (rs->status == MEI_CL_DISCONN_SUCCESS)
487 cl->state = MEI_FILE_DISCONNECTED; 463 cl->state = MEI_FILE_DISCONNECTED;
488 464
@@ -523,40 +499,41 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
523{ 499{
524 500
525 struct mei_cl *cl; 501 struct mei_cl *cl;
526 struct mei_cl_cb *pos = NULL, *next = NULL; 502 struct mei_cl_cb *cb, *next;
527 503
528 dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", 504 dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
529 rs->me_addr, rs->host_addr, 505 rs->me_addr, rs->host_addr,
530 mei_cl_conn_status_str(rs->status)); 506 mei_cl_conn_status_str(rs->status));
531 507
532 /* if WD or iamthif client treat specially */ 508 cl = NULL;
533 509
534 if (is_treat_specially_client(&dev->wd_cl, rs)) { 510 list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) {
535 dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
536 mei_watchdog_register(dev);
537 511
538 return; 512 cl = cb->cl;
539 } 513 /* this should not happen */
514 if (WARN_ON(!cl)) {
515 list_del_init(&cb->list);
516 continue;
517 }
540 518
541 if (is_treat_specially_client(&dev->iamthif_cl, rs)) { 519 if (cb->fop_type != MEI_FOP_CONNECT)
542 dev->iamthif_state = MEI_IAMTHIF_IDLE; 520 continue;
543 return;
544 }
545 list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
546 521
547 cl = pos->cl; 522 if (mei_hbm_cl_addr_equal(cl, rs)) {
548 if (!cl) { 523 list_del(&cb->list);
549 list_del(&pos->list); 524 break;
550 return;
551 }
552 if (pos->fop_type == MEI_FOP_CONNECT) {
553 if (is_treat_specially_client(cl, rs)) {
554 list_del(&pos->list);
555 cl->timer_count = 0;
556 break;
557 }
558 } 525 }
559 } 526 }
527
528 if (!cl)
529 return;
530
531 cl->timer_count = 0;
532 if (rs->status == MEI_CL_CONN_SUCCESS)
533 cl->state = MEI_FILE_CONNECTED;
534 else
535 cl->state = MEI_FILE_DISCONNECTED;
536 cl->status = mei_cl_conn_status_to_errno(rs->status);
560} 537}
561 538
562 539
@@ -582,10 +559,6 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev,
582 disconnect_req->me_addr); 559 disconnect_req->me_addr);
583 cl->state = MEI_FILE_DISCONNECTED; 560 cl->state = MEI_FILE_DISCONNECTED;
584 cl->timer_count = 0; 561 cl->timer_count = 0;
585 if (cl == &dev->wd_cl)
586 dev->wd_pending = false;
587 else if (cl == &dev->iamthif_cl)
588 dev->iamthif_timer = 0;
589 562
590 cb = mei_io_cb_init(cl, NULL); 563 cb = mei_io_cb_init(cl, NULL);
591 if (!cb) 564 if (!cb)
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 75ff4092953e..61ceb781cd20 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -487,7 +487,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
487 wake_up_interruptible(&dev->wait_stop_wd); 487 wake_up_interruptible(&dev->wait_stop_wd);
488 } 488 }
489 489
490 if (dev->dev_state == MEI_DEV_ENABLED) { 490 if (mei_cl_is_connected(&dev->wd_cl)) {
491 if (dev->wd_pending && 491 if (dev->wd_pending &&
492 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) { 492 mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
493 if (mei_wd_send(dev)) 493 if (mei_wd_send(dev))
@@ -613,6 +613,9 @@ void mei_timer(struct work_struct *work)
613 } 613 }
614 } 614 }
615 615
616 if (!mei_cl_is_connected(&dev->iamthif_cl))
617 goto out;
618
616 if (dev->iamthif_stall_timer) { 619 if (dev->iamthif_stall_timer) {
617 if (--dev->iamthif_stall_timer == 0) { 620 if (--dev->iamthif_stall_timer == 0) {
618 dev_err(&dev->pdev->dev, "timer: amthif hanged.\n"); 621 dev_err(&dev->pdev->dev, "timer: amthif hanged.\n");
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
index 49025fa202ae..030b29e1c92e 100644
--- a/drivers/misc/mei/mei_dev.h
+++ b/drivers/misc/mei/mei_dev.h
@@ -543,7 +543,7 @@ int mei_wd_host_init(struct mei_device *dev);
543 * once we got connection to the WD Client 543 * once we got connection to the WD Client
544 * @dev - mei device 544 * @dev - mei device
545 */ 545 */
546void mei_watchdog_register(struct mei_device *dev); 546int mei_watchdog_register(struct mei_device *dev);
547/* 547/*
548 * mei_watchdog_unregister - Unregistering watchdog interface 548 * mei_watchdog_unregister - Unregistering watchdog interface
549 * @dev - mei device 549 * @dev - mei device
diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
index f70945ed96f6..8c302829a194 100644
--- a/drivers/misc/mei/wd.c
+++ b/drivers/misc/mei/wd.c
@@ -87,15 +87,20 @@ int mei_wd_host_init(struct mei_device *dev)
87 87
88 cl->state = MEI_FILE_CONNECTING; 88 cl->state = MEI_FILE_CONNECTING;
89 89
90 if (mei_hbm_cl_connect_req(dev, cl)) { 90 ret = mei_cl_connect(cl, NULL);
91 dev_err(&dev->pdev->dev, "wd: failed to connect to the client\n"); 91
92 cl->state = MEI_FILE_DISCONNECTED; 92 if (ret) {
93 cl->host_client_id = 0; 93 dev_err(&dev->pdev->dev, "wd: failed to connect = %d\n", ret);
94 return -EIO; 94 mei_cl_unlink(cl);
95 return ret;
95 } 96 }
96 cl->timer_count = MEI_CONNECT_TIMEOUT;
97 97
98 return 0; 98 ret = mei_watchdog_register(dev);
99 if (ret) {
100 mei_cl_disconnect(cl);
101 mei_cl_unlink(cl);
102 }
103 return ret;
99} 104}
100 105
101/** 106/**
@@ -363,17 +368,25 @@ static struct watchdog_device amt_wd_dev = {
363}; 368};
364 369
365 370
366void mei_watchdog_register(struct mei_device *dev) 371int mei_watchdog_register(struct mei_device *dev)
367{ 372{
368 if (watchdog_register_device(&amt_wd_dev)) { 373
369 dev_err(&dev->pdev->dev, 374 int ret;
370 "wd: unable to register watchdog device.\n"); 375
371 return; 376 /* unlock to perserve correct locking order */
377 mutex_unlock(&dev->device_lock);
378 ret = watchdog_register_device(&amt_wd_dev);
379 mutex_lock(&dev->device_lock);
380 if (ret) {
381 dev_err(&dev->pdev->dev, "wd: unable to register watchdog device = %d.\n",
382 ret);
383 return ret;
372 } 384 }
373 385
374 dev_dbg(&dev->pdev->dev, 386 dev_dbg(&dev->pdev->dev,
375 "wd: successfully register watchdog interface.\n"); 387 "wd: successfully register watchdog interface.\n");
376 watchdog_set_drvdata(&amt_wd_dev, dev); 388 watchdog_set_drvdata(&amt_wd_dev, dev);
389 return 0;
377} 390}
378 391
379void mei_watchdog_unregister(struct mei_device *dev) 392void mei_watchdog_unregister(struct mei_device *dev)