/*
 * Part of Intel(R) Manageability Engine Interface Linux driver
 *
 * Copyright (c) 2003 - 2008 Intel Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/aio.h>
#include <linux/pci.h>
#include <linux/reboot.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/list.h>
#include <linux/unistd.h>
#include <linux/delay.h>

#include "heci_data_structures.h"
#include "heci.h"
#include "heci_interface.h"
#include "heci_version.h"


/**
 * heci_ioctl_get_version - the get driver version IOCTL function
 *
 * @dev: Device object for our driver
 * @if_num:  minor number
 * @*u_msg: pointer to user data struct in user space
 * @k_msg: data in kernel on the stack
 * @file_ext: private data of the file object
 *
 * returns 0 on success, <0 on failure.
 */
int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
			   struct heci_message_data __user *u_msg,
			   struct heci_message_data k_msg,
			   struct heci_file_private *file_ext)
{
	int rets = 0;
	struct heci_driver_version *version;
	struct heci_message_data res_msg;

	if ((if_num != HECI_MINOR_NUMBER) || (!dev)
	    || (!file_ext))
		return -ENODEV;

	if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) {
		DBG("user buffer less than heci_driver_version.\n");
		return -EMSGSIZE;
	}

	res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL);
	if (!res_msg.data) {
		DBG("failed allocation response buffer size = %d.\n",
		    (int) sizeof(struct heci_driver_version));
		return -ENOMEM;
	}

	version = (struct heci_driver_version *) res_msg.data;
	version->major = MAJOR_VERSION;
	version->minor = MINOR_VERSION;
	version->hotfix = QUICK_FIX_NUMBER;
	version->build = VER_BUILD;
	res_msg.size = sizeof(struct heci_driver_version);
	if (k_msg.size < sizeof(struct heci_driver_version))
		res_msg.size -= 2;

	rets = file_ext->status;
	/* now copy the data to user space */
	if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
		rets = -EFAULT;
		goto end;
	}
	if (put_user(res_msg.size, &u_msg->size)) {
		rets = -EFAULT;
		goto end;
	}
end:
	kfree(res_msg.data);
	return rets;
}

/**
 * heci_ioctl_connect_client - the connect to fw client IOCTL function
 *
 * @dev: Device object for our driver
 * @if_num:  minor number
 * @*u_msg: pointer to user data struct in user space
 * @k_msg: data in kernel on the stack
 * @file_ext: private data of the file object
 *
 * returns 0 on success, <0 on failure.
 */
