/*
 *
 *  sep_driver.c - Security Processor Driver main group of functions
 *
 *  Copyright(c) 2009,2010 Intel Corporation. All rights reserved.
 *  Contributions(c) 2009,2010 Discretix. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that 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.
 *
 *  You should have received a copy of the GNU General Public License along with
 *  this program; if not, write to the Free Software Foundation, Inc., 59
 *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *  CONTACTS:
 *
 *  Mark Allyn		mark.a.allyn@intel.com
 *  Jayant Mangalampalli jayant.mangalampalli@intel.com
 *
 *  CHANGES:
 *
 *  2009.06.26	Initial publish
 *  2010.09.14  Upgrade to Medfield
 *
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/mutex.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <asm/current.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/pagemap.h>
#include <asm/cacheflush.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/rar_register.h>

#include "sep_driver_hw_defs.h"
#include "sep_driver_config.h"
#include "sep_driver_api.h"
#include "sep_dev.h"

/*----------------------------------------
	DEFINES
-----------------------------------------*/

#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000

/*--------------------------------------------
	GLOBAL variables
--------------------------------------------*/

/* Keep this a single static object for now to keep the conversion easy */

static struct sep_device *sep_dev;

/**
 *	sep_dump_message - dump the message that is pending
 *	@sep: SEP device
 */
static void sep_dump_message(struct sep_device *sep)
{
	int count;
	u32 *p = sep->shared_addr;
	for (count = 0; count < 12 * 4; count += 4)
		dev_dbg(&sep->pdev->dev, "Word %d of the message is %x\n",
								count, *p++);
}

/**
 *	sep_map_and_alloc_shared_area -	allocate shared block
 *	@sep: security processor
 *	@size: size of shared area
 */
static int sep_map_and_alloc_shared_area(struct sep_device *sep)
{
	sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev,
		sep->shared_size,
		&sep->shared_bus, GFP_KERNEL);

	if (!sep->shared_addr) {
		dev_warn(&sep->pdev->dev,
			"shared memory dma_alloc_coherent failed\n");
		return -ENOMEM;
	}
	dev_dbg(&sep->pdev->dev,
		"shared_addr %zx bytes @%p (bus %llx)\n",
				sep->shared_size, sep->shared_addr,
				(unsigned long long)sep->shared_bus);
	return 0;
}

/**
 *	sep_unmap_and_free_shared_area - free shared block
 *	@sep: security processor
 */
static void sep_unmap_and_free_shared_area(struct sep_device *sep)
{
	dma_free_coherent(&sep->pdev->dev, sep->shared_size,
				sep->shared_addr, sep->shared_bus);
}

/**
 *	sep_shared_bus_to_virt - convert bus/virt addresses
 *	@sep: pointer to struct sep_device
 *	@bus_address: address to convert
 *
 *	Returns virtual address inside the shared area according
 *	to the bus address.
 */
static void *sep_shared_bus_to_virt(struct sep_device *sep,
						dma_addr_t bus_address)
{
	return sep->shared_addr + (bus_address - sep->shared_bus);
}

/**
 *	open function for the singleton driver
 *	@inode_ptr struct inode *
 *	@file_ptr struct file *
 *
 *	Called when the user opens the singleton device interface
 */
static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr)
{
	struct sep_device *sep;

	/*
	 * Get the SEP device structure and use it for the
	 * private_data field in filp for other methods
	 */
	sep = sep_dev;

	file_ptr->private_data = sep;

	if (test_and_set_bit(0, &sep->singleton_access_flag))
		return -EBUSY;
	return 0;
}

/**
 *	sep_open - device open method
 *	@inode: inode of SEP device
 *	@filp: file handle to SEP device
 *
 *	Open method for the SEP device. Called when userspace opens
 *	the SEP device node.
 *
 *	Returns zero on success otherwise an error code.
 */
static int sep_open(struct inode *inode, struct file *filp)
{
	struct sep_device *sep;

	/*
	 * Get the SEP device structure and use it for the
	 * private_data field in filp for other methods
	 */
	sep = sep_dev;
	filp->private_data = sep;

	/* Anyone can open; locking takes place at transaction level */
	return 0;
}

/**
 *	sep_singleton_release - close a SEP singleton device
 *	@inode: inode of SEP device
 *	@filp: file handle being closed
 *
 *	Called on the final close of a SEP device. As the open protects against
 *	multiple simultaenous opens that means this method is called when the
 *	final reference to the open handle is dropped.
 */
static int sep_singleton_release(struct inode *inode, struct file *filp)
{
	struct sep_device *sep = filp->private_data;

	clear_bit(0, &sep->singleton_access_flag);
	return 0;
}

/**
 *	sep_request_daemon_open - request daemon open method
 *	@inode: inode of SEP device
 *	@filp: file handle to SEP device
 *
 *	Open method for the SEP request daemon. Called when
 *	request daemon in userspace opens the SEP device node.
 *
 *	Returns zero on success otherwise an error code.
 */
static int sep_request_daemon_open(struct inode *inode, struct file *filp)
{
	struct sep_device *sep = sep_dev;
	int error = 0;

	filp->private_data = sep;

	/* There is supposed to be only one request daemon */
	if (test_and_set_bit(0, &sep->request_daemon_open))
		error = -EBUSY;
	return error;
}

/**
 *	sep_request_daemon_release - close a SEP daemon
 *	@inode: inode of SEP device
 *	@filp: file handle being closed
 *
 *	Called on the final close of a SEP daemon.
 */
static int sep_request_daemon_release(struct inode *inode, struct file *filp)
{
	struct sep_device *sep = filp->private_data;

	dev_dbg(&sep->pdev->dev, "Request daemon release for pid %d\n",
		current->pid);

	/* Clear the request_daemon_open flag */
	clear_bit(0, &sep->request_daemon_open);
	return 0;
}

/**
 *	sep_req_daemon_send_reply_command_handler - poke the SEP
 *	@sep: struct sep_device *
 *
 *	This function raises interrupt to SEPm that signals that is has a
 *	new command from HOST
 */
static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep)
{
	unsigned long lck_flags;

	sep_dump_message(sep);

	/* Counters are lockable region */
	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
	sep->send_ct++;
	sep->reply_ct++;

	/* Send the interrupt to SEP */
	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
	sep->send_ct++;

	spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);

	dev_dbg(&sep->pdev->dev,
		"sep_req_daemon_send_reply send_ct %lx reply_ct %lx\n",
		sep->send_ct, sep->reply_ct);

	return 0;
}


/**
 *	sep_free_dma_table_data_handler - free DMA table
 *	@sep: pointere to struct sep_device
 *
 *	Handles the request to  free DMA table for synchronic actions
 */
static int sep_free_dma_table_data_handler(struct sep_device *sep)
{
	int count;
	int dcb_counter;
	/* Pointer to the current dma_resource struct */
	struct sep_dma_resource *dma;

	for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) {
		dma = &sep->dma_res_arr[dcb_counter];

		/* Unmap and free input map array */
		if (dma->in_map_array) {
			for (count = 0; count < dma->in_num_pages; count++) {
				dma_unmap_page(&sep->pdev->dev,
					dma->in_map_array[count].dma_addr,
					dma->in_map_array[count].size,
					DMA_TO_DEVICE);
			}
			kfree(dma->in_map_array);
		}

		/* Unmap output map array, DON'T free it yet */
		if (dma->out_map_array) {
			for (count = 0; count < dma->out_num_pages; count++) {
				dma_unmap_page(&sep->pdev->dev,
					dma->out_map_array[count].dma_addr,
					dma->out_map_array[count].size,
					DMA_FROM_DEVICE);
			}
			kfree(dma->out_map_array);
		}

		/* Free page cache for output */
		if (dma->in_page_array) {
			for (count = 0; count < dma->in_num_pages; count++) {
				flush_dcache_page(dma->in_page_array[count]);
				page_cache_release(dma->in_page_array[count]);
			}
			kfree(dma->in_page_array);
		}

		if (dma->out_page_array) {
			for (count = 0; count < dma->out_num_pages; count++) {
				if (!PageReserved(dma->out_page_array[count]))
					SetPageDirty(dma->out_page_array[count]);
				flush_dcache_page(dma->out_page_array[count]);
				page_cache_release(dma->out_page_array[count]);
			}
			kfree(dma->out_page_array);
		}

		/* Reset all the values */
		dma->in_page_array = NULL;
		dma->out_page_array = NULL;
		dma->in_num_pages = 0;
		dma->out_num_pages = 0;
		dma->in_map_array = NULL;
		dma->out_map_array = NULL;
		dma->in_map_num_entries = 0;
		dma->out_map_num_entries = 0;
	}

	sep->nr_dcb_creat = 0;
	sep->num_lli_tables_created = 0;

	return 0;
}

/**
 *	sep_request_daemon_mmap - maps the shared area to user space
 *	@filp: pointer to struct file
 *	@vma: pointer to vm_area_struct
 *
 *	Called by the kernel when the daemon attempts an mmap() syscall
 *	using our handle.
 */
static int sep_request_daemon_mmap(struct file  *filp,
	struct vm_area_struct  *vma)
{
	struct sep_device *sep = filp->private_data;
	dma_addr_t bus_address;
	int error = 0;

	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
		error = -EINVAL;
		goto end_function;
	}

	/* Get physical address */
	bus_address = sep->shared_bus;

	if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT,
		vma->vm_end - vma->vm_start, vma->vm_page_prot)) {

		dev_warn(&sep->pdev->dev, "remap_page_range failed\n");
		error = -EAGAIN;
		goto end_function;
	}

end_function:
	return error;
}

/**
 *	sep_request_daemon_poll - poll implementation
 *	@sep: struct sep_device * for current SEP device
 *	@filp: struct file * for open file
 *	@wait: poll_table * for poll
 *
 *	Called when our device is part of a poll() or select() syscall
 */
static unsigned int sep_request_daemon_poll(struct file *filp,
	poll_table  *wait)
{
	u32	mask = 0;
	/* GPR2 register */
	u32	retval2;
	unsigned long lck_flags;
	struct sep_device *sep = filp->private_data;

	poll_wait(filp, &sep->event_request_daemon, wait);

	dev_dbg(&sep->pdev->dev, "daemon poll: send_ct is %lx reply ct is %lx\n",
						sep->send_ct, sep->reply_ct);

	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
	/* Check if the data is ready */
	if (sep->send_ct == sep->reply_ct) {
		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);

		retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
		dev_dbg(&sep->pdev->dev,
			"daemon poll: data check (GPR2) is %x\n", retval2);

		/* Check if PRINT request */
		if ((retval2 >> 30) & 0x1) {
			dev_dbg(&sep->pdev->dev, "daemon poll: PRINTF request in\n");
			mask |= POLLIN;
			goto end_function;
		}
		/* Check if NVS request */
		if (retval2 >> 31) {
			dev_dbg(&sep->pdev->dev, "daemon poll: NVS request in\n");
			mask |= POLLPRI | POLLWRNORM;
		}
	} else {
		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
		dev_dbg(&sep->pdev->dev,
			"daemon poll: no reply received; returning 0\n");
		mask = 0;
	}
