/*
 *      memrar_handler 1.0:  An Intel restricted access region handler device
 *
 *      Copyright (C) 2010 Intel Corporation. All rights reserved.
 *
 *      This program is free software; you can redistribute it and/or
 *      modify it under the terms of version 2 of the GNU General
 *      Public License as published by the Free Software Foundation.
 *
 *      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.
 *      The full GNU General Public License is included in this
 *      distribution in the file called COPYING.
 *
 * -------------------------------------------------------------------
 *
 *      Moorestown restricted access regions (RAR) provide isolated
 *      areas of main memory that are only acceessible by authorized
 *      devices.
 *
 *      The Intel Moorestown RAR handler module exposes a kernel space
 *      RAR memory management mechanism.  It is essentially a
 *      RAR-specific allocator.
 *
 *      Besides providing RAR buffer management, the RAR handler also
 *      behaves in many ways like an OS virtual memory manager.  For
 *      example, the RAR "handles" created by the RAR handler are
 *      analogous to user space virtual addresses.
 *
 *      RAR memory itself is never accessed directly by the RAR
 *      handler.
 */

#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/kref.h>
#include <linux/mutex.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/io.h>

#include "../rar_register/rar_register.h"

#include "memrar.h"
#include "memrar_allocator.h"


#define MEMRAR_VER "1.0"

/*
 * Moorestown supports three restricted access regions.
 *
 * We only care about the first two, video and audio.  The third,
 * reserved for Chaabi and the P-unit, will be handled by their
 * respective drivers.
 */
#define MRST_NUM_RAR 2

/* ---------------- -------------------- ------------------- */

/**
 * struct memrar_buffer_info - struct that keeps track of all RAR buffers
 * @list:	Linked list of memrar_buffer_info objects.
 * @buffer:	Core RAR buffer information.
 * @refcount:	Reference count.
 * @owner:	File handle corresponding to process that reserved the
 *		block of memory in RAR.  This will be zero for buffers
 *		allocated by other drivers instead of by a user space
 *		process.
 *
 * This structure encapsulates a link list of RAR buffers, as well as
 * other characteristics specific to a given list node, such as the
 * reference count on the corresponding RAR buffer.
 */
struct memrar_buffer_info {
	struct list_head list;
	struct RAR_buffer buffer;
	struct kref refcount;
	struct file *owner;
};

/**
 * struct memrar_rar_info - characteristics of a given RAR
 * @base:	Base bus address of the RAR.
 * @length:	Length of the RAR.
 * @iobase:	Virtual address of RAR mapped into kernel.
 * @allocator:	Allocator associated with the RAR.  Note the allocator
 *		"capacity" may be smaller than the RAR length if the
 *		length is not a multiple of the configured allocator
 *		block size.
 * @buffers:	Table that keeps track of all reserved RAR buffers.
 * @lock:	Lock used to synchronize access to RAR-specific data
 *		structures.
 *
 * Each RAR has an associated memrar_rar_info structure that describes
 * where in memory the RAR is located, how large it is, and a list of
 * reserved RAR buffers inside that RAR.  Each RAR also has a mutex
 * associated with it to reduce lock contention when operations on
 * multiple RARs are performed in parallel.
 */
struct memrar_rar_info {
	dma_addr_t base;
	unsigned long length;
	void __iomem *iobase;
	struct memrar_allocator *allocator;
	struct memrar_buffer_info buffers;
	struct mutex lock;
	int allocated;	/* True if we own this RAR */
};

/*
 * Array of RAR characteristics.
 */
static struct memrar_rar_info memrars[MRST_NUM_RAR];

/* ---------------- -------------------- ------------------- */

/* Validate RAR type. */
static inline int memrar_is_valid_rar_type(u32 type)
{
	return type == RAR_TYPE_VIDEO || type == RAR_TYPE_AUDIO;
}

/* Check if an address/handle falls with the given RAR memory range. */
static inline int memrar_handle_in_range(struct memrar_rar_info *rar,
					 u32 vaddr)
{
	unsigned long const iobase = (unsigned long) (rar->iobase);
	return (vaddr >= iobase && vaddr < iobase + rar->length);
}

