/*
 * dspapi.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Common DSP API functions, also includes the wrapper
 * functions called directly by the DeviceIOControl interface.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
#include <linux/types.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/cfg.h>
#include <dspbridge/ntfy.h>
#include <dspbridge/services.h>

/*  ----------------------------------- Platform Manager */
#include <dspbridge/chnl.h>
#include <dspbridge/dev.h>
#include <dspbridge/drv.h>

#include <dspbridge/proc.h>
#include <dspbridge/strm.h>

/*  ----------------------------------- Resource Manager */
#include <dspbridge/disp.h>
#include <dspbridge/mgr.h>
#include <dspbridge/node.h>
#include <dspbridge/rmm.h>

/*  ----------------------------------- Others */
#include <dspbridge/msg.h>
#include <dspbridge/cmm.h>
#include <dspbridge/io.h>

/*  ----------------------------------- This */
#include <dspbridge/dspapi.h>
#include <dspbridge/dbdcd.h>

#include <dspbridge/resourcecleanup.h>

/*  ----------------------------------- Defines, Data Structures, Typedefs */
#define MAX_TRACEBUFLEN 255
#define MAX_LOADARGS    16
#define MAX_NODES       64
#define MAX_STREAMS     16
#define MAX_BUFS	64

/* Used to get dspbridge ioctl table */
#define DB_GET_IOC_TABLE(cmd)	(DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT)

/* Device IOCtl function pointer */
struct api_cmd {
	u32(*fxn) (union trapped_args *args, void *pr_ctxt);
	u32 dw_index;
};

/*  ----------------------------------- Globals */
static u32 api_c_refs;

/*
 *  Function tables.
 *  The order of these functions MUST be the same as the order of the command
 *  numbers defined in dspapi-ioctl.h  This is how an IOCTL number in user mode
 *  turns into a function call in kernel mode.
 */

/* MGR wrapper functions */
static struct api_cmd mgr_cmd[] = {
	{mgrwrap_enum_node_info},	/* MGR_ENUMNODE_INFO */
	{mgrwrap_enum_proc_info},	/* MGR_ENUMPROC_INFO */
	{mgrwrap_register_object},	/* MGR_REGISTEROBJECT */
	{mgrwrap_unregister_object},	/* MGR_UNREGISTEROBJECT */
	{mgrwrap_wait_for_bridge_events},	/* MGR_WAIT */
	{mgrwrap_get_process_resources_info},	/* MGR_GET_PROC_RES */
};

/* PROC wrapper functions */
static struct api_cmd proc_cmd[] = {
	{procwrap_attach},	/* PROC_ATTACH */
	{procwrap_ctrl},	/* PROC_CTRL */
	{procwrap_detach},	/* PROC_DETACH */
	{procwrap_enum_node_info},	/* PROC_ENUMNODE */
	{procwrap_enum_resources},	/* PROC_ENUMRESOURCES */
	{procwrap_get_state},	/* PROC_GET_STATE */
	{procwrap_get_trace},	/* PROC_GET_TRACE */
	{procwrap_load},	/* PROC_LOAD */
	{procwrap_register_notify},	/* PROC_REGISTERNOTIFY */
	{procwrap_start},	/* PROC_START */
	{procwrap_reserve_memory},	/* PROC_RSVMEM */
	{procwrap_un_reserve_memory},	/* PROC_UNRSVMEM */
	{procwrap_map},		/* PROC_MAPMEM */
	{procwrap_un_map},	/* PROC_UNMAPMEM */
	{procwrap_flush_memory},	/* PROC_FLUSHMEMORY */
	{procwrap_stop},	/* PROC_STOP */
	{procwrap_invalidate_memory},	/* PROC_INVALIDATEMEMORY */
	{procwrap_begin_dma},	/* PROC_BEGINDMA */
	{procwrap_end_dma},	/* PROC_ENDDMA */
};

