4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Common DSP API functions, also includes the wrapper
7 * functions called directly by the DeviceIOControl interface.
9 * Copyright (C) 2005-2006 Texas Instruments, Inc.
11 * This package is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 #include <linux/types.h>
21 /* ----------------------------------- Host OS */
22 #include <dspbridge/host_os.h>
24 /* ----------------------------------- DSP/BIOS Bridge */
25 #include <dspbridge/dbdefs.h>
27 /* ----------------------------------- Trace & Debug */
28 #include <dspbridge/dbc.h>
30 /* ----------------------------------- OS Adaptation Layer */
31 #include <dspbridge/ntfy.h>
33 /* ----------------------------------- Platform Manager */
34 #include <dspbridge/chnl.h>
35 #include <dspbridge/dev.h>
36 #include <dspbridge/drv.h>
38 #include <dspbridge/proc.h>
39 #include <dspbridge/strm.h>
41 /* ----------------------------------- Resource Manager */
42 #include <dspbridge/disp.h>
43 #include <dspbridge/mgr.h>
44 #include <dspbridge/node.h>
45 #include <dspbridge/rmm.h>
47 /* ----------------------------------- Others */
48 #include <dspbridge/msg.h>
49 #include <dspbridge/cmm.h>
50 #include <dspbridge/io.h>
52 /* ----------------------------------- This */
53 #include <dspbridge/dspapi.h>
54 #include <dspbridge/dbdcd.h>
56 #include <dspbridge/resourcecleanup.h>
58 /* ----------------------------------- Defines, Data Structures, Typedefs */
59 #define MAX_TRACEBUFLEN 255
60 #define MAX_LOADARGS 16
62 #define MAX_STREAMS 16
65 /* Used to get dspbridge ioctl table */
66 #define DB_GET_IOC_TABLE(cmd) (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT)
68 /* Device IOCtl function pointer */
70 u32(*fxn) (union trapped_args *args, void *pr_ctxt);
74 /* ----------------------------------- Globals */
75 static u32 api_c_refs;
79 * The order of these functions MUST be the same as the order of the command
80 * numbers defined in dspapi-ioctl.h This is how an IOCTL number in user mode
81 * turns into a function call in kernel mode.
84 /* MGR wrapper functions */
85 static struct api_cmd mgr_cmd[] = {
86 {mgrwrap_enum_node_info}, /* MGR_ENUMNODE_INFO */
87 {mgrwrap_enum_proc_info}, /* MGR_ENUMPROC_INFO */
88 {mgrwrap_register_object}, /* MGR_REGISTEROBJECT */
89 {mgrwrap_unregister_object}, /* MGR_UNREGISTEROBJECT */
90 {mgrwrap_wait_for_bridge_events}, /* MGR_WAIT */
91 {mgrwrap_get_process_resources_info}, /* MGR_GET_PROC_RES */
94 /* PROC wrapper functions */
95 static struct api_cmd proc_cmd[] = {
96 {procwrap_attach}, /* PROC_ATTACH */
97 {procwrap_ctrl}, /* PROC_CTRL */
98 {procwrap_detach}, /* PROC_DETACH */
99 {procwrap_enum_node_info}, /* PROC_ENUMNODE */
100 {procwrap_enum_resources}, /* PROC_ENUMRESOURCES */
101 {procwrap_get_state}, /* PROC_GET_STATE */
102 {procwrap_get_trace}, /* PROC_GET_TRACE */
103 {procwrap_load}, /* PROC_LOAD */
104 {procwrap_register_notify}, /* PROC_REGISTERNOTIFY */
105 {procwrap_start}, /* PROC_START */
106 {procwrap_reserve_memory}, /* PROC_RSVMEM */
107 {procwrap_un_reserve_memory}, /* PROC_UNRSVMEM */
108 {procwrap_map}, /* PROC_MAPMEM */
109 {procwrap_un_map}, /* PROC_UNMAPMEM */
110 {procwrap_flush_memory}, /* PROC_FLUSHMEMORY */
111 {procwrap_stop}, /* PROC_STOP */
112 {procwrap_invalidate_memory}, /* PROC_INVALIDATEMEMORY */
113 {procwrap_begin_dma}, /* PROC_BEGINDMA */
114 {procwrap_end_dma}, /* PROC_ENDDMA */
117 /* NODE wrapper functions */
118 static struct api_cmd node_cmd[] = {
119 {nodewrap_allocate}, /* NODE_ALLOCATE */
120 {nodewrap_alloc_msg_buf}, /* NODE_ALLOCMSGBUF */
121 {nodewrap_change_priority}, /* NODE_CHANGEPRIORITY */
122 {nodewrap_connect}, /* NODE_CONNECT */
123 {nodewrap_create}, /* NODE_CREATE */
124 {nodewrap_delete}, /* NODE_DELETE */
125 {nodewrap_free_msg_buf}, /* NODE_FREEMSGBUF */
126 {nodewrap_get_attr}, /* NODE_GETATTR */
127 {nodewrap_get_message}, /* NODE_GETMESSAGE */
128 {nodewrap_pause}, /* NODE_PAUSE */
129 {nodewrap_put_message}, /* NODE_PUTMESSAGE */
130 {nodewrap_register_notify}, /* NODE_REGISTERNOTIFY */
131 {nodewrap_run}, /* NODE_RUN */
132 {nodewrap_terminate}, /* NODE_TERMINATE */
133 {nodewrap_get_uuid_props}, /* NODE_GETUUIDPROPS */
136 /* STRM wrapper functions */
137 static struct api_cmd strm_cmd[] = {
138 {strmwrap_allocate_buffer}, /* STRM_ALLOCATEBUFFER */
139 {strmwrap_close}, /* STRM_CLOSE */
140 {strmwrap_free_buffer}, /* STRM_FREEBUFFER */
141 {strmwrap_get_event_handle}, /* STRM_GETEVENTHANDLE */
142 {strmwrap_get_info}, /* STRM_GETINFO */
143 {strmwrap_idle}, /* STRM_IDLE */
144 {strmwrap_issue}, /* STRM_ISSUE */
145 {strmwrap_open}, /* STRM_OPEN */
146 {strmwrap_reclaim}, /* STRM_RECLAIM */
147 {strmwrap_register_notify}, /* STRM_REGISTERNOTIFY */
148 {strmwrap_select}, /* STRM_SELECT */
151 /* CMM wrapper functions */
152 static struct api_cmd cmm_cmd[] = {
153 {cmmwrap_calloc_buf}, /* CMM_ALLOCBUF */
154 {cmmwrap_free_buf}, /* CMM_FREEBUF */
155 {cmmwrap_get_handle}, /* CMM_GETHANDLE */
156 {cmmwrap_get_info}, /* CMM_GETINFO */
159 /* Array used to store ioctl table sizes. It can hold up to 8 entries */
160 static u8 size_cmd[] = {
162 ARRAY_SIZE(proc_cmd),
163 ARRAY_SIZE(node_cmd),
164 ARRAY_SIZE(strm_cmd),
168 static inline void _cp_fm_usr(void *to, const void __user * from,
169 int *err, unsigned long bytes)
174 if (unlikely(!from)) {
179 if (unlikely(copy_from_user(to, from, bytes)))
183 #define CP_FM_USR(to, from, err, n) \
184 _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to)))
186 static inline void _cp_to_usr(void __user *to, const void *from,
187 int *err, unsigned long bytes)
197 if (unlikely(copy_to_user(to, from, bytes)))
201 #define CP_TO_USR(to, from, err, n) \
202 _cp_to_usr(to, from, &(err), (n) * sizeof(*(from)))
205 * ======== api_call_dev_ioctl ========
207 * Call the (wrapper) function for the corresponding API IOCTL.
209 inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args,
210 u32 *result, void *pr_ctxt)
212 u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL;
215 if (_IOC_TYPE(cmd) != DB) {
216 pr_err("%s: Incompatible dspbridge ioctl number\n", __func__);
220 if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) {
221 pr_err("%s: undefined ioctl module\n", __func__);
225 /* Check the size of the required cmd table */
227 if (i > size_cmd[DB_GET_IOC_TABLE(cmd)]) {
228 pr_err("%s: requested ioctl %d out of bounds for table %d\n",
229 __func__, i, DB_GET_IOC_TABLE(cmd));
233 switch (DB_GET_MODULE(cmd)) {
235 ioctl_cmd = mgr_cmd[i].fxn;
238 ioctl_cmd = proc_cmd[i].fxn;
241 ioctl_cmd = node_cmd[i].fxn;
244 ioctl_cmd = strm_cmd[i].fxn;
247 ioctl_cmd = cmm_cmd[i].fxn;
252 pr_err("%s: requested ioctl not defined\n", __func__);
255 *result = (*ioctl_cmd) (args, pr_ctxt);
265 * ======== api_exit ========
269 DBC_REQUIRE(api_c_refs > 0);
272 if (api_c_refs == 0) {
273 /* Release all modules initialized in api_init(). */
287 DBC_ENSURE(api_c_refs >= 0);
291 * ======== api_init ========
293 * Module initialization used by Bridge API.
298 bool fdrv, fdev, fcod, fchnl, fmsg, fio;
299 bool fmgr, fproc, fnode, fdisp, fstrm, frmm;
301 if (api_c_refs == 0) {
302 /* initialize driver and other modules */
311 fmsg = msg_mod_init();
315 ret = fdrv && fdev && fchnl && fcod && fmsg && fio;
316 ret = ret && fmgr && fproc && frmm;
363 * ======== api_init_complete2 ========
365 * Perform any required bridge initialization which cannot
366 * be performed in api_init() or dev_start_device() due
367 * to the fact that some services are not yet
368 * completely initialized.
371 * 0: Allow this device to load
374 * Bridge API initialized.
377 int api_init_complete2(void)
380 struct cfg_devnode *dev_node;
381 struct dev_object *hdev_obj;
382 struct drv_data *drv_datap;
385 DBC_REQUIRE(api_c_refs > 0);
387 /* Walk the list of DevObjects, get each devnode, and attempting to
388 * autostart the board. Note that this requires COF loading, which
390 for (hdev_obj = dev_get_first(); hdev_obj != NULL;
391 hdev_obj = dev_get_next(hdev_obj)) {
392 if (dev_get_dev_node(hdev_obj, &dev_node))
395 if (dev_get_dev_type(hdev_obj, &dev_type))
398 if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
399 drv_datap = dev_get_drvdata(bridge);
401 if (drv_datap && drv_datap->base_img)
402 proc_auto_start(dev_node, hdev_obj);
409 /* TODO: Remove deprecated and not implemented ioctl wrappers */
412 * ======== mgrwrap_enum_node_info ========
414 u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
419 u32 size = args->args_mgr_enumnode_info.undb_props_size;
421 if (size < sizeof(struct dsp_ndbprops))
424 pndb_props = kmalloc(size, GFP_KERNEL);
425 if (pndb_props == NULL)
430 mgr_enum_node_info(args->args_mgr_enumnode_info.node_id,
431 (struct dsp_ndbprops *)pndb_props, size,
434 CP_TO_USR(args->args_mgr_enumnode_info.pndb_props, pndb_props, status,
436 CP_TO_USR(args->args_mgr_enumnode_info.pu_num_nodes, &num_nodes, status,
444 * ======== mgrwrap_enum_proc_info ========
446 u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt)
451 u32 size = args->args_mgr_enumproc_info.processor_info_size;
453 if (size < sizeof(struct dsp_processorinfo))
456 processor_info = kmalloc(size, GFP_KERNEL);
457 if (processor_info == NULL)
462 mgr_enum_processor_info(args->args_mgr_enumproc_info.
464 (struct dsp_processorinfo *)
465 processor_info, size, &num_procs);
467 CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info,
469 CP_TO_USR(args->args_mgr_enumproc_info.pu_num_procs, &num_procs,
471 kfree(processor_info);
476 #define WRAP_MAP2CALLER(x) x
478 * ======== mgrwrap_register_object ========
480 u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
483 struct dsp_uuid uuid_obj;
485 char *psz_path_name = NULL;
488 CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
491 /* path_size is increased by 1 to accommodate NULL */
492 path_size = strlen_user((char *)
493 args->args_mgr_registerobject.psz_path_name) +
495 psz_path_name = kmalloc(path_size, GFP_KERNEL);
498 ret = strncpy_from_user(psz_path_name,
499 (char *)args->args_mgr_registerobject.
500 psz_path_name, path_size);
506 if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE)
509 status = dcd_register_object(&uuid_obj,
510 args->args_mgr_registerobject.obj_type,
511 (char *)psz_path_name);
513 kfree(psz_path_name);
518 * ======== mgrwrap_unregister_object ========
520 u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt)
523 struct dsp_uuid uuid_obj;
525 CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
529 status = dcd_unregister_object(&uuid_obj,
530 args->args_mgr_unregisterobject.
538 * ======== mgrwrap_wait_for_bridge_events ========
540 u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
543 struct dsp_notification *anotifications[MAX_EVENTS];
544 struct dsp_notification notifications[MAX_EVENTS];
546 u32 count = args->args_mgr_wait.count;
548 if (count > MAX_EVENTS)
551 /* get the array of pointers to user structures */
552 CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
555 for (i = 0; i < count; i++) {
556 CP_FM_USR(¬ifications[i], anotifications[i], status, 1);
557 if (status || !notifications[i].handle) {
561 /* set the array of pointers to kernel structures */
562 anotifications[i] = ¬ifications[i];
565 status = mgr_wait_for_bridge_events(anotifications, count,
570 CP_TO_USR(args->args_mgr_wait.pu_index, &index, status, 1);
575 * ======== MGRWRAP_GetProcessResourceInfo ========
577 u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args,
580 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
585 * ======== procwrap_attach ========
587 u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
591 struct dsp_processorattrin proc_attr_in, *attr_in = NULL;
593 /* Optional argument */
594 if (args->args_proc_attach.attr_in) {
595 CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status,
598 attr_in = &proc_attr_in;
603 status = proc_attach(args->args_proc_attach.processor_id, attr_in,
604 &processor, pr_ctxt);
605 CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1);
611 * ======== procwrap_ctrl ========
613 u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt)
615 u32 cb_data_size, __user * psize = (u32 __user *)
616 args->args_proc_ctrl.pargs;
619 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
622 if (get_user(cb_data_size, psize)) {
626 cb_data_size += sizeof(u32);
627 pargs = kmalloc(cb_data_size, GFP_KERNEL);
633 CP_FM_USR(pargs, args->args_proc_ctrl.pargs, status,
637 status = proc_ctrl(hprocessor,
638 args->args_proc_ctrl.dw_cmd,
639 (struct dsp_cbdata *)pargs);
642 /* CP_TO_USR(args->args_proc_ctrl.pargs, pargs, status, 1); */
649 * ======== procwrap_detach ========
651 u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt)
653 /* proc_detach called at bridge_release only */
654 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
659 * ======== procwrap_enum_node_info ========
661 u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
664 void *node_tab[MAX_NODES];
667 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
669 if (!args->args_proc_enumnode_info.node_tab_size)
672 status = proc_enum_nodes(hprocessor,
674 args->args_proc_enumnode_info.node_tab_size,
675 &num_nodes, &alloc_cnt);
676 CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status,
678 CP_TO_USR(args->args_proc_enumnode_info.pu_num_nodes, &num_nodes,
680 CP_TO_USR(args->args_proc_enumnode_info.pu_allocated, &alloc_cnt,
685 u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt)
689 if (args->args_proc_dma.dir >= DMA_NONE)
692 status = proc_end_dma(pr_ctxt,
693 args->args_proc_dma.pmpu_addr,
694 args->args_proc_dma.ul_size,
695 args->args_proc_dma.dir);
699 u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt)
703 if (args->args_proc_dma.dir >= DMA_NONE)
706 status = proc_begin_dma(pr_ctxt,
707 args->args_proc_dma.pmpu_addr,
708 args->args_proc_dma.ul_size,
709 args->args_proc_dma.dir);
714 * ======== procwrap_flush_memory ========
716 u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt)
720 if (args->args_proc_flushmemory.ul_flags >
721 PROC_WRITEBACK_INVALIDATE_MEM)
724 status = proc_flush_memory(pr_ctxt,
725 args->args_proc_flushmemory.pmpu_addr,
726 args->args_proc_flushmemory.ul_size,
727 args->args_proc_flushmemory.ul_flags);
732 * ======== procwrap_invalidate_memory ========
734 u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt)
739 proc_invalidate_memory(pr_ctxt,
740 args->args_proc_invalidatememory.pmpu_addr,
741 args->args_proc_invalidatememory.ul_size);
746 * ======== procwrap_enum_resources ========
748 u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt)
751 struct dsp_resourceinfo resource_info;
752 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
754 if (args->args_proc_enumresources.resource_info_size <
755 sizeof(struct dsp_resourceinfo))
759 proc_get_resource_info(hprocessor,
760 args->args_proc_enumresources.resource_type,
762 args->args_proc_enumresources.
765 CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info,
773 * ======== procwrap_get_state ========
775 u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt)
778 struct dsp_processorstate proc_state;
779 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
781 if (args->args_proc_getstate.state_info_size <
782 sizeof(struct dsp_processorstate))
785 status = proc_get_state(hprocessor, &proc_state,
786 args->args_proc_getstate.state_info_size);
787 CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status,
794 * ======== procwrap_get_trace ========
796 u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt)
800 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
802 if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN)
805 pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL);
807 status = proc_get_trace(hprocessor, pbuf,
808 args->args_proc_gettrace.max_size);
812 CP_TO_USR(args->args_proc_gettrace.pbuf, pbuf, status,
813 args->args_proc_gettrace.max_size);
820 * ======== procwrap_load ========
822 u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
827 s32 count = args->args_proc_load.argc_index;
828 u8 **argv = NULL, **envp = NULL;
829 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
831 if (count <= 0 || count > MAX_LOADARGS) {
836 argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
842 CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
849 for (i = 0; i < count; i++) {
851 /* User space pointer to argument */
852 temp = (char *)argv[i];
853 /* len is increased by 1 to accommodate NULL */
854 len = strlen_user((char *)temp) + 1;
855 /* Kernel space pointer to argument */
856 argv[i] = kmalloc(len, GFP_KERNEL);
858 CP_FM_USR(argv[i], temp, status, len);
870 /* TODO: validate this */
871 if (args->args_proc_load.user_envp) {
872 /* number of elements in the envp array including NULL */
875 get_user(temp, args->args_proc_load.user_envp + count);
878 envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
884 CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
890 for (i = 0; envp[i]; i++) {
891 /* User space pointer to argument */
892 temp = (char *)envp[i];
893 /* len is increased by 1 to accommodate NULL */
894 len = strlen_user((char *)temp) + 1;
895 /* Kernel space pointer to argument */
896 envp[i] = kmalloc(len, GFP_KERNEL);
898 CP_FM_USR(envp[i], temp, status, len);
912 status = proc_load(hprocessor,
913 args->args_proc_load.argc_index,
914 (const char **)argv, (const char **)envp);
926 count = args->args_proc_load.argc_index;
927 for (i = 0; (i < count) && argv[i]; i++)
937 * ======== procwrap_map ========
939 u32 procwrap_map(union trapped_args *args, void *pr_ctxt)
943 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
945 if (!args->args_proc_mapmem.ul_size)
948 status = proc_map(args->args_proc_mapmem.hprocessor,
949 args->args_proc_mapmem.pmpu_addr,
950 args->args_proc_mapmem.ul_size,
951 args->args_proc_mapmem.req_addr, &map_addr,
952 args->args_proc_mapmem.ul_map_attr, pr_ctxt);
954 if (put_user(map_addr, args->args_proc_mapmem.pp_map_addr)) {
956 proc_un_map(hprocessor, map_addr, pr_ctxt);
964 * ======== procwrap_register_notify ========
966 u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
969 struct dsp_notification notification;
970 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
972 /* Initialize the notification data structure */
973 notification.ps_name = NULL;
974 notification.handle = NULL;
976 status = proc_register_notify(hprocessor,
977 args->args_proc_register_notify.event_mask,
978 args->args_proc_register_notify.notify_type,
980 CP_TO_USR(args->args_proc_register_notify.hnotification, ¬ification,
986 * ======== procwrap_reserve_memory ========
988 u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
992 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
994 if ((args->args_proc_rsvmem.ul_size <= 0) ||
995 (args->args_proc_rsvmem.ul_size & (PG_SIZE4K - 1)) != 0)
998 status = proc_reserve_memory(hprocessor,
999 args->args_proc_rsvmem.ul_size, &prsv_addr,
1002 if (put_user(prsv_addr, args->args_proc_rsvmem.pp_rsv_addr)) {
1004 proc_un_reserve_memory(args->args_proc_rsvmem.
1005 hprocessor, prsv_addr, pr_ctxt);
1012 * ======== procwrap_start ========
1014 u32 procwrap_start(union trapped_args *args, void *pr_ctxt)
1018 ret = proc_start(((struct process_context *)pr_ctxt)->hprocessor);
1023 * ======== procwrap_un_map ========
1025 u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
1029 status = proc_un_map(((struct process_context *)pr_ctxt)->hprocessor,
1030 args->args_proc_unmapmem.map_addr, pr_ctxt);
1035 * ======== procwrap_un_reserve_memory ========
1037 u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
1040 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
1042 status = proc_un_reserve_memory(hprocessor,
1043 args->args_proc_unrsvmem.prsv_addr,
1049 * ======== procwrap_stop ========
1051 u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
1055 ret = proc_stop(((struct process_context *)pr_ctxt)->hprocessor);
1061 * ======== find_handle =========
1063 inline void find_node_handle(struct node_res_object **noderes,
1064 void *pr_ctxt, void *hnode)
1067 *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
1075 * ======== nodewrap_allocate ========
1077 u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
1080 struct dsp_uuid node_uuid;
1081 u32 cb_data_size = 0;
1082 u32 __user *psize = (u32 __user *) args->args_node_allocate.pargs;
1084 struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
1085 struct node_res_object *node_res;
1087 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
1089 /* Optional argument */
1091 if (get_user(cb_data_size, psize))
1094 cb_data_size += sizeof(u32);
1096 pargs = kmalloc(cb_data_size, GFP_KERNEL);
1101 CP_FM_USR(pargs, args->args_node_allocate.pargs, status,
1104 CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
1107 /* Optional argument */
1108 if (args->args_node_allocate.attr_in) {
1109 CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in,
1112 attr_in = &proc_attr_in;
1118 status = node_allocate(hprocessor,
1119 &node_uuid, (struct dsp_cbdata *)pargs,
1120 attr_in, &node_res, pr_ctxt);
1123 nodeid = node_res->id + 1;
1124 CP_TO_USR(args->args_node_allocate.ph_node, &nodeid,
1128 node_delete(node_res, pr_ctxt);
1138 * ======== nodewrap_alloc_msg_buf ========
1140 u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
1143 struct dsp_bufferattr *pattr = NULL;
1144 struct dsp_bufferattr attr;
1146 struct node_res_object *node_res;
1148 find_node_handle(&node_res, pr_ctxt,
1149 args->args_node_allocmsgbuf.hnode);
1154 if (!args->args_node_allocmsgbuf.usize)
1157 if (args->args_node_allocmsgbuf.pattr) { /* Optional argument */
1158 CP_FM_USR(&attr, args->args_node_allocmsgbuf.pattr, status, 1);
1164 CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.pbuffer, status, 1);
1166 status = node_alloc_msg_buf(node_res->hnode,
1167 args->args_node_allocmsgbuf.usize,
1170 CP_TO_USR(args->args_node_allocmsgbuf.pbuffer, &pbuffer, status, 1);
1175 * ======== nodewrap_change_priority ========
1177 u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
1180 struct node_res_object *node_res;
1182 find_node_handle(&node_res, pr_ctxt,
1183 args->args_node_changepriority.hnode);
1188 ret = node_change_priority(node_res->hnode,
1189 args->args_node_changepriority.prio);
1195 * ======== nodewrap_connect ========
1197 u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
1200 struct dsp_strmattr attrs;
1201 struct dsp_strmattr *pattrs = NULL;
1203 u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
1205 struct node_res_object *node_res1, *node_res2;
1206 struct node_object *node1 = NULL, *node2 = NULL;
1208 if ((int)args->args_node_connect.hnode != DSP_HGPPNODE) {
1209 find_node_handle(&node_res1, pr_ctxt,
1210 args->args_node_connect.hnode);
1212 node1 = node_res1->hnode;
1214 node1 = args->args_node_connect.hnode;
1217 if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
1218 find_node_handle(&node_res2, pr_ctxt,
1219 args->args_node_connect.other_node);
1221 node2 = node_res2->hnode;
1223 node2 = args->args_node_connect.other_node;
1226 if (!node1 || !node2)
1229 /* Optional argument */
1231 if (get_user(cb_data_size, psize))
1234 cb_data_size += sizeof(u32);
1236 pargs = kmalloc(cb_data_size, GFP_KERNEL);
1237 if (pargs == NULL) {
1243 CP_FM_USR(pargs, args->args_node_connect.conn_param, status,
1248 if (args->args_node_connect.pattrs) { /* Optional argument */
1249 CP_FM_USR(&attrs, args->args_node_connect.pattrs, status, 1);
1255 status = node_connect(node1,
1256 args->args_node_connect.stream_id,
1258 args->args_node_connect.other_stream,
1259 pattrs, (struct dsp_cbdata *)pargs);
1268 * ======== nodewrap_create ========
1270 u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
1273 struct node_res_object *node_res;
1275 find_node_handle(&node_res, pr_ctxt, args->args_node_create.hnode);
1280 ret = node_create(node_res->hnode);
1286 * ======== nodewrap_delete ========
1288 u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
1291 struct node_res_object *node_res;
1293 find_node_handle(&node_res, pr_ctxt, args->args_node_delete.hnode);
1298 ret = node_delete(node_res, pr_ctxt);
1304 * ======== nodewrap_free_msg_buf ========
1306 u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
1309 struct dsp_bufferattr *pattr = NULL;
1310 struct dsp_bufferattr attr;
1311 struct node_res_object *node_res;
1313 find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.hnode);
1318 if (args->args_node_freemsgbuf.pattr) { /* Optional argument */
1319 CP_FM_USR(&attr, args->args_node_freemsgbuf.pattr, status, 1);
1325 if (!args->args_node_freemsgbuf.pbuffer)
1329 status = node_free_msg_buf(node_res->hnode,
1330 args->args_node_freemsgbuf.pbuffer,
1338 * ======== nodewrap_get_attr ========
1340 u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
1343 struct dsp_nodeattr attr;
1344 struct node_res_object *node_res;
1346 find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.hnode);
1351 status = node_get_attr(node_res->hnode, &attr,
1352 args->args_node_getattr.attr_size);
1353 CP_TO_USR(args->args_node_getattr.pattr, &attr, status, 1);
1359 * ======== nodewrap_get_message ========
1361 u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
1365 struct node_res_object *node_res;
1367 find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.hnode);
1372 status = node_get_message(node_res->hnode, &msg,
1373 args->args_node_getmessage.utimeout);
1375 CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);
1381 * ======== nodewrap_pause ========
1383 u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
1386 struct node_res_object *node_res;
1388 find_node_handle(&node_res, pr_ctxt, args->args_node_pause.hnode);
1393 ret = node_pause(node_res->hnode);
1399 * ======== nodewrap_put_message ========
1401 u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
1405 struct node_res_object *node_res;
1407 find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.hnode);
1412 CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
1416 node_put_message(node_res->hnode, &msg,
1417 args->args_node_putmessage.utimeout);
1424 * ======== nodewrap_register_notify ========
1426 u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
1429 struct dsp_notification notification;
1430 struct node_res_object *node_res;
1432 find_node_handle(&node_res, pr_ctxt,
1433 args->args_node_registernotify.hnode);
1438 /* Initialize the notification data structure */
1439 notification.ps_name = NULL;
1440 notification.handle = NULL;
1442 if (!args->args_proc_register_notify.event_mask)
1443 CP_FM_USR(¬ification,
1444 args->args_proc_register_notify.hnotification,
1447 status = node_register_notify(node_res->hnode,
1448 args->args_node_registernotify.event_mask,
1449 args->args_node_registernotify.
1450 notify_type, ¬ification);
1451 CP_TO_USR(args->args_node_registernotify.hnotification, ¬ification,
1457 * ======== nodewrap_run ========
1459 u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
1462 struct node_res_object *node_res;
1464 find_node_handle(&node_res, pr_ctxt, args->args_node_run.hnode);
1469 ret = node_run(node_res->hnode);
1475 * ======== nodewrap_terminate ========
1477 u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
1481 struct node_res_object *node_res;
1483 find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.hnode);
1488 status = node_terminate(node_res->hnode, &tempstatus);
1490 CP_TO_USR(args->args_node_terminate.pstatus, &tempstatus, status, 1);
1496 * ======== nodewrap_get_uuid_props ========
1498 u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt)
1501 struct dsp_uuid node_uuid;
1502 struct dsp_ndbprops *pnode_props = NULL;
1503 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
1505 CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status,
1509 pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL);
1510 if (pnode_props != NULL) {
1512 node_get_uuid_props(hprocessor, &node_uuid, pnode_props);
1513 CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props,
1523 * ======== find_strm_handle =========
1525 inline void find_strm_handle(struct strm_res_object **strmres,
1526 void *pr_ctxt, void *hstream)
1529 *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id,
1536 * ======== strmwrap_allocate_buffer ========
1538 u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt)
1541 u8 **ap_buffer = NULL;
1542 u32 num_bufs = args->args_strm_allocatebuffer.num_bufs;
1543 struct strm_res_object *strm_res;
1545 find_strm_handle(&strm_res, pr_ctxt,
1546 args->args_strm_allocatebuffer.hstream);
1551 if (num_bufs > MAX_BUFS)
1554 ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
1555 if (ap_buffer == NULL)
1558 status = strm_allocate_buffer(strm_res,
1559 args->args_strm_allocatebuffer.usize,
1560 ap_buffer, num_bufs, pr_ctxt);
1562 CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer,
1566 strm_free_buffer(strm_res,
1567 ap_buffer, num_bufs, pr_ctxt);
1576 * ======== strmwrap_close ========
1578 u32 strmwrap_close(union trapped_args *args, void *pr_ctxt)
1580 struct strm_res_object *strm_res;
1582 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.hstream);
1587 return strm_close(strm_res, pr_ctxt);
1591 * ======== strmwrap_free_buffer ========
1593 u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
1596 u8 **ap_buffer = NULL;
1597 u32 num_bufs = args->args_strm_freebuffer.num_bufs;
1598 struct strm_res_object *strm_res;
1600 find_strm_handle(&strm_res, pr_ctxt,
1601 args->args_strm_freebuffer.hstream);
1606 if (num_bufs > MAX_BUFS)
1609 ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
1610 if (ap_buffer == NULL)
1613 CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status,
1617 status = strm_free_buffer(strm_res,
1618 ap_buffer, num_bufs, pr_ctxt);
1620 CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status,
1628 * ======== strmwrap_get_event_handle ========
1630 u32 __deprecated strmwrap_get_event_handle(union trapped_args * args,
1633 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1638 * ======== strmwrap_get_info ========
1640 u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt)
1643 struct stream_info strm_info;
1644 struct dsp_streaminfo user;
1645 struct dsp_streaminfo *temp;
1646 struct strm_res_object *strm_res;
1648 find_strm_handle(&strm_res, pr_ctxt,
1649 args->args_strm_getinfo.hstream);
1654 CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1);
1655 temp = strm_info.user_strm;
1657 strm_info.user_strm = &user;
1660 status = strm_get_info(strm_res->hstream,
1662 args->args_strm_getinfo.
1665 CP_TO_USR(temp, strm_info.user_strm, status, 1);
1666 strm_info.user_strm = temp;
1667 CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1);
1672 * ======== strmwrap_idle ========
1674 u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt)
1677 struct strm_res_object *strm_res;
1679 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.hstream);
1684 ret = strm_idle(strm_res->hstream, args->args_strm_idle.flush_flag);
1690 * ======== strmwrap_issue ========
1692 u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt)
1695 struct strm_res_object *strm_res;
1697 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.hstream);
1702 if (!args->args_strm_issue.pbuffer)
1705 /* No need of doing CP_FM_USR for the user buffer (pbuffer)
1706 as this is done in Bridge internal function bridge_chnl_add_io_req
1708 status = strm_issue(strm_res->hstream,
1709 args->args_strm_issue.pbuffer,
1710 args->args_strm_issue.dw_bytes,
1711 args->args_strm_issue.dw_buf_size,
1712 args->args_strm_issue.dw_arg);
1718 * ======== strmwrap_open ========
1720 u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
1723 struct strm_attr attr;
1724 struct strm_res_object *strm_res_obj;
1725 struct dsp_streamattrin strm_attr_in;
1726 struct node_res_object *node_res;
1729 find_node_handle(&node_res, pr_ctxt, args->args_strm_open.hnode);
1734 CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
1736 if (attr.stream_attr_in != NULL) { /* Optional argument */
1737 CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1);
1739 attr.stream_attr_in = &strm_attr_in;
1740 if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA)
1745 status = strm_open(node_res->hnode,
1746 args->args_strm_open.direction,
1747 args->args_strm_open.index, &attr, &strm_res_obj,
1750 strmid = strm_res_obj->id + 1;
1751 CP_TO_USR(args->args_strm_open.ph_stream, &strmid, status, 1);
1757 * ======== strmwrap_reclaim ========
1759 u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt)
1766 struct strm_res_object *strm_res;
1768 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.hstream);
1773 status = strm_reclaim(strm_res->hstream, &buf_ptr,
1774 &ul_bytes, &ul_buf_size, &dw_arg);
1775 CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1);
1776 CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1);
1777 CP_TO_USR(args->args_strm_reclaim.pdw_arg, &dw_arg, status, 1);
1779 if (args->args_strm_reclaim.buf_size_ptr != NULL) {
1780 CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size,
1788 * ======== strmwrap_register_notify ========
1790 u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt)
1793 struct dsp_notification notification;
1794 struct strm_res_object *strm_res;
1796 find_strm_handle(&strm_res, pr_ctxt,
1797 args->args_strm_registernotify.hstream);
1802 /* Initialize the notification data structure */
1803 notification.ps_name = NULL;
1804 notification.handle = NULL;
1806 status = strm_register_notify(strm_res->hstream,
1807 args->args_strm_registernotify.event_mask,
1808 args->args_strm_registernotify.
1809 notify_type, ¬ification);
1810 CP_TO_USR(args->args_strm_registernotify.hnotification, ¬ification,
1817 * ======== strmwrap_select ========
1819 u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
1822 struct strm_object *strm_tab[MAX_STREAMS];
1824 struct strm_res_object *strm_res;
1825 int *ids[MAX_STREAMS];
1828 if (args->args_strm_select.strm_num > MAX_STREAMS)
1831 CP_FM_USR(ids, args->args_strm_select.stream_tab, status,
1832 args->args_strm_select.strm_num);
1837 for (i = 0; i < args->args_strm_select.strm_num; i++) {
1838 find_strm_handle(&strm_res, pr_ctxt, ids[i]);
1843 strm_tab[i] = strm_res->hstream;
1847 status = strm_select(strm_tab, args->args_strm_select.strm_num,
1848 &mask, args->args_strm_select.utimeout);
1850 CP_TO_USR(args->args_strm_select.pmask, &mask, status, 1);
1857 * ======== cmmwrap_calloc_buf ========
1859 u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
1861 /* This operation is done in kernel */
1862 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1867 * ======== cmmwrap_free_buf ========
1869 u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt)
1871 /* This operation is done in kernel */
1872 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1877 * ======== cmmwrap_get_handle ========
1879 u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt)
1882 struct cmm_object *hcmm_mgr;
1883 void *hprocessor = ((struct process_context *)pr_ctxt)->hprocessor;
1885 status = cmm_get_handle(hprocessor, &hcmm_mgr);
1887 CP_TO_USR(args->args_cmm_gethandle.ph_cmm_mgr, &hcmm_mgr, status, 1);
1893 * ======== cmmwrap_get_info ========
1895 u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt)
1898 struct cmm_info cmm_info_obj;
1900 status = cmm_get_info(args->args_cmm_getinfo.hcmm_mgr, &cmm_info_obj);
1902 CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status,