int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
			      struct heci_message_data __user *u_msg,
			      struct heci_message_data k_msg,
			      struct file *file)
{
	int rets = 0;
	struct heci_message_data req_msg, res_msg;
	struct heci_cb_private *priv_cb = NULL;
	struct heci_client *client;
	struct heci_file_private *file_ext;
	struct heci_file_private *file_pos = NULL;
	struct heci_file_private *file_next = NULL;
	long timeout = 15;	/*15 second */
	__u8 i;
	int err = 0;

	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file))
		return -ENODEV;

	file_ext = file->private_data;
	if (!file_ext)
		return -ENODEV;

	if (k_msg.size != sizeof(struct guid)) {
		DBG("user buffer size is not equal to size of struct "
				"guid(16).\n");
		return -EMSGSIZE;
	}

	if (!k_msg.data)
		return -EIO;

	req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL);
	res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL);

	if (!res_msg.data) {
		DBG("failed allocation response buffer size = %d.\n",
		    (int) sizeof(struct heci_client));
		kfree(req_msg.data);
		return -ENOMEM;
	}
	if (!req_msg.data) {
		DBG("failed allocation request buffer size = %d.\n",
		    (int) sizeof(struct guid));
		kfree(res_msg.data);
		return -ENOMEM;
	}
	req_msg.size = sizeof(struct guid);
	res_msg.size = sizeof(struct heci_client);

	/* copy the message to kernel space -
	 * use a pointer already copied into kernel space
	 */
	if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) {
		rets = -EFAULT;
		goto end;
	}
	/* buffered ioctl cb */
	priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
	if (!priv_cb) {
		rets = -ENOMEM;
		goto end;
	}
	INIT_LIST_HEAD(&priv_cb->cb_list);
	priv_cb->response_buffer.data = res_msg.data;
	priv_cb->response_buffer.size = res_msg.size;
	priv_cb->request_buffer.data = req_msg.data;
	priv_cb->request_buffer.size = req_msg.size;
	priv_cb->major_file_operations = HECI_IOCTL;
	spin_lock_bh(&dev->device_lock);
	if (dev->heci_state != HECI_ENABLED) {
		rets = -ENODEV;
		spin_unlock_bh(&dev->device_lock);
		goto end;
	}
	if ((file_ext->state != HECI_FILE_INITIALIZING) &&
	    (file_ext->state != HECI_FILE_DISCONNECTED)) {
		rets = -EBUSY;
		spin_unlock_bh(&dev->device_lock);
		goto end;
	}

	/* find ME client we're trying to connect to */
	for (i = 0; i < dev->num_heci_me_clients; i++) {
		if (memcmp((struct guid *)req_msg.data,
			    &dev->me_clients[i].props.protocol_name,
			    sizeof(struct guid)) == 0) {
			if (dev->me_clients[i].props.fixed_address == 0) {
				file_ext->me_client_id =
				    dev->me_clients[i].client_id;
				file_ext->state = HECI_FILE_CONNECTING;
			}
			break;
		}
	}
	/* if we're connecting to PTHI client so we will use the exist
	 * connection
	 */
	if (memcmp((struct guid *)req_msg.data, &heci_pthi_guid,
				sizeof(struct guid)) == 0) {
		if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
			rets = -ENODEV;
			spin_unlock_bh(&dev->device_lock);
			goto end;
		}
		dev->heci_host_clients[file_ext->host_client_id / 8] &=
			~(1 << (file_ext->host_client_id % 8));
		list_for_each_entry_safe(file_pos,
		    file_next, &dev->file_list, link) {
			if (heci_fe_same_id(file_ext, file_pos)) {
				DBG("remove file private data node host"
				    " client = %d, ME client = %d.\n",
				    file_pos->host_client_id,
				    file_pos->me_client_id);
				list_del(&file_pos->link);
			}

		}
		DBG("free file private data memory.\n");
		kfree(file_ext);
		file_ext = NULL;
		file->private_data = &dev->iamthif_file_ext;
		client = (struct heci_client *) res_msg.data;
		client->max_msg_length =
			dev->me_clients[i].props.max_msg_length;
		client->protocol_version =
			dev->me_clients[i].props.protocol_version;
		rets = dev->iamthif_file_ext.status;
		spin_unlock_bh(&dev->device_lock);

		/* now copy the data to user space */
		if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
			rets = -EFAULT;
			goto end;
		}
		if (put_user(res_msg.size, &u_msg->size)) {
			rets = -EFAULT;
			goto end;
		}
		goto end;
	}
	spin_lock(&file_ext->file_lock);
	if (file_ext->state != HECI_FILE_CONNECTING) {
		rets = -ENODEV;
		spin_unlock(&file_ext->file_lock);
		spin_unlock_bh(&dev->device_lock);
		goto end;
	}
	spin_unlock(&file_ext->file_lock);
	/* prepare the output buffer */
	client = (struct heci_client *) res_msg.data;
	client->max_msg_length = dev->me_clients[i].props.max_msg_length;
	client->protocol_version = dev->me_clients[i].props.protocol_version;
	if (dev->host_buffer_is_empty
	    && !other_client_is_connecting(dev, file_ext)) {
		dev->host_buffer_is_empty = 0;
		if (!heci_connect(dev, file_ext)) {
			rets = -ENODEV;
			spin_unlock_bh(&dev->device_lock);
			goto end;
		} else {
			file_ext->timer_count = HECI_CONNECT_TIMEOUT;
			priv_cb->file_private = file_ext;
			list_add_tail(&priv_cb->cb_list,
				      &dev->ctrl_rd_list.heci_cb.
				      cb_list);
		}


	} else {
		priv_cb->file_private = file_ext;
		DBG("add connect cb to control write list.\n");
		list_add_tail(&priv_cb->cb_list,
			      &dev->ctrl_wr_list.heci_cb.cb_list);
	}
	spin_unlock_bh(&dev->device_lock);
	err = wait_event_timeout(dev->wait_recvd_msg,
			(HECI_FILE_CONNECTED == file_ext->state
			 || HECI_FILE_DISCONNECTED == file_ext->state),
			timeout * HZ);

	if (HECI_FILE_CONNECTED == file_ext->state) {
		DBG("successfully connected to FW client.\n");
		rets = file_ext->status;
		/* now copy the data to user space */
		if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
			rets = -EFAULT;
			goto end;
		}
		if (put_user(res_msg.size, &u_msg->size)) {
			rets = -EFAULT;
			goto end;
		}
		goto end;
	} else {
		DBG("failed to connect to FW client.file_ext->state = %d.\n",
		    file_ext->state);
		if (!err) {
			DBG("wait_event_interruptible_timeout failed on client"
			    " connect message fw response message.\n");
		}
		rets = -EFAULT;
		goto remove_list;
	}