end_function:
	return mask;
}

/**
 *	sep_release - close a SEP device
 *	@inode: inode of SEP device
 *	@filp: file handle being closed
 *
 *	Called on the final close of a SEP device.
 */
static int sep_release(struct inode *inode, struct file *filp)
{
	struct sep_device *sep = filp->private_data;

	dev_dbg(&sep->pdev->dev, "Release for pid %d\n", current->pid);

	mutex_lock(&sep->sep_mutex);
	/* Is this the process that has a transaction open?
	 * If so, lets reset pid_doing_transaction to 0 and
	 * clear the in use flags, and then wake up sep_event
	 * so that other processes can do transactions
	 */
	if (sep->pid_doing_transaction == current->pid) {
		clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags);
		clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags);
		sep_free_dma_table_data_handler(sep);
		wake_up(&sep->event);
		sep->pid_doing_transaction = 0;
	}

	mutex_unlock(&sep->sep_mutex);
	return 0;
}

/**
 *	sep_mmap -  maps the shared area to user space
 *	@filp: pointer to struct file
 *	@vma: pointer to vm_area_struct
 *
 *	Called on an mmap of our space via the normal SEP device
 */
static int sep_mmap(struct file *filp, struct vm_area_struct *vma)
{
	dma_addr_t bus_addr;
	struct sep_device *sep = filp->private_data;
	unsigned long error = 0;

	/* Set the transaction busy (own the device) */
	wait_event_interruptible(sep->event,
		test_and_set_bit(SEP_MMAP_LOCK_BIT,
		&sep->in_use_flags) == 0);

	if (signal_pending(current)) {
		error = -EINTR;
		goto end_function_with_error;
	}
	/*
	 * The pid_doing_transaction indicates that this process
	 * now owns the facilities to performa a transaction with
	 * the SEP. While this process is performing a transaction,
	 * no other process who has the SEP device open can perform
	 * any transactions. This method allows more than one process
	 * to have the device open at any given time, which provides
	 * finer granularity for device utilization by multiple
	 * processes.
	 */
	mutex_lock(&sep->sep_mutex);
	sep->pid_doing_transaction = current->pid;
	mutex_unlock(&sep->sep_mutex);

	/* Zero the pools and the number of data pool alocation pointers */
	sep->data_pool_bytes_allocated = 0;
	sep->num_of_data_allocations = 0;

	/*
	 * Check that the size of the mapped range is as the size of the message
	 * shared area
	 */
	if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) {
		error = -EINVAL;
		goto end_function_with_error;
	}

	dev_dbg(&sep->pdev->dev, "shared_addr is %p\n", sep->shared_addr);

	/* Get bus address */
	bus_addr = sep->shared_bus;

	if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT,
		vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
		dev_warn(&sep->pdev->dev, "remap_page_range failed\n");
		error = -EAGAIN;
		goto end_function_with_error;
	}
	goto end_function;

end_function_with_error:
	/* Clear the bit */
	clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags);
	mutex_lock(&sep->sep_mutex);
	sep->pid_doing_transaction = 0;
	mutex_unlock(&sep->sep_mutex);

	/* Raise event for stuck contextes */

	wake_up(&sep->event);

end_function:
	return error;
}

/**
 *	sep_poll - poll handler
 *	@filp: pointer to struct file
 *	@wait: pointer to poll_table
 *
 *	Called by the OS when the kernel is asked to do a poll on
 *	a SEP file handle.
 */
static unsigned int sep_poll(struct file *filp, poll_table *wait)
{
	u32 mask = 0;
	u32 retval = 0;
	u32 retval2 = 0;
	unsigned long lck_flags;

	struct sep_device *sep = filp->private_data;

	/* Am I the process that owns the transaction? */
	mutex_lock(&sep->sep_mutex);
	if (current->pid != sep->pid_doing_transaction) {
		dev_dbg(&sep->pdev->dev, "poll; wrong pid\n");
		mask = POLLERR;
		mutex_unlock(&sep->sep_mutex);
		goto end_function;
	}
	mutex_unlock(&sep->sep_mutex);

	/* Check if send command or send_reply were activated previously */
	if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) {
		mask = POLLERR;
		goto end_function;
	}

	/* Add the event to the polling wait table */
	dev_dbg(&sep->pdev->dev, "poll: calling wait sep_event\n");

	poll_wait(filp, &sep->event, wait);

	dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n",
		sep->send_ct, sep->reply_ct);

	/* Check if error occurred during poll */
	retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR);
	if (retval2 != 0x0) {
		dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2);
		mask |= POLLERR;
		goto end_function;
	}

	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);

	if (sep->send_ct == sep->reply_ct) {
		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
		retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
		dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2)  %x\n",
			retval);

		/* Check if printf request  */
		if ((retval >> 30) & 0x1) {
			dev_dbg(&sep->pdev->dev, "poll: SEP printf request\n");
			wake_up(&sep->event_request_daemon);
			goto end_function;
		}

		/* Check if the this is SEP reply or request */
		if (retval >> 31) {
			dev_dbg(&sep->pdev->dev, "poll: SEP request\n");
			wake_up(&sep->event_request_daemon);
		} else {
			dev_dbg(&sep->pdev->dev, "poll: normal return\n");
			/* In case it is again by send_reply_comand */
			clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags);
			sep_dump_message(sep);
			dev_dbg(&sep->pdev->dev,
				"poll; SEP reply POLLIN | POLLRDNORM\n");
			mask |= POLLIN | POLLRDNORM;
		}
	} else {
		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);
		dev_dbg(&sep->pdev->dev,
			"poll; no reply received; returning mask of 0\n");
		mask = 0;
	}

end_function:
	return mask;
}

/**
 *	sep_time_address - address in SEP memory of time
 *	@sep: SEP device we want the address from
 *
 *	Return the address of the two dwords in memory used for time
 *	setting.
 */
static u32 *sep_time_address(struct sep_device *sep)
{
	return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
}

/**
 *	sep_set_time - set the SEP time
 *	@sep: the SEP we are setting the time for
 *
 *	Calculates time and sets it at the predefined address.
 *	Called with the SEP mutex held.
 */
static unsigned long sep_set_time(struct sep_device *sep)
{
	struct timeval time;
	u32 *time_addr;	/* Address of time as seen by the kernel */


	do_gettimeofday(&time);

	/* Set value in the SYSTEM MEMORY offset */
	time_addr = sep_time_address(sep);

	time_addr[0] = SEP_TIME_VAL_TOKEN;
	time_addr[1] = time.tv_sec;

	dev_dbg(&sep->pdev->dev, "time.tv_sec is %lu\n", time.tv_sec);
	dev_dbg(&sep->pdev->dev, "time_addr is %p\n", time_addr);
	dev_dbg(&sep->pdev->dev, "sep->shared_addr is %p\n", sep->shared_addr);

	return time.tv_sec;
}

/**
 *	sep_set_caller_id_handler - insert caller id entry
 *	@sep: SEP device
 *	@arg: pointer to struct caller_id_struct
 *
 *	Inserts the data into the caller id table. Note that this function
 *	falls under the ioctl lock
 */
static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg)
{
	void __user *hash;
	int   error = 0;
	int   i;
	struct caller_id_struct command_args;

	for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) {
		if (sep->caller_id_table[i].pid == 0)
			break;
	}

	if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) {
		dev_dbg(&sep->pdev->dev, "no more caller id entries left\n");
		dev_dbg(&sep->pdev->dev, "maximum number is %d\n",
					SEP_CALLER_ID_TABLE_NUM_ENTRIES);
		error = -EUSERS;
		goto end_function;
	}

	/* Copy the data */
	if (copy_from_user(&command_args, (void __user *)arg,
		sizeof(command_args))) {
		error = -EFAULT;
		goto end_function;
	}

	hash = (void __user *)(unsigned long)command_args.callerIdAddress;

	if (!command_args.pid || !command_args.callerIdSizeInBytes) {
		error = -EINVAL;
		goto end_function;
	}

	dev_dbg(&sep->pdev->dev, "pid is %x\n", command_args.pid);
	dev_dbg(&sep->pdev->dev, "callerIdSizeInBytes is %x\n",
		command_args.callerIdSizeInBytes);

	if (command_args.callerIdSizeInBytes >
					SEP_CALLER_ID_HASH_SIZE_IN_BYTES) {
		error = -EMSGSIZE;
		goto end_function;
	}

	sep->caller_id_table[i].pid = command_args.pid;

	if (copy_from_user(sep->caller_id_table[i].callerIdHash,
		hash, command_args.callerIdSizeInBytes))
		error = -EFAULT;
end_function:
	return error;
}

/**
 *	sep_set_current_caller_id - set the caller id
 *	@sep: pointer to struct_sep_device
 *
 *	Set the caller ID (if it exists) to the SEP. Note that this
 *	function falls under the ioctl lock
 */
static int sep_set_current_caller_id(struct sep_device *sep)
{
	int i;
	u32 *hash_buf_ptr;

	/* Zero the previous value */
	memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES,
					0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES);

	for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) {
		if (sep->caller_id_table[i].pid == current->pid) {
			dev_dbg(&sep->pdev->dev, "Caller Id found\n");

			memcpy(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES,
				(void *)(sep->caller_id_table[i].callerIdHash),
				SEP_CALLER_ID_HASH_SIZE_IN_BYTES);
			break;
		}
	}
	/* Ensure data is in little endian */
	hash_buf_ptr = (u32 *)sep->shared_addr +
		SEP_CALLER_ID_OFFSET_BYTES;

	for (i = 0; i < SEP_CALLER_ID_HASH_SIZE_IN_WORDS; i++)
		hash_buf_ptr[i] = cpu_to_le32(hash_buf_ptr[i]);

	return 0;
}

/**
 *	sep_send_command_handler - kick off a command
 *	@sep: SEP being signalled
 *
 *	This function raises interrupt to SEP that signals that is has a new
 *	command from the host
 *
 *      Note that this function does fall under the ioctl lock
 */