/* NODE wrapper functions */
static struct api_cmd node_cmd[] = {
	{nodewrap_allocate},	/* NODE_ALLOCATE */
	{nodewrap_alloc_msg_buf},	/* NODE_ALLOCMSGBUF */
	{nodewrap_change_priority},	/* NODE_CHANGEPRIORITY */
	{nodewrap_connect},	/* NODE_CONNECT */
	{nodewrap_create},	/* NODE_CREATE */
	{nodewrap_delete},	/* NODE_DELETE */
	{nodewrap_free_msg_buf},	/* NODE_FREEMSGBUF */
	{nodewrap_get_attr},	/* NODE_GETATTR */
	{nodewrap_get_message},	/* NODE_GETMESSAGE */
	{nodewrap_pause},	/* NODE_PAUSE */
	{nodewrap_put_message},	/* NODE_PUTMESSAGE */
	{nodewrap_register_notify},	/* NODE_REGISTERNOTIFY */
	{nodewrap_run},		/* NODE_RUN */
	{nodewrap_terminate},	/* NODE_TERMINATE */
	{nodewrap_get_uuid_props},	/* NODE_GETUUIDPROPS */
};

/* STRM wrapper functions */
static struct api_cmd strm_cmd[] = {
	{strmwrap_allocate_buffer},	/* STRM_ALLOCATEBUFFER */
	{strmwrap_close},	/* STRM_CLOSE */
	{strmwrap_free_buffer},	/* STRM_FREEBUFFER */
	{strmwrap_get_event_handle},	/* STRM_GETEVENTHANDLE */
	{strmwrap_get_info},	/* STRM_GETINFO */
	{strmwrap_idle},	/* STRM_IDLE */
	{strmwrap_issue},	/* STRM_ISSUE */
	{strmwrap_open},	/* STRM_OPEN */
	{strmwrap_reclaim},	/* STRM_RECLAIM */
	{strmwrap_register_notify},	/* STRM_REGISTERNOTIFY */
	{strmwrap_select},	/* STRM_SELECT */
};

/* CMM wrapper functions */
static struct api_cmd cmm_cmd[] = {
	{cmmwrap_calloc_buf},	/* CMM_ALLOCBUF */
	{cmmwrap_free_buf},	/* CMM_FREEBUF */
	{cmmwrap_get_handle},	/* CMM_GETHANDLE */
	{cmmwrap_get_info},	/* CMM_GETINFO */
};

/* Array used to store ioctl table sizes. It can hold up to 8 entries */
static u8 size_cmd[] = {
	ARRAY_SIZE(mgr_cmd),
	ARRAY_SIZE(proc_cmd),
	ARRAY_SIZE(node_cmd),
	ARRAY_SIZE(strm_cmd),
	ARRAY_SIZE(cmm_cmd),
};

static inline void _cp_fm_usr(void *to, const void __user * from,
			      int *err, unsigned long bytes)
{
	if (*err)
		return;

	if (unlikely(!from)) {
		*err = -EFAULT;
		return;
	}

	if (unlikely(copy_from_user(to, from, bytes)))
		*err = -EFAULT;
}

#define CP_FM_USR(to, from, err, n)				\
	_cp_fm_usr(to, from, &(err), (n) * sizeof(*(to)))

static inline void _cp_to_usr(void __user *to, const void *from,
			      int *err, unsigned long bytes)
{
	if (*err)
		return;

	if (unlikely(!to)) {
		*err = -EFAULT;
		return;
	}

	if (unlikely(copy_to_user(to, from, bytes)))
		*err = -EFAULT;
}

#define CP_TO_USR(to, from, err, n)				\
	_cp_to_usr(to, from, &(err), (n) * sizeof(*(from)))

/*
 *  ======== api_call_dev_ioctl ========
 *  Purpose:
 *      Call the (wrapper) function for the corresponding API IOCTL.
 */
inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args,
				      u32 *result, void *pr_ctxt)
{
	u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL;
	int i;

	if (_IOC_TYPE(cmd) != DB) {
		pr_err("%s: Incompatible dspbridge ioctl number\n", __func__);
		goto err;
	}

	if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) {
		pr_err("%s: undefined ioctl module\n", __func__);
		goto err;
	}

	/* Check the size of the required cmd table */
	i = DB_GET_IOC(cmd);
	if (i > size_cmd[DB_GET_IOC_TABLE(cmd)]) {
		pr_err("%s: requested ioctl %d out of bounds for table %d\n",
		       __func__, i, DB_GET_IOC_TABLE(cmd));
		goto err;
	}

	switch (DB_GET_MODULE(cmd)) {
	case DB_MGR:
		ioctl_cmd = mgr_cmd[i].fxn;
		break;
	case DB_PROC:
		ioctl_cmd = proc_cmd[i].fxn;
		break;
	case DB_NODE:
		ioctl_cmd = node_cmd[i].fxn;
		break;
	case DB_STRM:
		ioctl_cmd = strm_cmd[i].fxn;
		break;
	case DB_CMM:
		ioctl_cmd = cmm_cmd[i].fxn;
		break;
	}

	if (!ioctl_cmd) {
		pr_err("%s: requested ioctl not defined\n", __func__);
		goto err;
	} else {
		*result = (*ioctl_cmd) (args, pr_ctxt);
	}

	return 0;

