u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_notification *anotifications[MAX_EVENTS];
    struct dsp_notification notifications[MAX_EVENTS];
    u32 index, i;
    u32 count = args->args_mgr_wait.count;

    if (count > MAX_EVENTS)
        status = -EINVAL;


    CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
              status, count);

    for (i = 0; i < count; i++) {
        CP_FM_USR(&notifications[i], anotifications[i], status, 1);
        if (status || !notifications[i].handle) {
            status = -EINVAL;
            break;
        }

        anotifications[i] = &notifications[i];
    }
    if (!status) {
        status = mgr_wait_for_bridge_events(anotifications, count,
                                            &index,
                                            args->args_mgr_wait.
                                            timeout);
    }
    CP_TO_USR(args->args_mgr_wait.index, &index, status, 1);
    return status;
}
u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct strm_attr attr;
    struct strm_res_object *strm_res_obj;
    struct dsp_streamattrin strm_attr_in;
    struct node_res_object *node_res;
    int strmid;

    find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node);

    if (!node_res)
        return -EFAULT;

    CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);

    if (attr.stream_attr_in != NULL) {
        CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1);
        if (!status) {
            attr.stream_attr_in = &strm_attr_in;
            if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA)
                return -ENOSYS;
        }

    }
    status = strm_open(node_res->node,
                       args->args_strm_open.direction,
                       args->args_strm_open.index, &attr, &strm_res_obj,
                       pr_ctxt);
    if (!status) {
        strmid = strm_res_obj->id + 1;
        CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1);
    }
    return status;
}
u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_bufferattr *pattr = NULL;
    struct dsp_bufferattr attr;
    u8 *pbuffer = NULL;
    struct node_res_object *node_res;

    find_node_handle(&node_res,  pr_ctxt,
                     args->args_node_allocmsgbuf.node);

    if (!node_res)
        return -EFAULT;

    if (!args->args_node_allocmsgbuf.size)
        return -EINVAL;

    if (args->args_node_allocmsgbuf.attr) {
        CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1);
        if (!status)
            pattr = &attr;

    }

    CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1);
    if (!status) {
        status = node_alloc_msg_buf(node_res->node,
                                    args->args_node_allocmsgbuf.size,
                                    pattr, &pbuffer);
    }
    CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1);
    return status;
}
u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_uuid node_uuid;
    u32 cb_data_size = 0;
    u32 __user *psize = (u32 __user *) args->args_node_allocate.args;
    u8 *pargs = NULL;
    struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
    struct node_res_object *node_res;
    int nodeid;
    void *hprocessor = ((struct process_context *)pr_ctxt)->processor;


    if (psize) {
        if (get_user(cb_data_size, psize))
            status = -EPERM;

        cb_data_size += sizeof(u32);
        if (!status) {
            pargs = kmalloc(cb_data_size, GFP_KERNEL);
            if (pargs == NULL)
                status = -ENOMEM;

        }
        CP_FM_USR(pargs, args->args_node_allocate.args, status,
                  cb_data_size);
    }
    CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
    if (status)
        goto func_cont;

    if (args->args_node_allocate.attr_in) {
        CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in,
                  status, 1);
        if (!status)
            attr_in = &proc_attr_in;
        else
            status = -ENOMEM;

    }
    if (!status) {
        status = node_allocate(hprocessor,
                               &node_uuid, (struct dsp_cbdata *)pargs,
                               attr_in, &node_res, pr_ctxt);
    }
    if (!status) {
        nodeid = node_res->id + 1;
        CP_TO_USR(args->args_node_allocate.node, &nodeid,
                  status, 1);
        if (status) {
            status = -EFAULT;
            node_delete(node_res, pr_ctxt);
        }
    }
