summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakamath <akamath@nvidia.com>2010-04-19 14:48:12 +0530
committerGary King <gking@nvidia.com>2010-05-12 19:35:43 -0700
commitb9166ad37e5695f47c6a1b5d34a9241dfb5d4c9c (patch)
tree3be51bc5217e7fc7df221e0f21b3a29d320d96de
parentab20a6c358810453240d160f9bb6953d025f5618 (diff)
tegra RM : Bug 661401 Move RM transport into a seperate device node
Change-Id: Ia2153071522be2badfb192057c6facad227f6dd4 Reviewed-on: http://git-master/r/1148 Tested-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rwxr-xr-xarch/arm/mach-tegra/include/linux/nvrpc_ioctl.h102
-rwxr-xr-xarch/arm/mach-tegra/nvrpc_user.c658
3 files changed, 761 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 8aece41dcc6c..4dc32e649534 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_MACH_TEGRA_GENERIC) += nvodm/
obj-$(CONFIG_MACH_TEGRA_GENERIC) += odm_kit/
obj-$(CONFIG_MACH_TEGRA_GENERIC) += nvos_user.o
obj-$(CONFIG_MACH_TEGRA_GENERIC) += nvrm_user.o
+obj-$(CONFIG_MACH_TEGRA_GENERIC) += nvrpc_user.o
obj-$(CONFIG_MACH_TEGRA_GENERIC) += init_common.o
obj-$(CONFIG_MACH_TEGRA_GENERIC) += board_nvodm.o
obj-$(CONFIG_MACH_TEGRA_GENERIC) += odm_to_plat.o
diff --git a/arch/arm/mach-tegra/include/linux/nvrpc_ioctl.h b/arch/arm/mach-tegra/include/linux/nvrpc_ioctl.h
new file mode 100755
index 000000000000..5158aa7199b3
--- /dev/null
+++ b/arch/arm/mach-tegra/include/linux/nvrpc_ioctl.h
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/mach-tegra/include/linux/nvrpc_ioctl.h
+ *
+ * structure declarations for nvrpc user-space ioctls
+ *
+ * Copyright (c) 2009, NVIDIA Corporation.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#if !defined(__KERNEL__)
+#define __user
+#endif
+
+#ifndef _MACH_TEGRA_NVRPC_IOCTL_H_
+#define _MACH_TEGRA_NVRPC_IOCTL_H_
+
+struct nvrpc_handle_param {
+ __u32 handle;
+ __u32 param;
+ __u32 ret_val; /* operation status */
+};
+
+struct nvrpc_open_params {
+ __u32 rm_handle; /* rm device handle */
+ __u32 port_name_size; /* port name buffer size */
+ __u32 receive_sem_handle; /* receive semaphore handle */
+ __u32 transport_handle; /* transport handle */
+ __u32 ret_val; /* operation status */
+ unsigned long port_name; /* port name */
+};
+
+struct nvrpc_set_queue_depth_params {
+ __u32 transport_handle; /* transport handle */
+ __u32 max_queue_depth; /* maximum number of message in Queue */
+ __u32 max_message_size; /* maximum size of the message in bytes */
+ __u32 ret_val; /* operation status */
+};
+
+struct nvrpc_msg_params {
+ __u32 transport_handle; /* transport handle */
+ __u32 max_message_size; /* maximum size of the message in bytes */
+ __u32 params; /* timeout in ms */
+ __u32 ret_val; /* operation status */
+ unsigned long msg_buffer;
+};
+
+#define NVRPC_IOC_MAGIC 'N'
+
+#define NVRPC_IOCTL_INIT \
+ _IOWR(NVRPC_IOC_MAGIC, 0x30, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_OPEN \
+ _IOWR(NVRPC_IOC_MAGIC, 0x31, struct nvrpc_open_params)
+#define NVRPC_IOCTL_GET_PORTNAME \
+ _IOWR(NVRPC_IOC_MAGIC, 0x32, struct nvrpc_open_params)
+#define NVRPC_IOCTL_CLOSE \
+ _IOWR(NVRPC_IOC_MAGIC, 0x33, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_DEINIT \
+ _IOWR(NVRPC_IOC_MAGIC, 0x34, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_WAIT_FOR_CONNECT \
+ _IOWR(NVRPC_IOC_MAGIC, 0x35, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_CONNECT \
+ _IOWR(NVRPC_IOC_MAGIC, 0x36, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_SET_QUEUE_DEPTH \
+ _IOWR(NVRPC_IOC_MAGIC, 0x37, struct nvrpc_set_queue_depth_params)
+#define NVRPC_IOCTL_SEND_MSG \
+ _IOWR(NVRPC_IOC_MAGIC, 0x38, struct nvrpc_msg_params)
+#define NVRPC_IOCTL_SEND_MSG_LP0 \
+ _IOWR(NVRPC_IOC_MAGIC, 0x39, struct nvrpc_msg_params)
+#define NVRPC_IOCTL_RECV_MSG \
+ _IOWR(NVRPC_IOC_MAGIC, 0x3A, struct nvrpc_msg_params)
+#define NVRPC_IOCTL_XPC_INIT \
+ _IOWR(NVRPC_IOC_MAGIC, 0x3B, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_XPC_ACQUIRE \
+ _IOWR(NVRPC_IOC_MAGIC, 0x3C, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_XPC_RELEASE \
+ _IOWR(NVRPC_IOC_MAGIC, 0x3D, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_XPC_GET_MSG \
+ _IOWR(NVRPC_IOC_MAGIC, 0x3E, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_XPC_SEND_MSG \
+ _IOWR(NVRPC_IOC_MAGIC, 0x3F, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_XPC_DESTROY \
+ _IOWR(NVRPC_IOC_MAGIC, 0x40, struct nvrpc_handle_param)
+#define NVRPC_IOCTL_XPC_CREATE \
+ _IOWR(NVRPC_IOC_MAGIC, 0x41, struct nvrpc_handle_param)
+
+#endif
diff --git a/arch/arm/mach-tegra/nvrpc_user.c b/arch/arm/mach-tegra/nvrpc_user.c
new file mode 100755
index 000000000000..0989eff4dcb6
--- /dev/null
+++ b/arch/arm/mach-tegra/nvrpc_user.c
@@ -0,0 +1,658 @@
+/*
+ * arch/arm/mach-tegra/nvrpc_user.c
+ *
+ * User-land access to NvRm transport APIs
+ *
+ * Copyright (c) 2008-2010, NVIDIA Corporation.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <mach/nvrm_linux.h>
+#include "nvcommon.h"
+#include "nvassert.h"
+#include "nvos.h"
+#include "nvrm_transport.h"
+#include "nvrm_xpc.h"
+#include "linux/nvrpc_ioctl.h"
+
+#define DEVICE_NAME "nvrpc"
+#define NVRPC_MAX_LOCAL_STACK 256
+#define nvrpc_stack_kzalloc(stackbuf, size, gfp) \
+ ((size) > sizeof((stackbuf)) ? kzalloc((size),(gfp)) : (stackbuf))
+#define nvrpc_stack_kfree(stackbuf, buf) \
+ do { \
+ if ((buf) && (buf)!=(stackbuf)) \
+ kfree(buf); \
+ } while (0);
+
+static int nvrpc_open(struct inode *inode, struct file *file);
+static int nvrpc_close(struct inode *inode, struct file *file);
+static long nvrpc_unlocked_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+
+//Ioctl functions
+static int nvrpc_ioctl_open(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_get_port_name(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_close(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_wait_for_connect(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_connect(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_set_queue_depth(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_send_msg(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_send_msg_lp0(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_recv_msg(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_init(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_acquire(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_release(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_get_msg(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_send_msg(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_destroy(struct file *filp,
+ unsigned int cmd, void __user *arg);
+static int nvrpc_ioctl_xpc_create(struct file *filp,
+ unsigned int cmd, void __user *arg);
+// local function
+static int nvrpc_make_error_code(NvError e);
+
+static const struct file_operations nvrpc_fops =
+{
+ .owner = THIS_MODULE,
+ .open = nvrpc_open,
+ .release = nvrpc_close,
+ .unlocked_ioctl = nvrpc_unlocked_ioctl,
+};
+
+static struct miscdevice nvrpc_dev =
+{
+ .name = DEVICE_NAME,
+ .fops = &nvrpc_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+};
+
+static DEFINE_MUTEX(nvrpc_device_lock);
+
+int nvrpc_open(struct inode *inode, struct file *file)
+{
+ NvError e = NvSuccess;
+ static NvBool init_done = NV_FALSE;
+
+ mutex_lock(&nvrpc_device_lock);
+ if (init_done == NV_FALSE)
+ {
+ e = NvRmTransportInit(s_hRmGlobal);
+ init_done = NV_TRUE;
+ }
+ mutex_unlock(&nvrpc_device_lock);
+
+ if (e == NvSuccess)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+int nvrpc_close(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int nvrpc_make_error_code(NvError e)
+{
+ int error = 0;
+ if (error != NvSuccess)
+ {
+ if (e == NvError_InvalidAddress)
+ error = -EFAULT;
+ else if (e == NvError_BadParameter)
+ error = -EINVAL;
+ else
+ error = -EIO;
+ }
+ return error;
+}
+
+static int nvrpc_ioctl_open(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ NvError e = NvSuccess;
+ int error;
+ struct nvrpc_open_params op;
+ char *p_name = NULL;
+ NvOsSemaphoreHandle recv_sem = NULL;
+ NvU32 port_name[NVRPC_MAX_LOCAL_STACK/sizeof(NvU32)];
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+
+ if (op.port_name_size)
+ {
+ p_name = nvrpc_stack_kzalloc(port_name, op.port_name_size, GFP_KERNEL);
+ if (!p_name)
+ {
+ error = -ENOMEM;
+ goto fail;
+ }
+ error = copy_from_user(p_name,
+ (const void*)op.port_name,
+ op.port_name_size);
+ if (error)
+ goto fail;
+ if (p_name[op.port_name_size - 1] != 0)
+ {
+ error = -EINVAL;
+ goto fail;
+ }
+ }
+ if (op.receive_sem_handle)
+ {
+ NV_CHECK_ERROR_CLEANUP(NvOsSemaphoreUnmarshal(
+ (NvOsSemaphoreHandle)op.receive_sem_handle,
+ &recv_sem));
+ }
+ op.ret_val = NvRmTransportOpen(
+ (NvRmDeviceHandle)op.rm_handle,
+ p_name,
+ recv_sem,
+ (void*)&op.transport_handle);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ nvrpc_stack_kfree(port_name, p_name);
+ if (recv_sem)
+ NvOsSemaphoreDestroy(recv_sem);
+ if (e != NvSuccess)
+ error = nvrpc_make_error_code(e);
+ return error;
+}
+
+static int nvrpc_ioctl_get_port_name(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_open_params op;
+ NvS8 *p_name = NULL;
+ NvU32 port_name[NVRPC_MAX_LOCAL_STACK/sizeof(NvU32)];
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ if (op.port_name_size && op.port_name)
+ {
+ p_name = nvrpc_stack_kzalloc(port_name, op.port_name_size, GFP_KERNEL);
+ if (!p_name)
+ {
+ error = -ENOMEM;
+ goto fail;
+ }
+ }
+ NvRmTransportGetPortName((NvRmTransportHandle)op.transport_handle,
+ p_name,
+ op.port_name_size);
+
+ if (op.port_name_size && p_name)
+ {
+ error = copy_to_user((void*)op.port_name,
+ p_name,
+ op.port_name_size * sizeof(NvU8));
+ }
+
+fail:
+ nvrpc_stack_kfree(port_name, p_name);
+ return error;
+}
+
+static int nvrpc_ioctl_close(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ NvRmTransportClose((void*)op.handle);
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_wait_for_connect(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ NvError e = NvSuccess;
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmTransportWaitForConnect(
+ (void *)op.handle,
+ op.param);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ if (e != NvSuccess)
+ error = nvrpc_make_error_code(e);
+ return error;
+}
+
+static int nvrpc_ioctl_connect(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ NvError e = NvSuccess;
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmTransportConnect(
+ (void *)op.handle,
+ op.param);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ if (e != NvSuccess)
+ error = nvrpc_make_error_code(e);
+ return error;
+}
+
+static int nvrpc_ioctl_set_queue_depth(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ NvError e = NvSuccess;
+ int error;
+ struct nvrpc_set_queue_depth_params op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmTransportSetQueueDepth(
+ (NvRmTransportHandle)op.transport_handle,
+ op.max_queue_depth,
+ op.max_message_size);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ if (e != NvSuccess)
+ error = nvrpc_make_error_code(e);
+ return error;
+}
+
+static int nvrpc_ioctl_send_msg(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_msg_params op;
+ void* msg_buffer = NULL;
+ NvU32 buffer[NVRPC_MAX_LOCAL_STACK/sizeof(NvU32)];
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ if (op.msg_buffer && op.max_message_size)
+ {
+ msg_buffer = nvrpc_stack_kzalloc(buffer,
+ op.max_message_size,
+ GFP_KERNEL);
+ if (!msg_buffer)
+ {
+ error = -ENOMEM;
+ goto fail;
+ }
+ error = copy_from_user(msg_buffer,
+ (void*)op.msg_buffer,
+ op.max_message_size);
+ if (error)
+ goto fail;
+ }
+
+ op.ret_val = NvRmTransportSendMsg(
+ (NvRmTransportHandle)op.transport_handle,
+ msg_buffer,
+ op.max_message_size,
+ op.params);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ nvrpc_stack_kfree(buffer, msg_buffer);
+ return error;
+}
+
+static int nvrpc_ioctl_send_msg_lp0(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_msg_params op;
+ void* msg_buffer = NULL;
+ NvU32 buffer[NVRPC_MAX_LOCAL_STACK/sizeof(NvU32)];
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ if (op.msg_buffer && op.max_message_size)
+ {
+ msg_buffer =
+ nvrpc_stack_kzalloc(buffer, op.max_message_size, GFP_KERNEL);
+ if (!msg_buffer)
+ {
+ error = -ENOMEM;
+ goto fail;
+ }
+ error = copy_from_user(msg_buffer,
+ (void*)op.msg_buffer,
+ op.max_message_size);
+ if (error)
+ goto fail;
+ }
+ op.ret_val = NvRmTransportSendMsgInLP0(
+ (NvRmTransportHandle)op.transport_handle,
+ msg_buffer,
+ op.max_message_size);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ nvrpc_stack_kfree(buffer, msg_buffer);
+ return error;
+}
+
+static int nvrpc_ioctl_recv_msg(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_msg_params op;
+ void* msg_buffer = NULL;
+ NvU32 buffer[NVRPC_MAX_LOCAL_STACK/sizeof(NvU32)];
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ if (op.msg_buffer && op.max_message_size)
+ {
+ msg_buffer =
+ nvrpc_stack_kzalloc(buffer, op.max_message_size, GFP_KERNEL);
+ if (!msg_buffer)
+ {
+ error = -ENOMEM;
+ goto fail;
+ }
+ }
+ else
+ {
+ error = -EINVAL;
+ goto fail;
+
+ }
+ op.ret_val = NvRmTransportRecvMsg(
+ (NvRmTransportHandle)op.transport_handle,
+ msg_buffer,
+ op.max_message_size,
+ &op.params);
+ error = copy_to_user(arg, &op, sizeof(op));
+ if (op.msg_buffer && msg_buffer)
+ {
+ error = copy_to_user((void*)op.msg_buffer,
+ msg_buffer,
+ op.max_message_size);
+ if (error)
+ goto fail;
+ }
+
+fail:
+ nvrpc_stack_kfree(buffer, msg_buffer);
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_init(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmXpcInitArbSemaSystem((void *)op.handle);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_acquire(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ NvRmXpcModuleAcquire(op.param);
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_release(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ NvRmXpcModuleRelease(op.param);
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_get_msg(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmPrivXpcGetMessage(
+ (NvRmPrivXpcMessageHandle)op.handle);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_send_msg(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmPrivXpcSendMessage(
+ (NvRmPrivXpcMessageHandle)op.handle,
+ op.param);
+ error = copy_to_user(arg, &op, sizeof(op));
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_destroy(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ NvRmPrivXpcDestroy((NvRmPrivXpcMessageHandle)op.handle);
+
+fail:
+ return error;
+}
+
+static int nvrpc_ioctl_xpc_create(struct file *filp,
+ unsigned int cmd, void __user *arg)
+{
+ int error;
+ struct nvrpc_handle_param op;
+
+ error = copy_from_user(&op, arg, sizeof(op));
+ if (error)
+ goto fail;
+ op.ret_val = NvRmPrivXpcCreate(
+ (NvRmDeviceHandle)op.handle,
+ (void*)&op.param);
+ error = copy_to_user(&op, arg, sizeof(op));
+
+fail:
+ return error;
+}
+
+
+static long nvrpc_unlocked_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ void __user *uarg = (void __user *)arg;
+
+ if (_IOC_TYPE(cmd) != NVRPC_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd));
+ if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd));
+
+ if (err)
+ return -EFAULT;
+ switch (cmd) {
+ case NVRPC_IOCTL_OPEN:
+ err = nvrpc_ioctl_open(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_GET_PORTNAME:
+ err = nvrpc_ioctl_get_port_name(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_CLOSE:
+ err = nvrpc_ioctl_close(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_INIT:
+ case NVRPC_IOCTL_DEINIT:
+ break;
+
+ case NVRPC_IOCTL_WAIT_FOR_CONNECT:
+ err = nvrpc_ioctl_wait_for_connect(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_CONNECT:
+ err = nvrpc_ioctl_connect(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_SET_QUEUE_DEPTH:
+ err = nvrpc_ioctl_set_queue_depth(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_SEND_MSG:
+ err = nvrpc_ioctl_send_msg(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_SEND_MSG_LP0:
+ err = nvrpc_ioctl_send_msg_lp0(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_RECV_MSG:
+ err = nvrpc_ioctl_recv_msg(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_INIT:
+ err = nvrpc_ioctl_xpc_init(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_ACQUIRE:
+ err = nvrpc_ioctl_xpc_acquire(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_RELEASE:
+ err = nvrpc_ioctl_xpc_release(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_GET_MSG:
+ err = nvrpc_ioctl_xpc_get_msg(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_SEND_MSG:
+ err = nvrpc_ioctl_xpc_send_msg(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_DESTROY:
+ err = nvrpc_ioctl_xpc_destroy(file, cmd, uarg);
+ break;
+
+ case NVRPC_IOCTL_XPC_CREATE:
+ err = nvrpc_ioctl_xpc_create(file, cmd, uarg);
+ break;
+
+ default:
+ return -ENOTTY;
+ }
+ return err;
+}
+
+static int __init nvrpc_init(void)
+{
+ int ret = 0;
+
+ ret = misc_register(&nvrpc_dev);
+ if (ret){
+ pr_err( "%s misc register FAILED\n", __func__);
+ }
+ return ret;
+}
+
+static void __exit nvrpc_deinit(void)
+{
+ misc_deregister(&nvrpc_dev);
+}
+
+module_init(nvrpc_init);
+module_exit(nvrpc_deinit);