static int sep_send_command_handler(struct sep_device *sep)
{
	unsigned long lck_flags;
	int error = 0;

	if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) {
		error = -EPROTO;
		goto end_function;
	}
	sep_set_time(sep);

	sep_set_current_caller_id(sep);

	sep_dump_message(sep);

	/* Update counter */
	spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
	sep->send_ct++;
	spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);

	dev_dbg(&sep->pdev->dev,
		"sep_send_command_handler send_ct %lx reply_ct %lx\n",
						sep->send_ct, sep->reply_ct);

	/* Send interrupt to SEP */
	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);

end_function:
	return error;
}

/**
 *	sep_allocate_data_pool_memory_handler -allocate pool memory
 *	@sep: pointer to struct sep_device
 *	@arg: pointer to struct alloc_struct
 *
 *	This function handles the allocate data pool memory request
 *	This function returns calculates the bus address of the
 *	allocated memory, and the offset of this area from the mapped address.
 *	Therefore, the FVOs in user space can calculate the exact virtual
 *	address of this allocated memory
 */
static int sep_allocate_data_pool_memory_handler(struct sep_device *sep,
	unsigned long arg)
{
	int error = 0;
	struct alloc_struct command_args;

	/* Holds the allocated buffer address in the system memory pool */
	u32 *token_addr;

	if (copy_from_user(&command_args, (void __user *)arg,
					sizeof(struct alloc_struct))) {
		error = -EFAULT;
		goto end_function;
	}

	/* Allocate memory */
	if ((sep->data_pool_bytes_allocated + command_args.num_bytes) >
		SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) {
		error = -ENOMEM;
		goto end_function;
	}

	dev_dbg(&sep->pdev->dev,
		"data pool bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated);
	dev_dbg(&sep->pdev->dev,
		"offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES);
	/* Set the virtual and bus address */
	command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES +
		sep->data_pool_bytes_allocated;

	/* Place in the shared area that is known by the SEP */
	token_addr = (u32 *)(sep->shared_addr +
		SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES +
		(sep->num_of_data_allocations)*2*sizeof(u32));

	token_addr[0] = SEP_DATA_POOL_POINTERS_VAL_TOKEN;
	token_addr[1] = (u32)sep->shared_bus +
		SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES +
		sep->data_pool_bytes_allocated;

	/* Write the memory back to the user space */
	error = copy_to_user((void *)arg, (void *)&command_args,
		sizeof(struct alloc_struct));
	if (error) {
		error = -EFAULT;
		goto end_function;
	}

	/* Update the allocation */
	sep->data_pool_bytes_allocated += command_args.num_bytes;
	sep->num_of_data_allocations += 1;

end_function:
	return error;
}

/**
 *	sep_lock_kernel_pages - map kernel pages for DMA
 *	@sep: pointer to struct sep_device
 *	@kernel_virt_addr: address of data buffer in kernel
 *	@data_size: size of data
 *	@lli_array_ptr: lli array
 *	@in_out_flag: input into device or output from device
 *
 *	This function locks all the physical pages of the kernel virtual buffer
 *	and construct a basic lli  array, where each entry holds the physical
 *	page address and the size that application data holds in this page
 *	This function is used only during kernel crypto mod calls from within
 *	the kernel (when ioctl is not used)
 */
static int sep_lock_kernel_pages(struct sep_device *sep,
	unsigned long kernel_virt_addr,
	u32 data_size,
	struct sep_lli_entry **lli_array_ptr,
	int in_out_flag)

{
	int error = 0;
	/* Array of lli */
	struct sep_lli_entry *lli_array;
	/* Map array */
	struct sep_dma_map *map_array;

	dev_dbg(&sep->pdev->dev, "lock kernel pages kernel_virt_addr is %08lx\n",
				(unsigned long)kernel_virt_addr);
	dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size);

	lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC);
	if (!lli_array) {
		error = -ENOMEM;
		goto end_function;
	}
	map_array = kmalloc(sizeof(struct sep_dma_map), GFP_ATOMIC);
	if (!map_array) {
		error = -ENOMEM;
		goto end_function_with_error;
	}

	map_array[0].dma_addr =
		dma_map_single(&sep->pdev->dev, (void *)kernel_virt_addr,
		data_size, DMA_BIDIRECTIONAL);
	map_array[0].size = data_size;


	/*
	 * Set the start address of the first page - app data may start not at
	 * the beginning of the page
	 */
	lli_array[0].bus_address = (u32)map_array[0].dma_addr;
	lli_array[0].block_size = map_array[0].size;

	dev_dbg(&sep->pdev->dev,
	"lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n",
		(unsigned long)lli_array[0].bus_address,
		lli_array[0].block_size);

	/* Set the output parameters */
	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
		*lli_array_ptr = lli_array;
		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1;
		sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL;
		sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array;
		sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = 1;
	} else {
		*lli_array_ptr = lli_array;
		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = 1;
		sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL;
		sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array;
		sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1;
	}
	goto end_function;

end_function_with_error:
	kfree(lli_array);

end_function:
	return error;
}

/**
 *	sep_lock_user_pages - lock and map user pages for DMA
 *	@sep: pointer to struct sep_device
 *	@app_virt_addr: user memory data buffer
 *	@data_size: size of data buffer
 *	@lli_array_ptr: lli array
 *	@in_out_flag: input or output to device
 *
 *	This function locks all the physical pages of the application
 *	virtual buffer and construct a basic lli  array, where each entry
 *	holds the physical page address and the size that application
 *	data holds in this physical pages
 */
static int sep_lock_user_pages(struct sep_device *sep,
	u32 app_virt_addr,
	u32 data_size,
	struct sep_lli_entry **lli_array_ptr,
	int in_out_flag)

{
	int error = 0;
	u32 count;
	int result;
	/* The the page of the end address of the user space buffer */
	u32 end_page;
	/* The page of the start address of the user space buffer */
	u32 start_page;
	/* The range in pages */
	u32 num_pages;
	/* Array of pointers to page */
	struct page **page_array;
	/* Array of lli */
	struct sep_lli_entry *lli_array;
	/* Map array */
	struct sep_dma_map *map_array;
	/* Direction of the DMA mapping for locked pages */
	enum dma_data_direction	dir;

	/* Set start and end pages  and num pages */
	end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT;
	start_page = app_virt_addr >> PAGE_SHIFT;
	num_pages = end_page - start_page + 1;

	dev_dbg(&sep->pdev->dev, "lock user pages app_virt_addr is %x\n", app_virt_addr);
	dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size);
	dev_dbg(&sep->pdev->dev, "start_page is %x\n", start_page);
	dev_dbg(&sep->pdev->dev, "end_page is %x\n", end_page);
	dev_dbg(&sep->pdev->dev, "num_pages is %x\n", num_pages);

	/* Allocate array of pages structure pointers */
	page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC);
	if (!page_array) {
		error = -ENOMEM;
		goto end_function;
	}
	map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC);
	if (!map_array) {
		dev_warn(&sep->pdev->dev, "kmalloc for map_array failed\n");
		error = -ENOMEM;
		goto end_function_with_error1;
	}

	lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages,
		GFP_ATOMIC);

	if (!lli_array) {
		dev_warn(&sep->pdev->dev, "kmalloc for lli_array failed\n");
		error = -ENOMEM;
		goto end_function_with_error2;
	}

	/* Convert the application virtual address into a set of physical */
	down_read(&current->mm->mmap_sem);
	result = get_user_pages(current, current->mm, app_virt_addr,
		num_pages,
		((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1),
		0, page_array, NULL);

	up_read(&current->mm->mmap_sem);

	/* Check the number of pages locked - if not all then exit with error */
	if (result != num_pages) {
		dev_warn(&sep->pdev->dev,
			"not all pages locked by get_user_pages\n");
		error = -ENOMEM;
		goto end_function_with_error3;
	}

	dev_dbg(&sep->pdev->dev, "get_user_pages succeeded\n");

	/* Set direction */
	if (in_out_flag == SEP_DRIVER_IN_FLAG)
		dir = DMA_TO_DEVICE;
	else
		dir = DMA_FROM_DEVICE;

	/*
	 * Fill the array using page array data and
	 * map the pages - this action will also flush the cache as needed
	 */
	for (count = 0; count < num_pages; count++) {
		/* Fill the map array */
		map_array[count].dma_addr =
			dma_map_page(&sep->pdev->dev, page_array[count],
			0, PAGE_SIZE, /*dir*/DMA_BIDIRECTIONAL);

		map_array[count].size = PAGE_SIZE;

		/* Fill the lli array entry */
		lli_array[count].bus_address = (u32)map_array[count].dma_addr;
		lli_array[count].block_size = PAGE_SIZE;

		dev_warn(&sep->pdev->dev, "lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n",
			count, (unsigned long)lli_array[count].bus_address,
			count, lli_array[count].block_size);
	}

	/* Check the offset for the first page */
	lli_array[0].bus_address =
		lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK));

	/* Check that not all the data is in the first page only */
	if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size)
		lli_array[0].block_size = data_size;
	else
		lli_array[0].block_size =
			PAGE_SIZE - (app_virt_addr & (~PAGE_MASK));

	dev_dbg(&sep->pdev->dev,
		"lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n",
		(unsigned long)lli_array[count].bus_address,
		lli_array[count].block_size);

	/* Check the size of the last page */
	if (num_pages > 1) {
		lli_array[num_pages - 1].block_size =
			(app_virt_addr + data_size) & (~PAGE_MASK);
		if (lli_array[num_pages - 1].block_size == 0)
			lli_array[num_pages - 1].block_size = PAGE_SIZE;

		dev_warn(&sep->pdev->dev,
			"lli_array[%x].bus_address is "
			"%08lx, lli_array[%x].block_size is %x\n",
			num_pages - 1,
			(unsigned long)lli_array[num_pages - 1].bus_address,
			num_pages - 1,
			lli_array[num_pages - 1].block_size);
	}

	/* Set output params according to the in_out flag */
	if (in_out_flag == SEP_DRIVER_IN_FLAG) {
		*lli_array_ptr = lli_array;
		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages;
		sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = page_array;
		sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array;
		sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries =
								num_pages;
	} else {
		*lli_array_ptr = lli_array;
		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = num_pages;
		sep->dma_res_arr[sep->nr_dcb_creat].out_page_array =
								page_array;
		sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array;
		sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries =
								num_pages;
	}
	goto end_function;

end_function_with_error3:
	/* Free lli array */
	kfree(lli_array);

end_function_with_error2:
	kfree(map_array);

end_function_with_error1:
	/* Free page array */
	kfree(page_array);

end_function:
	return error;
}

/**
 *	u32 sep_calculate_lli_table_max_size - size the LLI table
 *	@sep: pointer to struct sep_device
 *	@lli_in_array_ptr
 *	@num_array_entries
 *	@last_table_flag
 *
 *	This function calculates the size of data that can be inserted into
 *	the lli table from this array, such that either the table is full
 *	(all entries are entered), or there are no more entries in the
 *	lli array
 */
