/*
 *
 * 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/delay.h>

#include "mei_dev.h"
#include "hw.h"
#include "interface.h"
#include <linux/mei.h>

const char *mei_dev_state_str(int state)
{
#define MEI_DEV_STATE(state) case MEI_DEV_##state: return #state
	switch (state) {
	MEI_DEV_STATE(INITIALIZING);
	MEI_DEV_STATE(INIT_CLIENTS);
	MEI_DEV_STATE(ENABLED);
	MEI_DEV_STATE(RESETING);
	MEI_DEV_STATE(DISABLED);
	MEI_DEV_STATE(RECOVERING_FROM_RESET);
	MEI_DEV_STATE(POWER_DOWN);
	MEI_DEV_STATE(POWER_UP);
	default:
		return "unkown";
	}
#undef MEI_DEV_STATE
}


const uuid_le mei_amthi_guid  = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
						0xa8, 0x46, 0xe0, 0xff, 0x65,
						0x81, 0x4c);

/**
 * mei_io_list_init - Sets up a queue list.
 *
 * @list: An instance io list structure
 * @dev: the device structure
 */
void mei_io_list_init(struct mei_io_list *list)
{
	/* initialize our queue list */
	INIT_LIST_HEAD(&list->mei_cb.cb_list);
}

/**
 * mei_io_list_flush - removes list entry belonging to cl.
 *
 * @list:  An instance of our list structure
 * @cl: private data of the file object
 */
void mei_io_list_flush(struct mei_io_list *list, struct mei_cl *cl)
{
	struct mei_cl_cb *pos;
	struct mei_cl_cb *next;

	list_for_each_entry_safe(pos, next, &list->mei_cb.cb_list, cb_list) {
		if (pos->file_private) {
			struct mei_cl *cl_tmp;
			cl_tmp = (struct mei_cl *)pos->file_private;
			if (mei_cl_cmp_id(cl, cl_tmp))
				list_del(&pos->cb_list);
		}
	}
}
/**
 * mei_cl_flush_queues - flushes queue lists belonging to cl.
 *
 * @dev: the device structure
 * @cl: private data of the file object
 */
int mei_cl_flush_queues(struct mei_cl *cl)
{
	if (!cl || !cl->dev)
		return -EINVAL;

	dev_dbg(&cl->dev->pdev->dev, "remove list entry belonging to cl\n");
	mei_io_list_flush(&cl->dev->read_list, cl);
	mei_io_list_flush(&cl->dev->write_list, cl);
	mei_io_list_flush(&cl->dev->write_waiting_list, cl);
	mei_io_list_flush(&cl->dev->ctrl_wr_list, cl);
	mei_io_list_flush(&cl->dev->ctrl_rd_list, cl);
	mei_io_list_flush(&cl->dev->amthi_cmd_list, cl);
	mei_io_list_flush(&cl->dev->amthi_read_complete_list, cl);
	return 0;
}



/**
 * mei_reset_iamthif_params - initializes mei device iamthif
 *
 * @dev: the device structure
 */
static void mei_reset_iamthif_params(struct mei_device *dev)
{
	/* reset iamthif parameters. */
	dev->iamthif_current_cb = NULL;
	dev->iamthif_msg_buf_size = 0;
	dev->iamthif_msg_buf_index = 0;
	dev->iamthif_canceled = false;
	dev->iamthif_ioctl = false;
	dev->iamthif_state = MEI_IAMTHIF_IDLE;
	dev->iamthif_timer = 0;
}

/**
 * init_mei_device - allocates and initializes the mei device structure
 *
 * @pdev: The pci device structure
 *
 * returns The mei_device_device pointer on success, NULL on failure.
 */
struct mei_device *mei_device_init(struct pci_dev *pdev)
{
	struct mei_device *dev;

	dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL);
	if (!dev)
		return NULL;

	/* setup our list array */
	INIT_LIST_HEAD(&dev->file_list);
	INIT_LIST_HEAD(&dev->wd_cl.link);
	INIT_LIST_HEAD(&dev->iamthif_cl.link);
	mutex_init(&dev->device_lock);
	init_waitqueue_head(&dev->wait_recvd_msg);
	init_waitqueue_head(&dev->wait_stop_wd);
	dev->dev_state = MEI_DEV_INITIALIZING;
	dev->iamthif_state = MEI_IAMTHIF_IDLE;
	dev->wd_interface_reg = false;


	mei_io_list_init(&dev->read_list);
	mei_io_list_init(&dev->write_list);
	mei_io_list_init(&dev->write_waiting_list);
	mei_io_list_init(&dev->ctrl_wr_list);
	mei_io_list_init(&dev->ctrl_rd_list);
	mei_io_list_init(&dev->amthi_cmd_list);
	mei_io_list_init(&dev->amthi_read_complete_list);
	dev->pdev = pdev;
	return dev;
}

/**
 * mei_hw_init - initializes host and fw to start work.
 *
 * @dev: the device structure
 *
 * returns 0 on success, <0 on failure.
 */
int mei_hw_init(struct mei_device *dev)
{
	int err = 0;
	int ret;

	mutex_lock(&dev->device_lock);

	dev->host_hw_state = mei_hcsr_read(dev);
	dev->me_hw_state = mei_mecsr_read(dev);
	dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n",
	    dev->host_hw_state, dev->me_hw_state);

	/* acknowledge interrupt and stop interupts */
	if ((dev->host_hw_state & H_IS) == H_IS)
		mei_reg_write(dev, H_CSR, dev->host_hw_state);

	/* Doesn't change in runtime */
	dev->hbuf_depth = (dev->host_hw_state & H_CBD) >> 24;

	dev->recvd_msg = false;
	dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");

	mei_reset(dev, 1);

	dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
	    dev->host_hw_state, dev->me_hw_state);

	/* wait for ME to turn on ME_RDY */
	if (!dev->recvd_msg) {
		mutex_unlock(&dev->device_lock);
		err = wait_event_interruptible_timeout(dev->wait_recvd_msg,
			dev->recvd_msg, MEI_INTEROP_TIMEOUT);
		mutex_lock(&dev->device_lock);
	}

	if (err <= 0 && !dev->recvd_msg) {
		dev->dev_state = MEI_DEV_DISABLED;
		dev_dbg(&dev->pdev->dev,
			"wait_event_interruptible_timeout failed"
			"on wait for ME to turn on ME_RDY.\n");
		ret = -ENODEV;
		goto out;
	}

	if (!(((dev->host_hw_state & H_RDY) == H_RDY) &&
	      ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
		dev->dev_state = MEI_DEV_DISABLED;
		dev_dbg(&dev->pdev->dev,
			"host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
			dev->host_hw_state, dev->me_hw_state);

		if (!(dev->host_hw_state & H_RDY))
			dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n");

		if (!(dev->me_hw_state & ME_RDY_HRA))
			dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n");

		dev_err(&dev->pdev->dev, "link layer initialization failed.\n");
		ret = -ENODEV;
		goto out;
	}

	if (dev->version.major_version != HBM_MAJOR_VERSION ||
	    dev->version.minor_version != HBM_MINOR_VERSION) {
		dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
		ret = -ENODEV;
		goto out;
	}

	dev->recvd_msg = false;
	dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
	    dev->host_hw_state, dev->me_hw_state);
	dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n");
	dev_dbg(&dev->pdev->dev, "link layer has been established.\n");
	dev_dbg(&dev->pdev->dev, "MEI  start success.\n");
	ret = 0;

out:
	mutex_unlock(&dev->device_lock);
	return ret;
}

/**
 * mei_hw_reset - resets fw via mei csr register.
 *
 * @dev: the device structure
 * @interrupts_enabled: if interrupt should be enabled after reset.
 */
static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled)
{
	dev->host_hw_state |= (H_RST | H_IG);

	if (interrupts_enabled)
		mei_enable_interrupts(dev);
	else
		mei_disable_interrupts(dev);
}

/**
 * mei_reset - resets host and fw.
 *
 * @dev: the device structure
 * @interrupts_enabled: if interrupt should be enabled after reset.
 */