err:
	return -EINVAL;
}

/*
 *  ======== api_exit ========
 */
void api_exit(void)
{
	DBC_REQUIRE(api_c_refs > 0);
	api_c_refs--;

	if (api_c_refs == 0) {
		/* Release all modules initialized in api_init(). */
		cod_exit();
		dev_exit();
		chnl_exit();
		msg_exit();
		io_exit();
		strm_exit();
		disp_exit();
		node_exit();
		proc_exit();
		mgr_exit();
		rmm_exit();
		drv_exit();
	}
	DBC_ENSURE(api_c_refs >= 0);
}

/*
 *  ======== api_init ========
 *  Purpose:
 *      Module initialization used by Bridge API.
 */
bool api_init(void)
{
	bool ret = true;
	bool fdrv, fdev, fcod, fchnl, fmsg, fio;
	bool fmgr, fproc, fnode, fdisp, fstrm, frmm;

	if (api_c_refs == 0) {
		/* initialize driver and other modules */
		fdrv = drv_init();
		fmgr = mgr_init();
		fproc = proc_init();
		fnode = node_init();
		fdisp = disp_init();
		fstrm = strm_init();
		frmm = rmm_init();
		fchnl = chnl_init();
		fmsg = msg_mod_init();
		fio = io_init();
		fdev = dev_init();
		fcod = cod_init();
		ret = fdrv && fdev && fchnl && fcod && fmsg && fio;
		ret = ret && fmgr && fproc && frmm;
		if (!ret) {
			if (fdrv)
				drv_exit();

			if (fmgr)
				mgr_exit();

			if (fstrm)
				strm_exit();

			if (fproc)
				proc_exit();

			if (fnode)
				node_exit();

			if (fdisp)
				disp_exit();

			if (fchnl)
				chnl_exit();

			if (fmsg)
				msg_exit();

			if (fio)
				io_exit();

			if (fdev)
				dev_exit();

			if (fcod)
				cod_exit();

			if (frmm)
				rmm_exit();

		}
	}
	if (ret)
		api_c_refs++;

	return ret;
}

/*
 *  ======== api_init_complete2 ========
 *  Purpose:
 *      Perform any required bridge initialization which cannot
 *      be performed in api_init() or dev_start_device() due
 *      to the fact that some services are not yet
 *      completely initialized.
 *  Parameters:
 *  Returns:
 *      0:	Allow this device to load
 *      -EPERM:      Failure.
 *  Requires:
 *      Bridge API initialized.
 *  Ensures:
 */
int api_init_complete2(void)
{
	int status = 0;
	struct cfg_devnode *dev_node;
	struct dev_object *hdev_obj;
	u8 dev_type;
	u32 tmp;

	DBC_REQUIRE(api_c_refs > 0);

	/*  Walk the list of DevObjects, get each devnode, and attempting to
	 *  autostart the board. Note that this requires COF loading, which
	 *  requires KFILE. */
	for (hdev_obj = dev_get_first(); hdev_obj != NULL;
	     hdev_obj = dev_get_next(hdev_obj)) {
		if (dev_get_dev_node(hdev_obj, &dev_node))
			continue;

		if (dev_get_dev_type(hdev_obj, &dev_type))
			continue;

		if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT))
			if (cfg_get_auto_start(dev_node, &tmp) == 0
									&& tmp)
				proc_auto_start(dev_node, hdev_obj);
	}

	return status;
}

/* TODO: Remove deprecated and not implemented ioctl wrappers */

/*
 * ======== mgrwrap_enum_node_info ========
 */