static u32 sep_calculate_lli_table_max_size(struct sep_device *sep,
	struct sep_lli_entry *lli_in_array_ptr,
	u32 num_array_entries,
	u32 *last_table_flag)
{
	u32 counter;
	/* Table data size */
	u32 table_data_size = 0;
	/* Data size for the next table */
	u32 next_table_data_size;

	*last_table_flag = 0;

	/*
	 * Calculate the data in the out lli table till we fill the whole
	 * table or till the data has ended
	 */
	for (counter = 0;
		(counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) &&
			(counter < num_array_entries); counter++)
		table_data_size += lli_in_array_ptr[counter].block_size;

	/*
	 * Check if we reached the last entry,
	 * meaning this ia the last table to build,
	 * and no need to check the block alignment
	 */
	if (counter == num_array_entries) {
		/* Set the last table flag */
		*last_table_flag = 1;
		goto end_function;
	}

	/*
	 * Calculate the data size of the next table.
	 * Stop if no entries left or if data size is more the DMA restriction
	 */
	next_table_data_size = 0;
	for (; counter < num_array_entries; counter++) {
		next_table_data_size += lli_in_array_ptr[counter].block_size;
		if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)
			break;
	}

	/*
	 * Check if the next table data size is less then DMA rstriction.
	 * if it is - recalculate the current table size, so that the next
	 * table data size will be adaquete for DMA
	 */
	if (next_table_data_size &&
		next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE)

		table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE -
			next_table_data_size);

end_function:
	return table_data_size;
}

/**
 *	sep_build_lli_table - build an lli array for the given table
 *	@sep: pointer to struct sep_device
 *	@lli_array_ptr: pointer to lli array
 *	@lli_table_ptr: pointer to lli table
 *	@num_processed_entries_ptr: pointer to number of entries
 *	@num_table_entries_ptr: pointer to number of tables
 *	@table_data_size: total data size
 *
 *	Builds ant lli table from the lli_array according to
 *	the given size of data
 */
static void sep_build_lli_table(struct sep_device *sep,
	struct sep_lli_entry	*lli_array_ptr,
	struct sep_lli_entry	*lli_table_ptr,
	u32 *num_processed_entries_ptr,
	u32 *num_table_entries_ptr,
	u32 table_data_size)
{
	/* Current table data size */
	u32 curr_table_data_size;
	/* Counter of lli array entry */
	u32 array_counter;

	/* Init currrent table data size and lli array entry counter */
	curr_table_data_size = 0;
	array_counter = 0;
	*num_table_entries_ptr = 1;

	dev_dbg(&sep->pdev->dev, "build lli table table_data_size is %x\n", table_data_size);

	/* Fill the table till table size reaches the needed amount */
	while (curr_table_data_size < table_data_size) {
		/* Update the number of entries in table */
		(*num_table_entries_ptr)++;

		lli_table_ptr->bus_address =
			cpu_to_le32(lli_array_ptr[array_counter].bus_address);

		lli_table_ptr->block_size =
			cpu_to_le32(lli_array_ptr[array_counter].block_size);

		curr_table_data_size += lli_array_ptr[array_counter].block_size;

		dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n",
								lli_table_ptr);
		dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n",
				(unsigned long)lli_table_ptr->bus_address);
		dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n",
			lli_table_ptr->block_size);

		/* Check for overflow of the table data */
		if (curr_table_data_size > table_data_size) {
			dev_dbg(&sep->pdev->dev,
				"curr_table_data_size too large\n");

			/* Update the size of block in the table */
			lli_table_ptr->block_size -=
			cpu_to_le32((curr_table_data_size - table_data_size));

			/* Update the physical address in the lli array */
			lli_array_ptr[array_counter].bus_address +=
			cpu_to_le32(lli_table_ptr->block_size);

			/* Update the block size left in the lli array */
			lli_array_ptr[array_counter].block_size =
				(curr_table_data_size - table_data_size);
		} else
			/* Advance to the next entry in the lli_array */
			array_counter++;

		dev_dbg(&sep->pdev->dev,
			"lli_table_ptr->bus_address is %08lx\n",
				(unsigned long)lli_table_ptr->bus_address);
		dev_dbg(&sep->pdev->dev,
			"lli_table_ptr->block_size is %x\n",
			lli_table_ptr->block_size);

		/* Move to the next entry in table */
		lli_table_ptr++;
	}

	/* Set the info entry to default */
	lli_table_ptr->bus_address = 0xffffffff;
	lli_table_ptr->block_size = 0;

	/* Set the output parameter */
	*num_processed_entries_ptr += array_counter;

}

/**
 *	sep_shared_area_virt_to_bus - map shared area to bus address
 *	@sep: pointer to struct sep_device
 *	@virt_address: virtual address to convert
 *
 *	This functions returns the physical address inside shared area according
 *	to the virtual address. It can be either on the externa RAM device
 *	(ioremapped), or on the system RAM
 *	This implementation is for the external RAM
 */
static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep,
	void *virt_address)
{
	dev_dbg(&sep->pdev->dev, "sh virt to phys v %p\n", virt_address);
	dev_dbg(&sep->pdev->dev, "sh virt to phys p %08lx\n",
		(unsigned long)
		sep->shared_bus + (virt_address - sep->shared_addr));

	return sep->shared_bus + (size_t)(virt_address - sep->shared_addr);
}

/**
 *	sep_shared_area_bus_to_virt - map shared area bus address to kernel
 *	@sep: pointer to struct sep_device
 *	@bus_address: bus address to convert
 *
 *	This functions returns the virtual address inside shared area
 *	according to the physical address. It can be either on the
 *	externa RAM device (ioremapped), or on the system RAM
 *	This implementation is for the external RAM
 */
static void *sep_shared_area_bus_to_virt(struct sep_device *sep,
	dma_addr_t bus_address)
{
	dev_dbg(&sep->pdev->dev, "shared bus to virt b=%lx v=%lx\n",
		(unsigned long)bus_address, (unsigned long)(sep->shared_addr +
			(size_t)(bus_address - sep->shared_bus)));

	return sep->shared_addr	+ (size_t)(bus_address - sep->shared_bus);
}

/**
 *	sep_debug_print_lli_tables - dump LLI table
 *	@sep: pointer to struct sep_device
 *	@lli_table_ptr: pointer to sep_lli_entry
 *	@num_table_entries: number of entries
 *	@table_data_size: total data size
 *
 *	Walk the the list of the print created tables and print all the data
 */
static void sep_debug_print_lli_tables(struct sep_device *sep,
	struct sep_lli_entry *lli_table_ptr,
	unsigned long num_table_entries,
	unsigned long table_data_size)
{
	unsigned long table_count = 1;
	unsigned long entries_count = 0;

	dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables start\n");

	while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) {
		dev_dbg(&sep->pdev->dev,
			"lli table %08lx, table_data_size is %lu\n",
			table_count, table_data_size);
		dev_dbg(&sep->pdev->dev, "num_table_entries is %lu\n",
							num_table_entries);

		/* Print entries of the table (without info entry) */
		for (entries_count = 0; entries_count < num_table_entries;
			entries_count++, lli_table_ptr++) {

			dev_dbg(&sep->pdev->dev,
				"lli_table_ptr address is %08lx\n",
				(unsigned long) lli_table_ptr);

			dev_dbg(&sep->pdev->dev,
				"phys address is %08lx block size is %x\n",
				(unsigned long)lli_table_ptr->bus_address,
				lli_table_ptr->block_size);
		}
		/* Point to the info entry */
		lli_table_ptr--;

		dev_dbg(&sep->pdev->dev,
			"phys lli_table_ptr->block_size is %x\n",
			lli_table_ptr->block_size);

		dev_dbg(&sep->pdev->dev,
			"phys lli_table_ptr->physical_address is %08lu\n",
			(unsigned long)lli_table_ptr->bus_address);


		table_data_size = lli_table_ptr->block_size & 0xffffff;
		num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff;

		dev_dbg(&sep->pdev->dev,
			"phys table_data_size is %lu num_table_entries is"
			" %lu bus_address is%lu\n", table_data_size,
			num_table_entries, (unsigned long)lli_table_ptr->bus_address);

		if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff)
			lli_table_ptr = (struct sep_lli_entry *)
				sep_shared_bus_to_virt(sep,
				(unsigned long)lli_table_ptr->bus_address);

		table_count++;
	}
	dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables end\n");
}


/**
 *	sep_prepare_empty_lli_table - create a blank LLI table
 *	@sep: pointer to struct sep_device
 *	@lli_table_addr_ptr: pointer to lli table
 *	@num_entries_ptr: pointer to number of entries
 *	@table_data_size_ptr: point to table data size
 *
 *	This function creates empty lli tables when there is no data
 */
static void sep_prepare_empty_lli_table(struct sep_device *sep,
		dma_addr_t *lli_table_addr_ptr,
		u32 *num_entries_ptr,
		u32 *table_data_size_ptr)
{
	struct sep_lli_entry *lli_table_ptr;

	/* Find the area for new table */
	lli_table_ptr =
		(struct sep_lli_entry *)(sep->shared_addr +
		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
		sep->num_lli_tables_created * sizeof(struct sep_lli_entry) *
			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);

	lli_table_ptr->bus_address = 0;
	lli_table_ptr->block_size = 0;

	lli_table_ptr++;
	lli_table_ptr->bus_address = 0xFFFFFFFF;
	lli_table_ptr->block_size = 0;

	/* Set the output parameter value */
	*lli_table_addr_ptr = sep->shared_bus +
		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
		sep->num_lli_tables_created *
		sizeof(struct sep_lli_entry) *
		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;

	/* Set the num of entries and table data size for empty table */
	*num_entries_ptr = 2;
	*table_data_size_ptr = 0;

	/* Update the number of created tables */
	sep->num_lli_tables_created++;
}

/**
 *	sep_prepare_input_dma_table - prepare input DMA mappings
 *	@sep: pointer to struct sep_device
 *	@data_size:
 *	@block_size:
 *	@lli_table_ptr:
 *	@num_entries_ptr:
 *	@table_data_size_ptr:
 *	@is_kva: set for kernel data (kernel cryptio call)
 *
 *	This function prepares only input DMA table for synhronic symmetric
 *	operations (HASH)
 *	Note that all bus addresses that are passed to the SEP
 *	are in 32 bit format; the SEP is a 32 bit device
 */
