diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2014-08-21 07:29:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-24 01:57:48 -0400 |
commit | 12f45ed414c8d2eac1a98bf2deaf4117e8c0324f (patch) | |
tree | fead16c23e9916ee9db645c5ad3c2ff9e2a74361 | |
parent | 5a8373fba0ab2cec8d206747ad60ca4a30821a37 (diff) |
mei: revamp connect and disconnect response handling
Both responses have same flow only the client status
update is different. We introduce handler mei_hbm_cl_res()
that handles both responses
Also we use per client wait queue (cl->wait) rather then
global dev->wait_recvd_msg
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/client.c | 4 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 118 |
2 files changed, 65 insertions, 57 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index efac33929e53..449bb4564241 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -534,7 +534,7 @@ int mei_cl_disconnect(struct mei_cl *cl) | |||
534 | } | 534 | } |
535 | mutex_unlock(&dev->device_lock); | 535 | mutex_unlock(&dev->device_lock); |
536 | 536 | ||
537 | wait_event_timeout(dev->wait_recvd_msg, | 537 | wait_event_timeout(cl->wait, |
538 | MEI_FILE_DISCONNECTED == cl->state, | 538 | MEI_FILE_DISCONNECTED == cl->state, |
539 | mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); | 539 | mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); |
540 | 540 | ||
@@ -639,7 +639,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) | |||
639 | } | 639 | } |
640 | 640 | ||
641 | mutex_unlock(&dev->device_lock); | 641 | mutex_unlock(&dev->device_lock); |
642 | wait_event_timeout(dev->wait_recvd_msg, | 642 | wait_event_timeout(cl->wait, |
643 | (cl->state == MEI_FILE_CONNECTED || | 643 | (cl->state == MEI_FILE_CONNECTED || |
644 | cl->state == MEI_FILE_DISCONNECTED), | 644 | cl->state == MEI_FILE_DISCONNECTED), |
645 | mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); | 645 | mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); |
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index d50c8d1fb36d..cda914191a2f 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c | |||
@@ -495,39 +495,24 @@ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) | |||
495 | } | 495 | } |
496 | 496 | ||
497 | /** | 497 | /** |
498 | * mei_hbm_cl_disconnect_res - disconnect response from ME | 498 | * mei_hbm_cl_disconnect_res - update the client state according |
499 | * disconnect response | ||
499 | * | 500 | * |
500 | * @dev: the device structure | 501 | * @cl: mei host client |
501 | * @rs: disconnect response bus message | 502 | * @cmd: disconnect client response host bus message |
502 | */ | 503 | */ |
503 | static void mei_hbm_cl_disconnect_res(struct mei_device *dev, | 504 | static void mei_hbm_cl_disconnect_res(struct mei_cl *cl, |
504 | struct hbm_client_connect_response *rs) | 505 | struct mei_hbm_cl_cmd *cmd) |
505 | { | 506 | { |
506 | struct mei_cl *cl; | 507 | struct hbm_client_connect_response *rs = |
507 | struct mei_cl_cb *cb, *next; | 508 | (struct hbm_client_connect_response *)cmd; |
508 | 509 | ||
509 | dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", | 510 | dev_dbg(&cl->dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n", |
510 | rs->me_addr, rs->host_addr, rs->status); | 511 | rs->me_addr, rs->host_addr, rs->status); |
511 | 512 | ||
512 | list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { | 513 | if (rs->status == MEI_CL_DISCONN_SUCCESS) |
513 | cl = cb->cl; | 514 | cl->state = MEI_FILE_DISCONNECTED; |
514 | 515 | cl->status = 0; | |
515 | /* this should not happen */ | ||
516 | if (WARN_ON(!cl)) { | ||
517 | list_del(&cb->list); | ||
518 | return; | ||
519 | } | ||
520 | |||
521 | if (mei_hbm_cl_addr_equal(cl, rs)) { | ||
522 | list_del(&cb->list); | ||
523 | if (rs->status == MEI_CL_DISCONN_SUCCESS) | ||
524 | cl->state = MEI_FILE_DISCONNECTED; | ||
525 | |||
526 | cl->status = 0; | ||
527 | cl->timer_count = 0; | ||
528 | break; | ||
529 | } | ||
530 | } | ||
531 | } | 516 | } |
532 | 517 | ||
533 | /** | 518 | /** |
@@ -545,24 +530,45 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) | |||
545 | } | 530 | } |
546 | 531 | ||
547 | /** | 532 | /** |
548 | * mei_hbm_cl_connect_res - connect response from the ME | 533 | * mei_hbm_cl_connect_res - update the client state according |
534 | * connection response | ||
549 | * | 535 | * |
550 | * @dev: the device structure | 536 | * @cl: mei host client |
551 | * @rs: connect response bus message | 537 | * @cmd: connect client response host bus message |
552 | */ | 538 | */ |
553 | static void mei_hbm_cl_connect_res(struct mei_device *dev, | 539 | static void mei_hbm_cl_connect_res(struct mei_cl *cl, |
554 | struct hbm_client_connect_response *rs) | 540 | struct mei_hbm_cl_cmd *cmd) |
555 | { | 541 | { |
542 | struct hbm_client_connect_response *rs = | ||
543 | (struct hbm_client_connect_response *)cmd; | ||
556 | 544 | ||
557 | struct mei_cl *cl; | 545 | dev_dbg(&cl->dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", |
558 | struct mei_cl_cb *cb, *next; | ||
559 | |||
560 | dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n", | ||
561 | rs->me_addr, rs->host_addr, | 546 | rs->me_addr, rs->host_addr, |
562 | mei_cl_conn_status_str(rs->status)); | 547 | mei_cl_conn_status_str(rs->status)); |
563 | 548 | ||
564 | cl = NULL; | 549 | if (rs->status == MEI_CL_CONN_SUCCESS) |
550 | cl->state = MEI_FILE_CONNECTED; | ||
551 | else | ||
552 | cl->state = MEI_FILE_DISCONNECTED; | ||
553 | cl->status = mei_cl_conn_status_to_errno(rs->status); | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * mei_hbm_cl_res - process hbm response received on behalf | ||
558 | * an client | ||
559 | * | ||
560 | * @dev: the device structure | ||
561 | * @rs: hbm client message | ||
562 | * @fop_type: file operation type | ||
563 | */ | ||
564 | static void mei_hbm_cl_res(struct mei_device *dev, | ||
565 | struct mei_hbm_cl_cmd *rs, | ||
566 | enum mei_cb_file_ops fop_type) | ||
567 | { | ||
568 | struct mei_cl *cl; | ||
569 | struct mei_cl_cb *cb, *next; | ||
565 | 570 | ||
571 | cl = NULL; | ||
566 | list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { | 572 | list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) { |
567 | 573 | ||
568 | cl = cb->cl; | 574 | cl = cb->cl; |
@@ -572,7 +578,7 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, | |||
572 | continue; | 578 | continue; |
573 | } | 579 | } |
574 | 580 | ||
575 | if (cb->fop_type != MEI_FOP_CONNECT) | 581 | if (cb->fop_type != fop_type) |
576 | continue; | 582 | continue; |
577 | 583 | ||
578 | if (mei_hbm_cl_addr_equal(cl, rs)) { | 584 | if (mei_hbm_cl_addr_equal(cl, rs)) { |
@@ -584,12 +590,19 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, | |||
584 | if (!cl) | 590 | if (!cl) |
585 | return; | 591 | return; |
586 | 592 | ||
593 | switch (fop_type) { | ||
594 | case MEI_FOP_CONNECT: | ||
595 | mei_hbm_cl_connect_res(cl, rs); | ||
596 | break; | ||
597 | case MEI_FOP_DISCONNECT: | ||
598 | mei_hbm_cl_disconnect_res(cl, rs); | ||
599 | break; | ||
600 | default: | ||
601 | return; | ||
602 | } | ||
603 | |||
587 | cl->timer_count = 0; | 604 | cl->timer_count = 0; |
588 | if (rs->status == MEI_CL_CONN_SUCCESS) | 605 | wake_up(&cl->wait); |
589 | cl->state = MEI_FILE_CONNECTED; | ||
590 | else | ||
591 | cl->state = MEI_FILE_DISCONNECTED; | ||
592 | cl->status = mei_cl_conn_status_to_errno(rs->status); | ||
593 | } | 606 | } |
594 | 607 | ||
595 | 608 | ||
@@ -657,17 +670,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) | |||
657 | { | 670 | { |
658 | struct mei_bus_message *mei_msg; | 671 | struct mei_bus_message *mei_msg; |
659 | struct hbm_host_version_response *version_res; | 672 | struct hbm_host_version_response *version_res; |
660 | struct hbm_client_connect_response *connect_res; | ||
661 | struct hbm_client_connect_response *disconnect_res; | ||
662 | struct hbm_client_connect_request *disconnect_req; | ||
663 | struct hbm_flow_control *flow_control; | ||
664 | struct hbm_props_response *props_res; | 673 | struct hbm_props_response *props_res; |
665 | struct hbm_host_enum_response *enum_res; | 674 | struct hbm_host_enum_response *enum_res; |
666 | 675 | ||
676 | struct mei_hbm_cl_cmd *cl_cmd; | ||
677 | struct hbm_client_connect_request *disconnect_req; | ||
678 | struct hbm_flow_control *flow_control; | ||
679 | |||
667 | /* read the message to our buffer */ | 680 | /* read the message to our buffer */ |
668 | BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf)); | 681 | BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf)); |
669 | mei_read_slots(dev, dev->rd_msg_buf, hdr->length); | 682 | mei_read_slots(dev, dev->rd_msg_buf, hdr->length); |
670 | mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; | 683 | mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; |
684 | cl_cmd = (struct mei_hbm_cl_cmd *)mei_msg; | ||
671 | 685 | ||
672 | /* ignore spurious message and prevent reset nesting | 686 | /* ignore spurious message and prevent reset nesting |
673 | * hbm is put to idle during system reset | 687 | * hbm is put to idle during system reset |
@@ -730,18 +744,12 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) | |||
730 | 744 | ||
731 | case CLIENT_CONNECT_RES_CMD: | 745 | case CLIENT_CONNECT_RES_CMD: |
732 | dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n"); | 746 | dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n"); |
733 | 747 | mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT); | |
734 | connect_res = (struct hbm_client_connect_response *) mei_msg; | ||
735 | mei_hbm_cl_connect_res(dev, connect_res); | ||
736 | wake_up(&dev->wait_recvd_msg); | ||
737 | break; | 748 | break; |
738 | 749 | ||
739 | case CLIENT_DISCONNECT_RES_CMD: | 750 | case CLIENT_DISCONNECT_RES_CMD: |
740 | dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n"); | 751 | dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n"); |
741 | 752 | mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT); | |
742 | disconnect_res = (struct hbm_client_connect_response *) mei_msg; | ||
743 | mei_hbm_cl_disconnect_res(dev, disconnect_res); | ||
744 | wake_up(&dev->wait_recvd_msg); | ||
745 | break; | 753 | break; |
746 | 754 | ||
747 | case MEI_FLOW_CONTROL_CMD: | 755 | case MEI_FLOW_CONTROL_CMD: |