u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
{
	u8 *pndb_props;
	u32 num_nodes;
	int status = 0;
	u32 size = args->args_mgr_enumnode_info.undb_props_size;

	if (size < sizeof(struct dsp_ndbprops))
		return -EINVAL;

	pndb_props = kmalloc(size, GFP_KERNEL);
	if (pndb_props == NULL)
		status = -ENOMEM;

	if (!status) {
		status =
		    mgr_enum_node_info(args->args_mgr_enumnode_info.node_id,
				       (struct dsp_ndbprops *)pndb_props, size,
				       &num_nodes);
	}
	CP_TO_USR(args->args_mgr_enumnode_info.pndb_props, pndb_props, status,
		  size);
	CP_TO_USR(args->args_mgr_enumnode_info.pu_num_nodes, &num_nodes, status,
		  1);
	kfree(pndb_props);

	return status;
}

/*
 * ======== mgrwrap_enum_proc_info ========
 */
u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt)
{
	u8 *processor_info;
	u8 num_procs;
	int status = 0;
	u32 size = args->args_mgr_enumproc_info.processor_info_size;

	if (size < sizeof(struct dsp_processorinfo))
		return -EINVAL;

	processor_info = kmalloc(size, GFP_KERNEL);
	if (processor_info == NULL)
		status = -ENOMEM;

	if (!status) {
		status =
		    mgr_enum_processor_info(args->args_mgr_enumproc_info.
					    processor_id,
					    (struct dsp_processorinfo *)
					    processor_info, size, &num_procs);
	}
	CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info,
		  status, size);
	CP_TO_USR(args->args_mgr_enumproc_info.pu_num_procs, &num_procs,
		  status, 1);
	kfree(processor_info);

	return status;
}

#define WRAP_MAP2CALLER(x) x
/*
 * ======== mgrwrap_register_object ========
 */
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 is increased by 1 to accommodate NULL */
	path_size = strlen_user((char *)
				args->args_mgr_registerobject.psz_path_name) +
	    1;
	psz_path_name = kmalloc(path_size, GFP_KERNEL);
	if (!psz_path_name)
		goto func_end;
	ret = strncpy_from_user(psz_path_name,
				(char *)args->args_mgr_registerobject.
				psz_path_name, path_size);
	if (!ret) {
		status = -EFAULT;
		goto func_end;
	}

	if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE)
		return -EINVAL;

	status = dcd_register_object(&uuid_obj,
				     args->args_mgr_registerobject.obj_type,
				     (char *)psz_path_name);
func_end:
	kfree(psz_path_name);
	return status;
}

/*
 * ======== mgrwrap_unregister_object ========
 */
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;

}

/*
 * ======== mgrwrap_wait_for_bridge_events ========
 */
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;

	/* get the array of pointers to user structures */
	CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
		  status, count);
	/* get the events */
	for (i = 0; i < count; i++) {
		CP_FM_USR(&notifications[i], anotifications[i], status, 1);
		if (status || !notifications[i].handle) {
			status = -EINVAL;
			break;
		}
		/* set the array of pointers to kernel structures */
		anotifications[i] = &notifications[i];
	}
	if (!status) {
		status = mgr_wait_for_bridge_events(anotifications, count,
							 &index,
							 args->args_mgr_wait.
							 utimeout);
	}
	CP_TO_USR(args->args_mgr_wait.pu_index, &index, status, 1);
	return status;
}

/*
 * ======== MGRWRAP_GetProcessResourceInfo ========
 */
u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args,
						    void *pr_ctxt)
{
	pr_err("%s: deprecated dspbridge ioctl\n", __func__);
	return 0;
}

/*
 * ======== procwrap_attach ========
 */
u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
{
	void *processor;
	int status = 0;
	struct dsp_processorattrin proc_attr_in, *attr_in = NULL;

	/* Optional argument */
	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;
}

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

	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.pargs, status,
			  cb_data_size);
	}
	if (!status) {
		status = proc_ctrl(hprocessor,
				   args->args_proc_ctrl.dw_cmd,
				   (struct dsp_cbdata *)pargs);
	}

	/* CP_TO_USR(args->args_proc_ctrl.pargs, pargs, status, 1); */
	kfree(pargs);
func_end:
	return status;
}

/*
 * ======== procwrap_detach ========
 */
u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt)
{
	/* proc_detach called at bridge_release only */
	pr_err("%s: deprecated dspbridge ioctl\n", __func__);
	return 0;
}

