mei: support HBM versioning
authorTomas Winkler <tomas.winkler@intel.com>
Sun, 16 Jun 2013 06:16:31 +0000 (09:16 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Jun 2013 23:43:09 +0000 (16:43 -0700)
Driver can work properly if device support driver HBM version
or driver can downgrade its supported HBM version level

Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mei/hbm.c
drivers/misc/mei/hbm.h
drivers/misc/mei/init.c

index 6916045166eb4fda8eb347ff8978aac5c6ca6fc9..565027b1bc73a185b59912b834d6d7934df58c3c 100644 (file)
@@ -535,6 +535,20 @@ static void mei_hbm_fw_disconnect_req(struct mei_device *dev,
 }
 
 
+/**
+ * mei_hbm_version_is_supported - checks whether the driver can
+ *     support the hbm version of the device
+ *
+ * @dev: the device structure
+ * returns true if driver can support hbm version of the device
+ */
+bool mei_hbm_version_is_supported(struct mei_device *dev)
+{
+       return  (dev->version.major_version < HBM_MAJOR_VERSION) ||
+               (dev->version.major_version == HBM_MAJOR_VERSION &&
+                dev->version.minor_version <= HBM_MINOR_VERSION);
+}
+
 /**
  * mei_hbm_dispatch - bottom half read routine after ISR to
  * handle the read bus message cmd processing.
@@ -562,9 +576,24 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
        switch (mei_msg->hbm_cmd) {
        case HOST_START_RES_CMD:
                version_res = (struct hbm_host_version_response *)mei_msg;
-               if (!version_res->host_version_supported) {
-                       dev->version = version_res->me_max_version;
-                       dev_dbg(&dev->pdev->dev, "version mismatch.\n");
+
+               dev_dbg(&dev->pdev->dev, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
+                               HBM_MAJOR_VERSION, HBM_MINOR_VERSION,
+                               version_res->me_max_version.major_version,
+                               version_res->me_max_version.minor_version);
+
+               if (version_res->host_version_supported) {
+                       dev->version.major_version = HBM_MAJOR_VERSION;
+                       dev->version.minor_version = HBM_MINOR_VERSION;
+               } else {
+                       dev->version.major_version =
+                               version_res->me_max_version.major_version;
+                       dev->version.minor_version =
+                               version_res->me_max_version.minor_version;
+               }
+
+               if (!mei_hbm_version_is_supported(dev)) {
+                       dev_warn(&dev->pdev->dev, "hbm version mismatch: stopping the driver.\n");
 
                        dev->hbm_state = MEI_HBM_STOP;
                        mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
@@ -575,8 +604,6 @@ void mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
                        return;
                }
 
-               dev->version.major_version = HBM_MAJOR_VERSION;
-               dev->version.minor_version = HBM_MINOR_VERSION;
                if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
                    dev->hbm_state == MEI_HBM_START) {
                        dev->init_clients_timer = 0;
index e80dc24ef3e23e8aed24014821cb3807f0578fd6..4ae2e56e404f8d9a99808c24df94d69e6c21ca3b 100644 (file)
@@ -54,7 +54,7 @@ int mei_hbm_start_wait(struct mei_device *dev);
 int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl);
 int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
 int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl);
-
+bool mei_hbm_version_is_supported(struct mei_device *dev);
 
 #endif /* _MEI_HBM_H_ */
 
index f580d30bb7842c564e81dba6b4406b1b01bfdee1..79e9e1c3056295f6ab68b98ff3294bcfc1fe39d8 100644 (file)
@@ -106,8 +106,7 @@ int mei_start(struct mei_device *dev)
                goto err;
        }
 
-       if (dev->version.major_version != HBM_MAJOR_VERSION ||
-           dev->version.minor_version != HBM_MINOR_VERSION) {
+       if (!mei_hbm_version_is_supported(dev)) {
                dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
                goto err;
        }