mei: revamp connect and disconnect response handling
authorTomas Winkler <tomas.winkler@intel.com>
Thu, 21 Aug 2014 11:29:18 +0000 (14:29 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 24 Sep 2014 05:57:48 +0000 (22:57 -0700)
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>
drivers/misc/mei/client.c
drivers/misc/mei/hbm.c

index efac33929e53976e40d3188362fd7ae403e82e56..449bb45642411afa2d845556f725fbba222e7de2 100644 (file)
@@ -534,7 +534,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
        }
        mutex_unlock(&dev->device_lock);
 
-       wait_event_timeout(dev->wait_recvd_msg,
+       wait_event_timeout(cl->wait,
                        MEI_FILE_DISCONNECTED == cl->state,
                        mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
 
@@ -639,7 +639,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
        }
 
        mutex_unlock(&dev->device_lock);
-       wait_event_timeout(dev->wait_recvd_msg,
+       wait_event_timeout(cl->wait,
                        (cl->state == MEI_FILE_CONNECTED ||
                         cl->state == MEI_FILE_DISCONNECTED),
                        mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
index d50c8d1fb36d1baa2f6d2e9e65ef3d923bd71b76..cda914191a2fc04b0c00bd9f4ff21cfe94dd9c62 100644 (file)
@@ -495,39 +495,24 @@ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl)
 }
 
 /**
- * mei_hbm_cl_disconnect_res - disconnect response from ME
+ * mei_hbm_cl_disconnect_res - update the client state according
+ *       disconnect response
  *
- * @dev: the device structure
- * @rs: disconnect response bus message
+ * @cl: mei host client
+ * @cmd: disconnect client response host bus message
  */
-static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
-               struct hbm_client_connect_response *rs)
+static void mei_hbm_cl_disconnect_res(struct mei_cl *cl,
+                                     struct mei_hbm_cl_cmd *cmd)
 {
-       struct mei_cl *cl;
-       struct mei_cl_cb *cb, *next;
+       struct hbm_client_connect_response *rs =
+               (struct hbm_client_connect_response *)cmd;
 
-       dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n",
+       dev_dbg(&cl->dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n",
                        rs->me_addr, rs->host_addr, rs->status);
 
-       list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) {
-               cl = cb->cl;
-
-               /* this should not happen */
-               if (WARN_ON(!cl)) {
-                       list_del(&cb->list);
-                       return;
-               }
-
-               if (mei_hbm_cl_addr_equal(cl, rs)) {
-                       list_del(&cb->list);
-                       if (rs->status == MEI_CL_DISCONN_SUCCESS)
-                               cl->state = MEI_FILE_DISCONNECTED;
-
-                       cl->status = 0;
-                       cl->timer_count = 0;
-                       break;
-               }
-       }
+       if (rs->status == MEI_CL_DISCONN_SUCCESS)
+               cl->state = MEI_FILE_DISCONNECTED;
+       cl->status = 0;
 }
 
 /**
@@ -545,24 +530,45 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
 }
 
 /**
- * mei_hbm_cl_connect_res - connect response from the ME
+ * mei_hbm_cl_connect_res - update the client state according
+ *        connection response
  *
- * @dev: the device structure
- * @rs: connect response bus message
+ * @cl: mei host client
+ * @cmd: connect client response host bus message
  */
-static void mei_hbm_cl_connect_res(struct mei_device *dev,
-               struct hbm_client_connect_response *rs)
+static void mei_hbm_cl_connect_res(struct mei_cl *cl,
+                                  struct mei_hbm_cl_cmd *cmd)
 {
+       struct hbm_client_connect_response *rs =
+               (struct hbm_client_connect_response *)cmd;
 
-       struct mei_cl *cl;
-       struct mei_cl_cb *cb, *next;
-
-       dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
+       dev_dbg(&cl->dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
                        rs->me_addr, rs->host_addr,
                        mei_cl_conn_status_str(rs->status));
 
-       cl = NULL;
+       if (rs->status == MEI_CL_CONN_SUCCESS)
+               cl->state = MEI_FILE_CONNECTED;
+       else
+               cl->state = MEI_FILE_DISCONNECTED;
+       cl->status = mei_cl_conn_status_to_errno(rs->status);
+}
+
+/**
+ * mei_hbm_cl_res - process hbm response received on behalf
+ *         an client
+ *
+ * @dev: the device structure
+ * @rs:  hbm client message
+ * @fop_type: file operation type
+ */
+static void mei_hbm_cl_res(struct mei_device *dev,
+                          struct mei_hbm_cl_cmd *rs,
+                          enum mei_cb_file_ops fop_type)
+{
+       struct mei_cl *cl;
+       struct mei_cl_cb *cb, *next;
 
+       cl = NULL;
        list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) {
 
                cl = cb->cl;
@@ -572,7 +578,7 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
                        continue;
                }
 
-               if (cb->fop_type !=  MEI_FOP_CONNECT)
+               if (cb->fop_type != fop_type)
                        continue;
 
                if (mei_hbm_cl_addr_equal(cl, rs)) {
@@ -584,12 +590,19 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
        if (!cl)
                return;
 
+       switch (fop_type) {
+       case MEI_FOP_CONNECT:
+               mei_hbm_cl_connect_res(cl, rs);
+               break;
+       case MEI_FOP_DISCONNECT:
+               mei_hbm_cl_disconnect_res(cl, rs);
+               break;
+       default:
+               return;
+       }
+
        cl->timer_count = 0;
-       if (rs->status == MEI_CL_CONN_SUCCESS)
-               cl->state = MEI_FILE_CONNECTED;
-       else
-               cl->state = MEI_FILE_DISCONNECTED;
-       cl->status = mei_cl_conn_status_to_errno(rs->status);
+       wake_up(&cl->wait);
 }
 
 
@@ -657,17 +670,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
 {
        struct mei_bus_message *mei_msg;
        struct hbm_host_version_response *version_res;
-       struct hbm_client_connect_response *connect_res;
-       struct hbm_client_connect_response *disconnect_res;
-       struct hbm_client_connect_request *disconnect_req;
-       struct hbm_flow_control *flow_control;
        struct hbm_props_response *props_res;
        struct hbm_host_enum_response *enum_res;
 
+       struct mei_hbm_cl_cmd *cl_cmd;
+       struct hbm_client_connect_request *disconnect_req;
+       struct hbm_flow_control *flow_control;
+
        /* read the message to our buffer */
        BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
        mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
        mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;
+       cl_cmd  = (struct mei_hbm_cl_cmd *)mei_msg;
 
        /* ignore spurious message and prevent reset nesting
         * 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)
 
        case CLIENT_CONNECT_RES_CMD:
                dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n");
-
-               connect_res = (struct hbm_client_connect_response *) mei_msg;
-               mei_hbm_cl_connect_res(dev, connect_res);
-               wake_up(&dev->wait_recvd_msg);
+               mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT);
                break;
 
        case CLIENT_DISCONNECT_RES_CMD:
                dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n");
-
-               disconnect_res = (struct hbm_client_connect_response *) mei_msg;
-               mei_hbm_cl_disconnect_res(dev, disconnect_res);
-               wake_up(&dev->wait_recvd_msg);
+               mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT);
                break;
 
        case MEI_FLOW_CONTROL_CMD:
This page took 0.031717 seconds and 5 git commands to generate.