/*
 *
 * Intel Management Engine Interface (Intel MEI) Linux driver
 * Copyright (c) 2003-2012, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/mei.h>

#include "mei_dev.h"
#include "hbm.h"
#include "hw-me.h"

/**
 * mei_hbm_me_cl_allocate - allocates storage for me clients
 *
 * @dev: the device structure
 *
 * returns 0 on success -ENOMEM on allocation failure
 */
static int mei_hbm_me_cl_allocate(struct mei_device *dev)
{
	struct mei_me_client *clients;
	int b;

	dev->me_clients_num = 0;
	dev->me_client_presentation_num = 0;
	dev->me_client_index = 0;

	/* count how many ME clients we have */
	for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
		dev->me_clients_num++;

	if (dev->me_clients_num == 0)
		return 0;

	kfree(dev->me_clients);
	dev->me_clients = NULL;

	dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%ld.\n",
		dev->me_clients_num * sizeof(struct mei_me_client));
	/* allocate storage for ME clients representation */
	clients = kcalloc(dev->me_clients_num,
			sizeof(struct mei_me_client), GFP_KERNEL);
	if (!clients) {
		dev_err(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
		return -ENOMEM;
	}
	dev->me_clients = clients;
	return 0;
}

/**
 * mei_hbm_cl_hdr - construct client hbm header
 *
 * @cl: - client
 * @hbm_cmd: host bus message command
 * @buf: buffer for cl header
 * @len: buffer length
 */
static inline
void mei_hbm_cl_hdr(struct mei_cl *cl, u8 hbm_cmd, void *buf, size_t len)
{
	struct mei_hbm_cl_cmd *cmd = buf;

	memset(cmd, 0, len);

	cmd->hbm_cmd = hbm_cmd;
	cmd->host_addr = cl->host_client_id;
	cmd->me_addr = cl->me_client_id;
}

/**
 * same_disconn_addr - tells if they have the same address
 *
 * @file: private data of the file object.
 * @disconn: disconnection request.
 *
 * returns true if addres are same
 */
static inline
bool mei_hbm_cl_addr_equal(struct mei_cl *cl, void *buf)
{
	struct mei_hbm_cl_cmd *cmd = buf;
	return cl->host_client_id == cmd->host_addr &&
		cl->me_client_id == cmd->me_addr;
}


/**
 * is_treat_specially_client - checks if the message belongs
 * to the file private data.
 *
 * @cl: private data of the file object
 * @rs: connect response bus message
 *
 */
static bool is_treat_specially_client(struct mei_cl *cl,
		struct hbm_client_connect_response *rs)
{
	if (mei_hbm_cl_addr_equal(cl, rs)) {
		if (!rs->status) {
			cl->state = MEI_FILE_CONNECTED;
			cl->status = 0;

		} else {
			cl->state = MEI_FILE_DISCONNECTED;
			cl->status = -ENODEV;
		}
		cl->timer_count = 0;

		return true;
	}
	return false;
}

/**
 * mei_hbm_idle - set hbm to idle state
 *
 * @dev: the device structure
 */
void mei_hbm_idle(struct mei_device *dev)
{
	dev->init_clients_timer = 0;
	dev->hbm_state = MEI_HBM_IDLE;
}

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_STARTED,
			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, "waiting for mei start failed\n");
		return -ETIMEDOUT;
	}
	return 0;
}

/**
 * mei_hbm_start_req - sends start request message.
 *
 * @dev: the device structure
 *
 * returns 0 on success and < 0 on failure
 */
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;
	const size_t len = sizeof(struct hbm_host_version_request);
	int ret;

	mei_hbm_hdr(mei_hdr, len);

	/* host start message */
	start_req = (struct hbm_host_version_request *)dev->wr_msg.data;
	memset(start_req, 0, len);
	start_req->hbm_cmd = HOST_START_REQ_CMD;
	start_req->host_version.major_version = HBM_MAJOR_VERSION;
	start_req->host_version.minor_version = HBM_MINOR_VERSION;

	dev->hbm_state = MEI_HBM_IDLE;
	ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
	if (ret) {
		dev_err(&dev->pdev->dev, "version message write failed: ret = %d\n",
			ret);
		return ret;
	}

	dev->hbm_state = MEI_HBM_START;
	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	return 0;
}