func_cont:
    kfree(pargs);

    return status;
}
u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt)
{
    u32 cb_data_size, __user * psize = (u32 __user *)
                                       args->args_proc_ctrl.args;
    u8 *pargs = NULL;
    int status = 0;
    void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

    if (psize) {
        if (get_user(cb_data_size, psize)) {
            status = -EPERM;
            goto func_end;
        }
        cb_data_size += sizeof(u32);
        pargs = kmalloc(cb_data_size, GFP_KERNEL);
        if (pargs == NULL) {
            status = -ENOMEM;
            goto func_end;
        }

        CP_FM_USR(pargs, args->args_proc_ctrl.args, status,
                  cb_data_size);
    }
    if (!status) {
        status = proc_ctrl(hprocessor,
                           args->args_proc_ctrl.cmd,
                           (struct dsp_cbdata *)pargs);
    }


    kfree(pargs);
func_end:
    return status;
}
u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_bufferattr *pattr = NULL;
    struct dsp_bufferattr attr;
    struct node_res_object *node_res;

    find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node);

    if (!node_res)
        return -EFAULT;

    if (args->args_node_freemsgbuf.attr) {
        CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1);
        if (!status)
            pattr = &attr;

    }

    if (!args->args_node_freemsgbuf.buffer)
        return -EFAULT;

    if (!status) {
        status = node_free_msg_buf(node_res->node,
                                   args->args_node_freemsgbuf.buffer,
                                   pattr);
    }

    return status;
}
u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
{
    u32 mask;
    struct strm_object *strm_tab[MAX_STREAMS];
    int status = 0;
    struct strm_res_object *strm_res;
    int *ids[MAX_STREAMS];
    int i;

    if (args->args_strm_select.strm_num > MAX_STREAMS)
        return -EINVAL;

    CP_FM_USR(ids, args->args_strm_select.stream_tab, status,
              args->args_strm_select.strm_num);

    if (status)
        return status;

    for (i = 0; i < args->args_strm_select.strm_num; i++) {
        find_strm_handle(&strm_res, pr_ctxt, ids[i]);

        if (!strm_res)
            return -EFAULT;

        strm_tab[i] = strm_res->stream;
    }

    if (!status) {
        status = strm_select(strm_tab, args->args_strm_select.strm_num,
                             &mask, args->args_strm_select.timeout);
    }
    CP_TO_USR(args->args_strm_select.mask, &mask, status, 1);
    return status;
}
u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct stream_info strm_info;
    struct dsp_streaminfo user;
    struct dsp_streaminfo *temp;
    struct strm_res_object *strm_res;

    find_strm_handle(&strm_res, pr_ctxt,
                     args->args_strm_getinfo.stream);

    if (!strm_res)
        return -EFAULT;

    CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1);
    temp = strm_info.user_strm;

    strm_info.user_strm = &user;

    if (!status) {
        status = strm_get_info(strm_res->stream,
                               &strm_info,
                               args->args_strm_getinfo.
                               stream_info_size);
    }
    CP_TO_USR(temp, strm_info.user_strm, status, 1);
    strm_info.user_strm = temp;
    CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1);
    return status;
}
u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    u8 **ap_buffer = NULL;
    u32 num_bufs = args->args_strm_freebuffer.num_bufs;
    struct strm_res_object *strm_res;

    find_strm_handle(&strm_res, pr_ctxt,
                     args->args_strm_freebuffer.stream);

    if (!strm_res)
        return -EFAULT;

    if (num_bufs > MAX_BUFS)
        return -EINVAL;

    ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
    if (ap_buffer == NULL)
        return -ENOMEM;

    CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status,
              num_bufs);

    if (!status)
        status = strm_free_buffer(strm_res,
                                  ap_buffer, num_bufs, pr_ctxt);

    CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status,
              num_bufs);
    kfree(ap_buffer);

    return status;
}
u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_notification notification;
    struct node_res_object *node_res;

    find_node_handle(&node_res, pr_ctxt,
                     args->args_node_registernotify.node);

    if (!node_res)
        return -EFAULT;


    notification.name = NULL;
    notification.handle = NULL;

    if (!args->args_proc_register_notify.event_mask)
        CP_FM_USR(&notification,
                  args->args_proc_register_notify.notification,
                  status, 1);

    status = node_register_notify(node_res->node,
                                  args->args_node_registernotify.event_mask,
                                  args->args_node_registernotify.
                                  notify_type, &notification);
    CP_TO_USR(args->args_node_registernotify.notification, &notification,
              status, 1);
    return status;
}
u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_uuid uuid_obj;

    CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
    if (status)
        goto func_end;

    status = dcd_unregister_object(&uuid_obj,
                                   args->args_mgr_unregisterobject.
                                   obj_type);