/* Retrieve RAR information associated with the given handle. */
static struct memrar_rar_info *memrar_get_rar_info(u32 vaddr)
{
	int i;
	for (i = 0; i < MRST_NUM_RAR; ++i) {
		struct memrar_rar_info * const rar = &memrars[i];
		if (memrar_handle_in_range(rar, vaddr))
			return rar;
	}

	return NULL;
}

/**
 *	memrar_get_bus address		-	handle to bus address
 *
 *	Retrieve bus address from given handle.
 *
 *	Returns address corresponding to given handle.  Zero if handle is
 *	invalid.
 */
static dma_addr_t memrar_get_bus_address(
	struct memrar_rar_info *rar,
	u32 vaddr)
{
	unsigned long const iobase = (unsigned long) (rar->iobase);

	if (!memrar_handle_in_range(rar, vaddr))
		return 0;

	/*
	 * An assumption is made that the virtual address offset is
	 * the same as the bus address offset, at least based on the
	 * way this driver is implemented.  For example, vaddr + 2 ==
	 * baddr + 2.
	 *
	 * @todo Is that a valid assumption?
	 */
	return rar->base + (vaddr - iobase);
}

/**
 *	memrar_get_physical_address	-	handle to physical address
 *
 *	Retrieve physical address from given handle.
 *
 *	Returns address corresponding to given handle.  Zero if handle is
 *	invalid.
 */
static dma_addr_t memrar_get_physical_address(
	struct memrar_rar_info *rar,
	u32 vaddr)
{
	/*
	 * @todo This assumes that the bus address and physical
	 *       address are the same.  That is true for Moorestown
	 *       but not necessarily on other platforms.  This
	 *       deficiency should be addressed at some point.
	 */
	return memrar_get_bus_address(rar, vaddr);
}

/**
 *	memrar_release_block	-	release a block to the pool
 *	@kref: kref of block
 *
 *	Core block release code. A node has hit zero references so can
 *	be released and the lists must be updated.
 *
 *	Note: This code removes the node from a list.  Make sure any list
 *	iteration is performed using list_for_each_safe().
 */
static void memrar_release_block_i(struct kref *ref)
{
	/*
	 * Last reference is being released.  Remove from the table,
	 * and reclaim resources.
	 */

	struct memrar_buffer_info * const node =
		container_of(ref, struct memrar_buffer_info, refcount);

	struct RAR_block_info * const user_info =
		&node->buffer.info;

	struct memrar_allocator * const allocator =
		memrars[user_info->type].allocator;

	list_del(&node->list);

	memrar_allocator_free(allocator, user_info->handle);

	kfree(node);
}

/**
 *	memrar_init_rar_resources	-	configure a RAR
 *	@rarnum: rar that has been allocated
 *	@devname: name of our device
 *
 *	Initialize RAR parameters, such as bus addresses, etc and make
 *	the resource accessible.
 */