/*
 * ======== procwrap_enum_node_info ========
 */
u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
{
	int status;
	void *node_tab[MAX_NODES];
	u32 num_nodes;
	u32 alloc_cnt;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	if (!args->args_proc_enumnode_info.node_tab_size)
		return -EINVAL;

	status = proc_enum_nodes(hprocessor,
				 node_tab,
				 args->args_proc_enumnode_info.node_tab_size,
				 &num_nodes, &alloc_cnt);
	CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status,
		  num_nodes);
	CP_TO_USR(args->args_proc_enumnode_info.pu_num_nodes, &num_nodes,
		  status, 1);
	CP_TO_USR(args->args_proc_enumnode_info.pu_allocated, &alloc_cnt,
		  status, 1);
	return status;
}

u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt)
{
	int status;

	if (args->args_proc_dma.dir >= DMA_NONE)
		return -EINVAL;

	status = proc_end_dma(pr_ctxt,
				   args->args_proc_dma.pmpu_addr,
				   args->args_proc_dma.ul_size,
				   args->args_proc_dma.dir);
	return status;
}

u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt)
{
	int status;

	if (args->args_proc_dma.dir >= DMA_NONE)
		return -EINVAL;

	status = proc_begin_dma(pr_ctxt,
				   args->args_proc_dma.pmpu_addr,
				   args->args_proc_dma.ul_size,
				   args->args_proc_dma.dir);
	return status;
}

/*
 * ======== procwrap_flush_memory ========
 */
u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt)
{
	int status;

	if (args->args_proc_flushmemory.ul_flags >
	    PROC_WRITEBACK_INVALIDATE_MEM)
		return -EINVAL;

	status = proc_flush_memory(pr_ctxt,
				   args->args_proc_flushmemory.pmpu_addr,
				   args->args_proc_flushmemory.ul_size,
				   args->args_proc_flushmemory.ul_flags);
	return status;
}

/*
 * ======== procwrap_invalidate_memory ========
 */
u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt)
{
	int status;

	status =
	    proc_invalidate_memory(pr_ctxt,
				   args->args_proc_invalidatememory.pmpu_addr,
				   args->args_proc_invalidatememory.ul_size);
	return status;
}

/*
 * ======== procwrap_enum_resources ========
 */
u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	struct dsp_resourceinfo resource_info;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	if (args->args_proc_enumresources.resource_info_size <
	    sizeof(struct dsp_resourceinfo))
		return -EINVAL;

	status =
	    proc_get_resource_info(hprocessor,
				   args->args_proc_enumresources.resource_type,
				   &resource_info,
				   args->args_proc_enumresources.
				   resource_info_size);

	CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info,
		  status, 1);

	return status;

}

/*
 * ======== procwrap_get_state ========
 */
u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt)
{
	int status;
	struct dsp_processorstate proc_state;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	if (args->args_proc_getstate.state_info_size <
	    sizeof(struct dsp_processorstate))
		return -EINVAL;

	status = proc_get_state(hprocessor, &proc_state,
			   args->args_proc_getstate.state_info_size);
	CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status,
		  1);
	return status;

}

/*
 * ======== procwrap_get_trace ========
 */
u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt)
{
	int status;
	u8 *pbuf;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN)
		return -EINVAL;

	pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL);
	if (pbuf != NULL) {
		status = proc_get_trace(hprocessor, pbuf,
					args->args_proc_gettrace.max_size);
	} else {
		status = -ENOMEM;
	}
	CP_TO_USR(args->args_proc_gettrace.pbuf, pbuf, status,
		  args->args_proc_gettrace.max_size);
	kfree(pbuf);

	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)->hprocessor;

	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 {
			get_user(temp, args->args_proc_load.user_envp + count);
			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;
}

/*
 * ======== procwrap_map ========
 */
u32 procwrap_map(union trapped_args *args, void *pr_ctxt)
{
	int status;
	void *map_addr;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	if (!args->args_proc_mapmem.ul_size)
		return -EINVAL;

	status = proc_map(args->args_proc_mapmem.hprocessor,
			  args->args_proc_mapmem.pmpu_addr,
			  args->args_proc_mapmem.ul_size,
			  args->args_proc_mapmem.req_addr, &map_addr,
			  args->args_proc_mapmem.ul_map_attr, pr_ctxt);
	if (!status) {
		if (put_user(map_addr, args->args_proc_mapmem.pp_map_addr)) {
			status = -EINVAL;
			proc_un_map(hprocessor, map_addr, pr_ctxt);
		}

	}
	return status;
}