void mei_reset(struct mei_device *dev, int interrupts_enabled)
{
	struct mei_cl *cl_pos = NULL;
	struct mei_cl *cl_next = NULL;
	struct mei_cl_cb *cb_pos = NULL;
	struct mei_cl_cb *cb_next = NULL;
	bool unexpected;

	if (dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
		dev->need_reset = true;
		return;
	}

	unexpected = (dev->dev_state != MEI_DEV_INITIALIZING &&
			dev->dev_state != MEI_DEV_DISABLED &&
			dev->dev_state != MEI_DEV_POWER_DOWN &&
			dev->dev_state != MEI_DEV_POWER_UP);

	dev->host_hw_state = mei_hcsr_read(dev);

	dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n",
	    dev->host_hw_state);

	mei_hw_reset(dev, interrupts_enabled);

	dev->host_hw_state &= ~H_RST;
	dev->host_hw_state |= H_IG;

	mei_hcsr_set(dev);

	dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n",
	    dev->host_hw_state);

	dev->need_reset = false;

	if (dev->dev_state != MEI_DEV_INITIALIZING) {
		if (dev->dev_state != MEI_DEV_DISABLED &&
		    dev->dev_state != MEI_DEV_POWER_DOWN)
			dev->dev_state = MEI_DEV_RESETING;

		list_for_each_entry_safe(cl_pos,
				cl_next, &dev->file_list, link) {
			cl_pos->state = MEI_FILE_DISCONNECTED;
			cl_pos->mei_flow_ctrl_creds = 0;
			cl_pos->read_cb = NULL;
			cl_pos->timer_count = 0;
		}
		/* remove entry if already in list */
		dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n");
		mei_remove_client_from_file_list(dev,
				dev->wd_cl.host_client_id);

		mei_remove_client_from_file_list(dev,
				dev->iamthif_cl.host_client_id);

		mei_reset_iamthif_params(dev);
		dev->extra_write_index = 0;
	}

	dev->me_clients_num = 0;
	dev->rd_msg_hdr = 0;
	dev->wd_pending = false;

	/* update the state of the registers after reset */
	dev->host_hw_state = mei_hcsr_read(dev);
	dev->me_hw_state = mei_mecsr_read(dev);

	dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
	    dev->host_hw_state, dev->me_hw_state);

	if (unexpected)
		dev_warn(&dev->pdev->dev, "unexpected reset: dev_state = %s\n",
			 mei_dev_state_str(dev->dev_state));

	/* Wake up all readings so they can be interrupted */
	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
		if (waitqueue_active(&cl_pos->rx_wait)) {
			dev_dbg(&dev->pdev->dev, "Waking up client!\n");
			wake_up_interruptible(&cl_pos->rx_wait);
		}
	}
	/* remove all waiting requests */
	list_for_each_entry_safe(cb_pos, cb_next,
			&dev->write_list.mei_cb.cb_list, cb_list) {
		list_del(&cb_pos->cb_list);
		mei_free_cb_private(cb_pos);
	}
}



/**
 * host_start_message - mei host sends start message.
 *
 * @dev: the device structure
 *
 * returns none.
 */
void mei_host_start_message(struct mei_device *dev)
{
	struct mei_msg_hdr *mei_hdr;
	struct hbm_host_version_request *host_start_req;

	/* host start message */
	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
	mei_hdr->host_addr = 0;
	mei_hdr->me_addr = 0;
	mei_hdr->length = sizeof(struct hbm_host_version_request);
	mei_hdr->msg_complete = 1;
	mei_hdr->reserved = 0;

	host_start_req =
	    (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
	memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
	host_start_req->hbm_cmd = HOST_START_REQ_CMD;
	host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
	host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
	dev->recvd_msg = false;
	if (mei_write_message(dev, mei_hdr, (unsigned char *)host_start_req,
				       mei_hdr->length)) {
		dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
		dev->dev_state = MEI_DEV_RESETING;
		mei_reset(dev, 1);
	}
	dev->init_clients_state = MEI_START_MESSAGE;
	dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
	return ;
}

/**
 * host_enum_clients_message - host sends enumeration client request message.
 *
 * @dev: the device structure
 *
 * returns none.
 */
void mei_host_enum_clients_message(struct mei_device *dev)
{
	struct mei_msg_hdr *mei_hdr;
	struct hbm_host_enum_request *host_enum_req;
	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
	/* enumerate clients */
	mei_hdr->host_addr = 0;
	mei_hdr->me_addr = 0;
	mei_hdr->length = sizeof(struct hbm_host_enum_request);
	mei_hdr->msg_complete = 1;
	mei_hdr->reserved = 0;

	host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
	memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
	host_enum_req->hbm_cmd = HOST_ENUM_REQ_CMD;
	if (mei_write_message(dev, mei_hdr, (unsigned char *)host_enum_req,
				mei_hdr->length)) {
		dev->dev_state = MEI_DEV_RESETING;
		dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
		mei_reset(dev, 1);
	}
	dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
	dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
	return;
}


/**
 * allocate_me_clients_storage - allocates storage for me clients
 *
 * @dev: the device structure
 *
 * returns none.
 */
void mei_allocate_me_clients_storage(struct mei_device *dev)
{
	struct mei_me_client *clients;
	int b;

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


	if (dev->me_clients != NULL) {
		kfree(dev->me_clients);
		dev->me_clients = NULL;
	}
	dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\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_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
		dev->dev_state = MEI_DEV_RESETING;
		mei_reset(dev, 1);
		return ;
	}
	dev->me_clients = clients;
	return ;
}
/**
 * host_client_properties - reads properties for client
 *
 * @dev: the device structure
 *
 * returns:
 * 	< 0 - Error.
 *  = 0 - no more clients.
 *  = 1 - still have clients to send properties request.
 */