static int memrar_init_rar_resources(int rarnum, char const *devname)
{
	/* ---- Sanity Checks ----
	 * 1. RAR bus addresses in both Lincroft and Langwell RAR
	 *    registers should be the same.
	 *    a. There's no way we can do this through IA.
	 *
	 * 2. Secure device ID in Langwell RAR registers should be set
	 *    appropriately, e.g. only LPE DMA for the audio RAR, and
	 *    security for the other Langwell based RAR registers.
	 *    a. There's no way we can do this through IA.
	 *
	 * 3. Audio and video RAR registers and RAR access should be
	 *    locked down.  If not, enable RAR access control.  Except
	 *    for debugging purposes, there is no reason for them to
	 *    be unlocked.
	 *    a.  We can only do this for the Lincroft (IA) side.
	 *
	 * @todo Should the RAR handler driver even be aware of audio
	 *       and video RAR settings?
	 */

	/*
	 * RAR buffer block size.
	 *
	 * We choose it to be the size of a page to simplify the
	 * /dev/memrar mmap() implementation and usage.  Otherwise
	 * paging is not involved once an RAR is locked down.
	 */
	static size_t const RAR_BLOCK_SIZE = PAGE_SIZE;

	dma_addr_t low, high;
	struct memrar_rar_info * const rar = &memrars[rarnum];

	BUG_ON(MRST_NUM_RAR != ARRAY_SIZE(memrars));
	BUG_ON(!memrar_is_valid_rar_type(rarnum));
	BUG_ON(rar->allocated);

	mutex_init(&rar->lock);

	/*
	 * Initialize the process table before we reach any
	 * code that exit on failure since the finalization
	 * code requires an initialized list.
	 */
	INIT_LIST_HEAD(&rar->buffers.list);

	if (rar_get_address(rarnum, &low, &high) != 0)
		/* No RAR is available. */
		return -ENODEV;
	
	if (low == 0 || high == 0) {
		rar->base      = 0;
		rar->length    = 0;
		rar->iobase    = NULL;
		rar->allocator = NULL;
		return -ENOSPC;
	}

	/*
	 * @todo Verify that LNC and LNW RAR register contents
	 *       addresses, security, etc are compatible and
	 *       consistent).
	 */

	rar->length = high - low + 1;

	/* Claim RAR memory as our own. */
	if (request_mem_region(low, rar->length, devname) == NULL) {
		rar->length = 0;
		pr_err("%s: Unable to claim RAR[%d] memory.\n", devname, rarnum);
		pr_err("%s: RAR[%d] disabled.\n", devname, rarnum);
		return -EBUSY;
	}

	rar->base = low;

	/*
	 * Now map it into the kernel address space.
	 *
	 * Note that the RAR memory may only be accessed by IA
	 * when debugging.  Otherwise attempts to access the
	 * RAR memory when it is locked down will result in
	 * behavior similar to writing to /dev/null and
	 * reading from /dev/zero.  This behavior is enforced
	 * by the hardware.  Even if we don't access the
	 * memory, mapping it into the kernel provides us with
	 * a convenient RAR handle to bus address mapping.
	 */
	rar->iobase = ioremap_nocache(rar->base, rar->length);
	if (rar->iobase == NULL) {
		pr_err("%s: Unable to map RAR memory.\n", devname);
		release_mem_region(low, rar->length);
		return -ENOMEM;
	}

	/* Initialize corresponding memory allocator. */
	rar->allocator = memrar_create_allocator((unsigned long) rar->iobase,
						rar->length, RAR_BLOCK_SIZE);
	if (rar->allocator == NULL) {
		iounmap(rar->iobase);
		release_mem_region(low, rar->length);
		return -ENOMEM;
	}

	pr_info("%s: BRAR[%d] bus address range = [0x%lx, 0x%lx]\n",
			devname, rarnum, (unsigned long) low, (unsigned long) high);

	pr_info("%s: BRAR[%d] size = %zu KiB\n",
			devname, rarnum, rar->allocator->capacity / 1024);

	rar->allocated = 1;
	return 0;
}

/**
 *	memrar_fini_rar_resources	-	free up RAR resources
 *
 *	Finalize RAR resources. Free up the resource tables, hand the memory
 *	back to the kernel, unmap the device and release the address space.
 */
static void memrar_fini_rar_resources(void)
{
	int z;
	struct memrar_buffer_info *pos;
	struct memrar_buffer_info *tmp;

	/*
	 * @todo Do we need to hold a lock at this point in time?
	 *       (module initialization failure or exit?)
	 */

	for (z = MRST_NUM_RAR; z-- != 0; ) {
		struct memrar_rar_info * const rar = &memrars[z];

		if (!rar->allocated)
			continue;

		/* Clean up remaining resources. */

		list_for_each_entry_safe(pos,
					 tmp,
					 &rar->buffers.list,
					 list) {
			kref_put(&pos->refcount, memrar_release_block_i);
		}

		memrar_destroy_allocator(rar->allocator);
		rar->allocator = NULL;

		iounmap(rar->iobase);
		release_mem_region(rar->base, rar->length);

		rar->iobase = NULL;
		rar->base = 0;
		rar->length = 0;

		unregister_rar(z);
	}
}

