[PATCH] Staging: memrar: moved user code away from core code moved memrar_ioctl, rar_reserve, rar_release, rar_handle_to_bus to memrar_user.c

Chris McIntosh rougechampion2002 at gmail.com
Thu Jul 29 05:12:21 UTC 2010


Signed-off-by: Chris McIntosh <rougechampion2002 at gmail.com>
---
 drivers/staging/memrar/memrar_handler.c |  207 ---------------------
 drivers/staging/memrar/memrar_user.c    |  305 +++++++++++++++++++++++++++++++
 2 files changed, 305 insertions(+), 207 deletions(-)
 create mode 100644 drivers/staging/memrar/memrar_user.c

diff --git a/drivers/staging/memrar/memrar_handler.c b/drivers/staging/memrar/memrar_handler.c
index 5fe6028..7b4511c 100644
--- a/drivers/staging/memrar/memrar_handler.c
+++ b/drivers/staging/memrar/memrar_handler.c
@@ -562,68 +562,6 @@ static long memrar_get_stat(struct RAR_stat *r)
  *	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
@@ -748,151 +686,6 @@ static int memrar_release(struct inode *inode, struct file *filp)
 	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,
diff --git a/drivers/staging/memrar/memrar_user.c b/drivers/staging/memrar/memrar_user.c
new file mode 100644
index 0000000..a035bce
--- /dev/null
+++ b/drivers/staging/memrar/memrar_user.c
@@ -0,0 +1,305 @@
+/*
+ *      memrar_user 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 <linux/rar_register.h>
+
+#include "memrar.h"
+#include "memrar_allocator.h"
+
+
+/*
+ * 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 memrar_rar_info; 
+static struct memrar_rar_info memrars[MRST_NUM_RAR];
+
+static inline int memrar_is_valid_rar_type(u32 type);
+static inline int memrar_handle_in_range(struct memrar_rar_info *rar,
+					 u32 vaddr);
+static struct memrar_rar_info *memrar_get_rar_info(u32 vaddr);
+static dma_addr_t memrar_get_bus_address(
+	struct memrar_rar_info *rar,
+	u32 vaddr);
+static dma_addr_t memrar_get_physical_address(
+	struct memrar_rar_info *rar,
+	u32 vaddr);
+static void memrar_release_block_i(struct kref *ref);
+static int memrar_init_rar_resources(int rarnum, char const *devname);
+static void memrar_fini_rar_resources(void);
+static long memrar_reserve_block(struct RAR_buffer *request,
+				 struct file *filp);
+static long memrar_release_block(u32 addr);
+static long memrar_get_stat(struct RAR_stat *r);
+static int memrar_mmap(struct file *filp, struct vm_area_struct *vma);
+static int memrar_open(struct inode *inode, struct file *filp);
+static int memrar_release(struct inode *inode, struct file *filp);
+static int memrar_registration_callback(unsigned long rar);
+
+/**
+ *	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;
+}
+
+/**
+ *	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);
-- 
1.7.0.4




More information about the devel mailing list