diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2014-02-17 08:13:21 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-18 13:05:07 -0500 |
commit | 64092858acfd995fae0def466126692423c30828 (patch) | |
tree | 6ec7408d1a8705e170d7aa668901f46b1eb4701b /drivers/misc/mei | |
parent | 285e2996655b7bbfb5eb83076a7d7e6f03e2f5c2 (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.c | 13 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 89 | ||||
-rw-r--r-- | drivers/misc/mei/interrupt.c | 5 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 2 | ||||
-rw-r--r-- | drivers/misc/mei/wd.c | 37 |
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 | */ | ||
144 | static 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 | */ |
546 | void mei_watchdog_register(struct mei_device *dev); | 546 | int 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 | ||
366 | void mei_watchdog_register(struct mei_device *dev) | 371 | int 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 | ||
379 | void mei_watchdog_unregister(struct mei_device *dev) | 392 | void mei_watchdog_unregister(struct mei_device *dev) |