aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2014-08-21 07:29:18 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-09-24 01:57:48 -0400
commit12f45ed414c8d2eac1a98bf2deaf4117e8c0324f (patch)
treefead16c23e9916ee9db645c5ad3c2ff9e2a74361
parent5a8373fba0ab2cec8d206747ad60ca4a30821a37 (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.c4
-rw-r--r--drivers/misc/mei/hbm.c118
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 */
503static void mei_hbm_cl_disconnect_res(struct mei_device *dev, 504static 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 */
553static void mei_hbm_cl_connect_res(struct mei_device *dev, 539static 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 */
564static 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: