|
@@ -123,12 +123,33 @@ static bool is_treat_specially_client(struct mei_cl *cl,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+int mei_hbm_start_wait(struct mei_device *dev)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+ if (dev->hbm_state > MEI_HBM_START)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ mutex_unlock(&dev->device_lock);
|
|
|
+ ret = wait_event_interruptible_timeout(dev->wait_recvd_msg,
|
|
|
+ dev->hbm_state == MEI_HBM_IDLE ||
|
|
|
+ dev->hbm_state > MEI_HBM_START,
|
|
|
+ mei_secs_to_jiffies(MEI_INTEROP_TIMEOUT));
|
|
|
+ mutex_lock(&dev->device_lock);
|
|
|
+
|
|
|
+ if (ret <= 0 && (dev->hbm_state <= MEI_HBM_START)) {
|
|
|
+ dev->hbm_state = MEI_HBM_IDLE;
|
|
|
+ dev_err(&dev->pdev->dev, "wating for mei start failed\n");
|
|
|
+ return -ETIMEDOUT;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* mei_hbm_start_req - sends start request message.
|
|
|
*
|
|
|
* @dev: the device structure
|
|
|
*/
|
|
|
-void mei_hbm_start_req(struct mei_device *dev)
|
|
|
+int mei_hbm_start_req(struct mei_device *dev)
|
|
|
{
|
|
|
struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
|
|
|
struct hbm_host_version_request *start_req;
|
|
@@ -143,18 +164,19 @@ void mei_hbm_start_req(struct mei_device *dev)
|
|
|
start_req->host_version.major_version = HBM_MAJOR_VERSION;
|
|
|
start_req->host_version.minor_version = HBM_MINOR_VERSION;
|
|
|
|
|
|
- dev->recvd_msg = false;
|
|
|
+ dev->hbm_state = MEI_HBM_IDLE;
|
|
|
if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
|
|
|
dev_err(&dev->pdev->dev, "version message writet failed\n");
|
|
|
dev->dev_state = MEI_DEV_RESETING;
|
|
|
mei_reset(dev, 1);
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- dev->init_clients_state = MEI_START_MESSAGE;
|
|
|
+ dev->hbm_state = MEI_HBM_START;
|
|
|
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
|
|
|
- return ;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
+/*
|
|
|
* mei_hbm_enum_clients_req - sends enumeration client request message.
|
|
|
*
|
|
|
* @dev: the device structure
|
|
@@ -178,7 +200,7 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev)
|
|
|
dev_err(&dev->pdev->dev, "enumeration request write failed.\n");
|
|
|
mei_reset(dev, 1);
|
|
|
}
|
|
|
- dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
|
|
|
+ dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
|
|
|
dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
|
|
|
return;
|
|
|
}
|
|
@@ -208,6 +230,7 @@ static int mei_hbm_prop_req(struct mei_device *dev)
|
|
|
|
|
|
/* We got all client properties */
|
|
|
if (next_client_index == MEI_CLIENTS_MAX) {
|
|
|
+ dev->hbm_state = MEI_HBM_STARTED;
|
|
|
schedule_work(&dev->init_work);
|
|
|
|
|
|
return 0;
|
|
@@ -542,27 +565,28 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
|
|
dev->version = version_res->me_max_version;
|
|
|
dev_dbg(&dev->pdev->dev, "version mismatch.\n");
|
|
|
|
|
|
+ dev->hbm_state = MEI_HBM_STOP;
|
|
|
mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
|
|
|
dev->wr_msg.data);
|
|
|
mei_write_message(dev, &dev->wr_msg.hdr,
|
|
|
dev->wr_msg.data);
|
|
|
+
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
dev->version.major_version = HBM_MAJOR_VERSION;
|
|
|
dev->version.minor_version = HBM_MINOR_VERSION;
|
|
|
if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
|
|
|
- dev->init_clients_state == MEI_START_MESSAGE) {
|
|
|
+ dev->hbm_state == MEI_HBM_START) {
|
|
|
dev->init_clients_timer = 0;
|
|
|
mei_hbm_enum_clients_req(dev);
|
|
|
} else {
|
|
|
- dev->recvd_msg = false;
|
|
|
dev_err(&dev->pdev->dev, "reset: wrong host start response\n");
|
|
|
mei_reset(dev, 1);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- dev->recvd_msg = true;
|
|
|
+ wake_up_interruptible(&dev->wait_recvd_msg);
|
|
|
dev_dbg(&dev->pdev->dev, "host start response message received.\n");
|
|
|
break;
|
|
|
|
|
@@ -603,7 +627,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
|
|
}
|
|
|
|
|
|
if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
|
|
|
- dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
|
|
|
+ dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
|
|
|
dev_err(&dev->pdev->dev, "reset: unexpected properties response\n");
|
|
|
mei_reset(dev, 1);
|
|
|
|
|
@@ -623,13 +647,12 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
|
|
enum_res = (struct hbm_host_enum_response *) mei_msg;
|
|
|
memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
|
|
|
if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
|
|
|
- dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
|
|
|
+ dev->hbm_state == MEI_HBM_ENUM_CLIENTS) {
|
|
|
dev->init_clients_timer = 0;
|
|
|
dev->me_client_presentation_num = 0;
|
|
|
dev->me_client_index = 0;
|
|
|
mei_hbm_me_cl_allocate(dev);
|
|
|
- dev->init_clients_state =
|
|
|
- MEI_CLIENT_PROPERTIES_MESSAGE;
|
|
|
+ dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;
|
|
|
|
|
|
/* first property reqeust */
|
|
|
mei_hbm_prop_req(dev);
|
|
@@ -641,6 +664,9 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
|
|
break;
|
|
|
|
|
|
case HOST_STOP_RES_CMD:
|
|
|
+
|
|
|
+ if (dev->hbm_state != MEI_HBM_STOP)
|
|
|
+ dev_err(&dev->pdev->dev, "unexpected stop response hbm.\n");
|
|
|
dev->dev_state = MEI_DEV_DISABLED;
|
|
|
dev_info(&dev->pdev->dev, "reset: FW stop response.\n");
|
|
|
mei_reset(dev, 1);
|
|
@@ -654,6 +680,7 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
|
|
|
|
|
|
case ME_STOP_REQ_CMD:
|
|
|
|
|
|
+ dev->hbm_state = MEI_HBM_STOP;
|
|
|
mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr,
|
|
|
dev->wr_ext_msg.data);
|
|
|
break;
|