int mei_host_client_properties(struct mei_device *dev)
{
	struct mei_msg_hdr *mei_header;
	struct hbm_props_request *host_cli_req;
	int b;
	u8 client_num = dev->me_client_presentation_num;

	b = dev->me_client_index;
	b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b);
	if (b < MEI_CLIENTS_MAX) {
		dev->me_clients[client_num].client_id = b;
		dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
		mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
		mei_header->host_addr = 0;
		mei_header->me_addr = 0;
		mei_header->length = sizeof(struct hbm_props_request);
		mei_header->msg_complete = 1;
		mei_header->reserved = 0;

		host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];

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

		host_cli_req->hbm_cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
		host_cli_req->address = b;

		if (mei_write_message(dev, mei_header,
				(unsigned char *)host_cli_req,
				mei_header->length)) {
			dev->dev_state = MEI_DEV_RESETING;
			dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
			mei_reset(dev, 1);
			return -EIO;
		}

		dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
		dev->me_client_index = b;
		return 1;
	}

	return 0;
}

/**
 * mei_init_file_private - initializes private file structure.
 *
 * @priv: private file structure to be initialized
 * @file: the file structure
 */
void mei_cl_init(struct mei_cl *priv, struct mei_device *dev)
{
	memset(priv, 0, sizeof(struct mei_cl));
	init_waitqueue_head(&priv->wait);
	init_waitqueue_head(&priv->rx_wait);
	init_waitqueue_head(&priv->tx_wait);
	INIT_LIST_HEAD(&priv->link);
	priv->reading_state = MEI_IDLE;
	priv->writing_state = MEI_IDLE;
	priv->dev = dev;
}

int mei_me_cl_by_uuid(const struct mei_device *dev, const uuid_le *cuuid)
{
	int i, res = -ENOENT;

	for (i = 0; i < dev->me_clients_num; ++i)
		if (uuid_le_cmp(*cuuid,
				dev->me_clients[i].props.protocol_name) == 0) {
			res = i;
			break;
		}

	return res;
}


/**
 * mei_me_cl_update_filext - searches for ME client guid
 *                       sets client_id in mei_file_private if found
 * @dev: the device structure
 * @cl: private file structure to set client_id in
 * @cuuid: searched uuid of ME client
 * @client_id: id of host client to be set in file private structure
 *
 * returns ME client index
 */
int mei_me_cl_update_filext(struct mei_device *dev, struct mei_cl *cl,
				const uuid_le *cuuid, u8 host_cl_id)
{
	int i;

	if (!dev || !cl || !cuuid)
		return -EINVAL;

	/* check for valid client id */
	i = mei_me_cl_by_uuid(dev, cuuid);
	if (i >= 0) {
		cl->me_client_id = dev->me_clients[i].client_id;
		cl->state = MEI_FILE_CONNECTING;
		cl->host_client_id = host_cl_id;

		list_add_tail(&cl->link, &dev->file_list);
		return (u8)i;
	}

	return -ENOENT;
}

/**
 * host_init_iamthif - mei initialization iamthif client.
 *
 * @dev: the device structure
 *
 */