func_end:
    return status;

}
u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_msg msg;
    struct node_res_object *node_res;

    find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node);

    if (!node_res)
        return -EFAULT;

    CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);

    if (!status) {
        status =
            node_put_message(node_res->node, &msg,
                             args->args_node_putmessage.timeout);
    }

    return status;
}
u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
{
    u32 ret;
    struct dsp_uuid uuid_obj;
    u32 path_size = 0;
    char *psz_path_name = NULL;
    int status = 0;

    CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
    if (status)
        goto func_end;

    path_size = strlen_user((char *)
                            args->args_mgr_registerobject.sz_path_name) +
                1;
    psz_path_name = kmalloc(path_size, GFP_KERNEL);
    if (!psz_path_name) {
        status = -ENOMEM;
        goto func_end;
    }
    ret = strncpy_from_user(psz_path_name,
                            (char *)args->args_mgr_registerobject.
                            sz_path_name, path_size);
    if (!ret) {
        status = -EFAULT;
        goto func_end;
    }

    if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) {
        status = -EINVAL;
        goto func_end;
    }

    status = dcd_register_object(&uuid_obj,
                                 args->args_mgr_registerobject.obj_type,
                                 (char *)psz_path_name);
func_end:
    kfree(psz_path_name);
    return status;
}
u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
{
    void *processor;
    int status = 0;
    struct dsp_processorattrin proc_attr_in, *attr_in = NULL;


    if (args->args_proc_attach.attr_in) {
        CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status,
                  1);
        if (!status)
            attr_in = &proc_attr_in;
        else
            goto func_end;

    }
    status = proc_attach(args->args_proc_attach.processor_id, attr_in,
                         &processor, pr_ctxt);
    CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1);
func_end:
    return status;
}
u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_uuid node_uuid;
    struct dsp_ndbprops *pnode_props = NULL;
    void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

    CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status,
              1);
    if (status)
        goto func_cont;
    pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL);
    if (pnode_props != NULL) {
        status =
            node_get_uuid_props(hprocessor, &node_uuid, pnode_props);
        CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props,
                  status, 1);
    } else
        status = -ENOMEM;
func_cont:
    kfree(pnode_props);
    return status;
}
u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
{
    s32 i, len;
    int status = 0;
    char *temp;
    s32 count = args->args_proc_load.argc_index;
    u8 **argv = NULL, **envp = NULL;
    void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

    if (count <= 0 || count > MAX_LOADARGS) {
        status = -EINVAL;
        goto func_cont;
    }

    argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
    if (!argv) {
        status = -ENOMEM;
        goto func_cont;
    }

    CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
    if (status) {
        kfree(argv);
        argv = NULL;
        goto func_cont;
    }

    for (i = 0; i < count; i++) {
        if (argv[i]) {

            temp = (char *)argv[i];

            len = strlen_user((char *)temp) + 1;

            argv[i] = kmalloc(len, GFP_KERNEL);
            if (argv[i]) {
                CP_FM_USR(argv[i], temp, status, len);
                if (status) {
                    kfree(argv[i]);
                    argv[i] = NULL;
                    goto func_cont;
                }
            } else {
                status = -ENOMEM;
                goto func_cont;
            }
        }
    }

    if (args->args_proc_load.user_envp) {

        count = 0;
        do {
            if (get_user(temp,
                         args->args_proc_load.user_envp + count)) {
                status = -EFAULT;
                goto func_cont;
            }
            count++;
        } while (temp);
        envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
        if (!envp) {
            status = -ENOMEM;
            goto func_cont;
        }

        CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
        if (status) {
            kfree(envp);
            envp = NULL;
            goto func_cont;
        }
        for (i = 0; envp[i]; i++) {

            temp = (char *)envp[i];

            len = strlen_user((char *)temp) + 1;

            envp[i] = kmalloc(len, GFP_KERNEL);
            if (envp[i]) {
                CP_FM_USR(envp[i], temp, status, len);
                if (status) {
                    kfree(envp[i]);
                    envp[i] = NULL;
                    goto func_cont;
                }
            } else {
                status = -ENOMEM;
                goto func_cont;
            }
        }
    }

    if (!status) {
        status = proc_load(hprocessor,
                           args->args_proc_load.argc_index,
                           (const char **)argv, (const char **)envp);
    }
func_cont:
    if (envp) {
        i = 0;
        while (envp[i])
            kfree(envp[i++]);

        kfree(envp);
    }

    if (argv) {
        count = args->args_proc_load.argc_index;
        for (i = 0; (i < count) && argv[i]; i++)
            kfree(argv[i]);

        kfree(argv);
    }

    return status;
}
u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
{
    int status = 0;
    struct dsp_strmattr attrs;
    struct dsp_strmattr *pattrs = NULL;
    u32 cb_data_size;
    u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
    u8 *pargs = NULL;
    struct node_res_object *node_res1, *node_res2;
    struct node_object *node1 = NULL, *node2 = NULL;

    if ((int)args->args_node_connect.node != DSP_HGPPNODE) {
        find_node_handle(&node_res1, pr_ctxt,
                         args->args_node_connect.node);
        if (node_res1)
            node1 = node_res1->node;
    } else {
        node1 = args->args_node_connect.node;
    }

    if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
        find_node_handle(&node_res2, pr_ctxt,
                         args->args_node_connect.other_node);
        if (node_res2)
            node2 = node_res2->node;
    } else {
        node2 = args->args_node_connect.other_node;
    }

    if (!node1 || !node2)
        return -EFAULT;


    if (psize) {
        if (get_user(cb_data_size, psize))
            status = -EPERM;

        cb_data_size += sizeof(u32);
        if (!status) {
            pargs = kmalloc(cb_data_size, GFP_KERNEL);
            if (pargs == NULL) {
                status = -ENOMEM;
                goto func_cont;
            }

        }
        CP_FM_USR(pargs, args->args_node_connect.conn_param, status,
                  cb_data_size);
        if (status)
            goto func_cont;
    }
    if (args->args_node_connect.attrs) {
        CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1);
        if (!status)
            pattrs = &attrs;

    }
    if (!status) {
        status = node_connect(node1,
                              args->args_node_connect.stream_id,
                              node2,
                              args->args_node_connect.other_stream,
                              pattrs, (struct dsp_cbdata *)pargs);
    }