remove_list:
	if (priv_cb) {
		spin_lock_bh(&dev->device_lock);
		heci_flush_list(&dev->ctrl_rd_list, file_ext);
		heci_flush_list(&dev->ctrl_wr_list, file_ext);
		spin_unlock_bh(&dev->device_lock);
	}
end:
	DBG("free connect cb memory.");
	kfree(req_msg.data);
	kfree(res_msg.data);
	kfree(priv_cb);
	return rets;
}

/**
 * heci_ioctl_wd  - the wd IOCTL function
 *
 * @dev: Device object for our driver
 * @if_num:  minor number
 * @k_msg: data in kernel on the stack
 * @file_ext: private data of the file object
 *
 * returns 0 on success, <0 on failure.
 */
int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
		  struct heci_message_data k_msg,
		  struct heci_file_private *file_ext)
{
	int rets = 0;
	struct heci_message_data req_msg;	/*in kernel on the stack */

	if (if_num != HECI_MINOR_NUMBER)
		return -ENODEV;

	spin_lock(&file_ext->file_lock);
	if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) {
		DBG("user buffer has invalid size.\n");
		spin_unlock(&file_ext->file_lock);
		return -EMSGSIZE;
	}
	spin_unlock(&file_ext->file_lock);

	req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL);
	if (!req_msg.data) {
		DBG("failed allocation request buffer size = %d.\n",
		    HECI_WATCHDOG_DATA_SIZE);
		return -ENOMEM;
	}
	req_msg.size = HECI_WATCHDOG_DATA_SIZE;

	/* copy the message to kernel space - use a pointer already
	 * copied into kernel space
	 */
	if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) {
		rets = -EFAULT;
		goto end;
	}
	spin_lock_bh(&dev->device_lock);
	if (dev->heci_state != HECI_ENABLED) {
		rets = -ENODEV;
		spin_unlock_bh(&dev->device_lock);
		goto end;
	}

	if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
		rets = -ENODEV;
		spin_unlock_bh(&dev->device_lock);
		goto end;
	}
	if (!dev->asf_mode) {
		rets = -EIO;
		spin_unlock_bh(&dev->device_lock);
		goto end;
	}

	memcpy(&dev->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data,
	       HECI_WATCHDOG_DATA_SIZE);

	dev->wd_timeout = (req_msg.data[1] << 8) + req_msg.data[0];
	dev->wd_pending = 0;
	dev->wd_due_counter = 1;	/* next timer */
	if (dev->wd_timeout == 0) {
		memcpy(dev->wd_data, heci_stop_wd_params,
		       HECI_WD_PARAMS_SIZE);
	} else {
		memcpy(dev->wd_data, heci_start_wd_params,
		       HECI_WD_PARAMS_SIZE);
		mod_timer(&dev->wd_timer, jiffies);
	}
	spin_unlock_bh(&dev->device_lock);
end:
	kfree(req_msg.data);
	return rets;
}


/**
 * heci_ioctl_bypass_wd  - the bypass_wd IOCTL function
 *
 * @dev: Device object for our driver
 * @if_num:  minor number
 * @k_msg: data in kernel on the stack
 * @file_ext: private data of the file object
 *
 * returns 0 on success, <0 on failure.
 */
int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
		  struct heci_message_data k_msg,
		  struct heci_file_private *file_ext)
{
	__u8 flag = 0;
	int rets = 0;

	if (if_num != HECI_MINOR_NUMBER)
		return -ENODEV;

