summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngela Stegmaier <angelabaker@ti.com>2010-06-22 18:19:48 -0500
committerRicardo Perez Olivares <x0081762@ti.com>2010-07-16 17:41:48 -0500
commit540687b9dd957a7b1059ddc36330f01d8103c033 (patch)
tree6a645a78d785e9996f6f4b3798f7907d46e80389
parent60383740705abbe3069f012d56fc29f1ea8a2185 (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.h2
-rw-r--r--drivers/dsp/syslink/multicore_ipc/ipc.c13
-rw-r--r--drivers/dsp/syslink/multicore_ipc/ipc_ioctl.c2
-rw-r--r--drivers/dsp/syslink/multicore_ipc/sysipc_ioctl.c148
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;
}