static int sep_prepare_input_dma_table(struct sep_device *sep,
	unsigned long app_virt_addr,
	u32 data_size,
	u32 block_size,
	dma_addr_t *lli_table_ptr,
	u32 *num_entries_ptr,
	u32 *table_data_size_ptr,
	bool is_kva)
{
	int error = 0;
	/* Pointer to the info entry of the table - the last entry */
	struct sep_lli_entry *info_entry_ptr;
	/* Array of pointers to page */
	struct sep_lli_entry *lli_array_ptr;
	/* Points to the first entry to be processed in the lli_in_array */
	u32 current_entry = 0;
	/* Num entries in the virtual buffer */
	u32 sep_lli_entries = 0;
	/* Lli table pointer */
	struct sep_lli_entry *in_lli_table_ptr;
	/* The total data in one table */
	u32 table_data_size = 0;
	/* Flag for last table */
	u32 last_table_flag = 0;
	/* Number of entries in lli table */
	u32 num_entries_in_table = 0;
	/* Next table address */
	void *lli_table_alloc_addr = 0;

	dev_dbg(&sep->pdev->dev, "prepare intput dma table data_size is %x\n", data_size);
	dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size);

	/* Initialize the pages pointers */
	sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL;
	sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0;

	/* Set the kernel address for first table to be allocated */
	lli_table_alloc_addr = (void *)(sep->shared_addr +
		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
		sep->num_lli_tables_created * sizeof(struct sep_lli_entry) *
		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);

	if (data_size == 0) {
		/* Special case  - create meptu table - 2 entries, zero data */
		sep_prepare_empty_lli_table(sep, lli_table_ptr,
				num_entries_ptr, table_data_size_ptr);
		goto update_dcb_counter;
	}

	/* Check if the pages are in Kernel Virtual Address layout */
	if (is_kva == true)
		/* Lock the pages in the kernel */
		error = sep_lock_kernel_pages(sep, app_virt_addr,
			data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG);
	else
		/*
		 * Lock the pages of the user buffer
		 * and translate them to pages
		 */
		error = sep_lock_user_pages(sep, app_virt_addr,
			data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG);

	if (error)
		goto end_function;

	dev_dbg(&sep->pdev->dev, "output sep_in_num_pages is %x\n",
		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages);

	current_entry = 0;
	info_entry_ptr = NULL;

	sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages;

	/* Loop till all the entries in in array are not processed */
	while (current_entry < sep_lli_entries) {

		/* Set the new input and output tables */
		in_lli_table_ptr =
			(struct sep_lli_entry *)lli_table_alloc_addr;

		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;

		if (lli_table_alloc_addr >
			((void *)sep->shared_addr +
			SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
			SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {

			error = -ENOMEM;
			goto end_function_error;

		}

		/* Update the number of created tables */
		sep->num_lli_tables_created++;

		/* Calculate the maximum size of data for input table */
		table_data_size = sep_calculate_lli_table_max_size(sep,
			&lli_array_ptr[current_entry],
			(sep_lli_entries - current_entry),
			&last_table_flag);

		/*
		 * If this is not the last table -
		 * then align it to the block size
		 */
		if (!last_table_flag)
			table_data_size =
				(table_data_size / block_size) * block_size;

		dev_dbg(&sep->pdev->dev, "output table_data_size is %x\n",
							table_data_size);

		/* Construct input lli table */
		sep_build_lli_table(sep, &lli_array_ptr[current_entry],
			in_lli_table_ptr,
			&current_entry, &num_entries_in_table, table_data_size);

		if (info_entry_ptr == NULL) {

			/* Set the output parameters to physical addresses */
			*lli_table_ptr = sep_shared_area_virt_to_bus(sep,
				in_lli_table_ptr);
			*num_entries_ptr = num_entries_in_table;
			*table_data_size_ptr = table_data_size;

			dev_dbg(&sep->pdev->dev,
				"output lli_table_in_ptr is %08lx\n",
				(unsigned long)*lli_table_ptr);

		} else {
			/* Update the info entry of the previous in table */
			info_entry_ptr->bus_address =
				sep_shared_area_virt_to_bus(sep,
							in_lli_table_ptr);
			info_entry_ptr->block_size =
				((num_entries_in_table) << 24) |
				(table_data_size);
		}
		/* Save the pointer to the info entry of the current tables */
		info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1;
	}
	/* Print input tables */
	sep_debug_print_lli_tables(sep, (struct sep_lli_entry *)
		sep_shared_area_bus_to_virt(sep, *lli_table_ptr),
		*num_entries_ptr, *table_data_size_ptr);
	/* The array of the pages */
	kfree(lli_array_ptr);

update_dcb_counter:
	/* Update DCB counter */
	sep->nr_dcb_creat++;
	goto end_function;

end_function_error:
	/* Free all the allocated resources */
	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array);
	kfree(lli_array_ptr);
	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array);

end_function:
	return error;

}
/**
 *	sep_construct_dma_tables_from_lli - prepare AES/DES mappings
 *	@sep: pointer to struct sep_device
 *	@lli_in_array:
 *	@sep_in_lli_entries:
 *	@lli_out_array:
 *	@sep_out_lli_entries
 *	@block_size
 *	@lli_table_in_ptr
 *	@lli_table_out_ptr
 *	@in_num_entries_ptr
 *	@out_num_entries_ptr
 *	@table_data_size_ptr
 *
 *	This function creates the input and output DMA tables for
 *	symmetric operations (AES/DES) according to the block
 *	size from LLI arays
 *	Note that all bus addresses that are passed to the SEP
 *	are in 32 bit format; the SEP is a 32 bit device
 */
static int sep_construct_dma_tables_from_lli(
	struct sep_device *sep,
	struct sep_lli_entry *lli_in_array,
	u32	sep_in_lli_entries,
	struct sep_lli_entry *lli_out_array,
	u32	sep_out_lli_entries,
	u32	block_size,
	dma_addr_t *lli_table_in_ptr,
	dma_addr_t *lli_table_out_ptr,
	u32	*in_num_entries_ptr,
	u32	*out_num_entries_ptr,
	u32	*table_data_size_ptr)
{
	/* Points to the area where next lli table can be allocated */
	void *lli_table_alloc_addr = 0;
	/* Input lli table */
	struct sep_lli_entry *in_lli_table_ptr = NULL;
	/* Output lli table */
	struct sep_lli_entry *out_lli_table_ptr = NULL;
	/* Pointer to the info entry of the table - the last entry */
	struct sep_lli_entry *info_in_entry_ptr = NULL;
	/* Pointer to the info entry of the table - the last entry */
	struct sep_lli_entry *info_out_entry_ptr = NULL;
	/* Points to the first entry to be processed in the lli_in_array */
	u32 current_in_entry = 0;
	/* Points to the first entry to be processed in the lli_out_array */
	u32 current_out_entry = 0;
	/* Max size of the input table */
	u32 in_table_data_size = 0;
	/* Max size of the output table */
	u32 out_table_data_size = 0;
	/* Flag te signifies if this is the last tables build */
	u32 last_table_flag = 0;
	/* The data size that should be in table */
	u32 table_data_size = 0;
	/* Number of etnries in the input table */
	u32 num_entries_in_table = 0;
	/* Number of etnries in the output table */
	u32 num_entries_out_table = 0;

	/* Initiate to point after the message area */
	lli_table_alloc_addr = (void *)(sep->shared_addr +
		SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
		(sep->num_lli_tables_created *
		(sizeof(struct sep_lli_entry) *
		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP)));

	/* Loop till all the entries in in array are not processed */
	while (current_in_entry < sep_in_lli_entries) {
		/* Set the new input and output tables */
		in_lli_table_ptr =
			(struct sep_lli_entry *)lli_table_alloc_addr;

		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;

		/* Set the first output tables */
		out_lli_table_ptr =
			(struct sep_lli_entry *)lli_table_alloc_addr;

		/* Check if the DMA table area limit was overrun */
		if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) *
			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) >
			((void *)sep->shared_addr +
			SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES +
			SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) {

			dev_warn(&sep->pdev->dev, "dma table limit overrun\n");
			return -ENOMEM;
		}

		/* Update the number of the lli tables created */
		sep->num_lli_tables_created += 2;

		lli_table_alloc_addr += sizeof(struct sep_lli_entry) *
			SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP;

		/* Calculate the maximum size of data for input table */
		in_table_data_size =
			sep_calculate_lli_table_max_size(sep,
			&lli_in_array[current_in_entry],
			(sep_in_lli_entries - current_in_entry),
			&last_table_flag);

		/* Calculate the maximum size of data for output table */
		out_table_data_size =
			sep_calculate_lli_table_max_size(sep,
			&lli_out_array[current_out_entry],
			(sep_out_lli_entries - current_out_entry),
			&last_table_flag);

		dev_dbg(&sep->pdev->dev,
			"construct tables from lli in_table_data_size is %x\n",
			in_table_data_size);

		dev_dbg(&sep->pdev->dev,
			"construct tables from lli out_table_data_size is %x\n",
			out_table_data_size);

		table_data_size = in_table_data_size;

		if (!last_table_flag) {
			/*
			 * If this is not the last table,
			 * then must check where the data is smallest
			 * and then align it to the block size
			 */
			if (table_data_size > out_table_data_size)
				table_data_size = out_table_data_size;

			/*
			 * Now calculate the table size so that
			 * it will be module block size
			 */
			table_data_size = (table_data_size / block_size) *
				block_size;
		}

		/* Construct input lli table */
		sep_build_lli_table(sep, &lli_in_array[current_in_entry],
			in_lli_table_ptr,
			&current_in_entry,
			&num_entries_in_table,
			table_data_size);

		/* Construct output lli table */
		sep_build_lli_table(sep, &lli_out_array[current_out_entry],
			out_lli_table_ptr,
			&current_out_entry,
			&num_entries_out_table,
			table_data_size);

		/* If info entry is null - this is the first table built */
		if (info_in_entry_ptr == NULL) {
			/* Set the output parameters to physical addresses */
			*lli_table_in_ptr =
			sep_shared_area_virt_to_bus(sep, in_lli_table_ptr);

			*in_num_entries_ptr = num_entries_in_table;

			*lli_table_out_ptr =
				sep_shared_area_virt_to_bus(sep,
				out_lli_table_ptr);

			*out_num_entries_ptr = num_entries_out_table;
			*table_data_size_ptr = table_data_size;

			dev_dbg(&sep->pdev->dev,
			"output lli_table_in_ptr is %08lx\n",
				(unsigned long)*lli_table_in_ptr);
			dev_dbg(&sep->pdev->dev,
			"output lli_table_out_ptr is %08lx\n",
				(unsigned long)*lli_table_out_ptr);
		} else {
			/* Update the info entry of the previous in table */
			info_in_entry_ptr->bus_address =
				sep_shared_area_virt_to_bus(sep,
				in_lli_table_ptr);

			info_in_entry_ptr->block_size =
				((num_entries_in_table) << 24) |
				(table_data_size);

			/* Update the info entry of the previous in table */
			info_out_entry_ptr->bus_address =
				sep_shared_area_virt_to_bus(sep,
				out_lli_table_ptr);

			info_out_entry_ptr->block_size =
				((num_entries_out_table) << 24) |
				(table_data_size);

			dev_dbg(&sep->pdev->dev,
				"output lli_table_in_ptr:%08lx %08x\n",
				(unsigned long)info_in_entry_ptr->bus_address,
				info_in_entry_ptr->block_size);

			dev_dbg(&sep->pdev->dev,
				"output lli_table_out_ptr:%08lx  %08x\n",
				(unsigned long)info_out_entry_ptr->bus_address,
				info_out_entry_ptr->block_size);
		}

		/* Save the pointer to the info entry of the current tables */
		info_in_entry_ptr = in_lli_table_ptr +
			num_entries_in_table - 1;
		info_out_entry_ptr = out_lli_table_ptr +
			num_entries_out_table - 1;

		dev_dbg(&sep->pdev->dev,
			"output num_entries_out_table is %x\n",
			(u32)num_entries_out_table);
		dev_dbg(&sep->pdev->dev,
			"output info_in_entry_ptr is %lx\n",
			(unsigned long)info_in_entry_ptr);
		dev_dbg(&sep->pdev->dev,
			"output info_out_entry_ptr is %lx\n",
			(unsigned long)info_out_entry_ptr);
	}

	/* Print input tables */
	sep_debug_print_lli_tables(sep,
	(struct sep_lli_entry *)
	sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr),
	*in_num_entries_ptr,
	*table_data_size_ptr);

	/* Print output tables */
	sep_debug_print_lli_tables(sep,
	(struct sep_lli_entry *)
	sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr),
	*out_num_entries_ptr,
	*table_data_size_ptr);

	return 0;
}

