diff options
Diffstat (limited to 'drivers/staging/tidspbridge/pmgr/dspapi.c')
-rw-r--r-- | drivers/staging/tidspbridge/pmgr/dspapi.c | 1841 |
1 files changed, 0 insertions, 1841 deletions
diff --git a/drivers/staging/tidspbridge/pmgr/dspapi.c b/drivers/staging/tidspbridge/pmgr/dspapi.c deleted file mode 100644 index c4ccf17d21c0..000000000000 --- a/drivers/staging/tidspbridge/pmgr/dspapi.c +++ /dev/null @@ -1,1841 +0,0 @@ -/* - * 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> - -/* ----------------------------------- OS Adaptation Layer */ -#include <dspbridge/ntfy.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 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) -{ - api_c_refs--; - - if (api_c_refs == 0) - mgr_exit(); -} - -/* - * ======== api_init ======== - * Purpose: - * Module initialization used by Bridge API. - */ -bool api_init(void) -{ - bool ret = true; - - if (api_c_refs == 0) - ret = mgr_init(); - - 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; - struct drv_data *drv_datap; - u8 dev_type; - - /* 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)) { - drv_datap = dev_get_drvdata(bridge); - - if (drv_datap && drv_datap->base_img) - 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 = 0; - int status; - u32 size = args->args_mgr_enumnode_info.ndb_props_size; - - if (size < sizeof(struct dsp_ndbprops)) - return -EINVAL; - size = sizeof(struct dsp_ndbprops); - - pndb_props = kmalloc(size, GFP_KERNEL); - if (pndb_props == NULL) - return -ENOMEM; - - 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.ndb_props, pndb_props, status, - size); - CP_TO_USR(args->args_mgr_enumnode_info.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 = 0; - int status; - u32 size = args->args_mgr_enumproc_info.processor_info_size; - - if (size < sizeof(struct dsp_processorinfo)) - return -EINVAL; - - if (size > sizeof(struct mgr_processorextinfo)) - size = sizeof(struct mgr_processorextinfo); - - processor_info = kzalloc(size, GFP_KERNEL); - if (processor_info == NULL) - return -ENOMEM; - - 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.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 = strlen_user((char *) - args->args_mgr_registerobject.sz_path_name); - if (!path_size) { - status = -EINVAL; - goto func_end; - } - - 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; -} - -/* - * ======== 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 = 0, i; - u32 count = args->args_mgr_wait.count; - - if (count > MAX_EVENTS) - return -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(¬ifications[i], anotifications[i], status, 1); - if (status || !notifications[i].handle) - return -EINVAL; - /* set the array of pointers to kernel structures */ - anotifications[i] = ¬ifications[i]; - } - 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; -} - -/* - * ======== 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.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); - } - - /* CP_TO_USR(args->args_proc_ctrl.args, 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)->processor; - - 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.num_nodes, &num_nodes, - status, 1); - CP_TO_USR(args->args_proc_enumnode_info.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.mpu_addr, - args->args_proc_dma.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.mpu_addr, - args->args_proc_dma.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.flags > - PROC_WRITEBACK_INVALIDATE_MEM) - return -EINVAL; - - status = proc_flush_memory(pr_ctxt, - args->args_proc_flushmemory.mpu_addr, - args->args_proc_flushmemory.size, - args->args_proc_flushmemory.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.mpu_addr, - args->args_proc_invalidatememory.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)->processor; - - 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)->processor; - - 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)->processor; - - 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.buf, 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)->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; -} - -/* - * ======== procwrap_map ======== - */ -u32 procwrap_map(union trapped_args *args, void *pr_ctxt) -{ - int status; - void *map_addr; - void *hprocessor = ((struct process_context *)pr_ctxt)->processor; - - if (!args->args_proc_mapmem.size) - return -EINVAL; - - status = proc_map(args->args_proc_mapmem.processor, - args->args_proc_mapmem.mpu_addr, - args->args_proc_mapmem.size, - args->args_proc_mapmem.req_addr, &map_addr, - args->args_proc_mapmem.map_attr, pr_ctxt); - if (!status) { - if (put_user(map_addr, args->args_proc_mapmem.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)->processor; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - status = proc_register_notify(hprocessor, - args->args_proc_register_notify.event_mask, - args->args_proc_register_notify.notify_type, - ¬ification); - CP_TO_USR(args->args_proc_register_notify.notification, ¬ification, - 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)->processor; - - if ((args->args_proc_rsvmem.size <= 0) || - (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0) - return -EINVAL; - - status = proc_reserve_memory(hprocessor, - args->args_proc_rsvmem.size, &prsv_addr, - pr_ctxt); - if (!status) { - if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) { - status = -EINVAL; - proc_un_reserve_memory(args->args_proc_rsvmem. - processor, 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)->processor); - 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)->processor, - 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)->processor; - - status = proc_un_reserve_memory(hprocessor, - args->args_proc_unrsvmem.rsv_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)->processor); - - 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.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; - - /* 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.args, 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.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.node); - - if (!node_res) - return -EFAULT; - - if (!args->args_node_allocmsgbuf.size) - return -EINVAL; - - if (args->args_node_allocmsgbuf.attr) { /* Optional argument */ - CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1); - if (!status) - pattr = &attr; - - } - /* argument */ - 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; -} - -/* - * ======== 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.node); - - if (!node_res) - return -EFAULT; - - ret = node_change_priority(node_res->node, - 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.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; - - /* 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.attrs) { /* Optional argument */ - 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; -} - -/* - * ======== 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.node); - - if (!node_res) - return -EFAULT; - - ret = node_create(node_res->node); - - 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.node); - - 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.node); - - if (!node_res) - return -EFAULT; - - if (args->args_node_freemsgbuf.attr) { /* Optional argument */ - 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; -} - -/* - * ======== 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.node); - - if (!node_res) - return -EFAULT; - - status = node_get_attr(node_res->node, &attr, - args->args_node_getattr.attr_size); - CP_TO_USR(args->args_node_getattr.attr, &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.node); - - if (!node_res) - return -EFAULT; - - status = node_get_message(node_res->node, &msg, - args->args_node_getmessage.timeout); - - 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.node); - - if (!node_res) - return -EFAULT; - - ret = node_pause(node_res->node); - - 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.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; -} - -/* - * ======== 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.node); - - if (!node_res) - return -EFAULT; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - if (!args->args_proc_register_notify.event_mask) - CP_FM_USR(¬ification, - 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, ¬ification); - CP_TO_USR(args->args_node_registernotify.notification, ¬ification, - 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.node); - - if (!node_res) - return -EFAULT; - - ret = node_run(node_res->node); - - 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.node); - - if (!node_res) - return -EFAULT; - - status = node_terminate(node_res->node, &tempstatus); - - CP_TO_USR(args->args_node_terminate.status, &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)->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; -} - -/* - * ======== 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.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; - - status = strm_allocate_buffer(strm_res, - args->args_strm_allocatebuffer.size, - 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.stream); - - 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.stream); - - if (!strm_res) - return -EFAULT; - - if (num_bufs > MAX_BUFS) - return -EINVAL; - - ap_buffer = kmalloc_array(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.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; -} - -/* - * ======== 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.stream); - - if (!strm_res) - return -EFAULT; - - ret = strm_idle(strm_res->stream, 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.stream); - - if (!strm_res) - return -EFAULT; - - if (!args->args_strm_issue.buffer) - 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->stream, - args->args_strm_issue.buffer, - args->args_strm_issue.bytes, - args->args_strm_issue.buf_size, - args->args_strm_issue.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.node); - - 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->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; -} - -/* - * ======== 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.stream); - - if (!strm_res) - return -EFAULT; - - status = strm_reclaim(strm_res->stream, &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.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.stream); - - if (!strm_res) - return -EFAULT; - - /* Initialize the notification data structure */ - notification.name = NULL; - notification.handle = NULL; - - status = strm_register_notify(strm_res->stream, - args->args_strm_registernotify.event_mask, - args->args_strm_registernotify. - notify_type, ¬ification); - CP_TO_USR(args->args_strm_registernotify.notification, ¬ification, - status, 1); - - return status; -} - -/* - * ======== strmwrap_select ======== - */ -u32 strmwrap_select(union trapped_args *args, void *pr_ctxt) -{ - u32 mask = 0; - 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; -} - -/* 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)->processor; - - status = cmm_get_handle(hprocessor, &hcmm_mgr); - - CP_TO_USR(args->args_cmm_gethandle.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.cmm_mgr, &cmm_info_obj); - - CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status, - 1); - - return status; -} |