/*
 * mei_hbm_enum_clients_req - sends enumeration client request message.
 *
 * @dev: the device structure
 *
 * returns 0 on success and < 0 on failure
 */
static int mei_hbm_enum_clients_req(struct mei_device *dev)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	struct hbm_host_enum_request *enum_req;
	const size_t len = sizeof(struct hbm_host_enum_request);
	int ret;

	/* enumerate clients */
	mei_hbm_hdr(mei_hdr, len);

	enum_req = (struct hbm_host_enum_request *)dev->wr_msg.data;
	memset(enum_req, 0, len);
	enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;

	ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
	if (ret) {
		dev_err(&dev->pdev->dev, "enumeration request write failed: ret = %d.\n",
			ret);
		return ret;
	}
	dev->hbm_state = MEI_HBM_ENUM_CLIENTS;
	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	return 0;
}

/**
 * mei_hbm_prop_req - request property for a single client
 *
 * @dev: the device structure
 *
 * returns 0 on success and < 0 on failure
 */

static int mei_hbm_prop_req(struct mei_device *dev)
{

	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	struct hbm_props_request *prop_req;
	const size_t len = sizeof(struct hbm_props_request);
	unsigned long next_client_index;
	unsigned long client_num;
	int ret;

	client_num = dev->me_client_presentation_num;

	next_client_index = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX,
					  dev->me_client_index);

	/* 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;
	}

	dev->me_clients[client_num].client_id = next_client_index;
	dev->me_clients[client_num].mei_flow_ctrl_creds = 0;

	mei_hbm_hdr(mei_hdr, len);
	prop_req = (struct hbm_props_request *)dev->wr_msg.data;

	memset(prop_req, 0, sizeof(struct hbm_props_request));


	prop_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
	prop_req->address = next_client_index;

	ret = mei_write_message(dev, mei_hdr, dev->wr_msg.data);
	if (ret) {
		dev_err(&dev->pdev->dev, "properties request write failed: ret = %d\n",
			ret);
		return ret;
	}

	dev->init_clients_timer = MEI_CLIENTS_INIT_TIMEOUT;
	dev->me_client_index = next_client_index;

	return 0;
}

/**
 * mei_hbm_stop_req_prepare - perpare stop request message
 *
 * @dev - mei device
 * @mei_hdr - mei message header
 * @data - hbm message body buffer
 */
static void mei_hbm_stop_req_prepare(struct mei_device *dev,
		struct mei_msg_hdr *mei_hdr, unsigned char *data)
{
	struct hbm_host_stop_request *req =
			(struct hbm_host_stop_request *)data;
	const size_t len = sizeof(struct hbm_host_stop_request);

	mei_hbm_hdr(mei_hdr, len);

	memset(req, 0, len);
	req->hbm_cmd = HOST_STOP_REQ_CMD;
	req->reason = DRIVER_STOP_REQUEST;
}

/**
 * mei_hbm_cl_flow_control_req - sends flow control requst.
 *
 * @dev: the device structure
 * @cl: client info
 *
 * This function returns -EIO on write failure
 */
int mei_hbm_cl_flow_control_req(struct mei_device *dev, struct mei_cl *cl)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	const size_t len = sizeof(struct hbm_flow_control);

	mei_hbm_hdr(mei_hdr, len);
	mei_hbm_cl_hdr(cl, MEI_FLOW_CONTROL_CMD, dev->wr_msg.data, len);

	dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
		cl->host_client_id, cl->me_client_id);

	return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
}

/**
 * mei_hbm_add_single_flow_creds - adds single buffer credentials.
 *
 * @dev: the device structure
 * @flow: flow control.
 */
static void mei_hbm_add_single_flow_creds(struct mei_device *dev,
				  struct hbm_flow_control *flow)
{
	struct mei_me_client *client;
	int i;

	for (i = 0; i < dev->me_clients_num; i++) {
		client = &dev->me_clients[i];
		if (client && flow->me_addr == client->client_id) {
			if (client->props.single_recv_buf) {
				client->mei_flow_ctrl_creds++;
				dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
				    flow->me_addr);
				dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
				    client->mei_flow_ctrl_creds);
			} else {
				BUG();	/* error in flow control */
			}
		}
	}
}

