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 <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Tomas Winkler 2013-06-16 09:16:31 +03:00 committed by Greg Kroah-Hartman
parent a151427ed0
commit 2c9b48ac3c
3 changed files with 34 additions and 8 deletions

View 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 * mei_hbm_dispatch - bottom half read routine after ISR to
* handle the read bus message cmd processing. * 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) { switch (mei_msg->hbm_cmd) {
case HOST_START_RES_CMD: case HOST_START_RES_CMD:
version_res = (struct hbm_host_version_response *)mei_msg; 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, "HBM VERSION: DRIVER=%02d:%02d DEVICE=%02d:%02d\n",
dev_dbg(&dev->pdev->dev, "version mismatch.\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; dev->hbm_state = MEI_HBM_STOP;
mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr, 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; return;
} }
dev->version.major_version = HBM_MAJOR_VERSION;
dev->version.minor_version = HBM_MINOR_VERSION;
if (dev->dev_state == MEI_DEV_INIT_CLIENTS && if (dev->dev_state == MEI_DEV_INIT_CLIENTS &&
dev->hbm_state == MEI_HBM_START) { dev->hbm_state == MEI_HBM_START) {
dev->init_clients_timer = 0; dev->init_clients_timer = 0;

View 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_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_disconnect_req(struct mei_device *dev, struct mei_cl *cl);
int mei_hbm_cl_connect_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_ */ #endif /* _MEI_HBM_H_ */

View File

@ -106,8 +106,7 @@ int mei_start(struct mei_device *dev)
goto err; goto err;
} }
if (dev->version.major_version != HBM_MAJOR_VERSION || if (!mei_hbm_version_is_supported(dev)) {
dev->version.minor_version != HBM_MINOR_VERSION) {
dev_dbg(&dev->pdev->dev, "MEI start failed.\n"); dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
goto err; goto err;
} }