/*
 * ======== procwrap_register_notify ========
 */
u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
{
	int status;
	struct dsp_notification notification;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	/* Initialize the notification data structure */
	notification.ps_name = NULL;
	notification.handle = NULL;

	status = proc_register_notify(hprocessor,
				 args->args_proc_register_notify.event_mask,
				 args->args_proc_register_notify.notify_type,
				 &notification);
	CP_TO_USR(args->args_proc_register_notify.hnotification, &notification,
		  status, 1);
	return status;
}

/*
 * ======== procwrap_reserve_memory ========
 */
u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
{
	int status;
	void *prsv_addr;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	if ((args->args_proc_rsvmem.ul_size <= 0) ||
	    (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0)
		return -EINVAL;

	status = proc_reserve_memory(hprocessor,
				     args->args_proc_rsvmem.ul_size, &prsv_addr,
				     pr_ctxt);
	if (!status) {
		if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) {
			status = -EINVAL;
			proc_un_reserve_memory(args->args_proc_rsvmem.
					       hprocessor, prsv_addr, pr_ctxt);
		}
	}
	return status;
}

/*
 * ======== procwrap_start ========
 */
u32 procwrap_start(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;

	ret = proc_start(((struct process_context *)pr_ctxt)->hprocessor);
	return ret;
}

/*
 * ======== procwrap_un_map ========
 */
u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
{
	int status;

	status = proc_un_map(((struct process_context *)pr_ctxt)->hprocessor,
			     args->args_proc_unmapmem.map_addr, pr_ctxt);
	return status;
}

/*
 * ======== procwrap_un_reserve_memory ========
 */
u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
{
	int status;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	status = proc_un_reserve_memory(hprocessor,
					args->args_proc_unrsvmem.prsv_addr,
					pr_ctxt);
	return status;
}

/*
 * ======== procwrap_stop ========
 */
u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;

	ret = proc_stop(((struct process_context *)pr_ctxt)->hprocessor);

	return ret;
}

/*
 * ======== find_handle =========
 */
inline void find_node_handle(struct node_res_object **noderes,
				void *pr_ctxt, void *hnode)
{
	rcu_read_lock();
	*noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
								(int)hnode - 1);
	rcu_read_unlock();
	return;
}


/*
 * ======== nodewrap_allocate ========
 */
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.pargs;
	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)->hprocessor;

	/* Optional argument */
	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.pargs, status,
			  cb_data_size);
	}
	CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
	if (status)
		goto func_cont;
	/* Optional argument */
	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.ph_node, &nodeid,
			status, 1);
		if (status) {
			status = -EFAULT;
			node_delete(node_res, pr_ctxt);
		}
	}
func_cont:
	kfree(pargs);

	return status;
}

/*
 *  ======== nodewrap_alloc_msg_buf ========
 */
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.hnode);

	if (!node_res)
		return -EFAULT;

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

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

	}
	/* argument */
	CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1);
	if (!status) {
		status = node_alloc_msg_buf(node_res->hnode,
					    args->args_node_allocmsgbuf.usize,
					    pattr, &pbuffer);
	}
	CP_TO_USR(args->args_node_allocmsgbuf.pbuffer, &pbuffer, status, 1);
	return status;
}

/*
 * ======== nodewrap_change_priority ========
 */
u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt,
				args->args_node_changepriority.hnode);

	if (!node_res)
		return -EFAULT;

	ret = node_change_priority(node_res->hnode,
				   args->args_node_changepriority.prio);

	return ret;
}

/*
 * ======== nodewrap_connect ========
 */
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.hnode != DSP_HGPPNODE) {
		find_node_handle(&node_res1, pr_ctxt,
				args->args_node_connect.hnode);
		if (node_res1)
			node1 = node_res1->hnode;
	} else {
		node1 = args->args_node_connect.hnode;
	}

	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->hnode;
	} else {
		node2 = args->args_node_connect.other_node;
	}

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

	/* Optional argument */
	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.pattrs) {	/* Optional argument */
		CP_FM_USR(&attrs, args->args_node_connect.pattrs, 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;
}

/*
 * ======== nodewrap_create ========
 */
u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode);

	if (!node_res)
		return -EFAULT;

	ret = node_create(node_res->hnode);

	return ret;
}