/**
 * mei_hbm_cl_flow_control_res - flow control response from me
 *
 * @dev: the device structure
 * @flow_control: flow control response bus message
 */
static void mei_hbm_cl_flow_control_res(struct mei_device *dev,
		struct hbm_flow_control *flow_control)
{
	struct mei_cl *cl = NULL;
	struct mei_cl *next = NULL;

	if (!flow_control->host_addr) {
		/* single receive buffer */
		mei_hbm_add_single_flow_creds(dev, flow_control);
		return;
	}

	/* normal connection */
	list_for_each_entry_safe(cl, next, &dev->file_list, link) {
		if (mei_hbm_cl_addr_equal(cl, flow_control)) {
			cl->mei_flow_ctrl_creds++;
			dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
				flow_control->host_addr, flow_control->me_addr);
			dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
				    cl->mei_flow_ctrl_creds);
				break;
		}
	}
}


/**
 * mei_hbm_cl_disconnect_req - sends disconnect message to fw.
 *
 * @dev: the device structure
 * @cl: a client to disconnect from
 *
 * This function returns -EIO on write failure
 */
int mei_hbm_cl_disconnect_req(struct mei_device *dev, struct mei_cl *cl)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	const size_t len = sizeof(struct hbm_client_connect_request);

	mei_hbm_hdr(mei_hdr, len);
	mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_REQ_CMD, dev->wr_msg.data, len);

	return mei_write_message(dev, mei_hdr, dev->wr_msg.data);
}

/**
 * mei_hbm_cl_disconnect_res - disconnect response from ME
 *
 * @dev: the device structure
 * @rs: disconnect response bus message
 */
static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
		struct hbm_client_connect_response *rs)
{
	struct mei_cl *cl;
	struct mei_cl_cb *pos = NULL, *next = NULL;

	dev_dbg(&dev->pdev->dev,
			"disconnect_response:\n"
			"ME Client = %d\n"
			"Host Client = %d\n"
			"Status = %d\n",
			rs->me_addr,
			rs->host_addr,
			rs->status);

	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
		cl = pos->cl;

		if (!cl) {
			list_del(&pos->list);
			return;
		}

		dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
		if (mei_hbm_cl_addr_equal(cl, rs)) {
			list_del(&pos->list);
			if (!rs->status)
				cl->state = MEI_FILE_DISCONNECTED;

			cl->status = 0;
			cl->timer_count = 0;
			break;
		}
	}
}

/**
 * mei_hbm_cl_connect_req - send connection request to specific me client
 *
 * @dev: the device structure
 * @cl: a client to connect to
 *
 * returns -EIO on write failure
 */
int mei_hbm_cl_connect_req(struct mei_device *dev, struct mei_cl *cl)
{
	struct mei_msg_hdr *mei_hdr = &dev->wr_msg.hdr;
	const size_t len = sizeof(struct hbm_client_connect_request);

	mei_hbm_hdr(mei_hdr, len);
	mei_hbm_cl_hdr(cl, CLIENT_CONNECT_REQ_CMD, dev->wr_msg.data, len);

	return mei_write_message(dev, mei_hdr,  dev->wr_msg.data);
}

/**
 * mei_hbm_cl_connect_res - connect resposne from the ME
 *
 * @dev: the device structure
 * @rs: connect response bus message
 */
static void mei_hbm_cl_connect_res(struct mei_device *dev,
		struct hbm_client_connect_response *rs)
{

	struct mei_cl *cl;
	struct mei_cl_cb *pos = NULL, *next = NULL;

	dev_dbg(&dev->pdev->dev,
			"connect_response:\n"
			"ME Client = %d\n"
			"Host Client = %d\n"
			"Status = %d\n",
			rs->me_addr,
			rs->host_addr,
			rs->status);

	/* if WD or iamthif client treat specially */

	if (is_treat_specially_client(&dev->wd_cl, rs)) {
		dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
		mei_watchdog_register(dev);

		return;
	}

	if (is_treat_specially_client(&dev->iamthif_cl, rs)) {
		dev->iamthif_state = MEI_IAMTHIF_IDLE;
		return;
	}
	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {

		cl = pos->cl;
		if (!cl) {
			list_del(&pos->list);
			return;
		}
		if (pos->fop_type == MEI_FOP_IOCTL) {
			if (is_treat_specially_client(cl, rs)) {
				list_del(&pos->list);
				cl->status = 0;
				cl->timer_count = 0;
				break;
			}
		}
	}
}