/**
 *	memrar_reserve_block	-	handle an allocation request
 *	@request: block being requested
 *	@filp: owner it is tied to
 *
 *	Allocate a block of the requested RAR. If successful return the
 *	request object filled in and zero, if not report an error code
 */

static long memrar_reserve_block(struct RAR_buffer *request,
				 struct file *filp)
{
	struct RAR_block_info * const rinfo = &request->info;
	struct RAR_buffer *buffer;
	struct memrar_buffer_info *buffer_info;
	u32 handle;
	struct memrar_rar_info *rar = NULL;

	/* Prevent array overflow. */
	if (!memrar_is_valid_rar_type(rinfo->type))
		return -EINVAL;

	rar = &memrars[rinfo->type];
	if (!rar->allocated)
		return -ENODEV;

	/* Reserve memory in RAR. */
	handle = memrar_allocator_alloc(rar->allocator, rinfo->size);
	if (handle == 0)
		return -ENOMEM;

	buffer_info = kmalloc(sizeof(*buffer_info), GFP_KERNEL);

	if (buffer_info == NULL) {
		memrar_allocator_free(rar->allocator, handle);
		return -ENOMEM;
	}

	buffer = &buffer_info->buffer;
	buffer->info.type = rinfo->type;
	buffer->info.size = rinfo->size;

	/* Memory handle corresponding to the bus address. */
	buffer->info.handle = handle;
	buffer->bus_address = memrar_get_bus_address(rar, handle);

	/*
	 * Keep track of owner so that we can later cleanup if
	 * necessary.
	 */
	buffer_info->owner = filp;

	kref_init(&buffer_info->refcount);

	mutex_lock(&rar->lock);
	list_add(&buffer_info->list, &rar->buffers.list);
	mutex_unlock(&rar->lock);

	rinfo->handle = buffer->info.handle;
	request->bus_address = buffer->bus_address;

	return 0;
}

/**
 *	memrar_release_block		-	release a RAR block
 *	@addr: address in RAR space
 *
 *	Release a previously allocated block. Releases act on complete
 *	blocks, partially freeing a block is not supported
 */

static long memrar_release_block(u32 addr)
{
	struct memrar_buffer_info *pos;
	struct memrar_buffer_info *tmp;
	struct memrar_rar_info * const rar = memrar_get_rar_info(addr);
	long result = -EINVAL;

	if (rar == NULL)
		return -ENOENT;

	mutex_lock(&rar->lock);

	/*
	 * Iterate through the buffer list to find the corresponding
	 * buffer to be released.
	 */
	list_for_each_entry_safe(pos,
				 tmp,
				 &rar->buffers.list,
				 list) {
		struct RAR_block_info * const info =
			&pos->buffer.info;

		/*
		 * Take into account handle offsets that may have been
		 * added to the base handle, such as in the following
		 * scenario:
		 *
		 *     u32 handle = base + offset;
		 *     rar_handle_to_bus(handle);
		 *     rar_release(handle);
		 */
		if (addr >= info->handle
		    && addr < (info->handle + info->size)
		    && memrar_is_valid_rar_type(info->type)) {
			kref_put(&pos->refcount, memrar_release_block_i);
			result = 0;
			break;
		}
	}

	mutex_unlock(&rar->lock);

	return result;
}

/**
 *	memrar_get_stats	-	read statistics for a RAR
 *	@r: statistics to be filled in
 *
 *	Returns the statistics data for the RAR, or an error code if
 *	the request cannot be completed
 */
