/*
 *
 * 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 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->mei_state = MEI_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->mei_state = MEI_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->mei_state = MEI_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->mei_state == MEI_RECOVERING_FROM_RESET) {
		dev->need_reset = true;
		return;
	}

	unexpected = (dev->mei_state != MEI_INITIALIZING &&
			dev->mei_state != MEI_DISABLED &&
			dev->mei_state != MEI_POWER_DOWN &&
			dev->mei_state != MEI_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->mei_state != MEI_INITIALIZING) {
		if (dev->mei_state != MEI_DISABLED &&
		    dev->mei_state != MEI_POWER_DOWN)
			dev->mei_state = MEI_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->stop = false;
	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.\n");

	/* 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->mei_state = MEI_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->mei_state = MEI_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->mei_state = MEI_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->mei_state = MEI_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_find_me_client_index(const struct mei_device *dev, uuid_le cuuid)
{
	int i, res = -1;

	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_find_me_client_update_filext - searches for ME client guid
 *                       sets client_id in mei_file_private if found
 * @dev: the device structure
 * @priv: private file structure to set client_id in
 * @cguid: searched guid of ME client
 * @client_id: id of host client to be set in file private structure
 *
 * returns ME client index
 */
u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv,
				const uuid_le *cguid, u8 client_id)
{
	int i;

	if (!dev || !priv || !cguid)
		return 0;

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

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

	return 0;
}

/**
 * host_init_iamthif - mei initialization iamthif client.
 *
 * @dev: the device structure
 *
 */
void mei_host_init_iamthif(struct mei_device *dev)
{
	u8 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_find_me_client_update_filext(dev, &dev->iamthif_cl,
			    &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
	if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) {
		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;
		}
	}
}