/*
 * ======== nodewrap_delete ========
 */
u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode);

	if (!node_res)
		return -EFAULT;

	ret = node_delete(node_res, pr_ctxt);

	return ret;
}

/*
 *  ======== nodewrap_free_msg_buf ========
 */
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.hnode);

	if (!node_res)
		return -EFAULT;

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

	}

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

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

	return status;
}

/*
 * ======== nodewrap_get_attr ========
 */
u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	struct dsp_nodeattr attr;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode);

	if (!node_res)
		return -EFAULT;

	status = node_get_attr(node_res->hnode, &attr,
			       args->args_node_getattr.attr_size);
	CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1);

	return status;
}

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

	find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode);

	if (!node_res)
		return -EFAULT;

	status = node_get_message(node_res->hnode, &msg,
				  args->args_node_getmessage.utimeout);

	CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);

	return status;
}

/*
 * ======== nodewrap_pause ========
 */
u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode);

	if (!node_res)
		return -EFAULT;

	ret = node_pause(node_res->hnode);

	return ret;
}

/*
 * ======== nodewrap_put_message ========
 */
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.hnode);

	if (!node_res)
		return -EFAULT;

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

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

	return status;
}

/*
 * ======== nodewrap_register_notify ========
 */
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.hnode);

	if (!node_res)
		return -EFAULT;

	/* Initialize the notification data structure */
	notification.ps_name = NULL;
	notification.handle = NULL;

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

	status = node_register_notify(node_res->hnode,
				      args->args_node_registernotify.event_mask,
				      args->args_node_registernotify.
				      notify_type, &notification);
	CP_TO_USR(args->args_node_registernotify.hnotification, &notification,
		  status, 1);
	return status;
}

/*
 * ======== nodewrap_run ========
 */
u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode);

	if (!node_res)
		return -EFAULT;

	ret = node_run(node_res->hnode);

	return ret;
}

/*
 * ======== nodewrap_terminate ========
 */
u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
{
	int status;
	int tempstatus;
	struct node_res_object *node_res;

	find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode);

	if (!node_res)
		return -EFAULT;

	status = node_terminate(node_res->hnode, &tempstatus);

	CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1);

	return status;
}

/*
 * ======== nodewrap_get_uuid_props ========
 */
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)->hprocessor;

	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;
}

/*
 * ======== find_strm_handle =========
 */
inline void find_strm_handle(struct strm_res_object **strmres,
				void *pr_ctxt, void *hstream)
{
	rcu_read_lock();
	*strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id,
							(int)hstream - 1);
	rcu_read_unlock();
	return;
}

/*
 * ======== strmwrap_allocate_buffer ========
 */
u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt)
{
	int status;
	u8 **ap_buffer = NULL;
	u32 num_bufs = args->args_strm_allocatebuffer.num_bufs;
	struct strm_res_object *strm_res;

	find_strm_handle(&strm_res, pr_ctxt,
		args->args_strm_allocatebuffer.hstream);

	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;

	status = strm_allocate_buffer(strm_res,
				      args->args_strm_allocatebuffer.usize,
				      ap_buffer, num_bufs, pr_ctxt);
	if (!status) {
		CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer,
			  status, num_bufs);
		if (status) {
			status = -EFAULT;
			strm_free_buffer(strm_res,
					 ap_buffer, num_bufs, pr_ctxt);
		}
	}
	kfree(ap_buffer);

	return status;
}

/*
 * ======== strmwrap_close ========
 */
u32 strmwrap_close(union trapped_args *args, void *pr_ctxt)
{
	struct strm_res_object *strm_res;

	find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.hstream);

	if (!strm_res)
		return -EFAULT;

	return strm_close(strm_res, pr_ctxt);
}

/*
 * ======== strmwrap_free_buffer ========
 */
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.hstream);

	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;
}

/*
 * ======== strmwrap_get_event_handle ========
 */
u32 __deprecated strmwrap_get_event_handle(union trapped_args * args,
					   void *pr_ctxt)
{
	pr_err("%s: deprecated dspbridge ioctl\n", __func__);
	return -ENOSYS;
}