	spin_lock(&file_ext->file_lock);
	if (k_msg.size < 1) {
		DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE.\n");
		spin_unlock(&file_ext->file_lock);
		return -EMSGSIZE;
	}
	spin_unlock(&file_ext->file_lock);
	if (copy_from_user(&flag, k_msg.data, 1)) {
		rets = -EFAULT;
		goto end;
	}

	spin_lock_bh(&dev->device_lock);
	flag = flag ? (1) : (0);
	dev->wd_bypass = flag;
	spin_unlock_bh(&dev->device_lock);
end:
	return rets;
}

/**
 * find_pthi_read_list_entry - finds a PTHIlist entry for current file
 *
 * @dev: Device object for our driver
 * @file: pointer to file object
 *
 * returns   returned a list entry on success, NULL on failure.
 */
struct heci_cb_private *find_pthi_read_list_entry(
		struct iamt_heci_device *dev,
		struct file *file)
{
	struct heci_file_private *file_ext_temp;
	struct heci_cb_private *priv_cb_pos = NULL;
	struct heci_cb_private *priv_cb_next = NULL;

	if ((dev->pthi_read_complete_list.status == 0) &&
	    !list_empty(&dev->pthi_read_complete_list.heci_cb.cb_list)) {
		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
		    &dev->pthi_read_complete_list.heci_cb.cb_list, cb_list) {
			file_ext_temp = (struct heci_file_private *)
					priv_cb_pos->file_private;
			if ((file_ext_temp != NULL) &&
			    (file_ext_temp == &dev->iamthif_file_ext) &&
			    (priv_cb_pos->file_object == file))
				return priv_cb_pos;
		}
	}
	return NULL;
}

/**
 * pthi_read - read data from pthi client
 *
 * @dev: Device object for our driver
 * @if_num:  minor number
 * @file: pointer to file object
 * @*ubuf: pointer to user data in user space
 * @length: data length to read
 * @offset: data read offset
 *
 * returns
 *  returned data length on success,
 *  zero if no data to read,
 *  negative on failure.
 */
int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
	      char __user *ubuf, size_t length, loff_t *offset)
{
	int rets = 0;
	struct heci_cb_private *priv_cb = NULL;
	struct heci_file_private *file_ext = file->private_data;
	__u8 i;
	unsigned long currtime = get_seconds();

	if ((if_num != HECI_MINOR_NUMBER) || (!dev))
		return -ENODEV;

	if ((file_ext == NULL) || (file_ext != &dev->iamthif_file_ext))
		return -ENODEV;

	spin_lock_bh(&dev->device_lock);
	for (i = 0; i < dev->num_heci_me_clients; i++) {
		if (dev->me_clients[i].client_id ==
		    dev->iamthif_file_ext.me_client_id)
			break;
	}
	BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
	if ((i == dev->num_heci_me_clients)
	    || (dev->me_clients[i].client_id !=
		dev->iamthif_file_ext.me_client_id)) {
		DBG("PTHI client not found.\n");
		spin_unlock_bh(&dev->device_lock);
		return -ENODEV;
	}
	priv_cb = find_pthi_read_list_entry(dev, file);
	if (!priv_cb) {
		spin_unlock_bh(&dev->device_lock);
		return 0; /* No more data to read */
	} else {
		if (priv_cb &&
		    (currtime - priv_cb->read_time > IAMTHIF_READ_TIMER)) {
			/* 15 sec for the message has expired */
			list_del(&priv_cb->cb_list);
			spin_unlock_bh(&dev->device_lock);
			rets = -ETIMEDOUT;
			goto free;
		}
		/* if the whole message will fit remove it from the list */
		if ((priv_cb->information >= *offset)  &&
		    (length >= (priv_cb->information - *offset)))
			list_del(&priv_cb->cb_list);
		else if ((priv_cb->information > 0) &&
		    (priv_cb->information <= *offset)) {
			/* end of the message has been reached */
			list_del(&priv_cb->cb_list);
			rets = 0;
			spin_unlock_bh(&dev->device_lock);
			goto free;
		}
		/* else means that not full buffer will be read and do not
		 * remove message from deletion list
		 */
	}
	DBG("pthi priv_cb->response_buffer size - %d\n",
	    priv_cb->response_buffer.size);
	DBG("pthi priv_cb->information - %lu\n",
	    priv_cb->information);
	spin_unlock_bh(&dev->device_lock);

	/* length is being turncated to PAGE_SIZE, however,
	 * the information may be longer */
	length = length < (priv_cb->information - *offset) ?
			length : (priv_cb->information - *offset);

	if (copy_to_user(ubuf,
			 priv_cb->response_buffer.data + *offset,
			 length))
		rets = -EFAULT;
	else {
		rets = length;
		if ((*offset + length) < priv_cb->information) {
			*offset += length;
			goto out;
		}
	}
free:
	DBG("free pthi cb memory.\n");
	*offset = 0;
	heci_free_cb_private(priv_cb);
out:
	return rets;
}