/**
 * mei_hbm_fw_disconnect_req - disconnect request initiated by me
 *  host sends disoconnect response
 *
 * @dev: the device structure.
 * @disconnect_req: disconnect request bus message from the me
 */
static void mei_hbm_fw_disconnect_req(struct mei_device *dev,
		struct hbm_client_connect_request *disconnect_req)
{
	struct mei_cl *cl, *next;
	const size_t len = sizeof(struct hbm_client_connect_response);

	list_for_each_entry_safe(cl, next, &dev->file_list, link) {
		if (mei_hbm_cl_addr_equal(cl, disconnect_req)) {
			dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
					disconnect_req->host_addr,
					disconnect_req->me_addr);
			cl->state = MEI_FILE_DISCONNECTED;
			cl->timer_count = 0;
			if (cl == &dev->wd_cl)
				dev->wd_pending = false;
			else if (cl == &dev->iamthif_cl)
				dev->iamthif_timer = 0;

			/* prepare disconnect response */
			mei_hbm_hdr(&dev->wr_ext_msg.hdr, len);
			mei_hbm_cl_hdr(cl, CLIENT_DISCONNECT_RES_CMD,
					 dev->wr_ext_msg.data, len);
			break;
		}
	}
}


/**
 * 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.
 *
 * @dev: the device structure
 * @mei_hdr: header of bus message
 *
 * returns 0 on success and < 0 on failure
 */