/**
 *	sep_prepare_input_output_dma_table - prepare DMA I/O table
 *	@app_virt_in_addr:
 *	@app_virt_out_addr:
 *	@data_size:
 *	@block_size:
 *	@lli_table_in_ptr:
 *	@lli_table_out_ptr:
 *	@in_num_entries_ptr:
 *	@out_num_entries_ptr:
 *	@table_data_size_ptr:
 *	@is_kva: set for kernel data; used only for kernel crypto module
 *
 *	This function builds input and output DMA tables for synhronic
 *	symmetric operations (AES, DES, HASH). It also checks that each table
 *	is of the modular block size
 *	Note that all bus addresses that are passed to the SEP
 *	are in 32 bit format; the SEP is a 32 bit device
 */
static int sep_prepare_input_output_dma_table(struct sep_device *sep,
	unsigned long app_virt_in_addr,
	unsigned long app_virt_out_addr,
	u32 data_size,
	u32 block_size,
	dma_addr_t *lli_table_in_ptr,
	dma_addr_t *lli_table_out_ptr,
	u32 *in_num_entries_ptr,
	u32 *out_num_entries_ptr,
	u32 *table_data_size_ptr,
	bool is_kva)

{
	int error = 0;
	/* Array of pointers of page */
	struct sep_lli_entry *lli_in_array;
	/* Array of pointers of page */
	struct sep_lli_entry *lli_out_array;

	if (data_size == 0) {
		/* Prepare empty table for input and output */
		sep_prepare_empty_lli_table(sep, lli_table_in_ptr,
			in_num_entries_ptr, table_data_size_ptr);

		sep_prepare_empty_lli_table(sep, lli_table_out_ptr,
			out_num_entries_ptr, table_data_size_ptr);

		goto update_dcb_counter;
	}

	/* Initialize the pages pointers */
	sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL;
	sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL;

	/* Lock the pages of the buffer and translate them to pages */
	if (is_kva == true) {
		error = sep_lock_kernel_pages(sep, app_virt_in_addr,
			data_size, &lli_in_array, SEP_DRIVER_IN_FLAG);

		if (error) {
			dev_warn(&sep->pdev->dev,
				"lock kernel for in failed\n");
			goto end_function;
		}

		error = sep_lock_kernel_pages(sep, app_virt_out_addr,
			data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG);

		if (error) {
			dev_warn(&sep->pdev->dev,
				"lock kernel for out failed\n");
			goto end_function;
		}
	}

	else {
		error = sep_lock_user_pages(sep, app_virt_in_addr,
				data_size, &lli_in_array, SEP_DRIVER_IN_FLAG);
		if (error) {
			dev_warn(&sep->pdev->dev,
				"sep_lock_user_pages for input virtual buffer failed\n");
			goto end_function;
		}

		error = sep_lock_user_pages(sep, app_virt_out_addr,
			data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG);

		if (error) {
			dev_warn(&sep->pdev->dev,
				"sep_lock_user_pages for output virtual buffer failed\n");
			goto end_function_free_lli_in;
		}
	}

	dev_dbg(&sep->pdev->dev, "prep input output dma table sep_in_num_pages is %x\n",
		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages);
	dev_dbg(&sep->pdev->dev, "sep_out_num_pages is %x\n",
		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages);
	dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n",
		SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP);

	/* Call the function that creates table from the lli arrays */
	error = sep_construct_dma_tables_from_lli(sep, lli_in_array,
		sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages,
		lli_out_array,
		sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages,
		block_size, lli_table_in_ptr, lli_table_out_ptr,
		in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr);

	if (error) {
		dev_warn(&sep->pdev->dev,
			"sep_construct_dma_tables_from_lli failed\n");
		goto end_function_with_error;
	}

	kfree(lli_out_array);
	kfree(lli_in_array);

update_dcb_counter:
	/* Update DCB counter */
	sep->nr_dcb_creat++;

	goto end_function;

end_function_with_error:
	kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_map_array);
	kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_page_array);
	kfree(lli_out_array);


end_function_free_lli_in:
	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array);
	kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array);
	kfree(lli_in_array);

end_function:

	return error;

}

/**
 *	sep_prepare_input_output_dma_table_in_dcb - prepare control blocks
 *	@app_in_address: unsigned long; for data buffer in (user space)
 *	@app_out_address: unsigned long; for data buffer out (user space)
 *	@data_in_size: u32; for size of data
 *	@block_size: u32; for block size
 *	@tail_block_size: u32; for size of tail block
 *	@isapplet: bool; to indicate external app
 *	@is_kva: bool; kernel buffer; only used for kernel crypto module
 *
 *	This function prepares the linked DMA tables and puts the
 *	address for the linked list of tables inta a DCB (data control
 *	block) the address of which is known by the SEP hardware
 *	Note that all bus addresses that are passed to the SEP
 *	are in 32 bit format; the SEP is a 32 bit device
 */
static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep,
	unsigned long  app_in_address,
	unsigned long  app_out_address,
	u32  data_in_size,
	u32  block_size,
	u32  tail_block_size,
	bool isapplet,
	bool	is_kva)
{
	int error = 0;
	/* Size of tail */
	u32 tail_size = 0;
	/* Address of the created DCB table */
	struct sep_dcblock *dcb_table_ptr = NULL;
	/* The physical address of the first input DMA table */
	dma_addr_t in_first_mlli_address = 0;
	/* Number of entries in the first input DMA table */
	u32  in_first_num_entries = 0;
	/* The physical address of the first output DMA table */
	dma_addr_t  out_first_mlli_address = 0;
	/* Number of entries in the first output DMA table */
	u32  out_first_num_entries = 0;
	/* Data in the first input/output table */
	u32  first_data_size = 0;

	if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) {
		/* No more DCBs to allocate */
		dev_warn(&sep->pdev->dev, "no more DCBs available\n");
		error = -ENOSPC;
		goto end_function;
	}

	/* Allocate new DCB */
	dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr +
		SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES +
		(sep->nr_dcb_creat * sizeof(struct sep_dcblock)));

	/* Set the default values in the DCB */
	dcb_table_ptr->input_mlli_address = 0;
	dcb_table_ptr->input_mlli_num_entries = 0;
	dcb_table_ptr->input_mlli_data_size = 0;
	dcb_table_ptr->output_mlli_address = 0;
	dcb_table_ptr->output_mlli_num_entries = 0;
	dcb_table_ptr->output_mlli_data_size = 0;
	dcb_table_ptr->tail_data_size = 0;
	dcb_table_ptr->out_vr_tail_pt = 0;

	if (isapplet == true) {

		/* Check if there is enough data for DMA operation */
		if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) {
			if (is_kva == true) {
				memcpy(dcb_table_ptr->tail_data,
					(void *)app_in_address, data_in_size);
			} else {
				if (copy_from_user(dcb_table_ptr->tail_data,
					(void __user *)app_in_address,
					data_in_size)) {
					error = -EFAULT;
					goto end_function;
				}
			}

			dcb_table_ptr->tail_data_size = data_in_size;

			/* Set the output user-space address for mem2mem op */
			if (app_out_address)
				dcb_table_ptr->out_vr_tail_pt =
							(aligned_u64)app_out_address;

			/*
			 * Update both data length parameters in order to avoid
			 * second data copy and allow building of empty mlli
			 * tables
			 */
			tail_size = 0x0;
			data_in_size = 0x0;

		} else {
			if (!app_out_address) {
				tail_size = data_in_size % block_size;
				if (!tail_size) {
					if (tail_block_size == block_size)
						tail_size = block_size;
				}
			} else {
				tail_size = 0;
			}
		}
		if (tail_size) {
			if (is_kva == true) {
				memcpy(dcb_table_ptr->tail_data,
					(void *)(app_in_address + data_in_size -
					tail_size), tail_size);
			} else {
				/* We have tail data - copy it to DCB */
				if (copy_from_user(dcb_table_ptr->tail_data,
					(void *)(app_in_address +
					data_in_size - tail_size), tail_size)) {
					error = -EFAULT;
					goto end_function;
				}
			}
			if (app_out_address)
				/*
				 * Calculate the output address
				 * according to tail data size
				 */
				dcb_table_ptr->out_vr_tail_pt =
					(aligned_u64)app_out_address + data_in_size
					- tail_size;

			/* Save the real tail data size */
			dcb_table_ptr->tail_data_size = tail_size;
			/*
			 * Update the data size without the tail
			 * data size AKA data for the dma
			 */
			data_in_size = (data_in_size - tail_size);
		}
	}
	/* Check if we need to build only input table or input/output */
	if (app_out_address) {
		/* Prepare input/output tables */
		error = sep_prepare_input_output_dma_table(sep,
			app_in_address,
			app_out_address,
			data_in_size,
			block_size,
			&in_first_mlli_address,
			&out_first_mlli_address,
			&in_first_num_entries,
			&out_first_num_entries,
			&first_data_size,
			is_kva);
	} else {
		/* Prepare input tables */
		error = sep_prepare_input_dma_table(sep,
			app_in_address,
			data_in_size,
			block_size,
			&in_first_mlli_address,
			&in_first_num_entries,
			&first_data_size,
			is_kva);
	}

	if (error) {
		dev_warn(&sep->pdev->dev, "prepare DMA table call failed from prepare DCB call\n");
		goto end_function;
	}

	/* Set the DCB values */
	dcb_table_ptr->input_mlli_address = in_first_mlli_address;
	dcb_table_ptr->input_mlli_num_entries = in_first_num_entries;
	dcb_table_ptr->input_mlli_data_size = first_data_size;
	dcb_table_ptr->output_mlli_address = out_first_mlli_address;
	dcb_table_ptr->output_mlli_num_entries = out_first_num_entries;
	dcb_table_ptr->output_mlli_data_size = first_data_size;

