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 /* ----------------------------------- OS Adaptation Layer */
28 #include <dspbridge/ntfy.h>
30 /* ----------------------------------- Platform Manager */
31 #include <dspbridge/chnl.h>
32 #include <dspbridge/dev.h>
33 #include <dspbridge/drv.h>
35 #include <dspbridge/proc.h>
36 #include <dspbridge/strm.h>
38 /* ----------------------------------- Resource Manager */
39 #include <dspbridge/disp.h>
40 #include <dspbridge/mgr.h>
41 #include <dspbridge/node.h>
42 #include <dspbridge/rmm.h>
44 /* ----------------------------------- Others */
45 #include <dspbridge/msg.h>
46 #include <dspbridge/cmm.h>
47 #include <dspbridge/io.h>
49 /* ----------------------------------- This */
50 #include <dspbridge/dspapi.h>
51 #include <dspbridge/dbdcd.h>
53 #include <dspbridge/resourcecleanup.h>
55 /* ----------------------------------- Defines, Data Structures, Typedefs */
56 #define MAX_TRACEBUFLEN 255
57 #define MAX_LOADARGS 16
59 #define MAX_STREAMS 16
62 /* Used to get dspbridge ioctl table */
63 #define DB_GET_IOC_TABLE(cmd) (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT)
65 /* Device IOCtl function pointer */
67 u32(*fxn
) (union trapped_args
*args
, void *pr_ctxt
);
71 /* ----------------------------------- Globals */
72 static u32 api_c_refs
;
76 * The order of these functions MUST be the same as the order of the command
77 * numbers defined in dspapi-ioctl.h This is how an IOCTL number in user mode
78 * turns into a function call in kernel mode.
81 /* MGR wrapper functions */
82 static struct api_cmd mgr_cmd
[] = {
83 {mgrwrap_enum_node_info
}, /* MGR_ENUMNODE_INFO */
84 {mgrwrap_enum_proc_info
}, /* MGR_ENUMPROC_INFO */
85 {mgrwrap_register_object
}, /* MGR_REGISTEROBJECT */
86 {mgrwrap_unregister_object
}, /* MGR_UNREGISTEROBJECT */
87 {mgrwrap_wait_for_bridge_events
}, /* MGR_WAIT */
88 {mgrwrap_get_process_resources_info
}, /* MGR_GET_PROC_RES */
91 /* PROC wrapper functions */
92 static struct api_cmd proc_cmd
[] = {
93 {procwrap_attach
}, /* PROC_ATTACH */
94 {procwrap_ctrl
}, /* PROC_CTRL */
95 {procwrap_detach
}, /* PROC_DETACH */
96 {procwrap_enum_node_info
}, /* PROC_ENUMNODE */
97 {procwrap_enum_resources
}, /* PROC_ENUMRESOURCES */
98 {procwrap_get_state
}, /* PROC_GET_STATE */
99 {procwrap_get_trace
}, /* PROC_GET_TRACE */
100 {procwrap_load
}, /* PROC_LOAD */
101 {procwrap_register_notify
}, /* PROC_REGISTERNOTIFY */
102 {procwrap_start
}, /* PROC_START */
103 {procwrap_reserve_memory
}, /* PROC_RSVMEM */
104 {procwrap_un_reserve_memory
}, /* PROC_UNRSVMEM */
105 {procwrap_map
}, /* PROC_MAPMEM */
106 {procwrap_un_map
}, /* PROC_UNMAPMEM */
107 {procwrap_flush_memory
}, /* PROC_FLUSHMEMORY */
108 {procwrap_stop
}, /* PROC_STOP */
109 {procwrap_invalidate_memory
}, /* PROC_INVALIDATEMEMORY */
110 {procwrap_begin_dma
}, /* PROC_BEGINDMA */
111 {procwrap_end_dma
}, /* PROC_ENDDMA */
114 /* NODE wrapper functions */
115 static struct api_cmd node_cmd
[] = {
116 {nodewrap_allocate
}, /* NODE_ALLOCATE */
117 {nodewrap_alloc_msg_buf
}, /* NODE_ALLOCMSGBUF */
118 {nodewrap_change_priority
}, /* NODE_CHANGEPRIORITY */
119 {nodewrap_connect
}, /* NODE_CONNECT */
120 {nodewrap_create
}, /* NODE_CREATE */
121 {nodewrap_delete
}, /* NODE_DELETE */
122 {nodewrap_free_msg_buf
}, /* NODE_FREEMSGBUF */
123 {nodewrap_get_attr
}, /* NODE_GETATTR */
124 {nodewrap_get_message
}, /* NODE_GETMESSAGE */
125 {nodewrap_pause
}, /* NODE_PAUSE */
126 {nodewrap_put_message
}, /* NODE_PUTMESSAGE */
127 {nodewrap_register_notify
}, /* NODE_REGISTERNOTIFY */
128 {nodewrap_run
}, /* NODE_RUN */
129 {nodewrap_terminate
}, /* NODE_TERMINATE */
130 {nodewrap_get_uuid_props
}, /* NODE_GETUUIDPROPS */
133 /* STRM wrapper functions */
134 static struct api_cmd strm_cmd
[] = {
135 {strmwrap_allocate_buffer
}, /* STRM_ALLOCATEBUFFER */
136 {strmwrap_close
}, /* STRM_CLOSE */
137 {strmwrap_free_buffer
}, /* STRM_FREEBUFFER */
138 {strmwrap_get_event_handle
}, /* STRM_GETEVENTHANDLE */
139 {strmwrap_get_info
}, /* STRM_GETINFO */
140 {strmwrap_idle
}, /* STRM_IDLE */
141 {strmwrap_issue
}, /* STRM_ISSUE */
142 {strmwrap_open
}, /* STRM_OPEN */
143 {strmwrap_reclaim
}, /* STRM_RECLAIM */
144 {strmwrap_register_notify
}, /* STRM_REGISTERNOTIFY */
145 {strmwrap_select
}, /* STRM_SELECT */
148 /* CMM wrapper functions */
149 static struct api_cmd cmm_cmd
[] = {
150 {cmmwrap_calloc_buf
}, /* CMM_ALLOCBUF */
151 {cmmwrap_free_buf
}, /* CMM_FREEBUF */
152 {cmmwrap_get_handle
}, /* CMM_GETHANDLE */
153 {cmmwrap_get_info
}, /* CMM_GETINFO */
156 /* Array used to store ioctl table sizes. It can hold up to 8 entries */
157 static u8 size_cmd
[] = {
159 ARRAY_SIZE(proc_cmd
),
160 ARRAY_SIZE(node_cmd
),
161 ARRAY_SIZE(strm_cmd
),
165 static inline void _cp_fm_usr(void *to
, const void __user
* from
,
166 int *err
, unsigned long bytes
)
171 if (unlikely(!from
)) {
176 if (unlikely(copy_from_user(to
, from
, bytes
)))
180 #define CP_FM_USR(to, from, err, n) \
181 _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to)))
183 static inline void _cp_to_usr(void __user
*to
, const void *from
,
184 int *err
, unsigned long bytes
)
194 if (unlikely(copy_to_user(to
, from
, bytes
)))
198 #define CP_TO_USR(to, from, err, n) \
199 _cp_to_usr(to, from, &(err), (n) * sizeof(*(from)))
202 * ======== api_call_dev_ioctl ========
204 * Call the (wrapper) function for the corresponding API IOCTL.
206 inline int api_call_dev_ioctl(u32 cmd
, union trapped_args
*args
,
207 u32
*result
, void *pr_ctxt
)
209 u32(*ioctl_cmd
) (union trapped_args
*args
, void *pr_ctxt
) = NULL
;
212 if (_IOC_TYPE(cmd
) != DB
) {
213 pr_err("%s: Incompatible dspbridge ioctl number\n", __func__
);
217 if (DB_GET_IOC_TABLE(cmd
) > ARRAY_SIZE(size_cmd
)) {
218 pr_err("%s: undefined ioctl module\n", __func__
);
222 /* Check the size of the required cmd table */
224 if (i
> size_cmd
[DB_GET_IOC_TABLE(cmd
)]) {
225 pr_err("%s: requested ioctl %d out of bounds for table %d\n",
226 __func__
, i
, DB_GET_IOC_TABLE(cmd
));
230 switch (DB_GET_MODULE(cmd
)) {
232 ioctl_cmd
= mgr_cmd
[i
].fxn
;
235 ioctl_cmd
= proc_cmd
[i
].fxn
;
238 ioctl_cmd
= node_cmd
[i
].fxn
;
241 ioctl_cmd
= strm_cmd
[i
].fxn
;
244 ioctl_cmd
= cmm_cmd
[i
].fxn
;
249 pr_err("%s: requested ioctl not defined\n", __func__
);
252 *result
= (*ioctl_cmd
) (args
, pr_ctxt
);
262 * ======== api_exit ========
268 if (api_c_refs
== 0) {
269 /* Release all modules initialized in api_init(). */
281 * ======== api_init ========
283 * Module initialization used by Bridge API.
288 bool fdev
, fchnl
, fmsg
, fio
;
289 bool fmgr
, fstrm
, frmm
;
291 if (api_c_refs
== 0) {
292 /* initialize driver and other modules */
297 fmsg
= msg_mod_init();
300 ret
= fdev
&& fchnl
&& fmsg
&& fio
;
301 ret
= ret
&& fmgr
&& frmm
;
334 * ======== api_init_complete2 ========
336 * Perform any required bridge initialization which cannot
337 * be performed in api_init() or dev_start_device() due
338 * to the fact that some services are not yet
339 * completely initialized.
342 * 0: Allow this device to load
345 * Bridge API initialized.
348 int api_init_complete2(void)
351 struct cfg_devnode
*dev_node
;
352 struct dev_object
*hdev_obj
;
353 struct drv_data
*drv_datap
;
356 /* Walk the list of DevObjects, get each devnode, and attempting to
357 * autostart the board. Note that this requires COF loading, which
359 for (hdev_obj
= dev_get_first(); hdev_obj
!= NULL
;
360 hdev_obj
= dev_get_next(hdev_obj
)) {
361 if (dev_get_dev_node(hdev_obj
, &dev_node
))
364 if (dev_get_dev_type(hdev_obj
, &dev_type
))
367 if ((dev_type
== DSP_UNIT
) || (dev_type
== IVA_UNIT
)) {
368 drv_datap
= dev_get_drvdata(bridge
);
370 if (drv_datap
&& drv_datap
->base_img
)
371 proc_auto_start(dev_node
, hdev_obj
);
378 /* TODO: Remove deprecated and not implemented ioctl wrappers */
381 * ======== mgrwrap_enum_node_info ========
383 u32
mgrwrap_enum_node_info(union trapped_args
*args
, void *pr_ctxt
)
388 u32 size
= args
->args_mgr_enumnode_info
.ndb_props_size
;
390 if (size
< sizeof(struct dsp_ndbprops
))
393 pndb_props
= kmalloc(size
, GFP_KERNEL
);
394 if (pndb_props
== NULL
)
399 mgr_enum_node_info(args
->args_mgr_enumnode_info
.node_id
,
400 (struct dsp_ndbprops
*)pndb_props
, size
,
403 CP_TO_USR(args
->args_mgr_enumnode_info
.ndb_props
, pndb_props
, status
,
405 CP_TO_USR(args
->args_mgr_enumnode_info
.num_nodes
, &num_nodes
, status
,
413 * ======== mgrwrap_enum_proc_info ========
415 u32
mgrwrap_enum_proc_info(union trapped_args
*args
, void *pr_ctxt
)
420 u32 size
= args
->args_mgr_enumproc_info
.processor_info_size
;
422 if (size
< sizeof(struct dsp_processorinfo
))
425 processor_info
= kmalloc(size
, GFP_KERNEL
);
426 if (processor_info
== NULL
)
431 mgr_enum_processor_info(args
->args_mgr_enumproc_info
.
433 (struct dsp_processorinfo
*)
434 processor_info
, size
, &num_procs
);
436 CP_TO_USR(args
->args_mgr_enumproc_info
.processor_info
, processor_info
,
438 CP_TO_USR(args
->args_mgr_enumproc_info
.num_procs
, &num_procs
,
440 kfree(processor_info
);
445 #define WRAP_MAP2CALLER(x) x
447 * ======== mgrwrap_register_object ========
449 u32
mgrwrap_register_object(union trapped_args
*args
, void *pr_ctxt
)
452 struct dsp_uuid uuid_obj
;
454 char *psz_path_name
= NULL
;
457 CP_FM_USR(&uuid_obj
, args
->args_mgr_registerobject
.uuid_obj
, status
, 1);
460 /* path_size is increased by 1 to accommodate NULL */
461 path_size
= strlen_user((char *)
462 args
->args_mgr_registerobject
.sz_path_name
) +
464 psz_path_name
= kmalloc(path_size
, GFP_KERNEL
);
465 if (!psz_path_name
) {
469 ret
= strncpy_from_user(psz_path_name
,
470 (char *)args
->args_mgr_registerobject
.
471 sz_path_name
, path_size
);
477 if (args
->args_mgr_registerobject
.obj_type
>= DSP_DCDMAXOBJTYPE
) {
482 status
= dcd_register_object(&uuid_obj
,
483 args
->args_mgr_registerobject
.obj_type
,
484 (char *)psz_path_name
);
486 kfree(psz_path_name
);
491 * ======== mgrwrap_unregister_object ========
493 u32
mgrwrap_unregister_object(union trapped_args
*args
, void *pr_ctxt
)
496 struct dsp_uuid uuid_obj
;
498 CP_FM_USR(&uuid_obj
, args
->args_mgr_registerobject
.uuid_obj
, status
, 1);
502 status
= dcd_unregister_object(&uuid_obj
,
503 args
->args_mgr_unregisterobject
.
511 * ======== mgrwrap_wait_for_bridge_events ========
513 u32
mgrwrap_wait_for_bridge_events(union trapped_args
*args
, void *pr_ctxt
)
516 struct dsp_notification
*anotifications
[MAX_EVENTS
];
517 struct dsp_notification notifications
[MAX_EVENTS
];
519 u32 count
= args
->args_mgr_wait
.count
;
521 if (count
> MAX_EVENTS
)
524 /* get the array of pointers to user structures */
525 CP_FM_USR(anotifications
, args
->args_mgr_wait
.anotifications
,
528 for (i
= 0; i
< count
; i
++) {
529 CP_FM_USR(¬ifications
[i
], anotifications
[i
], status
, 1);
530 if (status
|| !notifications
[i
].handle
) {
534 /* set the array of pointers to kernel structures */
535 anotifications
[i
] = ¬ifications
[i
];
538 status
= mgr_wait_for_bridge_events(anotifications
, count
,
543 CP_TO_USR(args
->args_mgr_wait
.index
, &index
, status
, 1);
548 * ======== MGRWRAP_GetProcessResourceInfo ========
550 u32 __deprecated
mgrwrap_get_process_resources_info(union trapped_args
* args
,
553 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
558 * ======== procwrap_attach ========
560 u32
procwrap_attach(union trapped_args
*args
, void *pr_ctxt
)
564 struct dsp_processorattrin proc_attr_in
, *attr_in
= NULL
;
566 /* Optional argument */
567 if (args
->args_proc_attach
.attr_in
) {
568 CP_FM_USR(&proc_attr_in
, args
->args_proc_attach
.attr_in
, status
,
571 attr_in
= &proc_attr_in
;
576 status
= proc_attach(args
->args_proc_attach
.processor_id
, attr_in
,
577 &processor
, pr_ctxt
);
578 CP_TO_USR(args
->args_proc_attach
.ph_processor
, &processor
, status
, 1);
584 * ======== procwrap_ctrl ========
586 u32
procwrap_ctrl(union trapped_args
*args
, void *pr_ctxt
)
588 u32 cb_data_size
, __user
* psize
= (u32 __user
*)
589 args
->args_proc_ctrl
.args
;
592 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
595 if (get_user(cb_data_size
, psize
)) {
599 cb_data_size
+= sizeof(u32
);
600 pargs
= kmalloc(cb_data_size
, GFP_KERNEL
);
606 CP_FM_USR(pargs
, args
->args_proc_ctrl
.args
, status
,
610 status
= proc_ctrl(hprocessor
,
611 args
->args_proc_ctrl
.cmd
,
612 (struct dsp_cbdata
*)pargs
);
615 /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */
622 * ======== procwrap_detach ========
624 u32 __deprecated
procwrap_detach(union trapped_args
* args
, void *pr_ctxt
)
626 /* proc_detach called at bridge_release only */
627 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
632 * ======== procwrap_enum_node_info ========
634 u32
procwrap_enum_node_info(union trapped_args
*args
, void *pr_ctxt
)
637 void *node_tab
[MAX_NODES
];
640 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
642 if (!args
->args_proc_enumnode_info
.node_tab_size
)
645 status
= proc_enum_nodes(hprocessor
,
647 args
->args_proc_enumnode_info
.node_tab_size
,
648 &num_nodes
, &alloc_cnt
);
649 CP_TO_USR(args
->args_proc_enumnode_info
.node_tab
, node_tab
, status
,
651 CP_TO_USR(args
->args_proc_enumnode_info
.num_nodes
, &num_nodes
,
653 CP_TO_USR(args
->args_proc_enumnode_info
.allocated
, &alloc_cnt
,
658 u32
procwrap_end_dma(union trapped_args
*args
, void *pr_ctxt
)
662 if (args
->args_proc_dma
.dir
>= DMA_NONE
)
665 status
= proc_end_dma(pr_ctxt
,
666 args
->args_proc_dma
.mpu_addr
,
667 args
->args_proc_dma
.size
,
668 args
->args_proc_dma
.dir
);
672 u32
procwrap_begin_dma(union trapped_args
*args
, void *pr_ctxt
)
676 if (args
->args_proc_dma
.dir
>= DMA_NONE
)
679 status
= proc_begin_dma(pr_ctxt
,
680 args
->args_proc_dma
.mpu_addr
,
681 args
->args_proc_dma
.size
,
682 args
->args_proc_dma
.dir
);
687 * ======== procwrap_flush_memory ========
689 u32
procwrap_flush_memory(union trapped_args
*args
, void *pr_ctxt
)
693 if (args
->args_proc_flushmemory
.flags
>
694 PROC_WRITEBACK_INVALIDATE_MEM
)
697 status
= proc_flush_memory(pr_ctxt
,
698 args
->args_proc_flushmemory
.mpu_addr
,
699 args
->args_proc_flushmemory
.size
,
700 args
->args_proc_flushmemory
.flags
);
705 * ======== procwrap_invalidate_memory ========
707 u32
procwrap_invalidate_memory(union trapped_args
*args
, void *pr_ctxt
)
712 proc_invalidate_memory(pr_ctxt
,
713 args
->args_proc_invalidatememory
.mpu_addr
,
714 args
->args_proc_invalidatememory
.size
);
719 * ======== procwrap_enum_resources ========
721 u32
procwrap_enum_resources(union trapped_args
*args
, void *pr_ctxt
)
724 struct dsp_resourceinfo resource_info
;
725 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
727 if (args
->args_proc_enumresources
.resource_info_size
<
728 sizeof(struct dsp_resourceinfo
))
732 proc_get_resource_info(hprocessor
,
733 args
->args_proc_enumresources
.resource_type
,
735 args
->args_proc_enumresources
.
738 CP_TO_USR(args
->args_proc_enumresources
.resource_info
, &resource_info
,
746 * ======== procwrap_get_state ========
748 u32
procwrap_get_state(union trapped_args
*args
, void *pr_ctxt
)
751 struct dsp_processorstate proc_state
;
752 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
754 if (args
->args_proc_getstate
.state_info_size
<
755 sizeof(struct dsp_processorstate
))
758 status
= proc_get_state(hprocessor
, &proc_state
,
759 args
->args_proc_getstate
.state_info_size
);
760 CP_TO_USR(args
->args_proc_getstate
.proc_state_obj
, &proc_state
, status
,
767 * ======== procwrap_get_trace ========
769 u32
procwrap_get_trace(union trapped_args
*args
, void *pr_ctxt
)
773 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
775 if (args
->args_proc_gettrace
.max_size
> MAX_TRACEBUFLEN
)
778 pbuf
= kzalloc(args
->args_proc_gettrace
.max_size
, GFP_KERNEL
);
780 status
= proc_get_trace(hprocessor
, pbuf
,
781 args
->args_proc_gettrace
.max_size
);
785 CP_TO_USR(args
->args_proc_gettrace
.buf
, pbuf
, status
,
786 args
->args_proc_gettrace
.max_size
);
793 * ======== procwrap_load ========
795 u32
procwrap_load(union trapped_args
*args
, void *pr_ctxt
)
800 s32 count
= args
->args_proc_load
.argc_index
;
801 u8
**argv
= NULL
, **envp
= NULL
;
802 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
804 if (count
<= 0 || count
> MAX_LOADARGS
) {
809 argv
= kmalloc(count
* sizeof(u8
*), GFP_KERNEL
);
815 CP_FM_USR(argv
, args
->args_proc_load
.user_args
, status
, count
);
822 for (i
= 0; i
< count
; i
++) {
824 /* User space pointer to argument */
825 temp
= (char *)argv
[i
];
826 /* len is increased by 1 to accommodate NULL */
827 len
= strlen_user((char *)temp
) + 1;
828 /* Kernel space pointer to argument */
829 argv
[i
] = kmalloc(len
, GFP_KERNEL
);
831 CP_FM_USR(argv
[i
], temp
, status
, len
);
843 /* TODO: validate this */
844 if (args
->args_proc_load
.user_envp
) {
845 /* number of elements in the envp array including NULL */
849 args
->args_proc_load
.user_envp
+ count
)) {
855 envp
= kmalloc(count
* sizeof(u8
*), GFP_KERNEL
);
861 CP_FM_USR(envp
, args
->args_proc_load
.user_envp
, status
, count
);
867 for (i
= 0; envp
[i
]; i
++) {
868 /* User space pointer to argument */
869 temp
= (char *)envp
[i
];
870 /* len is increased by 1 to accommodate NULL */
871 len
= strlen_user((char *)temp
) + 1;
872 /* Kernel space pointer to argument */
873 envp
[i
] = kmalloc(len
, GFP_KERNEL
);
875 CP_FM_USR(envp
[i
], temp
, status
, len
);
889 status
= proc_load(hprocessor
,
890 args
->args_proc_load
.argc_index
,
891 (const char **)argv
, (const char **)envp
);
903 count
= args
->args_proc_load
.argc_index
;
904 for (i
= 0; (i
< count
) && argv
[i
]; i
++)
914 * ======== procwrap_map ========
916 u32
procwrap_map(union trapped_args
*args
, void *pr_ctxt
)
920 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
922 if (!args
->args_proc_mapmem
.size
)
925 status
= proc_map(args
->args_proc_mapmem
.processor
,
926 args
->args_proc_mapmem
.mpu_addr
,
927 args
->args_proc_mapmem
.size
,
928 args
->args_proc_mapmem
.req_addr
, &map_addr
,
929 args
->args_proc_mapmem
.map_attr
, pr_ctxt
);
931 if (put_user(map_addr
, args
->args_proc_mapmem
.map_addr
)) {
933 proc_un_map(hprocessor
, map_addr
, pr_ctxt
);
941 * ======== procwrap_register_notify ========
943 u32
procwrap_register_notify(union trapped_args
*args
, void *pr_ctxt
)
946 struct dsp_notification notification
;
947 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
949 /* Initialize the notification data structure */
950 notification
.name
= NULL
;
951 notification
.handle
= NULL
;
953 status
= proc_register_notify(hprocessor
,
954 args
->args_proc_register_notify
.event_mask
,
955 args
->args_proc_register_notify
.notify_type
,
957 CP_TO_USR(args
->args_proc_register_notify
.notification
, ¬ification
,
963 * ======== procwrap_reserve_memory ========
965 u32
procwrap_reserve_memory(union trapped_args
*args
, void *pr_ctxt
)
969 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
971 if ((args
->args_proc_rsvmem
.size
<= 0) ||
972 (args
->args_proc_rsvmem
.size
& (PG_SIZE4K
- 1)) != 0)
975 status
= proc_reserve_memory(hprocessor
,
976 args
->args_proc_rsvmem
.size
, &prsv_addr
,
979 if (put_user(prsv_addr
, args
->args_proc_rsvmem
.rsv_addr
)) {
981 proc_un_reserve_memory(args
->args_proc_rsvmem
.
982 processor
, prsv_addr
, pr_ctxt
);
989 * ======== procwrap_start ========
991 u32
procwrap_start(union trapped_args
*args
, void *pr_ctxt
)
995 ret
= proc_start(((struct process_context
*)pr_ctxt
)->processor
);
1000 * ======== procwrap_un_map ========
1002 u32
procwrap_un_map(union trapped_args
*args
, void *pr_ctxt
)
1006 status
= proc_un_map(((struct process_context
*)pr_ctxt
)->processor
,
1007 args
->args_proc_unmapmem
.map_addr
, pr_ctxt
);
1012 * ======== procwrap_un_reserve_memory ========
1014 u32
procwrap_un_reserve_memory(union trapped_args
*args
, void *pr_ctxt
)
1017 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1019 status
= proc_un_reserve_memory(hprocessor
,
1020 args
->args_proc_unrsvmem
.rsv_addr
,
1026 * ======== procwrap_stop ========
1028 u32
procwrap_stop(union trapped_args
*args
, void *pr_ctxt
)
1032 ret
= proc_stop(((struct process_context
*)pr_ctxt
)->processor
);
1038 * ======== find_handle =========
1040 inline void find_node_handle(struct node_res_object
**noderes
,
1041 void *pr_ctxt
, void *hnode
)
1044 *noderes
= idr_find(((struct process_context
*)pr_ctxt
)->node_id
,
1052 * ======== nodewrap_allocate ========
1054 u32
nodewrap_allocate(union trapped_args
*args
, void *pr_ctxt
)
1057 struct dsp_uuid node_uuid
;
1058 u32 cb_data_size
= 0;
1059 u32 __user
*psize
= (u32 __user
*) args
->args_node_allocate
.args
;
1061 struct dsp_nodeattrin proc_attr_in
, *attr_in
= NULL
;
1062 struct node_res_object
*node_res
;
1064 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1066 /* Optional argument */
1068 if (get_user(cb_data_size
, psize
))
1071 cb_data_size
+= sizeof(u32
);
1073 pargs
= kmalloc(cb_data_size
, GFP_KERNEL
);
1078 CP_FM_USR(pargs
, args
->args_node_allocate
.args
, status
,
1081 CP_FM_USR(&node_uuid
, args
->args_node_allocate
.node_id_ptr
, status
, 1);
1084 /* Optional argument */
1085 if (args
->args_node_allocate
.attr_in
) {
1086 CP_FM_USR(&proc_attr_in
, args
->args_node_allocate
.attr_in
,
1089 attr_in
= &proc_attr_in
;
1095 status
= node_allocate(hprocessor
,
1096 &node_uuid
, (struct dsp_cbdata
*)pargs
,
1097 attr_in
, &node_res
, pr_ctxt
);
1100 nodeid
= node_res
->id
+ 1;
1101 CP_TO_USR(args
->args_node_allocate
.node
, &nodeid
,
1105 node_delete(node_res
, pr_ctxt
);
1115 * ======== nodewrap_alloc_msg_buf ========
1117 u32
nodewrap_alloc_msg_buf(union trapped_args
*args
, void *pr_ctxt
)
1120 struct dsp_bufferattr
*pattr
= NULL
;
1121 struct dsp_bufferattr attr
;
1123 struct node_res_object
*node_res
;
1125 find_node_handle(&node_res
, pr_ctxt
,
1126 args
->args_node_allocmsgbuf
.node
);
1131 if (!args
->args_node_allocmsgbuf
.size
)
1134 if (args
->args_node_allocmsgbuf
.attr
) { /* Optional argument */
1135 CP_FM_USR(&attr
, args
->args_node_allocmsgbuf
.attr
, status
, 1);
1141 CP_FM_USR(&pbuffer
, args
->args_node_allocmsgbuf
.buffer
, status
, 1);
1143 status
= node_alloc_msg_buf(node_res
->node
,
1144 args
->args_node_allocmsgbuf
.size
,
1147 CP_TO_USR(args
->args_node_allocmsgbuf
.buffer
, &pbuffer
, status
, 1);
1152 * ======== nodewrap_change_priority ========
1154 u32
nodewrap_change_priority(union trapped_args
*args
, void *pr_ctxt
)
1157 struct node_res_object
*node_res
;
1159 find_node_handle(&node_res
, pr_ctxt
,
1160 args
->args_node_changepriority
.node
);
1165 ret
= node_change_priority(node_res
->node
,
1166 args
->args_node_changepriority
.prio
);
1172 * ======== nodewrap_connect ========
1174 u32
nodewrap_connect(union trapped_args
*args
, void *pr_ctxt
)
1177 struct dsp_strmattr attrs
;
1178 struct dsp_strmattr
*pattrs
= NULL
;
1180 u32 __user
*psize
= (u32 __user
*) args
->args_node_connect
.conn_param
;
1182 struct node_res_object
*node_res1
, *node_res2
;
1183 struct node_object
*node1
= NULL
, *node2
= NULL
;
1185 if ((int)args
->args_node_connect
.node
!= DSP_HGPPNODE
) {
1186 find_node_handle(&node_res1
, pr_ctxt
,
1187 args
->args_node_connect
.node
);
1189 node1
= node_res1
->node
;
1191 node1
= args
->args_node_connect
.node
;
1194 if ((int)args
->args_node_connect
.other_node
!= DSP_HGPPNODE
) {
1195 find_node_handle(&node_res2
, pr_ctxt
,
1196 args
->args_node_connect
.other_node
);
1198 node2
= node_res2
->node
;
1200 node2
= args
->args_node_connect
.other_node
;
1203 if (!node1
|| !node2
)
1206 /* Optional argument */
1208 if (get_user(cb_data_size
, psize
))
1211 cb_data_size
+= sizeof(u32
);
1213 pargs
= kmalloc(cb_data_size
, GFP_KERNEL
);
1214 if (pargs
== NULL
) {
1220 CP_FM_USR(pargs
, args
->args_node_connect
.conn_param
, status
,
1225 if (args
->args_node_connect
.attrs
) { /* Optional argument */
1226 CP_FM_USR(&attrs
, args
->args_node_connect
.attrs
, status
, 1);
1232 status
= node_connect(node1
,
1233 args
->args_node_connect
.stream_id
,
1235 args
->args_node_connect
.other_stream
,
1236 pattrs
, (struct dsp_cbdata
*)pargs
);
1245 * ======== nodewrap_create ========
1247 u32
nodewrap_create(union trapped_args
*args
, void *pr_ctxt
)
1250 struct node_res_object
*node_res
;
1252 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_create
.node
);
1257 ret
= node_create(node_res
->node
);
1263 * ======== nodewrap_delete ========
1265 u32
nodewrap_delete(union trapped_args
*args
, void *pr_ctxt
)
1268 struct node_res_object
*node_res
;
1270 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_delete
.node
);
1275 ret
= node_delete(node_res
, pr_ctxt
);
1281 * ======== nodewrap_free_msg_buf ========
1283 u32
nodewrap_free_msg_buf(union trapped_args
*args
, void *pr_ctxt
)
1286 struct dsp_bufferattr
*pattr
= NULL
;
1287 struct dsp_bufferattr attr
;
1288 struct node_res_object
*node_res
;
1290 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_freemsgbuf
.node
);
1295 if (args
->args_node_freemsgbuf
.attr
) { /* Optional argument */
1296 CP_FM_USR(&attr
, args
->args_node_freemsgbuf
.attr
, status
, 1);
1302 if (!args
->args_node_freemsgbuf
.buffer
)
1306 status
= node_free_msg_buf(node_res
->node
,
1307 args
->args_node_freemsgbuf
.buffer
,
1315 * ======== nodewrap_get_attr ========
1317 u32
nodewrap_get_attr(union trapped_args
*args
, void *pr_ctxt
)
1320 struct dsp_nodeattr attr
;
1321 struct node_res_object
*node_res
;
1323 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_getattr
.node
);
1328 status
= node_get_attr(node_res
->node
, &attr
,
1329 args
->args_node_getattr
.attr_size
);
1330 CP_TO_USR(args
->args_node_getattr
.attr
, &attr
, status
, 1);
1336 * ======== nodewrap_get_message ========
1338 u32
nodewrap_get_message(union trapped_args
*args
, void *pr_ctxt
)
1342 struct node_res_object
*node_res
;
1344 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_getmessage
.node
);
1349 status
= node_get_message(node_res
->node
, &msg
,
1350 args
->args_node_getmessage
.timeout
);
1352 CP_TO_USR(args
->args_node_getmessage
.message
, &msg
, status
, 1);
1358 * ======== nodewrap_pause ========
1360 u32
nodewrap_pause(union trapped_args
*args
, void *pr_ctxt
)
1363 struct node_res_object
*node_res
;
1365 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_pause
.node
);
1370 ret
= node_pause(node_res
->node
);
1376 * ======== nodewrap_put_message ========
1378 u32
nodewrap_put_message(union trapped_args
*args
, void *pr_ctxt
)
1382 struct node_res_object
*node_res
;
1384 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_putmessage
.node
);
1389 CP_FM_USR(&msg
, args
->args_node_putmessage
.message
, status
, 1);
1393 node_put_message(node_res
->node
, &msg
,
1394 args
->args_node_putmessage
.timeout
);
1401 * ======== nodewrap_register_notify ========
1403 u32
nodewrap_register_notify(union trapped_args
*args
, void *pr_ctxt
)
1406 struct dsp_notification notification
;
1407 struct node_res_object
*node_res
;
1409 find_node_handle(&node_res
, pr_ctxt
,
1410 args
->args_node_registernotify
.node
);
1415 /* Initialize the notification data structure */
1416 notification
.name
= NULL
;
1417 notification
.handle
= NULL
;
1419 if (!args
->args_proc_register_notify
.event_mask
)
1420 CP_FM_USR(¬ification
,
1421 args
->args_proc_register_notify
.notification
,
1424 status
= node_register_notify(node_res
->node
,
1425 args
->args_node_registernotify
.event_mask
,
1426 args
->args_node_registernotify
.
1427 notify_type
, ¬ification
);
1428 CP_TO_USR(args
->args_node_registernotify
.notification
, ¬ification
,
1434 * ======== nodewrap_run ========
1436 u32
nodewrap_run(union trapped_args
*args
, void *pr_ctxt
)
1439 struct node_res_object
*node_res
;
1441 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_run
.node
);
1446 ret
= node_run(node_res
->node
);
1452 * ======== nodewrap_terminate ========
1454 u32
nodewrap_terminate(union trapped_args
*args
, void *pr_ctxt
)
1458 struct node_res_object
*node_res
;
1460 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_terminate
.node
);
1465 status
= node_terminate(node_res
->node
, &tempstatus
);
1467 CP_TO_USR(args
->args_node_terminate
.status
, &tempstatus
, status
, 1);
1473 * ======== nodewrap_get_uuid_props ========
1475 u32
nodewrap_get_uuid_props(union trapped_args
*args
, void *pr_ctxt
)
1478 struct dsp_uuid node_uuid
;
1479 struct dsp_ndbprops
*pnode_props
= NULL
;
1480 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1482 CP_FM_USR(&node_uuid
, args
->args_node_getuuidprops
.node_id_ptr
, status
,
1486 pnode_props
= kmalloc(sizeof(struct dsp_ndbprops
), GFP_KERNEL
);
1487 if (pnode_props
!= NULL
) {
1489 node_get_uuid_props(hprocessor
, &node_uuid
, pnode_props
);
1490 CP_TO_USR(args
->args_node_getuuidprops
.node_props
, pnode_props
,
1500 * ======== find_strm_handle =========
1502 inline void find_strm_handle(struct strm_res_object
**strmres
,
1503 void *pr_ctxt
, void *hstream
)
1506 *strmres
= idr_find(((struct process_context
*)pr_ctxt
)->stream_id
,
1513 * ======== strmwrap_allocate_buffer ========
1515 u32
strmwrap_allocate_buffer(union trapped_args
*args
, void *pr_ctxt
)
1518 u8
**ap_buffer
= NULL
;
1519 u32 num_bufs
= args
->args_strm_allocatebuffer
.num_bufs
;
1520 struct strm_res_object
*strm_res
;
1522 find_strm_handle(&strm_res
, pr_ctxt
,
1523 args
->args_strm_allocatebuffer
.stream
);
1528 if (num_bufs
> MAX_BUFS
)
1531 ap_buffer
= kmalloc((num_bufs
* sizeof(u8
*)), GFP_KERNEL
);
1532 if (ap_buffer
== NULL
)
1535 status
= strm_allocate_buffer(strm_res
,
1536 args
->args_strm_allocatebuffer
.size
,
1537 ap_buffer
, num_bufs
, pr_ctxt
);
1539 CP_TO_USR(args
->args_strm_allocatebuffer
.ap_buffer
, ap_buffer
,
1543 strm_free_buffer(strm_res
,
1544 ap_buffer
, num_bufs
, pr_ctxt
);
1553 * ======== strmwrap_close ========
1555 u32
strmwrap_close(union trapped_args
*args
, void *pr_ctxt
)
1557 struct strm_res_object
*strm_res
;
1559 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_close
.stream
);
1564 return strm_close(strm_res
, pr_ctxt
);
1568 * ======== strmwrap_free_buffer ========
1570 u32
strmwrap_free_buffer(union trapped_args
*args
, void *pr_ctxt
)
1573 u8
**ap_buffer
= NULL
;
1574 u32 num_bufs
= args
->args_strm_freebuffer
.num_bufs
;
1575 struct strm_res_object
*strm_res
;
1577 find_strm_handle(&strm_res
, pr_ctxt
,
1578 args
->args_strm_freebuffer
.stream
);
1583 if (num_bufs
> MAX_BUFS
)
1586 ap_buffer
= kmalloc((num_bufs
* sizeof(u8
*)), GFP_KERNEL
);
1587 if (ap_buffer
== NULL
)
1590 CP_FM_USR(ap_buffer
, args
->args_strm_freebuffer
.ap_buffer
, status
,
1594 status
= strm_free_buffer(strm_res
,
1595 ap_buffer
, num_bufs
, pr_ctxt
);
1597 CP_TO_USR(args
->args_strm_freebuffer
.ap_buffer
, ap_buffer
, status
,
1605 * ======== strmwrap_get_event_handle ========
1607 u32 __deprecated
strmwrap_get_event_handle(union trapped_args
* args
,
1610 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
1615 * ======== strmwrap_get_info ========
1617 u32
strmwrap_get_info(union trapped_args
*args
, void *pr_ctxt
)
1620 struct stream_info strm_info
;
1621 struct dsp_streaminfo user
;
1622 struct dsp_streaminfo
*temp
;
1623 struct strm_res_object
*strm_res
;
1625 find_strm_handle(&strm_res
, pr_ctxt
,
1626 args
->args_strm_getinfo
.stream
);
1631 CP_FM_USR(&strm_info
, args
->args_strm_getinfo
.stream_info
, status
, 1);
1632 temp
= strm_info
.user_strm
;
1634 strm_info
.user_strm
= &user
;
1637 status
= strm_get_info(strm_res
->stream
,
1639 args
->args_strm_getinfo
.
1642 CP_TO_USR(temp
, strm_info
.user_strm
, status
, 1);
1643 strm_info
.user_strm
= temp
;
1644 CP_TO_USR(args
->args_strm_getinfo
.stream_info
, &strm_info
, status
, 1);
1649 * ======== strmwrap_idle ========
1651 u32
strmwrap_idle(union trapped_args
*args
, void *pr_ctxt
)
1654 struct strm_res_object
*strm_res
;
1656 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_idle
.stream
);
1661 ret
= strm_idle(strm_res
->stream
, args
->args_strm_idle
.flush_flag
);
1667 * ======== strmwrap_issue ========
1669 u32
strmwrap_issue(union trapped_args
*args
, void *pr_ctxt
)
1672 struct strm_res_object
*strm_res
;
1674 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_issue
.stream
);
1679 if (!args
->args_strm_issue
.buffer
)
1682 /* No need of doing CP_FM_USR for the user buffer (pbuffer)
1683 as this is done in Bridge internal function bridge_chnl_add_io_req
1685 status
= strm_issue(strm_res
->stream
,
1686 args
->args_strm_issue
.buffer
,
1687 args
->args_strm_issue
.bytes
,
1688 args
->args_strm_issue
.buf_size
,
1689 args
->args_strm_issue
.arg
);
1695 * ======== strmwrap_open ========
1697 u32
strmwrap_open(union trapped_args
*args
, void *pr_ctxt
)
1700 struct strm_attr attr
;
1701 struct strm_res_object
*strm_res_obj
;
1702 struct dsp_streamattrin strm_attr_in
;
1703 struct node_res_object
*node_res
;
1706 find_node_handle(&node_res
, pr_ctxt
, args
->args_strm_open
.node
);
1711 CP_FM_USR(&attr
, args
->args_strm_open
.attr_in
, status
, 1);
1713 if (attr
.stream_attr_in
!= NULL
) { /* Optional argument */
1714 CP_FM_USR(&strm_attr_in
, attr
.stream_attr_in
, status
, 1);
1716 attr
.stream_attr_in
= &strm_attr_in
;
1717 if (attr
.stream_attr_in
->strm_mode
== STRMMODE_LDMA
)
1722 status
= strm_open(node_res
->node
,
1723 args
->args_strm_open
.direction
,
1724 args
->args_strm_open
.index
, &attr
, &strm_res_obj
,
1727 strmid
= strm_res_obj
->id
+ 1;
1728 CP_TO_USR(args
->args_strm_open
.stream
, &strmid
, status
, 1);
1734 * ======== strmwrap_reclaim ========
1736 u32
strmwrap_reclaim(union trapped_args
*args
, void *pr_ctxt
)
1743 struct strm_res_object
*strm_res
;
1745 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_reclaim
.stream
);
1750 status
= strm_reclaim(strm_res
->stream
, &buf_ptr
,
1751 &ul_bytes
, &ul_buf_size
, &dw_arg
);
1752 CP_TO_USR(args
->args_strm_reclaim
.buf_ptr
, &buf_ptr
, status
, 1);
1753 CP_TO_USR(args
->args_strm_reclaim
.bytes
, &ul_bytes
, status
, 1);
1754 CP_TO_USR(args
->args_strm_reclaim
.arg
, &dw_arg
, status
, 1);
1756 if (args
->args_strm_reclaim
.buf_size_ptr
!= NULL
) {
1757 CP_TO_USR(args
->args_strm_reclaim
.buf_size_ptr
, &ul_buf_size
,
1765 * ======== strmwrap_register_notify ========
1767 u32
strmwrap_register_notify(union trapped_args
*args
, void *pr_ctxt
)
1770 struct dsp_notification notification
;
1771 struct strm_res_object
*strm_res
;
1773 find_strm_handle(&strm_res
, pr_ctxt
,
1774 args
->args_strm_registernotify
.stream
);
1779 /* Initialize the notification data structure */
1780 notification
.name
= NULL
;
1781 notification
.handle
= NULL
;
1783 status
= strm_register_notify(strm_res
->stream
,
1784 args
->args_strm_registernotify
.event_mask
,
1785 args
->args_strm_registernotify
.
1786 notify_type
, ¬ification
);
1787 CP_TO_USR(args
->args_strm_registernotify
.notification
, ¬ification
,
1794 * ======== strmwrap_select ========
1796 u32
strmwrap_select(union trapped_args
*args
, void *pr_ctxt
)
1799 struct strm_object
*strm_tab
[MAX_STREAMS
];
1801 struct strm_res_object
*strm_res
;
1802 int *ids
[MAX_STREAMS
];
1805 if (args
->args_strm_select
.strm_num
> MAX_STREAMS
)
1808 CP_FM_USR(ids
, args
->args_strm_select
.stream_tab
, status
,
1809 args
->args_strm_select
.strm_num
);
1814 for (i
= 0; i
< args
->args_strm_select
.strm_num
; i
++) {
1815 find_strm_handle(&strm_res
, pr_ctxt
, ids
[i
]);
1820 strm_tab
[i
] = strm_res
->stream
;
1824 status
= strm_select(strm_tab
, args
->args_strm_select
.strm_num
,
1825 &mask
, args
->args_strm_select
.timeout
);
1827 CP_TO_USR(args
->args_strm_select
.mask
, &mask
, status
, 1);
1834 * ======== cmmwrap_calloc_buf ========
1836 u32 __deprecated
cmmwrap_calloc_buf(union trapped_args
* args
, void *pr_ctxt
)
1838 /* This operation is done in kernel */
1839 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
1844 * ======== cmmwrap_free_buf ========
1846 u32 __deprecated
cmmwrap_free_buf(union trapped_args
* args
, void *pr_ctxt
)
1848 /* This operation is done in kernel */
1849 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
1854 * ======== cmmwrap_get_handle ========
1856 u32
cmmwrap_get_handle(union trapped_args
*args
, void *pr_ctxt
)
1859 struct cmm_object
*hcmm_mgr
;
1860 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1862 status
= cmm_get_handle(hprocessor
, &hcmm_mgr
);
1864 CP_TO_USR(args
->args_cmm_gethandle
.cmm_mgr
, &hcmm_mgr
, status
, 1);
1870 * ======== cmmwrap_get_info ========
1872 u32
cmmwrap_get_info(union trapped_args
*args
, void *pr_ctxt
)
1875 struct cmm_info cmm_info_obj
;
1877 status
= cmm_get_info(args
->args_cmm_getinfo
.cmm_mgr
, &cmm_info_obj
);
1879 CP_TO_USR(args
->args_cmm_getinfo
.cmm_info_obj
, &cmm_info_obj
, status
,