void mei_host_init_iamthif(struct mei_device *dev)
{
	int i;
	unsigned char *msg_buf;

	mei_cl_init(&dev->iamthif_cl, dev);
	dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;

	/* find ME amthi client */
	i = mei_me_cl_update_filext(dev, &dev->iamthif_cl,
			    &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
	if (i < 0) {
		dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n");
		return;
	}

	/* Assign iamthif_mtu to the value received from ME  */

	dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
	dev_dbg(&dev->pdev->dev, "IAMTHIF_MTU = %d\n",
			dev->me_clients[i].props.max_msg_length);

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

	/* allocate storage for ME message buffer */
	msg_buf = kcalloc(dev->iamthif_mtu,
			sizeof(unsigned char), GFP_KERNEL);
	if (!msg_buf) {
		dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n");
		return;
	}

	dev->iamthif_msg_buf = msg_buf;

	if (mei_connect(dev, &dev->iamthif_cl)) {
		dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n");
		dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
		dev->iamthif_cl.host_client_id = 0;
	} else {
		dev->iamthif_cl.timer_count = CONNECT_TIMEOUT;
	}
}

/**
 * mei_alloc_file_private - allocates a private file structure and sets it up.
 * @file: the file structure
 *
 * returns  The allocated file or NULL on failure
 */
struct mei_cl *mei_cl_allocate(struct mei_device *dev)
{
	struct mei_cl *cl;

	cl = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
	if (!cl)
		return NULL;

	mei_cl_init(cl, dev);

	return cl;
}



/**
 * mei_disconnect_host_client - sends disconnect message to fw from host client.
 *
 * @dev: the device structure
 * @cl: private data of the file object
 *
 * Locking: called under "dev->device_lock" lock
 *
 * returns 0 on success, <0 on failure.
 */
int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
{
	int rets, err;
	long timeout = 15;	/* 15 seconds */
	struct mei_cl_cb *cb;

	if (!dev || !cl)
		return -ENODEV;

	if (cl->state != MEI_FILE_DISCONNECTING)
		return 0;

	cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
	if (!cb)
		return -ENOMEM;

	INIT_LIST_HEAD(&cb->cb_list);
	cb->file_private = cl;
	cb->major_file_operations = MEI_CLOSE;
	if (dev->mei_host_buffer_is_empty) {
		dev->mei_host_buffer_is_empty = false;
		if (mei_disconnect(dev, cl)) {
			rets = -ENODEV;
			dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n");
			goto free;
		}
		mdelay(10); /* Wait for hardware disconnection ready */
		list_add_tail(&cb->cb_list, &dev->ctrl_rd_list.mei_cb.cb_list);
	} else {
		dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
		list_add_tail(&cb->cb_list,
				&dev->ctrl_wr_list.mei_cb.cb_list);
	}
	mutex_unlock(&dev->device_lock);

	err = wait_event_timeout(dev->wait_recvd_msg,
		 (MEI_FILE_DISCONNECTED == cl->state),
		 timeout * HZ);

	mutex_lock(&dev->device_lock);
	if (MEI_FILE_DISCONNECTED == cl->state) {
		rets = 0;
		dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
	} else {
		rets = -ENODEV;
		if (MEI_FILE_DISCONNECTED != cl->state)
			dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");

		if (err)
			dev_dbg(&dev->pdev->dev,
					"wait failed disconnect err=%08x\n",
					err);

		dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
	}

	mei_io_list_flush(&dev->ctrl_rd_list, cl);
	mei_io_list_flush(&dev->ctrl_wr_list, cl);
free:
	mei_free_cb_private(cb);
	return rets;
}

/**
 * mei_remove_client_from_file_list -
 *	removes file private data from device file list
 *
 * @dev: the device structure
 * @host_client_id: host client id to be removed
 */
void mei_remove_client_from_file_list(struct mei_device *dev,
				       u8 host_client_id)
{
	struct mei_cl *cl_pos = NULL;
	struct mei_cl *cl_next = NULL;
	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
		if (host_client_id == cl_pos->host_client_id) {
			dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
					cl_pos->host_client_id,
					cl_pos->me_client_id);
			list_del_init(&cl_pos->link);
			break;
		}
	}
}