end_function:
	return error;

}

/**
 *	sep_free_dma_tables_and_dcb - free DMA tables and DCBs
 *	@sep: pointer to struct sep_device
 *	@isapplet: indicates external application (used for kernel access)
 *	@is_kva: indicates kernel addresses (only used for kernel crypto)
 *
 *	This function frees the DMA tables and DCB
 */
static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet,
	bool is_kva)
{
	int i = 0;
	int error = 0;
	int error_temp = 0;
	struct sep_dcblock *dcb_table_ptr;
	unsigned long pt_hold;
	void *tail_pt;

	if (isapplet == true) {
		/* Set pointer to first DCB table */
		dcb_table_ptr = (struct sep_dcblock *)
			(sep->shared_addr +
			SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES);

		/* Go over each DCB and see if tail pointer must be updated */
		for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) {
			if (dcb_table_ptr->out_vr_tail_pt) {
				pt_hold = (unsigned long)dcb_table_ptr->out_vr_tail_pt;
				tail_pt = (void *)pt_hold;
				if (is_kva == true) {
					memcpy(tail_pt,
						dcb_table_ptr->tail_data,
						dcb_table_ptr->tail_data_size);
				} else {
					error_temp = copy_to_user(
						tail_pt,
						dcb_table_ptr->tail_data,
						dcb_table_ptr->tail_data_size);
				}
				if (error_temp) {
					/* Release the DMA resource */
					error = -EFAULT;
					break;
				}
			}
		}
	}
	/* Free the output pages, if any */
	sep_free_dma_table_data_handler(sep);

	return error;
}

/**
 *	sep_get_static_pool_addr_handler - get static pool address
 *	@sep: pointer to struct sep_device
 *
 *	This function sets the bus and virtual addresses of the static pool
 */
static int sep_get_static_pool_addr_handler(struct sep_device *sep)
{
	u32 *static_pool_addr = NULL;

	static_pool_addr = (u32 *)(sep->shared_addr +
		SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES);

	static_pool_addr[0] = SEP_STATIC_POOL_VAL_TOKEN;
	static_pool_addr[1] = (u32)sep->shared_bus +
		SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES;

	dev_dbg(&sep->pdev->dev, "static pool segment: physical %x\n",
		(u32)static_pool_addr[1]);

	return 0;
}

/**
 *	sep_end_transaction_handler - end transaction
 *	@sep: pointer to struct sep_device
 *
 *	This API handles the end transaction request
 */
static int sep_end_transaction_handler(struct sep_device *sep)
{
	/* Clear the data pool pointers Token */
	memset((void *)(sep->shared_addr +
		SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES),
		0, sep->num_of_data_allocations*2*sizeof(u32));

	/* Check that all the DMA resources were freed */
	sep_free_dma_table_data_handler(sep);

	clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags);

	/*
	 * We are now through with the transaction. Let's
	 * allow other processes who have the device open
	 * to perform transactions
	 */
	mutex_lock(&sep->sep_mutex);
	sep->pid_doing_transaction = 0;
	mutex_unlock(&sep->sep_mutex);
	/* Raise event for stuck contextes */
	wake_up(&sep->event);

	return 0;
}

/**
 *	sep_prepare_dcb_handler - prepare a control block
 *	@sep: pointer to struct sep_device
 *	@arg: pointer to user parameters
 *
 *	This function will retrieve the RAR buffer physical addresses, type
 *	& size corresponding to the RAR handles provided in the buffers vector.
 */
static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg)
{
	int error;
	/* Command arguments */
	struct build_dcb_struct command_args;

	/* Get the command arguments */
	if (copy_from_user(&command_args, (void __user *)arg,
					sizeof(struct build_dcb_struct))) {
		error = -EFAULT;
		goto end_function;
	}

	dev_dbg(&sep->pdev->dev, "prep dcb handler app_in_address is %08llx\n",
						command_args.app_in_address);
	dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n",
						command_args.app_out_address);
	dev_dbg(&sep->pdev->dev, "data_size is %x\n",
						command_args.data_in_size);
	dev_dbg(&sep->pdev->dev, "block_size is %x\n",
						command_args.block_size);
	dev_dbg(&sep->pdev->dev, "tail block_size is %x\n",
						command_args.tail_block_size);

	error = sep_prepare_input_output_dma_table_in_dcb(sep,
		(unsigned long)command_args.app_in_address,
		(unsigned long)command_args.app_out_address,
		command_args.data_in_size, command_args.block_size,
		command_args.tail_block_size, true, false);

end_function:
	return error;

}

/**
 *	sep_free_dcb_handler - free control block resources
 *	@sep: pointer to struct sep_device
 *
 *	This function frees the DCB resources and updates the needed
 *	user-space buffers.
 */
static int sep_free_dcb_handler(struct sep_device *sep)
{
	return sep_free_dma_tables_and_dcb(sep, false, false);
}

/**
 *	sep_rar_prepare_output_msg_handler - prepare an output message
 *	@sep: pointer to struct sep_device
 *	@arg: pointer to user parameters
 *
 *	This function will retrieve the RAR buffer physical addresses, type
 *	& size corresponding to the RAR handles provided in the buffers vector.
 */
static int sep_rar_prepare_output_msg_handler(struct sep_device *sep,
	unsigned long arg)
{
	int error = 0;
	/* Command args */
	struct rar_hndl_to_bus_struct command_args;
	/* Bus address */
	dma_addr_t  rar_bus = 0;
	/* Holds the RAR address in the system memory offset */
	u32 *rar_addr;

	/* Copy the data */
	if (copy_from_user(&command_args, (void __user *)arg,
						sizeof(command_args))) {
		error = -EFAULT;
		goto end_function;
	}

	/* Call to translation function only if user handle is not NULL */
	if (command_args.rar_handle)
		return -EOPNOTSUPP;
	dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", (u32)rar_bus);

	/* Set value in the SYSTEM MEMORY offset */
	rar_addr = (u32 *)(sep->shared_addr +
		SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES);

	/* Copy the physical address to the System Area for the SEP */
	rar_addr[0] = SEP_RAR_VAL_TOKEN;
	rar_addr[1] = rar_bus;

end_function:
	return error;
}

/**
 *	sep_ioctl - ioctl api
 *	@filp: pointer to struct file
 *	@cmd: command
 *	@arg: pointer to argument structure
 *
 *	Implement the ioctl methods available on the SEP device.
 */
static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int error = 0;
	struct sep_device *sep = filp->private_data;

	/* Make sure we own this device */
	mutex_lock(&sep->sep_mutex);
	if ((current->pid != sep->pid_doing_transaction) &&
				(sep->pid_doing_transaction != 0)) {
		dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n");
		error = -EACCES;
	}
	mutex_unlock(&sep->sep_mutex);

	if (error)
		return error;

	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
		return -ENOTTY;

	/* Lock to prevent the daemon to interfere with operation */
	mutex_lock(&sep->ioctl_mutex);

	switch (cmd) {
	case SEP_IOCSENDSEPCOMMAND:
		/* Send command to SEP */
		error = sep_send_command_handler(sep);
		break;
	case SEP_IOCALLOCDATAPOLL:
		/* Allocate data pool */
		error = sep_allocate_data_pool_memory_handler(sep, arg);
		break;
	case SEP_IOCGETSTATICPOOLADDR:
		/* Inform the SEP the bus address of the static pool */
		error = sep_get_static_pool_addr_handler(sep);
		break;
	case SEP_IOCENDTRANSACTION:
		error = sep_end_transaction_handler(sep);
		break;
	case SEP_IOCRARPREPAREMESSAGE:
		error = sep_rar_prepare_output_msg_handler(sep, arg);
		break;
	case SEP_IOCPREPAREDCB:
		error = sep_prepare_dcb_handler(sep, arg);
		break;
	case SEP_IOCFREEDCB:
		error = sep_free_dcb_handler(sep);
		break;
	default:
		error = -ENOTTY;
		break;
	}

	mutex_unlock(&sep->ioctl_mutex);
	return error;
}

/**
 *	sep_singleton_ioctl - ioctl api for singleton interface
 *	@filp: pointer to struct file
 *	@cmd: command
 *	@arg: pointer to argument structure
 *
 *	Implement the additional ioctls for the singleton device
 */
static long sep_singleton_ioctl(struct file  *filp, u32 cmd, unsigned long arg)
{
	long error = 0;
	struct sep_device *sep = filp->private_data;

	/* Check that the command is for the SEP device */
	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
		return -ENOTTY;

	/* Make sure we own this device */
	mutex_lock(&sep->sep_mutex);
	if ((current->pid != sep->pid_doing_transaction) &&
				(sep->pid_doing_transaction != 0)) {
		dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n");
		mutex_unlock(&sep->sep_mutex);
		return -EACCES;
	}

	mutex_unlock(&sep->sep_mutex);

	switch (cmd) {
	case SEP_IOCTLSETCALLERID:
		mutex_lock(&sep->ioctl_mutex);
		error = sep_set_caller_id_handler(sep, arg);
		mutex_unlock(&sep->ioctl_mutex);
		break;
	default:
		error = sep_ioctl(filp, cmd, arg);
		break;
	}
	return error;
}

/**
 *	sep_request_daemon_ioctl - ioctl for daemon
 *	@filp: pointer to struct file
 *	@cmd: command
 *	@arg: pointer to argument structure
 *
 *	Called by the request daemon to perform ioctls on the daemon device
 */
