From 2c9b48ac3cb2cd2c84c43f235c65b7fc238f6f1f Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 16 Jun 2013 09:16:31 +0300 Subject: mei: support HBM versioning Driver can work properly if device support driver HBM version or driver can downgrade its supported HBM version level Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hbm.c | 37 ++++++++++++++++++++++++++++++++----- drivers/misc/mei/hbm.h | 2 +- drivers/misc/mei/init.c | 3 +-- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index 6916045166eb..565027b1bc73 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -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; diff --git a/drivers/misc/mei/hbm.h b/drivers/misc/mei/hbm.h index e80dc24ef3e2..4ae2e56e404f 100644 --- a/drivers/misc/mei/hbm.h +++ b/drivers/misc/mei/hbm.h @@ -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_ */ diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index f580d30bb784..79e9e1c30562 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -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; } -- cgit v1.2.3