func_cont:
    kfree(pargs);

    return status;
}
/*
 * ======== procwrap_load ========
 */
u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
{
	s32 i, len;
	int status = 0;
	char *temp;
	s32 count = args->args_proc_load.argc_index;
	u8 **argv = NULL, **envp = NULL;
	void *hprocessor = ((struct process_context *)pr_ctxt)->processor;

	if (count <= 0 || count > MAX_LOADARGS) {
		status = -EINVAL;
		goto func_cont;
	}

	argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
	if (!argv) {
		status = -ENOMEM;
		goto func_cont;
	}

	CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
	if (status) {
		kfree(argv);
		argv = NULL;
		goto func_cont;
	}

	for (i = 0; i < count; i++) {
		if (argv[i]) {
			/* User space pointer to argument */
			temp = (char *)argv[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			argv[i] = kmalloc(len, GFP_KERNEL);
			if (argv[i]) {
				CP_FM_USR(argv[i], temp, status, len);
				if (status) {
					kfree(argv[i]);
					argv[i] = NULL;
					goto func_cont;
				}
			} else {
				status = -ENOMEM;
				goto func_cont;
			}
		}
	}
	/* TODO: validate this */
	if (args->args_proc_load.user_envp) {
		/* number of elements in the envp array including NULL */
		count = 0;
		do {
			if (get_user(temp,
				     args->args_proc_load.user_envp + count)) {
				status = -EFAULT;
				goto func_cont;
			}
			count++;
		} while (temp);
		envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
		if (!envp) {
			status = -ENOMEM;
			goto func_cont;
		}

		CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
		if (status) {
			kfree(envp);
			envp = NULL;
			goto func_cont;
		}
		for (i = 0; envp[i]; i++) {
			/* User space pointer to argument */
			temp = (char *)envp[i];
			/* len is increased by 1 to accommodate NULL */
			len = strlen_user((char *)temp) + 1;
			/* Kernel space pointer to argument */
			envp[i] = kmalloc(len, GFP_KERNEL);
			if (envp[i]) {
				CP_FM_USR(envp[i], temp, status, len);
				if (status) {
					kfree(envp[i]);
					envp[i] = NULL;
					goto func_cont;
				}
			} else {
				status = -ENOMEM;
				goto func_cont;
			}
		}
	}

	if (!status) {
		status = proc_load(hprocessor,
				   args->args_proc_load.argc_index,
				   (const char **)argv, (const char **)envp);
	}
func_cont:
	if (envp) {
		i = 0;
		while (envp[i])
			kfree(envp[i++]);

		kfree(envp);
	}

	if (argv) {
		count = args->args_proc_load.argc_index;
		for (i = 0; (i < count) && argv[i]; i++)
			kfree(argv[i]);

		kfree(argv);
	}

	return status;
}