static long memrar_get_stat(struct RAR_stat *r)
{
	struct memrar_allocator *allocator;

 	if (!memrar_is_valid_rar_type(r->type))
		return -EINVAL;

	if (!memrars[r->type].allocated)
		return -ENODEV;

	allocator = memrars[r->type].allocator;

	BUG_ON(allocator == NULL);

	/*
	 * Allocator capacity doesn't change over time.  No
	 * need to synchronize.
	 */
	r->capacity = allocator->capacity;

	mutex_lock(&allocator->lock);
	r->largest_block_size = allocator->largest_free_area;
	mutex_unlock(&allocator->lock);
	return 0;
}

/**
 *	memrar_ioctl		-	ioctl callback
 *	@filp: file issuing the request
 *	@cmd: command
 *	@arg: pointer to control information
 *
 *	Perform one of the ioctls supported by the memrar device
 */

static long memrar_ioctl(struct file *filp,
			 unsigned int cmd,
			 unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	long result = 0;

	struct RAR_buffer buffer;
	struct RAR_block_info * const request = &buffer.info;
	struct RAR_stat rar_info;
	u32 rar_handle;

	switch (cmd) {
	case RAR_HANDLER_RESERVE:
		if (copy_from_user(request,
				   argp,
				   sizeof(*request)))
			return -EFAULT;

		result = memrar_reserve_block(&buffer, filp);
		if (result != 0)
			return result;

		return copy_to_user(argp, request, sizeof(*request));

	case RAR_HANDLER_RELEASE:
		if (copy_from_user(&rar_handle,
				   argp,
				   sizeof(rar_handle)))
			return -EFAULT;

		return memrar_release_block(rar_handle);

	case RAR_HANDLER_STAT:
		if (copy_from_user(&rar_info,
				   argp,
				   sizeof(rar_info)))
			return -EFAULT;

		/*
		 * Populate the RAR_stat structure based on the RAR
		 * type given by the user
		 */
		if (memrar_get_stat(&rar_info) != 0)
			return -EINVAL;

		/*
		 * @todo Do we need to verify destination pointer
		 *       "argp" is non-zero?  Is that already done by
		 *       copy_to_user()?
		 */
		return copy_to_user(argp,
				    &rar_info,
				    sizeof(rar_info)) ? -EFAULT : 0;

	default:
		return -ENOTTY;
	}

	return 0;
}

/**
 *	memrar_mmap		-	mmap helper for deubgging
 *	@filp: handle doing the mapping
 *	@vma: memory area
 *
 *	Support the mmap operation on the RAR space for debugging systems
 *	when the memory is not locked down.
 */

static int memrar_mmap(struct file *filp, struct vm_area_struct *vma)
{
	/*
	 * This mmap() implementation is predominantly useful for
	 * debugging since the CPU will be prevented from accessing
	 * RAR memory by the hardware when RAR is properly locked
	 * down.
	 *
	 * In order for this implementation to be useful RAR memory
	 * must be not be locked down.  However, we only want to do
	 * that when debugging.  DO NOT leave RAR memory unlocked in a
	 * deployed device that utilizes RAR.
	 */

	size_t const size = vma->vm_end - vma->vm_start;

	/* Users pass the RAR handle as the mmap() offset parameter. */
	unsigned long const handle = vma->vm_pgoff << PAGE_SHIFT;

	struct memrar_rar_info * const rar = memrar_get_rar_info(handle);
	unsigned long pfn;

	/* Only allow priviledged apps to go poking around this way */
	if (!capable(CAP_SYS_RAWIO))
		return -EPERM;

	/* Invalid RAR handle or size passed to mmap(). */
	if (rar == NULL
	    || handle == 0
	    || size > (handle - (unsigned long) rar->iobase))
		return -EINVAL;

	/*
	 * Retrieve physical address corresponding to the RAR handle,
	 * and convert it to a page frame.
	 */
	pfn = memrar_get_physical_address(rar, handle) >> PAGE_SHIFT;


	pr_debug("memrar: mapping RAR range [0x%lx, 0x%lx) into user space.\n",
		 handle,
		 handle + size);

	/*
	 * Map RAR memory into user space.  This is really only useful
	 * for debugging purposes since the memory won't be
	 * accessible, i.e. reads return zero and writes are ignored,
	 * when RAR access control is enabled.
	 */
	if (remap_pfn_range(vma,
			    vma->vm_start,
			    pfn,
			    size,
			    vma->vm_page_prot))
		return -EAGAIN;

	/* vma->vm_ops = &memrar_mem_ops; */

	return 0;
}