static long sep_request_daemon_ioctl(struct file *filp, u32 cmd,
	unsigned long arg)
{

	long error;
	struct sep_device *sep = filp->private_data;

	/* Check that the command is for SEP device */
	if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER)
		return -ENOTTY;

	/* Only one process can access ioctl at any given time */
	mutex_lock(&sep->ioctl_mutex);

	switch (cmd) {
	case SEP_IOCSENDSEPRPLYCOMMAND:
		/* Send reply command to SEP */
		error = sep_req_daemon_send_reply_command_handler(sep);
		break;
	case SEP_IOCENDTRANSACTION:
		/*
		 * End req daemon transaction, do nothing
		 * will be removed upon update in middleware
		 * API library
		 */
		error = 0;
		break;
	default:
		error = -ENOTTY;
	}
	mutex_unlock(&sep->ioctl_mutex);
	return error;
}

/**
 *	sep_inthandler - interrupt handler
 *	@irq: interrupt
 *	@dev_id: device id
 */
static irqreturn_t sep_inthandler(int irq, void *dev_id)
{
	irqreturn_t int_error = IRQ_HANDLED;
	unsigned long lck_flags;
	u32 reg_val, reg_val2 = 0;
	struct sep_device *sep = dev_id;

	/* Read the IRR register to check if this is SEP interrupt */
	reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR);

	if (reg_val & (0x1 << 13)) {
		/* Lock and update the counter of reply messages */
		spin_lock_irqsave(&sep->snd_rply_lck, lck_flags);
		sep->reply_ct++;
		spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags);

		dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n",
					sep->send_ct, sep->reply_ct);

		/* Is this printf or daemon request? */
		reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
		dev_dbg(&sep->pdev->dev,
			"SEP Interrupt - reg2 is %08x\n", reg_val2);

		if ((reg_val2 >> 30) & 0x1) {
			dev_dbg(&sep->pdev->dev, "int: printf request\n");
			wake_up(&sep->event_request_daemon);
		} else if (reg_val2 >> 31) {
			dev_dbg(&sep->pdev->dev, "int: daemon request\n");
			wake_up(&sep->event_request_daemon);
		} else {
			dev_dbg(&sep->pdev->dev, "int: SEP reply\n");
			wake_up(&sep->event);
		}
	} else {
		dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n");
		int_error = IRQ_NONE;
	}
	if (int_error == IRQ_HANDLED)
		sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val);

	return int_error;
}

/**
 *	sep_reconfig_shared_area - reconfigure shared area
 *	@sep: pointer to struct sep_device
 *
 *	Reconfig the shared area between HOST and SEP - needed in case
 *	the DX_CC_Init function was called before OS loading.
 */
static int sep_reconfig_shared_area(struct sep_device *sep)
{
	int ret_val;

	/* use to limit waiting for SEP */
	unsigned long end_time;

	/* Send the new SHARED MESSAGE AREA to the SEP */
	dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n",
				(unsigned long long)sep->shared_bus);

	sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);

	/* Poll for SEP response */
	ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);

	end_time = jiffies + (WAIT_TIME * HZ);

	while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) &&
		(ret_val != sep->shared_bus))
		ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR);

	/* Check the return value (register) */
	if (ret_val != sep->shared_bus) {
		dev_warn(&sep->pdev->dev, "could not reconfig shared area\n");
		dev_warn(&sep->pdev->dev, "result was %x\n", ret_val);
		ret_val = -ENOMEM;
	} else
		ret_val = 0;

	dev_dbg(&sep->pdev->dev, "reconfig shared area end\n");
	return ret_val;
}

/* File operation for singleton SEP operations */
static const struct file_operations singleton_file_operations = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = sep_singleton_ioctl,
	.poll = sep_poll,
	.open = sep_singleton_open,
	.release = sep_singleton_release,
	.mmap = sep_mmap,
};

/* File operation for daemon operations */
static const struct file_operations daemon_file_operations = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = sep_request_daemon_ioctl,
	.poll = sep_request_daemon_poll,
	.open = sep_request_daemon_open,
	.release = sep_request_daemon_release,
	.mmap = sep_request_daemon_mmap,
};

/* The files operations structure of the driver */
static const struct file_operations sep_file_operations = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = sep_ioctl,
	.poll = sep_poll,
	.open = sep_open,
	.release = sep_release,
	.mmap = sep_mmap,
};

/**
 *	sep_register_driver_with_fs - register misc devices
 *	@sep: pointer to struct sep_device
 *
 *	This function registers the driver with the file system
 */
static int sep_register_driver_with_fs(struct sep_device *sep)
{
	int ret_val;

	sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR;
	sep->miscdev_sep.name = SEP_DEV_NAME;
	sep->miscdev_sep.fops = &sep_file_operations;

	sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR;
	sep->miscdev_singleton.name = SEP_DEV_SINGLETON;
	sep->miscdev_singleton.fops = &singleton_file_operations;

	sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR;
	sep->miscdev_daemon.name = SEP_DEV_DAEMON;
	sep->miscdev_daemon.fops = &daemon_file_operations;

	ret_val = misc_register(&sep->miscdev_sep);
	if (ret_val) {
		dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n",
			ret_val);
		return ret_val;
	}

	ret_val = misc_register(&sep->miscdev_singleton);
	if (ret_val) {
		dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n",
			ret_val);
		misc_deregister(&sep->miscdev_sep);
		return ret_val;
	}

	ret_val = misc_register(&sep->miscdev_daemon);
	if (ret_val) {
		dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n",
			ret_val);
		misc_deregister(&sep->miscdev_sep);
		misc_deregister(&sep->miscdev_singleton);

		return ret_val;
	}
	return ret_val;
}


/**
 *	sep_probe - probe a matching PCI device
 *	@pdev: pci_device
 *	@end: pci_device_id
 *
 *	Attempt to set up and configure a SEP device that has been
 *	discovered by the PCI layer.
 */
static int __devinit sep_probe(struct pci_dev *pdev,
	const struct pci_device_id *ent)
{
	int error = 0;
	struct sep_device *sep;

	if (sep_dev != NULL) {
		dev_warn(&pdev->dev, "only one SEP supported.\n");
		return -EBUSY;
	}

	/* Enable the device */
	error = pci_enable_device(pdev);
	if (error) {
		dev_warn(&pdev->dev, "error enabling pci device\n");
		goto end_function;
	}

	/* Allocate the sep_device structure for this device */
	sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC);
	if (sep_dev == NULL) {
		dev_warn(&pdev->dev,
			"can't kmalloc the sep_device structure\n");
		error = -ENOMEM;
		goto end_function_disable_device;
	}

	/*
	 * We're going to use another variable for actually
	 * working with the device; this way, if we have
	 * multiple devices in the future, it would be easier
	 * to make appropriate changes
	 */
	sep = sep_dev;

	sep->pdev = pci_dev_get(pdev);

	init_waitqueue_head(&sep->event);
	init_waitqueue_head(&sep->event_request_daemon);
	spin_lock_init(&sep->snd_rply_lck);
	mutex_init(&sep->sep_mutex);
	mutex_init(&sep->ioctl_mutex);

	dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, device being prepared\n");
	dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision);

	/* Set up our register area */
	sep->reg_physical_addr = pci_resource_start(sep->pdev, 0);
	if (!sep->reg_physical_addr) {
		dev_warn(&sep->pdev->dev, "Error getting register start\n");
		error = -ENODEV;
		goto end_function_free_sep_dev;
	}

	sep->reg_physical_end = pci_resource_end(sep->pdev, 0);
	if (!sep->reg_physical_end) {
		dev_warn(&sep->pdev->dev, "Error getting register end\n");
		error = -ENODEV;
		goto end_function_free_sep_dev;
	}

	sep->reg_addr = ioremap_nocache(sep->reg_physical_addr,
		(size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1));
	if (!sep->reg_addr) {
		dev_warn(&sep->pdev->dev, "Error getting register virtual\n");
		error = -ENODEV;
		goto end_function_free_sep_dev;
	}

	dev_dbg(&sep->pdev->dev,
		"Register area start %llx end %llx virtual %p\n",
		(unsigned long long)sep->reg_physical_addr,
		(unsigned long long)sep->reg_physical_end,
		sep->reg_addr);

	/* Allocate the shared area */
	sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES +
		SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES +
		SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES +
		SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES +
		SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES;

	if (sep_map_and_alloc_shared_area(sep)) {
		error = -ENOMEM;
		/* Allocation failed */
		goto end_function_error;
	}

	/* Clear ICR register */
	sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF);

	/* Set the IMR register - open only GPR 2 */
	sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));

	/* Read send/receive counters from SEP */
	sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR);
	sep->reply_ct &= 0x3FFFFFFF;
	sep->send_ct = sep->reply_ct;

	/* Get the interrupt line */
	error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED,
		"sep_driver", sep);

	if (error)
		goto end_function_deallocate_sep_shared_area;

	/* The new chip requires a shared area reconfigure */
	if (sep->pdev->revision == 4) { /* Only for new chip */
		error = sep_reconfig_shared_area(sep);
		if (error)
			goto end_function_free_irq;
	}
	/* Finally magic up the device nodes */
	/* Register driver with the fs */
	error = sep_register_driver_with_fs(sep);
	if (error == 0)
		/* Success */
		return 0;

end_function_free_irq:
	free_irq(pdev->irq, sep);

end_function_deallocate_sep_shared_area:
	/* De-allocate shared area */
	sep_unmap_and_free_shared_area(sep);

end_function_error:
	iounmap(sep->reg_addr);

end_function_free_sep_dev:
	pci_dev_put(sep_dev->pdev);
	kfree(sep_dev);
	sep_dev = NULL;

end_function_disable_device:
	pci_disable_device(pdev);

end_function:
	return error;
}

static void sep_remove(struct pci_dev *pdev)
{
	struct sep_device *sep = sep_dev;

	/* Unregister from fs */
	misc_deregister(&sep->miscdev_sep);
	misc_deregister(&sep->miscdev_singleton);
	misc_deregister(&sep->miscdev_daemon);

	/* Free the irq */
	free_irq(sep->pdev->irq, sep);

	/* Free the shared area  */
	sep_unmap_and_free_shared_area(sep_dev);
	iounmap((void *) sep_dev->reg_addr);
}

static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = {
	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)},
	{0}
};

MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl);

/* Field for registering driver to PCI device */
static struct pci_driver sep_pci_driver = {
	.name = "sep_sec_driver",
	.id_table = sep_pci_id_tbl,
	.probe = sep_probe,
	.remove = sep_remove
};


/**
 *	sep_init - init function
 *
 *	Module load time. Register the PCI device driver.
 */
static int __init sep_init(void)
{
	return pci_register_driver(&sep_pci_driver);
}


/**
 *	sep_exit - called to unload driver
 *
 *	Drop the misc devices then remove and unmap the various resources
 *	that are not released by the driver remove method.
 */
static void __exit sep_exit(void)
{
	pci_unregister_driver(&sep_pci_driver);
}


module_init(sep_init);
module_exit(sep_exit);

MODULE_LICENSE("GPL");