/**
 * heci_start_read  - the start read client message function.
 *
 * @dev: Device object for our driver
 * @if_num:  minor number
 * @file_ext: private data of the file object
 *
 * returns 0 on success, <0 on failure.
 */
int heci_start_read(struct iamt_heci_device *dev, int if_num,
		    struct heci_file_private *file_ext)
{
	int rets = 0;
	__u8 i;
	struct heci_cb_private *priv_cb = NULL;

	if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) {
		DBG("received wrong function input param.\n");
		return -ENODEV;
	}
	if (file_ext->state != HECI_FILE_CONNECTED)
		return -ENODEV;

	spin_lock_bh(&dev->device_lock);
	if (dev->heci_state != HECI_ENABLED) {
		spin_unlock_bh(&dev->device_lock);
		return -ENODEV;
	}
	spin_unlock_bh(&dev->device_lock);
	DBG("check if read is pending.\n");
	if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
		DBG("read is pending.\n");
		return -EBUSY;
	}
	priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
	if (!priv_cb)
		return -ENOMEM;

	DBG("allocation call back success\n"
	    "host client = %d, ME client = %d\n",
	    file_ext->host_client_id, file_ext->me_client_id);
	spin_lock_bh(&dev->device_lock);
	for (i = 0; i < dev->num_heci_me_clients; i++) {
		if (dev->me_clients[i].client_id == file_ext->me_client_id)
			break;

	}

	BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
	if (i == dev->num_heci_me_clients) {
		rets = -ENODEV;
		goto unlock;
	}

	priv_cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
	spin_unlock_bh(&dev->device_lock);
	priv_cb->response_buffer.data =
	    kmalloc(priv_cb->response_buffer.size, GFP_KERNEL);
	if (!priv_cb->response_buffer.data) {
		rets = -ENOMEM;
		goto fail;
	}
	DBG("allocation call back data success.\n");
	priv_cb->major_file_operations = HECI_READ;
	/* make sure information is zero before we start */
	priv_cb->information = 0;
	priv_cb->file_private = (void *) file_ext;
	file_ext->read_cb = priv_cb;
	spin_lock_bh(&dev->device_lock);
	if (dev->host_buffer_is_empty) {
		dev->host_buffer_is_empty = 0;
		if (!heci_send_flow_control(dev, file_ext)) {
			rets = -ENODEV;
			goto unlock;
		} else {
			list_add_tail(&priv_cb->cb_list,
				      &dev->read_list.heci_cb.cb_list);
		}
	} else {
		list_add_tail(&priv_cb->cb_list,
			      &dev->ctrl_wr_list.heci_cb.cb_list);
	}
	spin_unlock_bh(&dev->device_lock);
	return rets;
unlock:
	spin_unlock_bh(&dev->device_lock);
fail:
	heci_free_cb_private(priv_cb);
	return rets;
}

/**
 * pthi_write - write iamthif data to pthi client
 *
 * @dev: Device object for our driver
 * @priv_cb: heci call back struct
 *
 * returns 0 on success, <0 on failure.
 */
int pthi_write(struct iamt_heci_device *dev,
	       struct heci_cb_private *priv_cb)
{
	int rets = 0;
	struct heci_msg_hdr heci_hdr;

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

	DBG("write data to pthi client.\n");

	dev->iamthif_state = HECI_IAMTHIF_WRITING;
	dev->iamthif_current_cb = priv_cb;
	dev->iamthif_file_object = priv_cb->file_object;
	dev->iamthif_canceled = 0;
	dev->iamthif_ioctl = 1;
	dev->iamthif_msg_buf_size = priv_cb->request_buffer.size;
	memcpy(dev->iamthif_msg_buf, priv_cb->request_buffer.data,
	    priv_cb->request_buffer.size);