/**
 *	memrar_open		-	device open method
 *	@inode: inode to open
 *	@filp: file handle
 *
 *	As we support multiple arbitary opens there is no work to be done
 *	really.
 */

static int memrar_open(struct inode *inode, struct file *filp)
{
	nonseekable_open(inode, filp);
	return 0;
}

/**
 *	memrar_release		-	close method for miscev
 *	@inode: inode of device
 *	@filp: handle that is going away
 *
 *	Free up all the regions that belong to this file handle. We use
 *	the handle as a natural Linux style 'lifetime' indicator and to
 *	ensure resources are not leaked when their owner explodes in an
 *	unplanned fashion.
 */

static int memrar_release(struct inode *inode, struct file *filp)
{
	/* Free all regions associated with the given file handle. */

	struct memrar_buffer_info *pos;
	struct memrar_buffer_info *tmp;
	int z;

	for (z = 0; z != MRST_NUM_RAR; ++z) {
		struct memrar_rar_info * const rar = &memrars[z];

		mutex_lock(&rar->lock);

		list_for_each_entry_safe(pos,
					 tmp,
					 &rar->buffers.list,
					 list) {
			if (filp == pos->owner)
				kref_put(&pos->refcount,
					 memrar_release_block_i);
		}

		mutex_unlock(&rar->lock);
	}

	return 0;
}

/**
 *	rar_reserve		-	reserve RAR memory
 *	@buffers: buffers to reserve
 *	@count: number wanted
 *
 *	Reserve a series of buffers in the RAR space. Returns the number of
 *	buffers successfully allocated
 */

size_t rar_reserve(struct RAR_buffer *buffers, size_t count)
{
	struct RAR_buffer * const end =
		(buffers == NULL ? buffers : buffers + count);
	struct RAR_buffer *i;

	size_t reserve_count = 0;

	for (i = buffers; i != end; ++i) {
		if (memrar_reserve_block(i, NULL) == 0)
			++reserve_count;
		else
			i->bus_address = 0;
	}

	return reserve_count;
}
EXPORT_SYMBOL(rar_reserve);

/**
 *	rar_release		-	return RAR buffers
 *	@buffers: buffers to release
 *	@size: size of released block
 *
 *	Return a set of buffers to the RAR pool
 */

size_t rar_release(struct RAR_buffer *buffers, size_t count)
{
	struct RAR_buffer * const end =
		(buffers == NULL ? buffers : buffers + count);
	struct RAR_buffer *i;

	size_t release_count = 0;

	for (i = buffers; i != end; ++i) {
		u32 * const handle = &i->info.handle;
		if (memrar_release_block(*handle) == 0) {
			/*
			 * @todo We assume we should do this each time
			 *       the ref count is decremented.  Should
			 *       we instead only do this when the ref
			 *       count has dropped to zero, and the
			 *       buffer has been completely
			 *       released/unmapped?
			 */
			*handle = 0;
			++release_count;
		}
	}

	return release_count;
}
EXPORT_SYMBOL(rar_release);

/**
 *	rar_handle_to_bus	-	RAR to bus address
 *	@buffers: RAR buffer structure
 *	@count: number of buffers to convert
 *
 *	Turn a list of RAR handle mappings into actual bus addresses. Note
 *	that when the device is locked down the bus addresses in question
 *	are not CPU accessible.
 */

