]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/misc/mei/hbm.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[linux.git] / drivers / misc / mei / hbm.c
index 4465d3f100609dc0778592b434467bd834f556b4..6916045166eb4fda8eb347ff8978aac5c6ca6fc9 100644 (file)
@@ -52,7 +52,7 @@ static void mei_hbm_me_cl_allocate(struct mei_device *dev)
                        sizeof(struct mei_me_client), GFP_KERNEL);
        if (!clients) {
                dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
-               dev->dev_state = MEI_DEV_RESETING;
+               dev->dev_state = MEI_DEV_RESETTING;
                mei_reset(dev, 1);
                return;
        }
@@ -124,12 +124,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;
@@ -144,18 +165,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_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
-               dev->dev_state = MEI_DEV_RESETING;
+               dev_err(&dev->pdev->dev, "version message writet failed\n");
+               dev->dev_state = MEI_DEV_RESETTING;
                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
@@ -175,11 +197,11 @@ static void mei_hbm_enum_clients_req(struct mei_device *dev)
        enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
 
        if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
-               dev->dev_state = MEI_DEV_RESETING;
-               dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
+               dev->dev_state = MEI_DEV_RESETTING;
+               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;
 }
@@ -209,6 +231,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;
@@ -227,8 +250,8 @@ static int mei_hbm_prop_req(struct mei_device *dev)
        prop_req->address = next_client_index;
 
        if (mei_write_message(dev, mei_hdr, dev->wr_msg.data)) {
-               dev->dev_state = MEI_DEV_RESETING;
-               dev_err(&dev->pdev->dev, "Properties request command failed\n");
+               dev->dev_state = MEI_DEV_RESETTING;
+               dev_err(&dev->pdev->dev, "properties request write failed\n");
                mei_reset(dev, 1);
 
                return -EIO;
@@ -543,27 +566,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_dbg(&dev->pdev->dev, "reset due to received hbm: host start\n");
+                       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;
 
@@ -592,23 +616,20 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
                me_client = &dev->me_clients[dev->me_client_presentation_num];
 
                if (props_res->status || !dev->me_clients) {
-                       dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
+                       dev_err(&dev->pdev->dev, "reset: properties response hbm wrong status.\n");
                        mei_reset(dev, 1);
                        return;
                }
 
                if (me_client->client_id != props_res->address) {
-                       dev_err(&dev->pdev->dev,
-                               "Host client properties reply mismatch\n");
+                       dev_err(&dev->pdev->dev, "reset: host properties response address mismatch\n");
                        mei_reset(dev, 1);
-
                        return;
                }
 
                if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
-                   dev->init_clients_state != MEI_CLIENT_PROPERTIES_MESSAGE) {
-                       dev_err(&dev->pdev->dev,
-                               "Unexpected client properties reply\n");
+                   dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
+                       dev_err(&dev->pdev->dev, "reset: unexpected properties response\n");
                        mei_reset(dev, 1);
 
                        return;
@@ -627,26 +648,28 @@ 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);
                } else {
-                       dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
+                       dev_err(&dev->pdev->dev, "reset: unexpected enumeration response hbm.\n");
                        mei_reset(dev, 1);
                        return;
                }
                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_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
+               dev_info(&dev->pdev->dev, "reset: FW stop response.\n");
                mei_reset(dev, 1);
                break;
 
@@ -658,6 +681,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;