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
.ndb_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
.ndb_props
, pndb_props
, status
,
436 CP_TO_USR(args
->args_mgr_enumnode_info
.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
.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
.sz_path_name
) +
495 psz_path_name
= kmalloc(path_size
, GFP_KERNEL
);
496 if (!psz_path_name
) {
500 ret
= strncpy_from_user(psz_path_name
,
501 (char *)args
->args_mgr_registerobject
.
502 sz_path_name
, path_size
);
508 if (args
->args_mgr_registerobject
.obj_type
>= DSP_DCDMAXOBJTYPE
) {
513 status
= dcd_register_object(&uuid_obj
,
514 args
->args_mgr_registerobject
.obj_type
,
515 (char *)psz_path_name
);
517 kfree(psz_path_name
);
522 * ======== mgrwrap_unregister_object ========
524 u32
mgrwrap_unregister_object(union trapped_args
*args
, void *pr_ctxt
)
527 struct dsp_uuid uuid_obj
;
529 CP_FM_USR(&uuid_obj
, args
->args_mgr_registerobject
.uuid_obj
, status
, 1);
533 status
= dcd_unregister_object(&uuid_obj
,
534 args
->args_mgr_unregisterobject
.
542 * ======== mgrwrap_wait_for_bridge_events ========
544 u32
mgrwrap_wait_for_bridge_events(union trapped_args
*args
, void *pr_ctxt
)
547 struct dsp_notification
*anotifications
[MAX_EVENTS
];
548 struct dsp_notification notifications
[MAX_EVENTS
];
550 u32 count
= args
->args_mgr_wait
.count
;
552 if (count
> MAX_EVENTS
)
555 /* get the array of pointers to user structures */
556 CP_FM_USR(anotifications
, args
->args_mgr_wait
.anotifications
,
559 for (i
= 0; i
< count
; i
++) {
560 CP_FM_USR(¬ifications
[i
], anotifications
[i
], status
, 1);
561 if (status
|| !notifications
[i
].handle
) {
565 /* set the array of pointers to kernel structures */
566 anotifications
[i
] = ¬ifications
[i
];
569 status
= mgr_wait_for_bridge_events(anotifications
, count
,
574 CP_TO_USR(args
->args_mgr_wait
.index
, &index
, status
, 1);
579 * ======== MGRWRAP_GetProcessResourceInfo ========
581 u32 __deprecated
mgrwrap_get_process_resources_info(union trapped_args
* args
,
584 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
589 * ======== procwrap_attach ========
591 u32
procwrap_attach(union trapped_args
*args
, void *pr_ctxt
)
595 struct dsp_processorattrin proc_attr_in
, *attr_in
= NULL
;
597 /* Optional argument */
598 if (args
->args_proc_attach
.attr_in
) {
599 CP_FM_USR(&proc_attr_in
, args
->args_proc_attach
.attr_in
, status
,
602 attr_in
= &proc_attr_in
;
607 status
= proc_attach(args
->args_proc_attach
.processor_id
, attr_in
,
608 &processor
, pr_ctxt
);
609 CP_TO_USR(args
->args_proc_attach
.ph_processor
, &processor
, status
, 1);
615 * ======== procwrap_ctrl ========
617 u32
procwrap_ctrl(union trapped_args
*args
, void *pr_ctxt
)
619 u32 cb_data_size
, __user
* psize
= (u32 __user
*)
620 args
->args_proc_ctrl
.args
;
623 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
626 if (get_user(cb_data_size
, psize
)) {
630 cb_data_size
+= sizeof(u32
);
631 pargs
= kmalloc(cb_data_size
, GFP_KERNEL
);
637 CP_FM_USR(pargs
, args
->args_proc_ctrl
.args
, status
,
641 status
= proc_ctrl(hprocessor
,
642 args
->args_proc_ctrl
.cmd
,
643 (struct dsp_cbdata
*)pargs
);
646 /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */
653 * ======== procwrap_detach ========
655 u32 __deprecated
procwrap_detach(union trapped_args
* args
, void *pr_ctxt
)
657 /* proc_detach called at bridge_release only */
658 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
663 * ======== procwrap_enum_node_info ========
665 u32
procwrap_enum_node_info(union trapped_args
*args
, void *pr_ctxt
)
668 void *node_tab
[MAX_NODES
];
671 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
673 if (!args
->args_proc_enumnode_info
.node_tab_size
)
676 status
= proc_enum_nodes(hprocessor
,
678 args
->args_proc_enumnode_info
.node_tab_size
,
679 &num_nodes
, &alloc_cnt
);
680 CP_TO_USR(args
->args_proc_enumnode_info
.node_tab
, node_tab
, status
,
682 CP_TO_USR(args
->args_proc_enumnode_info
.num_nodes
, &num_nodes
,
684 CP_TO_USR(args
->args_proc_enumnode_info
.allocated
, &alloc_cnt
,
689 u32
procwrap_end_dma(union trapped_args
*args
, void *pr_ctxt
)
693 if (args
->args_proc_dma
.dir
>= DMA_NONE
)
696 status
= proc_end_dma(pr_ctxt
,
697 args
->args_proc_dma
.mpu_addr
,
698 args
->args_proc_dma
.size
,
699 args
->args_proc_dma
.dir
);
703 u32
procwrap_begin_dma(union trapped_args
*args
, void *pr_ctxt
)
707 if (args
->args_proc_dma
.dir
>= DMA_NONE
)
710 status
= proc_begin_dma(pr_ctxt
,
711 args
->args_proc_dma
.mpu_addr
,
712 args
->args_proc_dma
.size
,
713 args
->args_proc_dma
.dir
);
718 * ======== procwrap_flush_memory ========
720 u32
procwrap_flush_memory(union trapped_args
*args
, void *pr_ctxt
)
724 if (args
->args_proc_flushmemory
.flags
>
725 PROC_WRITEBACK_INVALIDATE_MEM
)
728 status
= proc_flush_memory(pr_ctxt
,
729 args
->args_proc_flushmemory
.mpu_addr
,
730 args
->args_proc_flushmemory
.size
,
731 args
->args_proc_flushmemory
.flags
);
736 * ======== procwrap_invalidate_memory ========
738 u32
procwrap_invalidate_memory(union trapped_args
*args
, void *pr_ctxt
)
743 proc_invalidate_memory(pr_ctxt
,
744 args
->args_proc_invalidatememory
.mpu_addr
,
745 args
->args_proc_invalidatememory
.size
);
750 * ======== procwrap_enum_resources ========
752 u32
procwrap_enum_resources(union trapped_args
*args
, void *pr_ctxt
)
755 struct dsp_resourceinfo resource_info
;
756 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
758 if (args
->args_proc_enumresources
.resource_info_size
<
759 sizeof(struct dsp_resourceinfo
))
763 proc_get_resource_info(hprocessor
,
764 args
->args_proc_enumresources
.resource_type
,
766 args
->args_proc_enumresources
.
769 CP_TO_USR(args
->args_proc_enumresources
.resource_info
, &resource_info
,
777 * ======== procwrap_get_state ========
779 u32
procwrap_get_state(union trapped_args
*args
, void *pr_ctxt
)
782 struct dsp_processorstate proc_state
;
783 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
785 if (args
->args_proc_getstate
.state_info_size
<
786 sizeof(struct dsp_processorstate
))
789 status
= proc_get_state(hprocessor
, &proc_state
,
790 args
->args_proc_getstate
.state_info_size
);
791 CP_TO_USR(args
->args_proc_getstate
.proc_state_obj
, &proc_state
, status
,
798 * ======== procwrap_get_trace ========
800 u32
procwrap_get_trace(union trapped_args
*args
, void *pr_ctxt
)
804 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
806 if (args
->args_proc_gettrace
.max_size
> MAX_TRACEBUFLEN
)
809 pbuf
= kzalloc(args
->args_proc_gettrace
.max_size
, GFP_KERNEL
);
811 status
= proc_get_trace(hprocessor
, pbuf
,
812 args
->args_proc_gettrace
.max_size
);
816 CP_TO_USR(args
->args_proc_gettrace
.buf
, pbuf
, status
,
817 args
->args_proc_gettrace
.max_size
);
824 * ======== procwrap_load ========
826 u32
procwrap_load(union trapped_args
*args
, void *pr_ctxt
)
831 s32 count
= args
->args_proc_load
.argc_index
;
832 u8
**argv
= NULL
, **envp
= NULL
;
833 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
835 if (count
<= 0 || count
> MAX_LOADARGS
) {
840 argv
= kmalloc(count
* sizeof(u8
*), GFP_KERNEL
);
846 CP_FM_USR(argv
, args
->args_proc_load
.user_args
, status
, count
);
853 for (i
= 0; i
< count
; i
++) {
855 /* User space pointer to argument */
856 temp
= (char *)argv
[i
];
857 /* len is increased by 1 to accommodate NULL */
858 len
= strlen_user((char *)temp
) + 1;
859 /* Kernel space pointer to argument */
860 argv
[i
] = kmalloc(len
, GFP_KERNEL
);
862 CP_FM_USR(argv
[i
], temp
, status
, len
);
874 /* TODO: validate this */
875 if (args
->args_proc_load
.user_envp
) {
876 /* number of elements in the envp array including NULL */
880 args
->args_proc_load
.user_envp
+ count
)) {
886 envp
= kmalloc(count
* sizeof(u8
*), GFP_KERNEL
);
892 CP_FM_USR(envp
, args
->args_proc_load
.user_envp
, status
, count
);
898 for (i
= 0; envp
[i
]; i
++) {
899 /* User space pointer to argument */
900 temp
= (char *)envp
[i
];
901 /* len is increased by 1 to accommodate NULL */
902 len
= strlen_user((char *)temp
) + 1;
903 /* Kernel space pointer to argument */
904 envp
[i
] = kmalloc(len
, GFP_KERNEL
);
906 CP_FM_USR(envp
[i
], temp
, status
, len
);
920 status
= proc_load(hprocessor
,
921 args
->args_proc_load
.argc_index
,
922 (const char **)argv
, (const char **)envp
);
934 count
= args
->args_proc_load
.argc_index
;
935 for (i
= 0; (i
< count
) && argv
[i
]; i
++)
945 * ======== procwrap_map ========
947 u32
procwrap_map(union trapped_args
*args
, void *pr_ctxt
)
951 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
953 if (!args
->args_proc_mapmem
.size
)
956 status
= proc_map(args
->args_proc_mapmem
.processor
,
957 args
->args_proc_mapmem
.mpu_addr
,
958 args
->args_proc_mapmem
.size
,
959 args
->args_proc_mapmem
.req_addr
, &map_addr
,
960 args
->args_proc_mapmem
.map_attr
, pr_ctxt
);
962 if (put_user(map_addr
, args
->args_proc_mapmem
.map_addr
)) {
964 proc_un_map(hprocessor
, map_addr
, pr_ctxt
);
972 * ======== procwrap_register_notify ========
974 u32
procwrap_register_notify(union trapped_args
*args
, void *pr_ctxt
)
977 struct dsp_notification notification
;
978 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
980 /* Initialize the notification data structure */
981 notification
.name
= NULL
;
982 notification
.handle
= NULL
;
984 status
= proc_register_notify(hprocessor
,
985 args
->args_proc_register_notify
.event_mask
,
986 args
->args_proc_register_notify
.notify_type
,
988 CP_TO_USR(args
->args_proc_register_notify
.notification
, ¬ification
,
994 * ======== procwrap_reserve_memory ========
996 u32
procwrap_reserve_memory(union trapped_args
*args
, void *pr_ctxt
)
1000 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1002 if ((args
->args_proc_rsvmem
.size
<= 0) ||
1003 (args
->args_proc_rsvmem
.size
& (PG_SIZE4K
- 1)) != 0)
1006 status
= proc_reserve_memory(hprocessor
,
1007 args
->args_proc_rsvmem
.size
, &prsv_addr
,
1010 if (put_user(prsv_addr
, args
->args_proc_rsvmem
.rsv_addr
)) {
1012 proc_un_reserve_memory(args
->args_proc_rsvmem
.
1013 processor
, prsv_addr
, pr_ctxt
);
1020 * ======== procwrap_start ========
1022 u32
procwrap_start(union trapped_args
*args
, void *pr_ctxt
)
1026 ret
= proc_start(((struct process_context
*)pr_ctxt
)->processor
);
1031 * ======== procwrap_un_map ========
1033 u32
procwrap_un_map(union trapped_args
*args
, void *pr_ctxt
)
1037 status
= proc_un_map(((struct process_context
*)pr_ctxt
)->processor
,
1038 args
->args_proc_unmapmem
.map_addr
, pr_ctxt
);
1043 * ======== procwrap_un_reserve_memory ========
1045 u32
procwrap_un_reserve_memory(union trapped_args
*args
, void *pr_ctxt
)
1048 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1050 status
= proc_un_reserve_memory(hprocessor
,
1051 args
->args_proc_unrsvmem
.rsv_addr
,
1057 * ======== procwrap_stop ========
1059 u32
procwrap_stop(union trapped_args
*args
, void *pr_ctxt
)
1063 ret
= proc_stop(((struct process_context
*)pr_ctxt
)->processor
);
1069 * ======== find_handle =========
1071 inline void find_node_handle(struct node_res_object
**noderes
,
1072 void *pr_ctxt
, void *hnode
)
1075 *noderes
= idr_find(((struct process_context
*)pr_ctxt
)->node_id
,
1083 * ======== nodewrap_allocate ========
1085 u32
nodewrap_allocate(union trapped_args
*args
, void *pr_ctxt
)
1088 struct dsp_uuid node_uuid
;
1089 u32 cb_data_size
= 0;
1090 u32 __user
*psize
= (u32 __user
*) args
->args_node_allocate
.args
;
1092 struct dsp_nodeattrin proc_attr_in
, *attr_in
= NULL
;
1093 struct node_res_object
*node_res
;
1095 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1097 /* Optional argument */
1099 if (get_user(cb_data_size
, psize
))
1102 cb_data_size
+= sizeof(u32
);
1104 pargs
= kmalloc(cb_data_size
, GFP_KERNEL
);
1109 CP_FM_USR(pargs
, args
->args_node_allocate
.args
, status
,
1112 CP_FM_USR(&node_uuid
, args
->args_node_allocate
.node_id_ptr
, status
, 1);
1115 /* Optional argument */
1116 if (args
->args_node_allocate
.attr_in
) {
1117 CP_FM_USR(&proc_attr_in
, args
->args_node_allocate
.attr_in
,
1120 attr_in
= &proc_attr_in
;
1126 status
= node_allocate(hprocessor
,
1127 &node_uuid
, (struct dsp_cbdata
*)pargs
,
1128 attr_in
, &node_res
, pr_ctxt
);
1131 nodeid
= node_res
->id
+ 1;
1132 CP_TO_USR(args
->args_node_allocate
.node
, &nodeid
,
1136 node_delete(node_res
, pr_ctxt
);
1146 * ======== nodewrap_alloc_msg_buf ========
1148 u32
nodewrap_alloc_msg_buf(union trapped_args
*args
, void *pr_ctxt
)
1151 struct dsp_bufferattr
*pattr
= NULL
;
1152 struct dsp_bufferattr attr
;
1154 struct node_res_object
*node_res
;
1156 find_node_handle(&node_res
, pr_ctxt
,
1157 args
->args_node_allocmsgbuf
.node
);
1162 if (!args
->args_node_allocmsgbuf
.size
)
1165 if (args
->args_node_allocmsgbuf
.attr
) { /* Optional argument */
1166 CP_FM_USR(&attr
, args
->args_node_allocmsgbuf
.attr
, status
, 1);
1172 CP_FM_USR(&pbuffer
, args
->args_node_allocmsgbuf
.buffer
, status
, 1);
1174 status
= node_alloc_msg_buf(node_res
->node
,
1175 args
->args_node_allocmsgbuf
.size
,
1178 CP_TO_USR(args
->args_node_allocmsgbuf
.buffer
, &pbuffer
, status
, 1);
1183 * ======== nodewrap_change_priority ========
1185 u32
nodewrap_change_priority(union trapped_args
*args
, void *pr_ctxt
)
1188 struct node_res_object
*node_res
;
1190 find_node_handle(&node_res
, pr_ctxt
,
1191 args
->args_node_changepriority
.node
);
1196 ret
= node_change_priority(node_res
->node
,
1197 args
->args_node_changepriority
.prio
);
1203 * ======== nodewrap_connect ========
1205 u32
nodewrap_connect(union trapped_args
*args
, void *pr_ctxt
)
1208 struct dsp_strmattr attrs
;
1209 struct dsp_strmattr
*pattrs
= NULL
;
1211 u32 __user
*psize
= (u32 __user
*) args
->args_node_connect
.conn_param
;
1213 struct node_res_object
*node_res1
, *node_res2
;
1214 struct node_object
*node1
= NULL
, *node2
= NULL
;
1216 if ((int)args
->args_node_connect
.node
!= DSP_HGPPNODE
) {
1217 find_node_handle(&node_res1
, pr_ctxt
,
1218 args
->args_node_connect
.node
);
1220 node1
= node_res1
->node
;
1222 node1
= args
->args_node_connect
.node
;
1225 if ((int)args
->args_node_connect
.other_node
!= DSP_HGPPNODE
) {
1226 find_node_handle(&node_res2
, pr_ctxt
,
1227 args
->args_node_connect
.other_node
);
1229 node2
= node_res2
->node
;
1231 node2
= args
->args_node_connect
.other_node
;
1234 if (!node1
|| !node2
)
1237 /* Optional argument */
1239 if (get_user(cb_data_size
, psize
))
1242 cb_data_size
+= sizeof(u32
);
1244 pargs
= kmalloc(cb_data_size
, GFP_KERNEL
);
1245 if (pargs
== NULL
) {
1251 CP_FM_USR(pargs
, args
->args_node_connect
.conn_param
, status
,
1256 if (args
->args_node_connect
.attrs
) { /* Optional argument */
1257 CP_FM_USR(&attrs
, args
->args_node_connect
.attrs
, status
, 1);
1263 status
= node_connect(node1
,
1264 args
->args_node_connect
.stream_id
,
1266 args
->args_node_connect
.other_stream
,
1267 pattrs
, (struct dsp_cbdata
*)pargs
);
1276 * ======== nodewrap_create ========
1278 u32
nodewrap_create(union trapped_args
*args
, void *pr_ctxt
)
1281 struct node_res_object
*node_res
;
1283 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_create
.node
);
1288 ret
= node_create(node_res
->node
);
1294 * ======== nodewrap_delete ========
1296 u32
nodewrap_delete(union trapped_args
*args
, void *pr_ctxt
)
1299 struct node_res_object
*node_res
;
1301 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_delete
.node
);
1306 ret
= node_delete(node_res
, pr_ctxt
);
1312 * ======== nodewrap_free_msg_buf ========
1314 u32
nodewrap_free_msg_buf(union trapped_args
*args
, void *pr_ctxt
)
1317 struct dsp_bufferattr
*pattr
= NULL
;
1318 struct dsp_bufferattr attr
;
1319 struct node_res_object
*node_res
;
1321 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_freemsgbuf
.node
);
1326 if (args
->args_node_freemsgbuf
.attr
) { /* Optional argument */
1327 CP_FM_USR(&attr
, args
->args_node_freemsgbuf
.attr
, status
, 1);
1333 if (!args
->args_node_freemsgbuf
.buffer
)
1337 status
= node_free_msg_buf(node_res
->node
,
1338 args
->args_node_freemsgbuf
.buffer
,
1346 * ======== nodewrap_get_attr ========
1348 u32
nodewrap_get_attr(union trapped_args
*args
, void *pr_ctxt
)
1351 struct dsp_nodeattr attr
;
1352 struct node_res_object
*node_res
;
1354 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_getattr
.node
);
1359 status
= node_get_attr(node_res
->node
, &attr
,
1360 args
->args_node_getattr
.attr_size
);
1361 CP_TO_USR(args
->args_node_getattr
.attr
, &attr
, status
, 1);
1367 * ======== nodewrap_get_message ========
1369 u32
nodewrap_get_message(union trapped_args
*args
, void *pr_ctxt
)
1373 struct node_res_object
*node_res
;
1375 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_getmessage
.node
);
1380 status
= node_get_message(node_res
->node
, &msg
,
1381 args
->args_node_getmessage
.timeout
);
1383 CP_TO_USR(args
->args_node_getmessage
.message
, &msg
, status
, 1);
1389 * ======== nodewrap_pause ========
1391 u32
nodewrap_pause(union trapped_args
*args
, void *pr_ctxt
)
1394 struct node_res_object
*node_res
;
1396 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_pause
.node
);
1401 ret
= node_pause(node_res
->node
);
1407 * ======== nodewrap_put_message ========
1409 u32
nodewrap_put_message(union trapped_args
*args
, void *pr_ctxt
)
1413 struct node_res_object
*node_res
;
1415 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_putmessage
.node
);
1420 CP_FM_USR(&msg
, args
->args_node_putmessage
.message
, status
, 1);
1424 node_put_message(node_res
->node
, &msg
,
1425 args
->args_node_putmessage
.timeout
);
1432 * ======== nodewrap_register_notify ========
1434 u32
nodewrap_register_notify(union trapped_args
*args
, void *pr_ctxt
)
1437 struct dsp_notification notification
;
1438 struct node_res_object
*node_res
;
1440 find_node_handle(&node_res
, pr_ctxt
,
1441 args
->args_node_registernotify
.node
);
1446 /* Initialize the notification data structure */
1447 notification
.name
= NULL
;
1448 notification
.handle
= NULL
;
1450 if (!args
->args_proc_register_notify
.event_mask
)
1451 CP_FM_USR(¬ification
,
1452 args
->args_proc_register_notify
.notification
,
1455 status
= node_register_notify(node_res
->node
,
1456 args
->args_node_registernotify
.event_mask
,
1457 args
->args_node_registernotify
.
1458 notify_type
, ¬ification
);
1459 CP_TO_USR(args
->args_node_registernotify
.notification
, ¬ification
,
1465 * ======== nodewrap_run ========
1467 u32
nodewrap_run(union trapped_args
*args
, void *pr_ctxt
)
1470 struct node_res_object
*node_res
;
1472 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_run
.node
);
1477 ret
= node_run(node_res
->node
);
1483 * ======== nodewrap_terminate ========
1485 u32
nodewrap_terminate(union trapped_args
*args
, void *pr_ctxt
)
1489 struct node_res_object
*node_res
;
1491 find_node_handle(&node_res
, pr_ctxt
, args
->args_node_terminate
.node
);
1496 status
= node_terminate(node_res
->node
, &tempstatus
);
1498 CP_TO_USR(args
->args_node_terminate
.status
, &tempstatus
, status
, 1);
1504 * ======== nodewrap_get_uuid_props ========
1506 u32
nodewrap_get_uuid_props(union trapped_args
*args
, void *pr_ctxt
)
1509 struct dsp_uuid node_uuid
;
1510 struct dsp_ndbprops
*pnode_props
= NULL
;
1511 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1513 CP_FM_USR(&node_uuid
, args
->args_node_getuuidprops
.node_id_ptr
, status
,
1517 pnode_props
= kmalloc(sizeof(struct dsp_ndbprops
), GFP_KERNEL
);
1518 if (pnode_props
!= NULL
) {
1520 node_get_uuid_props(hprocessor
, &node_uuid
, pnode_props
);
1521 CP_TO_USR(args
->args_node_getuuidprops
.node_props
, pnode_props
,
1531 * ======== find_strm_handle =========
1533 inline void find_strm_handle(struct strm_res_object
**strmres
,
1534 void *pr_ctxt
, void *hstream
)
1537 *strmres
= idr_find(((struct process_context
*)pr_ctxt
)->stream_id
,
1544 * ======== strmwrap_allocate_buffer ========
1546 u32
strmwrap_allocate_buffer(union trapped_args
*args
, void *pr_ctxt
)
1549 u8
**ap_buffer
= NULL
;
1550 u32 num_bufs
= args
->args_strm_allocatebuffer
.num_bufs
;
1551 struct strm_res_object
*strm_res
;
1553 find_strm_handle(&strm_res
, pr_ctxt
,
1554 args
->args_strm_allocatebuffer
.stream
);
1559 if (num_bufs
> MAX_BUFS
)
1562 ap_buffer
= kmalloc((num_bufs
* sizeof(u8
*)), GFP_KERNEL
);
1563 if (ap_buffer
== NULL
)
1566 status
= strm_allocate_buffer(strm_res
,
1567 args
->args_strm_allocatebuffer
.size
,
1568 ap_buffer
, num_bufs
, pr_ctxt
);
1570 CP_TO_USR(args
->args_strm_allocatebuffer
.ap_buffer
, ap_buffer
,
1574 strm_free_buffer(strm_res
,
1575 ap_buffer
, num_bufs
, pr_ctxt
);
1584 * ======== strmwrap_close ========
1586 u32
strmwrap_close(union trapped_args
*args
, void *pr_ctxt
)
1588 struct strm_res_object
*strm_res
;
1590 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_close
.stream
);
1595 return strm_close(strm_res
, pr_ctxt
);
1599 * ======== strmwrap_free_buffer ========
1601 u32
strmwrap_free_buffer(union trapped_args
*args
, void *pr_ctxt
)
1604 u8
**ap_buffer
= NULL
;
1605 u32 num_bufs
= args
->args_strm_freebuffer
.num_bufs
;
1606 struct strm_res_object
*strm_res
;
1608 find_strm_handle(&strm_res
, pr_ctxt
,
1609 args
->args_strm_freebuffer
.stream
);
1614 if (num_bufs
> MAX_BUFS
)
1617 ap_buffer
= kmalloc((num_bufs
* sizeof(u8
*)), GFP_KERNEL
);
1618 if (ap_buffer
== NULL
)
1621 CP_FM_USR(ap_buffer
, args
->args_strm_freebuffer
.ap_buffer
, status
,
1625 status
= strm_free_buffer(strm_res
,
1626 ap_buffer
, num_bufs
, pr_ctxt
);
1628 CP_TO_USR(args
->args_strm_freebuffer
.ap_buffer
, ap_buffer
, status
,
1636 * ======== strmwrap_get_event_handle ========
1638 u32 __deprecated
strmwrap_get_event_handle(union trapped_args
* args
,
1641 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
1646 * ======== strmwrap_get_info ========
1648 u32
strmwrap_get_info(union trapped_args
*args
, void *pr_ctxt
)
1651 struct stream_info strm_info
;
1652 struct dsp_streaminfo user
;
1653 struct dsp_streaminfo
*temp
;
1654 struct strm_res_object
*strm_res
;
1656 find_strm_handle(&strm_res
, pr_ctxt
,
1657 args
->args_strm_getinfo
.stream
);
1662 CP_FM_USR(&strm_info
, args
->args_strm_getinfo
.stream_info
, status
, 1);
1663 temp
= strm_info
.user_strm
;
1665 strm_info
.user_strm
= &user
;
1668 status
= strm_get_info(strm_res
->stream
,
1670 args
->args_strm_getinfo
.
1673 CP_TO_USR(temp
, strm_info
.user_strm
, status
, 1);
1674 strm_info
.user_strm
= temp
;
1675 CP_TO_USR(args
->args_strm_getinfo
.stream_info
, &strm_info
, status
, 1);
1680 * ======== strmwrap_idle ========
1682 u32
strmwrap_idle(union trapped_args
*args
, void *pr_ctxt
)
1685 struct strm_res_object
*strm_res
;
1687 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_idle
.stream
);
1692 ret
= strm_idle(strm_res
->stream
, args
->args_strm_idle
.flush_flag
);
1698 * ======== strmwrap_issue ========
1700 u32
strmwrap_issue(union trapped_args
*args
, void *pr_ctxt
)
1703 struct strm_res_object
*strm_res
;
1705 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_issue
.stream
);
1710 if (!args
->args_strm_issue
.buffer
)
1713 /* No need of doing CP_FM_USR for the user buffer (pbuffer)
1714 as this is done in Bridge internal function bridge_chnl_add_io_req
1716 status
= strm_issue(strm_res
->stream
,
1717 args
->args_strm_issue
.buffer
,
1718 args
->args_strm_issue
.bytes
,
1719 args
->args_strm_issue
.buf_size
,
1720 args
->args_strm_issue
.arg
);
1726 * ======== strmwrap_open ========
1728 u32
strmwrap_open(union trapped_args
*args
, void *pr_ctxt
)
1731 struct strm_attr attr
;
1732 struct strm_res_object
*strm_res_obj
;
1733 struct dsp_streamattrin strm_attr_in
;
1734 struct node_res_object
*node_res
;
1737 find_node_handle(&node_res
, pr_ctxt
, args
->args_strm_open
.node
);
1742 CP_FM_USR(&attr
, args
->args_strm_open
.attr_in
, status
, 1);
1744 if (attr
.stream_attr_in
!= NULL
) { /* Optional argument */
1745 CP_FM_USR(&strm_attr_in
, attr
.stream_attr_in
, status
, 1);
1747 attr
.stream_attr_in
= &strm_attr_in
;
1748 if (attr
.stream_attr_in
->strm_mode
== STRMMODE_LDMA
)
1753 status
= strm_open(node_res
->node
,
1754 args
->args_strm_open
.direction
,
1755 args
->args_strm_open
.index
, &attr
, &strm_res_obj
,
1758 strmid
= strm_res_obj
->id
+ 1;
1759 CP_TO_USR(args
->args_strm_open
.stream
, &strmid
, status
, 1);
1765 * ======== strmwrap_reclaim ========
1767 u32
strmwrap_reclaim(union trapped_args
*args
, void *pr_ctxt
)
1774 struct strm_res_object
*strm_res
;
1776 find_strm_handle(&strm_res
, pr_ctxt
, args
->args_strm_reclaim
.stream
);
1781 status
= strm_reclaim(strm_res
->stream
, &buf_ptr
,
1782 &ul_bytes
, &ul_buf_size
, &dw_arg
);
1783 CP_TO_USR(args
->args_strm_reclaim
.buf_ptr
, &buf_ptr
, status
, 1);
1784 CP_TO_USR(args
->args_strm_reclaim
.bytes
, &ul_bytes
, status
, 1);
1785 CP_TO_USR(args
->args_strm_reclaim
.arg
, &dw_arg
, status
, 1);
1787 if (args
->args_strm_reclaim
.buf_size_ptr
!= NULL
) {
1788 CP_TO_USR(args
->args_strm_reclaim
.buf_size_ptr
, &ul_buf_size
,
1796 * ======== strmwrap_register_notify ========
1798 u32
strmwrap_register_notify(union trapped_args
*args
, void *pr_ctxt
)
1801 struct dsp_notification notification
;
1802 struct strm_res_object
*strm_res
;
1804 find_strm_handle(&strm_res
, pr_ctxt
,
1805 args
->args_strm_registernotify
.stream
);
1810 /* Initialize the notification data structure */
1811 notification
.name
= NULL
;
1812 notification
.handle
= NULL
;
1814 status
= strm_register_notify(strm_res
->stream
,
1815 args
->args_strm_registernotify
.event_mask
,
1816 args
->args_strm_registernotify
.
1817 notify_type
, ¬ification
);
1818 CP_TO_USR(args
->args_strm_registernotify
.notification
, ¬ification
,
1825 * ======== strmwrap_select ========
1827 u32
strmwrap_select(union trapped_args
*args
, void *pr_ctxt
)
1830 struct strm_object
*strm_tab
[MAX_STREAMS
];
1832 struct strm_res_object
*strm_res
;
1833 int *ids
[MAX_STREAMS
];
1836 if (args
->args_strm_select
.strm_num
> MAX_STREAMS
)
1839 CP_FM_USR(ids
, args
->args_strm_select
.stream_tab
, status
,
1840 args
->args_strm_select
.strm_num
);
1845 for (i
= 0; i
< args
->args_strm_select
.strm_num
; i
++) {
1846 find_strm_handle(&strm_res
, pr_ctxt
, ids
[i
]);
1851 strm_tab
[i
] = strm_res
->stream
;
1855 status
= strm_select(strm_tab
, args
->args_strm_select
.strm_num
,
1856 &mask
, args
->args_strm_select
.timeout
);
1858 CP_TO_USR(args
->args_strm_select
.mask
, &mask
, status
, 1);
1865 * ======== cmmwrap_calloc_buf ========
1867 u32 __deprecated
cmmwrap_calloc_buf(union trapped_args
* args
, void *pr_ctxt
)
1869 /* This operation is done in kernel */
1870 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
1875 * ======== cmmwrap_free_buf ========
1877 u32 __deprecated
cmmwrap_free_buf(union trapped_args
* args
, void *pr_ctxt
)
1879 /* This operation is done in kernel */
1880 pr_err("%s: deprecated dspbridge ioctl\n", __func__
);
1885 * ======== cmmwrap_get_handle ========
1887 u32
cmmwrap_get_handle(union trapped_args
*args
, void *pr_ctxt
)
1890 struct cmm_object
*hcmm_mgr
;
1891 void *hprocessor
= ((struct process_context
*)pr_ctxt
)->processor
;
1893 status
= cmm_get_handle(hprocessor
, &hcmm_mgr
);
1895 CP_TO_USR(args
->args_cmm_gethandle
.cmm_mgr
, &hcmm_mgr
, status
, 1);
1901 * ======== cmmwrap_get_info ========
1903 u32
cmmwrap_get_info(union trapped_args
*args
, void *pr_ctxt
)
1906 struct cmm_info cmm_info_obj
;
1908 status
= cmm_get_info(args
->args_cmm_getinfo
.cmm_mgr
, &cmm_info_obj
);
1910 CP_TO_USR(args
->args_cmm_getinfo
.cmm_info_obj
, &cmm_info_obj
, status
,