diff options
author | Angela Stegmaier <angelabaker@ti.com> | 2010-06-22 18:19:48 -0500 |
---|---|---|
committer | Ricardo Perez Olivares <x0081762@ti.com> | 2010-07-16 17:41:48 -0500 |
commit | 540687b9dd957a7b1059ddc36330f01d8103c033 (patch) | |
tree | 6a645a78d785e9996f6f4b3798f7907d46e80389 | |
parent | 60383740705abbe3069f012d56fc29f1ea8a2185 (diff) |
SYSLINK: ipc- resource cleanup sysipc changes
Changes to sysipc for resource cleanup.
Signed-off-by: Angela Stegmaier <angelabaker@ti.com>
-rw-r--r-- | arch/arm/plat-omap/include/syslink/sysipc_ioctl.h | 2 | ||||
-rw-r--r-- | drivers/dsp/syslink/multicore_ipc/ipc.c | 13 | ||||
-rw-r--r-- | drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/dsp/syslink/multicore_ipc/sysipc_ioctl.c | 148 |
4 files changed, 133 insertions, 32 deletions
diff --git a/arch/arm/plat-omap/include/syslink/sysipc_ioctl.h b/arch/arm/plat-omap/include/syslink/sysipc_ioctl.h index d5896c21c96d..d6f4428e7161 100644 --- a/arch/arm/plat-omap/include/syslink/sysipc_ioctl.h +++ b/arch/arm/plat-omap/include/syslink/sysipc_ioctl.h @@ -113,6 +113,6 @@ struct sysipc_cmd_args { */ /* ioctl interface function for sysmgr */ int sysipc_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long args); + unsigned int cmd, unsigned long args, bool user); #endif /* _SYSIPC_IOCTL_H_ */ diff --git a/drivers/dsp/syslink/multicore_ipc/ipc.c b/drivers/dsp/syslink/multicore_ipc/ipc.c index 7bcc697ce8b7..dd76e367a250 100644 --- a/drivers/dsp/syslink/multicore_ipc/ipc.c +++ b/drivers/dsp/syslink/multicore_ipc/ipc.c @@ -1512,6 +1512,19 @@ int ipc_destroy(void) if (ipc_module->ref_count == 0) { gate_leave_system(key); + if (unlikely(atomic_cmpmask_and_lt( + &(ipc_module->start_ref_count), + IPC_MAKE_MAGICSTAMP(0), + IPC_MAKE_MAGICSTAMP(1)) == false)) { + /* + * ipc_start was called, but ipc_stop never happened. + * Need to call ipc_stop here. + */ + /* Set the count to 1 so only need to call stop once. */ + atomic_set(&ipc_module->start_ref_count, + IPC_MAKE_MAGICSTAMP(1)); + ipc_stop(); + } status = platform_destroy(); if (status < 0) { status = IPC_E_FAIL; diff --git a/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c b/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c index 626390ca1dc6..34681da0da7e 100644 --- a/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c +++ b/drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c @@ -85,7 +85,7 @@ int ipc_ioc_router(u32 cmd, ulong arg, struct file *filp, bool user) else if (ioc_nr >= MESSAGEQ_BASE_CMD && ioc_nr <= MESSAGEQ_END_CMD) retval = messageq_ioctl(NULL, filp, cmd, arg, user); else if (ioc_nr >= IPC_BASE_CMD && ioc_nr <= IPC_END_CMD) - retval = sysipc_ioctl(NULL, filp, cmd, arg); + retval = sysipc_ioctl(NULL, filp, cmd, arg, user); /* else if (ioc_nr >= SYSMEMMGR_BASE_CMD && ioc_nr <= SYSMEMMGR_END_CMD) retval = sysmemmgr_ioctl(NULL, NULL, cmd, arg);*/ else if (ioc_nr >= HEAPMEMMP_BASE_CMD && ioc_nr <= HEAPMEMMP_END_CMD) diff --git a/drivers/dsp/syslink/multicore_ipc/sysipc_ioctl.c b/drivers/dsp/syslink/multicore_ipc/sysipc_ioctl.c index 9fa1af213b7d..6f94bc626496 100644 --- a/drivers/dsp/syslink/multicore_ipc/sysipc_ioctl.c +++ b/drivers/dsp/syslink/multicore_ipc/sysipc_ioctl.c @@ -32,6 +32,50 @@ /*#include <platform.h>*/ +static struct resource_info *find_sysipc_resource( + struct ipc_process_context *pr_ctxt, + unsigned int cmd, + struct sysipc_cmd_args *cargs) +{ + struct resource_info *info = NULL; + bool found = false; + + spin_lock(&pr_ctxt->res_lock); + + list_for_each_entry(info, &pr_ctxt->resources, res) { + struct sysipc_cmd_args *args = + (struct sysipc_cmd_args *)info->data; + if (info->cmd == cmd) { + switch (cmd) { + case CMD_IPC_CONTROL: + { + s32 cmd_id = args->args.control.cmd_id; + s32 t_cmd_id = cargs->args.control.cmd_id; + u16 proc_id = args->args.control.proc_id; + u16 t_proc_id = cargs->args.control.proc_id; + if (cmd_id == t_cmd_id && proc_id == t_proc_id) + found = true; + break; + } + case CMD_IPC_DESTROY: + { + found = true; + break; + } + } + if (found == true) + break; + } + } + + spin_unlock(&pr_ctxt->res_lock); + + if (found == false) + info = NULL; + + return info; +} + /* * ioctl interface to ipc_setup function */ @@ -142,66 +186,110 @@ static inline int sysipc_ioctl_destroy(struct sysipc_cmd_args *cargs) * ioctl interface function for sysmgr module */ int sysipc_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long args) + unsigned int cmd, unsigned long args, bool user) { - int os_status = 0; + int status = 0; struct sysipc_cmd_args __user *uarg = (struct sysipc_cmd_args __user *)args; struct sysipc_cmd_args cargs; unsigned long size; - - if (_IOC_DIR(cmd) & _IOC_READ) - os_status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); - else if (_IOC_DIR(cmd) & _IOC_WRITE) - os_status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); - if (os_status) { - os_status = -EFAULT; - goto exit; - } - - /* Copy the full args from user-side */ - size = copy_from_user(&cargs, uarg, sizeof(struct sysipc_cmd_args)); - if (size) { - os_status = -EFAULT; - goto exit; + struct ipc_process_context *pr_ctxt = + (struct ipc_process_context *)filp->private_data; + + if (user == true) { + if (_IOC_DIR(cmd) & _IOC_READ) + status = !access_ok(VERIFY_WRITE, uarg, _IOC_SIZE(cmd)); + else if (_IOC_DIR(cmd) & _IOC_WRITE) + status = !access_ok(VERIFY_READ, uarg, _IOC_SIZE(cmd)); + if (status) { + status = -EFAULT; + goto exit; + } + + /* Copy the full args from user-side */ + size = copy_from_user(&cargs, uarg, + sizeof(struct sysipc_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } + } else { + if (args != 0) + memcpy(&cargs, (void *)args, + sizeof(struct sysipc_cmd_args)); } switch (cmd) { case CMD_IPC_SETUP: - os_status = sysipc_ioctl_setup(&cargs); + status = sysipc_ioctl_setup(&cargs); + if (status >= 0) + add_pr_res(pr_ctxt, CMD_IPC_DESTROY, NULL); break; case CMD_IPC_DESTROY: - os_status = sysipc_ioctl_destroy(&cargs); + { + struct resource_info *info = NULL; + info = find_sysipc_resource(pr_ctxt, CMD_IPC_DESTROY, + &cargs); + status = sysipc_ioctl_destroy(&cargs); + remove_pr_res(pr_ctxt, info); break; + } case CMD_IPC_CONTROL: - os_status = sysipc_ioctl_control(&cargs); + { + u32 id = cargs.args.control.proc_id; + u32 ctrl_cmd = cargs.args.control.cmd_id; + struct resource_info *info = NULL; + + info = find_sysipc_resource(pr_ctxt, CMD_IPC_CONTROL, + &cargs); + + status = sysipc_ioctl_control(&cargs); + if (ctrl_cmd == IPC_CONTROLCMD_STARTCALLBACK) { + if (status >= 0) { + struct sysipc_cmd_args *temp = kmalloc( + sizeof(struct sysipc_cmd_args), + GFP_KERNEL); + temp->args.control.cmd_id = + IPC_CONTROLCMD_STOPCALLBACK; + temp->args.control.proc_id = id; + temp->args.control.arg = NULL; + add_pr_res(pr_ctxt, CMD_IPC_CONTROL, + (void *)temp); + } + } else if (ctrl_cmd == IPC_CONTROLCMD_STOPCALLBACK) { + remove_pr_res(pr_ctxt, info); + } break; + } case CMD_IPC_READCONFIG: - os_status = sysipc_ioctl_read_config(&cargs); + status = sysipc_ioctl_read_config(&cargs); break; case CMD_IPC_WRITECONFIG: - os_status = sysipc_ioctl_write_config(&cargs); + status = sysipc_ioctl_write_config(&cargs); break; default: WARN_ON(cmd); - os_status = -ENOTTY; + status = -ENOTTY; break; } - if (os_status < 0) + if (status < 0) goto exit; - /* Copy the full args to the user-side. */ - size = copy_to_user(uarg, &cargs, sizeof(struct sysipc_cmd_args)); - if (size) { - os_status = -EFAULT; - goto exit; + if (user == true) { + /* Copy the full args to the user-side. */ + size = copy_to_user(uarg, &cargs, + sizeof(struct sysipc_cmd_args)); + if (size) { + status = -EFAULT; + goto exit; + } } exit: - return os_status; + return status; } |