/*
 * ======== strmwrap_get_info ========
 */
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.hstream);

	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->hstream,
				       &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;
}

/*
 * ======== strmwrap_idle ========
 */
u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt)
{
	u32 ret;
	struct strm_res_object *strm_res;

	find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.hstream);

	if (!strm_res)
		return -EFAULT;

	ret = strm_idle(strm_res->hstream, args->args_strm_idle.flush_flag);

	return ret;
}

/*
 * ======== strmwrap_issue ========
 */
u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	struct strm_res_object *strm_res;

	find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.hstream);

	if (!strm_res)
		return -EFAULT;

	if (!args->args_strm_issue.pbuffer)
		return -EFAULT;

	/* No need of doing CP_FM_USR for the user buffer (pbuffer)
	   as this is done in Bridge internal function bridge_chnl_add_io_req
	   in chnl_sm.c */
	status = strm_issue(strm_res->hstream,
			    args->args_strm_issue.pbuffer,
			    args->args_strm_issue.dw_bytes,
			    args->args_strm_issue.dw_buf_size,
			    args->args_strm_issue.dw_arg);

	return status;
}

/*
 * ======== strmwrap_open ========
 */
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.hnode);

	if (!node_res)
		return -EFAULT;

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

	if (attr.stream_attr_in != NULL) {	/* Optional argument */
		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->hnode,
			   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.ph_stream, &strmid, status, 1);
	}
	return status;
}

/*
 * ======== strmwrap_reclaim ========
 */
u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	u8 *buf_ptr;
	u32 ul_bytes;
	u32 dw_arg;
	u32 ul_buf_size;
	struct strm_res_object *strm_res;

	find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.hstream);

	if (!strm_res)
		return -EFAULT;

	status = strm_reclaim(strm_res->hstream, &buf_ptr,
			      &ul_bytes, &ul_buf_size, &dw_arg);
	CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1);
	CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1);
	CP_TO_USR(args->args_strm_reclaim.pdw_arg, &dw_arg, status, 1);

	if (args->args_strm_reclaim.buf_size_ptr != NULL) {
		CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size,
			  status, 1);
	}

	return status;
}

/*
 * ======== strmwrap_register_notify ========
 */
u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	struct dsp_notification notification;
	struct strm_res_object *strm_res;

	find_strm_handle(&strm_res, pr_ctxt,
			args->args_strm_registernotify.hstream);

	if (!strm_res)
		return -EFAULT;

	/* Initialize the notification data structure */
	notification.ps_name = NULL;
	notification.handle = NULL;

	status = strm_register_notify(strm_res->hstream,
				      args->args_strm_registernotify.event_mask,
				      args->args_strm_registernotify.
				      notify_type, &notification);
	CP_TO_USR(args->args_strm_registernotify.hnotification, &notification,
		  status, 1);

	return status;
}

/*
 * ======== strmwrap_select ========
 */
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->hstream;
	}

	if (!status) {
		status = strm_select(strm_tab, args->args_strm_select.strm_num,
				     &mask, args->args_strm_select.utimeout);
	}
	CP_TO_USR(args->args_strm_select.pmask, &mask, status, 1);
	return status;
}

/* CMM */

/*
 * ======== cmmwrap_calloc_buf ========
 */
u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
{
	/* This operation is done in kernel */
	pr_err("%s: deprecated dspbridge ioctl\n", __func__);
	return -ENOSYS;
}

/*
 * ======== cmmwrap_free_buf ========
 */
u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt)
{
	/* This operation is done in kernel */
	pr_err("%s: deprecated dspbridge ioctl\n", __func__);
	return -ENOSYS;
}

/*
 * ======== cmmwrap_get_handle ========
 */
u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	struct cmm_object *hcmm_mgr;
	void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;

	status = cmm_get_handle(hprocessor, &hcmm_mgr);

	CP_TO_USR(args->args_cmm_gethandle.ph_cmm_mgr, &hcmm_mgr, status, 1);

	return status;
}

/*
 * ======== cmmwrap_get_info ========
 */
u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt)
{
	int status = 0;
	struct cmm_info cmm_info_obj;

	status = cmm_get_info(args->args_cmm_getinfo.hcmm_mgr, &cmm_info_obj);

	CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status,
		  1);

	return status;
}