size_t rar_handle_to_bus(struct RAR_buffer *buffers, size_t count)
{
	struct RAR_buffer * const end =
		(buffers == NULL ? buffers : buffers + count);
	struct RAR_buffer *i;
	struct memrar_buffer_info *pos;

	size_t conversion_count = 0;

	/*
	 * Find all bus addresses corresponding to the given handles.
	 *
	 * @todo Not liking this nested loop.  Optimize.
	 */
	for (i = buffers; i != end; ++i) {
		struct memrar_rar_info * const rar =
			memrar_get_rar_info(i->info.handle);

		/*
		 * Check if we have a bogus handle, and then continue
		 * with remaining buffers.
		 */
		if (rar == NULL) {
			i->bus_address = 0;
			continue;
		}

		mutex_lock(&rar->lock);

		list_for_each_entry(pos, &rar->buffers.list, list) {
			struct RAR_block_info * const user_info =
				&pos->buffer.info;

			/*
			 * Take into account handle offsets that may
			 * have been added to the base handle, such as
			 * in the following scenario:
			 *
			 *     u32 handle = base + offset;
			 *     rar_handle_to_bus(handle);
			 */

			if (i->info.handle >= user_info->handle
			    && i->info.handle < (user_info->handle
						 + user_info->size)) {
				u32 const offset =
					i->info.handle - user_info->handle;

				i->info.type = user_info->type;
				i->info.size = user_info->size - offset;
				i->bus_address =
					pos->buffer.bus_address
					+ offset;

				/* Increment the reference count. */
				kref_get(&pos->refcount);

				++conversion_count;
				break;
			} else {
				i->bus_address = 0;
			}
		}

		mutex_unlock(&rar->lock);
	}

	return conversion_count;
}
EXPORT_SYMBOL(rar_handle_to_bus);

static const struct file_operations memrar_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = memrar_ioctl,
	.mmap           = memrar_mmap,
	.open           = memrar_open,
	.release        = memrar_release,
};

static struct miscdevice memrar_miscdev = {
	.minor = MISC_DYNAMIC_MINOR,    /* dynamic allocation */
	.name = "memrar",               /* /dev/memrar */
	.fops = &memrar_fops
};

static char const banner[] __initdata =
	KERN_INFO
	"Intel RAR Handler: " MEMRAR_VER " initialized.\n";

/**
 *	memrar_registration_callback	-	RAR obtained
 *	@rar: RAR number
 *
 *	We have been granted ownership of the RAR. Add it to our memory
 *	management tables
 */

static int memrar_registration_callback(unsigned long rar)
{
	/*
	 * We initialize the RAR parameters early on so that we can
	 * discontinue memrar device initialization and registration
	 * if suitably configured RARs are not available.
	 */
	return memrar_init_rar_resources(rar, memrar_miscdev.name);
}

/**
 *	memrar_init	-	initialise RAR support
 *
 *	Initialise support for RAR handlers. This may get loaded before
 *	the RAR support is activated, but the callbacks on the registration
 *	will handle that situation for us anyway.
 */

static int __init memrar_init(void)
{
	int err;

	printk(banner);

	err = misc_register(&memrar_miscdev);
	if (err)
		return err;

	/* Now claim the two RARs we want */
	err = register_rar(0, memrar_registration_callback, 0);
	if (err)
		goto fail;

	err = register_rar(1, memrar_registration_callback, 1);
	if (err == 0)
		return 0;

	/* It is possible rar 0 registered and allocated resources then rar 1
	   failed so do a full resource free */
	memrar_fini_rar_resources();
fail:
	misc_deregister(&memrar_miscdev);
	return err;
}

/**
 *	memrar_exit	-	unregister and unload
 *
 *	Unregister the device and then unload any mappings and release
 *	the RAR resources
 */

static void __exit memrar_exit(void)
{
	misc_deregister(&memrar_miscdev);
	memrar_fini_rar_resources();
}


module_init(memrar_init);
module_exit(memrar_exit);


MODULE_AUTHOR("Ossama Othman <ossama.othman@intel.com>");
MODULE_DESCRIPTION("Intel Restricted Access Region Handler");
MODULE_LICENSE("GPL");
MODULE_VERSION(MEMRAR_VER);



/*
  Local Variables:
    c-file-style: "linux"
  End:
*/