int mei_hbm_dispatch(struct mei_device *dev, struct mei_msg_hdr *hdr)
{
	struct mei_bus_message *mei_msg;
	struct mei_me_client *me_client;
	struct hbm_host_version_response *version_res;
	struct hbm_client_connect_response *connect_res;
	struct hbm_client_connect_response *disconnect_res;
	struct hbm_client_connect_request *disconnect_req;
	struct hbm_flow_control *flow_control;
	struct hbm_props_response *props_res;
	struct hbm_host_enum_response *enum_res;

	/* read the message to our buffer */
	BUG_ON(hdr->length >= sizeof(dev->rd_msg_buf));
	mei_read_slots(dev, dev->rd_msg_buf, hdr->length);
	mei_msg = (struct mei_bus_message *)dev->rd_msg_buf;

	/* ignore spurious message and prevent reset nesting
	 * hbm is put to idle during system reset
	 */
	if (dev->hbm_state == MEI_HBM_IDLE) {
		dev_dbg(&dev->pdev->dev, "hbm: state is idle ignore spurious messages\n");
		return 0;
	}

	switch (mei_msg->hbm_cmd) {
	case HOST_START_RES_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: start: response message received.\n");

		dev->init_clients_timer = 0;

		version_res = (struct hbm_host_version_response *)mei_msg;

		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: start: version mismatch - stopping the driver.\n");

			dev->hbm_state = MEI_HBM_STOPPED;
			mei_hbm_stop_req_prepare(dev, &dev->wr_msg.hdr,
						dev->wr_msg.data);
			if (mei_write_message(dev, &dev->wr_msg.hdr,
					dev->wr_msg.data)) {
				dev_err(&dev->pdev->dev, "hbm: start: failed to send stop request\n");
				return -EIO;
			}
			break;
		}

		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
		    dev->hbm_state != MEI_HBM_START) {
			dev_err(&dev->pdev->dev, "hbm: start: state mismatch, [%d, %d]\n",
				dev->dev_state, dev->hbm_state);
			return -EPROTO;
		}

		dev->hbm_state = MEI_HBM_STARTED;

		if (mei_hbm_enum_clients_req(dev)) {
			dev_err(&dev->pdev->dev, "hbm: start: failed to send enumeration request\n");
			return -EIO;
		}

		wake_up_interruptible(&dev->wait_recvd_msg);
		break;

	case CLIENT_CONNECT_RES_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: client connect response: message received.\n");

		connect_res = (struct hbm_client_connect_response *) mei_msg;
		mei_hbm_cl_connect_res(dev, connect_res);
		wake_up(&dev->wait_recvd_msg);
		break;

	case CLIENT_DISCONNECT_RES_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: client disconnect response: message received.\n");

		disconnect_res = (struct hbm_client_connect_response *) mei_msg;
		mei_hbm_cl_disconnect_res(dev, disconnect_res);
		wake_up(&dev->wait_recvd_msg);
		break;

	case MEI_FLOW_CONTROL_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: client flow control response: message received.\n");

		flow_control = (struct hbm_flow_control *) mei_msg;
		mei_hbm_cl_flow_control_res(dev, flow_control);
		break;

	case HOST_CLIENT_PROPERTIES_RES_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: properties response: message received.\n");

		dev->init_clients_timer = 0;

		if (dev->me_clients == NULL) {
			dev_err(&dev->pdev->dev, "hbm: properties response: mei_clients not allocated\n");
			return -EPROTO;
		}

		props_res = (struct hbm_props_response *)mei_msg;
		me_client = &dev->me_clients[dev->me_client_presentation_num];

		if (props_res->status) {
			dev_err(&dev->pdev->dev, "hbm: properties response: wrong status = %d\n",
				props_res->status);
			return -EPROTO;
		}

		if (me_client->client_id != props_res->address) {
			dev_err(&dev->pdev->dev, "hbm: properties response: address mismatch %d ?= %d\n",
				me_client->client_id, props_res->address);
			return -EPROTO;
		}

		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
		    dev->hbm_state != MEI_HBM_CLIENT_PROPERTIES) {
			dev_err(&dev->pdev->dev, "hbm: properties response: state mismatch, [%d, %d]\n",
				dev->dev_state, dev->hbm_state);
			return -EPROTO;
		}

		me_client->props = props_res->client_properties;
		dev->me_client_index++;
		dev->me_client_presentation_num++;

		/* request property for the next client */
		if (mei_hbm_prop_req(dev))
			return -EIO;

		break;

	case HOST_ENUM_RES_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: enumeration response: message received\n");

		dev->init_clients_timer = 0;

		enum_res = (struct hbm_host_enum_response *) mei_msg;
		BUILD_BUG_ON(sizeof(dev->me_clients_map)
				< sizeof(enum_res->valid_addresses));
		memcpy(dev->me_clients_map, enum_res->valid_addresses,
			sizeof(enum_res->valid_addresses));

		if (dev->dev_state != MEI_DEV_INIT_CLIENTS ||
		    dev->hbm_state != MEI_HBM_ENUM_CLIENTS) {
			dev_err(&dev->pdev->dev, "hbm: enumeration response: state mismatch, [%d, %d]\n",
				dev->dev_state, dev->hbm_state);
			return -EPROTO;
		}

		if (mei_hbm_me_cl_allocate(dev)) {
			dev_err(&dev->pdev->dev, "hbm: enumeration response: cannot allocate clients array\n");
			return -ENOMEM;
		}

		dev->hbm_state = MEI_HBM_CLIENT_PROPERTIES;

		/* first property request */
		if (mei_hbm_prop_req(dev))
			return -EIO;

		break;

	case HOST_STOP_RES_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: stop response: message received\n");

		dev->init_clients_timer = 0;

		if (dev->hbm_state != MEI_HBM_STOPPED) {
			dev_err(&dev->pdev->dev, "hbm: stop response: state mismatch, [%d, %d]\n",
				dev->dev_state, dev->hbm_state);
			return -EPROTO;
		}

		dev->dev_state = MEI_DEV_DISABLED;
		dev_info(&dev->pdev->dev, "hbm: stop response: resetting.\n");
		/* force the reset */
		return -EPROTO;
		break;

	case CLIENT_DISCONNECT_REQ_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: disconnect request: message received\n");

		disconnect_req = (struct hbm_client_connect_request *)mei_msg;
		mei_hbm_fw_disconnect_req(dev, disconnect_req);
		break;

	case ME_STOP_REQ_CMD:
		dev_dbg(&dev->pdev->dev, "hbm: stop request: message received\n");

		dev->hbm_state = MEI_HBM_STOPPED;
		mei_hbm_stop_req_prepare(dev, &dev->wr_ext_msg.hdr,
					dev->wr_ext_msg.data);
		break;
	default:
		BUG();
		break;

	}
	return 0;
}