	if (flow_ctrl_creds(dev, &dev->iamthif_file_ext) &&
	    dev->host_buffer_is_empty) {
		dev->host_buffer_is_empty = 0;
		if (priv_cb->request_buffer.size >
		    (((dev->host_hw_state & H_CBD) >> 24) *
		    sizeof(__u32)) - sizeof(struct heci_msg_hdr)) {
			heci_hdr.length =
			    (((dev->host_hw_state & H_CBD) >> 24) *
			    sizeof(__u32)) - sizeof(struct heci_msg_hdr);
			heci_hdr.msg_complete = 0;
		} else {
			heci_hdr.length = priv_cb->request_buffer.size;
			heci_hdr.msg_complete = 1;
		}

		heci_hdr.host_addr = dev->iamthif_file_ext.host_client_id;
		heci_hdr.me_addr = dev->iamthif_file_ext.me_client_id;
		heci_hdr.reserved = 0;
		dev->iamthif_msg_buf_index += heci_hdr.length;
		if (!heci_write_message(dev, &heci_hdr,
					(unsigned char *)(dev->iamthif_msg_buf),
					heci_hdr.length))
			return -ENODEV;

		if (heci_hdr.msg_complete) {
			flow_ctrl_reduce(dev, &dev->iamthif_file_ext);
			dev->iamthif_flow_control_pending = 1;
			dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
			DBG("add pthi cb to write waiting list\n");
			dev->iamthif_current_cb = priv_cb;
			dev->iamthif_file_object = priv_cb->file_object;
			list_add_tail(&priv_cb->cb_list,
				      &dev->write_waiting_list.heci_cb.cb_list);
		} else {
			DBG("message does not complete, "
					"so add pthi cb to write list.\n");
			list_add_tail(&priv_cb->cb_list,
				      &dev->write_list.heci_cb.cb_list);
		}
	} else {
		if (!(dev->host_buffer_is_empty))
			DBG("host buffer is not empty");

		DBG("No flow control credentials, "
				"so add iamthif cb to write list.\n");
		list_add_tail(&priv_cb->cb_list,
			      &dev->write_list.heci_cb.cb_list);
	}
	return rets;
}

/**
 * iamthif_ioctl_send_msg - send cmd data to pthi client
 *
 * @dev: Device object for our driver
 *
 * returns 0 on success, <0 on failure.
 */
void run_next_iamthif_cmd(struct iamt_heci_device *dev)
{
	struct heci_file_private *file_ext_tmp;
	struct heci_cb_private *priv_cb_pos = NULL;
	struct heci_cb_private *priv_cb_next = NULL;
	int status = 0;

	if (!dev)
		return;

	dev->iamthif_msg_buf_size = 0;
	dev->iamthif_msg_buf_index = 0;
	dev->iamthif_canceled = 0;
	dev->iamthif_ioctl = 1;
	dev->iamthif_state = HECI_IAMTHIF_IDLE;
	dev->iamthif_timer = 0;
	dev->iamthif_file_object = NULL;

	if (dev->pthi_cmd_list.status == 0 &&
	    !list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)) {
		DBG("complete pthi cmd_list cb.\n");

		list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
		    &dev->pthi_cmd_list.heci_cb.cb_list, cb_list) {
			list_del(&priv_cb_pos->cb_list);
			file_ext_tmp = (struct heci_file_private *)
					priv_cb_pos->file_private;

			if ((file_ext_tmp != NULL) &&
			    (file_ext_tmp == &dev->iamthif_file_ext)) {
				status = pthi_write(dev, priv_cb_pos);
				if (status != 0) {
					DBG("pthi write failed status = %d\n",
							status);
					return;
				}
				break;
			}
		}
	}
}

/**
 * heci_free_cb_private - free heci_cb_private related memory
 *
 * @priv_cb: heci callback struct
 */
void heci_free_cb_private(struct heci_cb_private *priv_cb)
{
	if (priv_cb == NULL)
		return;

	kfree(priv_cb->request_buffer.data);
	kfree(priv_cb->response_buffer.data);
	kfree(priv_cb);
}

