Commit 12f45ed4 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman

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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 5a8373fb
...@@ -534,7 +534,7 @@ int mei_cl_disconnect(struct mei_cl *cl) ...@@ -534,7 +534,7 @@ int mei_cl_disconnect(struct mei_cl *cl)
} }
mutex_unlock(&dev->device_lock); mutex_unlock(&dev->device_lock);
wait_event_timeout(dev->wait_recvd_msg, wait_event_timeout(cl->wait,
MEI_FILE_DISCONNECTED == cl->state, MEI_FILE_DISCONNECTED == cl->state,
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
...@@ -639,7 +639,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file) ...@@ -639,7 +639,7 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
} }
mutex_unlock(&dev->device_lock); 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_CONNECTED ||
cl->state == MEI_FILE_DISCONNECTED), cl->state == MEI_FILE_DISCONNECTED),
mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT)); mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
......
...@@ -495,39 +495,24 @@ int mei_hbm_cl_disconnect_rsp(struct mei_device *dev, struct mei_cl *cl) ...@@ -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 * @cl: mei host client
* @rs: disconnect response bus message * @cmd: disconnect client response host bus message
*/ */
static void mei_hbm_cl_disconnect_res(struct mei_device *dev, static void mei_hbm_cl_disconnect_res(struct mei_cl *cl,
struct hbm_client_connect_response *rs) struct mei_hbm_cl_cmd *cmd)
{ {
struct mei_cl *cl; struct hbm_client_connect_response *rs =
struct mei_cl_cb *cb, *next; (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); 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) if (rs->status == MEI_CL_DISCONN_SUCCESS)
cl->state = MEI_FILE_DISCONNECTED; cl->state = MEI_FILE_DISCONNECTED;
cl->status = 0; cl->status = 0;
cl->timer_count = 0;
break;
}
}
} }
/** /**
...@@ -545,24 +530,45 @@ int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl) ...@@ -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 * @cl: mei host client
* @rs: connect response bus message * @cmd: connect client response host bus message
*/ */
static void mei_hbm_cl_connect_res(struct mei_device *dev, static void mei_hbm_cl_connect_res(struct mei_cl *cl,
struct hbm_client_connect_response *rs) struct mei_hbm_cl_cmd *cmd)
{ {
struct hbm_client_connect_response *rs =
(struct hbm_client_connect_response *)cmd;
struct mei_cl *cl; dev_dbg(&cl->dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
struct mei_cl_cb *cb, *next;
dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
rs->me_addr, rs->host_addr, rs->me_addr, rs->host_addr,
mei_cl_conn_status_str(rs->status)); 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) { list_for_each_entry_safe(cb, next, &dev->ctrl_rd_list.list, list) {
cl = cb->cl; cl = cb->cl;
...@@ -572,7 +578,7 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, ...@@ -572,7 +578,7 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
continue; continue;
} }
if (cb->fop_type != MEI_FOP_CONNECT) if (cb->fop_type != fop_type)
continue; continue;
if (mei_hbm_cl_addr_equal(cl, rs)) { if (mei_hbm_cl_addr_equal(cl, rs)) {
...@@ -584,12 +590,19 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev, ...@@ -584,12 +590,19 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
if (!cl) if (!cl)
return; 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; cl->timer_count = 0;
if (rs->status == MEI_CL_CONN_SUCCESS) wake_up(&cl->wait);
cl->state = MEI_FILE_CONNECTED;
else
cl->state = MEI_FILE_DISCONNECTED;
cl->status = mei_cl_conn_status_to_errno(rs->status);
} }
...@@ -657,17 +670,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr) ...@@ -657,17 +670,18 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
{ {
struct mei_bus_message *mei_msg; struct mei_bus_message *mei_msg;
struct hbm_host_version_response *version_res; 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_props_response *props_res;
struct hbm_host_enum_response *enum_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 */ /* read the message to our buffer */
BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf)); BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
mei_read_slots(dev, dev->rd_msg_buf, hdr->length); mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
mei_msg = (struct mei_bus_message *)dev->rd_msg_buf; 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 /* ignore spurious message and prevent reset nesting
* hbm is put to idle during system reset * 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,18 +744,12 @@ int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
case CLIENT_CONNECT_RES_CMD: case CLIENT_CONNECT_RES_CMD:
dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n"); dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n");
mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_CONNECT);
connect_res = (struct hbm_client_connect_response *) mei_msg;
mei_hbm_cl_connect_res(dev, connect_res);
wake_up(&dev->wait_recvd_msg);
break; break;
case CLIENT_DISCONNECT_RES_CMD: case CLIENT_DISCONNECT_RES_CMD:
dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n"); dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n");
mei_hbm_cl_res(dev, cl_cmd, MEI_FOP_DISCONNECT);
disconnect_res = (struct hbm_client_connect_response *) mei_msg;
mei_hbm_cl_disconnect_res(dev, disconnect_res);
wake_up(&dev->wait_recvd_msg);
break; break;
case MEI_FLOW_CONTROL_CMD: case MEI_FLOW_CONTROL_CMD:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment