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(). */
286 * ======== api_init ========
288 * Module initialization used by Bridge API.
293 bool fdrv, fdev, fcod, fchnl, fmsg, fio;
294 bool fmgr, fproc, fnode, fdisp, fstrm, frmm;
296 if (api_c_refs == 0) {
297 /* initialize driver and other modules */
306 fmsg = msg_mod_init();
310 ret = fdrv && fdev && fchnl && fcod && fmsg && fio;
311 ret = ret && fmgr && fproc && frmm;
358 * ======== api_init_complete2 ========
360 * Perform any required bridge initialization which cannot
361 * be performed in api_init() or dev_start_device() due
362 * to the fact that some services are not yet
363 * completely initialized.
366 * 0: Allow this device to load
369 * Bridge API initialized.
372 int api_init_complete2(void)
375 struct cfg_devnode *dev_node;
376 struct dev_object *hdev_obj;
377 struct drv_data *drv_datap;
380 /* Walk the list of DevObjects, get each devnode, and attempting to
381 * autostart the board. Note that this requires COF loading, which
383 for (hdev_obj = dev_get_first(); hdev_obj != NULL;
384 hdev_obj = dev_get_next(hdev_obj)) {
385 if (dev_get_dev_node(hdev_obj, &dev_node))
388 if (dev_get_dev_type(hdev_obj, &dev_type))
391 if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
392 drv_datap = dev_get_drvdata(bridge);
394 if (drv_datap && drv_datap->base_img)
395 proc_auto_start(dev_node, hdev_obj);
402 /* TODO: Remove deprecated and not implemented ioctl wrappers */
405 * ======== mgrwrap_enum_node_info ========
407 u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
412 u32 size = args->args_mgr_enumnode_info.ndb_props_size;
414 if (size < sizeof(struct dsp_ndbprops))
417 pndb_props = kmalloc(size, GFP_KERNEL);
418 if (pndb_props == NULL)
423 mgr_enum_node_info(args->args_mgr_enumnode_info.node_id,
424 (struct dsp_ndbprops *)pndb_props, size,
427 CP_TO_USR(args->args_mgr_enumnode_info.ndb_props, pndb_props, status,
429 CP_TO_USR(args->args_mgr_enumnode_info.num_nodes, &num_nodes, status,
437 * ======== mgrwrap_enum_proc_info ========
439 u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt)
444 u32 size = args->args_mgr_enumproc_info.processor_info_size;
446 if (size < sizeof(struct dsp_processorinfo))
449 processor_info = kmalloc(size, GFP_KERNEL);
450 if (processor_info == NULL)
455 mgr_enum_processor_info(args->args_mgr_enumproc_info.
457 (struct dsp_processorinfo *)
458 processor_info, size, &num_procs);
460 CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info,
462 CP_TO_USR(args->args_mgr_enumproc_info.num_procs, &num_procs,
464 kfree(processor_info);
469 #define WRAP_MAP2CALLER(x) x
471 * ======== mgrwrap_register_object ========
473 u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
476 struct dsp_uuid uuid_obj;
478 char *psz_path_name = NULL;
481 CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
484 /* path_size is increased by 1 to accommodate NULL */
485 path_size = strlen_user((char *)
486 args->args_mgr_registerobject.sz_path_name) +
488 psz_path_name = kmalloc(path_size, GFP_KERNEL);
489 if (!psz_path_name) {
493 ret = strncpy_from_user(psz_path_name,
494 (char *)args->args_mgr_registerobject.
495 sz_path_name, path_size);
501 if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) {
506 status = dcd_register_object(&uuid_obj,
507 args->args_mgr_registerobject.obj_type,
508 (char *)psz_path_name);
510 kfree(psz_path_name);
515 * ======== mgrwrap_unregister_object ========
517 u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt)
520 struct dsp_uuid uuid_obj;
522 CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
526 status = dcd_unregister_object(&uuid_obj,
527 args->args_mgr_unregisterobject.
535 * ======== mgrwrap_wait_for_bridge_events ========
537 u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
540 struct dsp_notification *anotifications[MAX_EVENTS];
541 struct dsp_notification notifications[MAX_EVENTS];
543 u32 count = args->args_mgr_wait.count;
545 if (count > MAX_EVENTS)
548 /* get the array of pointers to user structures */
549 CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
552 for (i = 0; i < count; i++) {
553 CP_FM_USR(¬ifications[i], anotifications[i], status, 1);
554 if (status || !notifications[i].handle) {
558 /* set the array of pointers to kernel structures */
559 anotifications[i] = ¬ifications[i];
562 status = mgr_wait_for_bridge_events(anotifications, count,
567 CP_TO_USR(args->args_mgr_wait.index, &index, status, 1);
572 * ======== MGRWRAP_GetProcessResourceInfo ========
574 u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args,
577 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
582 * ======== procwrap_attach ========
584 u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
588 struct dsp_processorattrin proc_attr_in, *attr_in = NULL;
590 /* Optional argument */
591 if (args->args_proc_attach.attr_in) {
592 CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status,
595 attr_in = &proc_attr_in;
600 status = proc_attach(args->args_proc_attach.processor_id, attr_in,
601 &processor, pr_ctxt);
602 CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1);
608 * ======== procwrap_ctrl ========
610 u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt)
612 u32 cb_data_size, __user * psize = (u32 __user *)
613 args->args_proc_ctrl.args;
616 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
619 if (get_user(cb_data_size, psize)) {
623 cb_data_size += sizeof(u32);
624 pargs = kmalloc(cb_data_size, GFP_KERNEL);
630 CP_FM_USR(pargs, args->args_proc_ctrl.args, status,
634 status = proc_ctrl(hprocessor,
635 args->args_proc_ctrl.cmd,
636 (struct dsp_cbdata *)pargs);
639 /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */
646 * ======== procwrap_detach ========
648 u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt)
650 /* proc_detach called at bridge_release only */
651 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
656 * ======== procwrap_enum_node_info ========
658 u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
661 void *node_tab[MAX_NODES];
664 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
666 if (!args->args_proc_enumnode_info.node_tab_size)
669 status = proc_enum_nodes(hprocessor,
671 args->args_proc_enumnode_info.node_tab_size,
672 &num_nodes, &alloc_cnt);
673 CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status,
675 CP_TO_USR(args->args_proc_enumnode_info.num_nodes, &num_nodes,
677 CP_TO_USR(args->args_proc_enumnode_info.allocated, &alloc_cnt,
682 u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt)
686 if (args->args_proc_dma.dir >= DMA_NONE)
689 status = proc_end_dma(pr_ctxt,
690 args->args_proc_dma.mpu_addr,
691 args->args_proc_dma.size,
692 args->args_proc_dma.dir);
696 u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt)
700 if (args->args_proc_dma.dir >= DMA_NONE)
703 status = proc_begin_dma(pr_ctxt,
704 args->args_proc_dma.mpu_addr,
705 args->args_proc_dma.size,
706 args->args_proc_dma.dir);
711 * ======== procwrap_flush_memory ========
713 u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt)
717 if (args->args_proc_flushmemory.flags >
718 PROC_WRITEBACK_INVALIDATE_MEM)
721 status = proc_flush_memory(pr_ctxt,
722 args->args_proc_flushmemory.mpu_addr,
723 args->args_proc_flushmemory.size,
724 args->args_proc_flushmemory.flags);
729 * ======== procwrap_invalidate_memory ========
731 u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt)
736 proc_invalidate_memory(pr_ctxt,
737 args->args_proc_invalidatememory.mpu_addr,
738 args->args_proc_invalidatememory.size);
743 * ======== procwrap_enum_resources ========
745 u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt)
748 struct dsp_resourceinfo resource_info;
749 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
751 if (args->args_proc_enumresources.resource_info_size <
752 sizeof(struct dsp_resourceinfo))
756 proc_get_resource_info(hprocessor,
757 args->args_proc_enumresources.resource_type,
759 args->args_proc_enumresources.
762 CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info,
770 * ======== procwrap_get_state ========
772 u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt)
775 struct dsp_processorstate proc_state;
776 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
778 if (args->args_proc_getstate.state_info_size <
779 sizeof(struct dsp_processorstate))
782 status = proc_get_state(hprocessor, &proc_state,
783 args->args_proc_getstate.state_info_size);
784 CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status,
791 * ======== procwrap_get_trace ========
793 u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt)
797 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
799 if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN)
802 pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL);
804 status = proc_get_trace(hprocessor, pbuf,
805 args->args_proc_gettrace.max_size);
809 CP_TO_USR(args->args_proc_gettrace.buf, pbuf, status,
810 args->args_proc_gettrace.max_size);
817 * ======== procwrap_load ========
819 u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
824 s32 count = args->args_proc_load.argc_index;
825 u8 **argv = NULL, **envp = NULL;
826 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
828 if (count <= 0 || count > MAX_LOADARGS) {
833 argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
839 CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
846 for (i = 0; i < count; i++) {
848 /* User space pointer to argument */
849 temp = (char *)argv[i];
850 /* len is increased by 1 to accommodate NULL */
851 len = strlen_user((char *)temp) + 1;
852 /* Kernel space pointer to argument */
853 argv[i] = kmalloc(len, GFP_KERNEL);
855 CP_FM_USR(argv[i], temp, status, len);
867 /* TODO: validate this */
868 if (args->args_proc_load.user_envp) {
869 /* number of elements in the envp array including NULL */
873 args->args_proc_load.user_envp + count)) {
879 envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
885 CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
891 for (i = 0; envp[i]; i++) {
892 /* User space pointer to argument */
893 temp = (char *)envp[i];
894 /* len is increased by 1 to accommodate NULL */
895 len = strlen_user((char *)temp) + 1;
896 /* Kernel space pointer to argument */
897 envp[i] = kmalloc(len, GFP_KERNEL);
899 CP_FM_USR(envp[i], temp, status, len);
913 status = proc_load(hprocessor,
914 args->args_proc_load.argc_index,
915 (const char **)argv, (const char **)envp);
927 count = args->args_proc_load.argc_index;
928 for (i = 0; (i < count) && argv[i]; i++)
938 * ======== procwrap_map ========
940 u32 procwrap_map(union trapped_args *args, void *pr_ctxt)
944 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
946 if (!args->args_proc_mapmem.size)
949 status = proc_map(args->args_proc_mapmem.processor,
950 args->args_proc_mapmem.mpu_addr,
951 args->args_proc_mapmem.size,
952 args->args_proc_mapmem.req_addr, &map_addr,
953 args->args_proc_mapmem.map_attr, pr_ctxt);
955 if (put_user(map_addr, args->args_proc_mapmem.map_addr)) {
957 proc_un_map(hprocessor, map_addr, pr_ctxt);
965 * ======== procwrap_register_notify ========
967 u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
970 struct dsp_notification notification;
971 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
973 /* Initialize the notification data structure */
974 notification.name = NULL;
975 notification.handle = NULL;
977 status = proc_register_notify(hprocessor,
978 args->args_proc_register_notify.event_mask,
979 args->args_proc_register_notify.notify_type,
981 CP_TO_USR(args->args_proc_register_notify.notification, ¬ification,
987 * ======== procwrap_reserve_memory ========
989 u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
993 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
995 if ((args->args_proc_rsvmem.size <= 0) ||
996 (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0)
999 status = proc_reserve_memory(hprocessor,
1000 args->args_proc_rsvmem.size, &prsv_addr,
1003 if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) {
1005 proc_un_reserve_memory(args->args_proc_rsvmem.
1006 processor, prsv_addr, pr_ctxt);
1013 * ======== procwrap_start ========
1015 u32 procwrap_start(union trapped_args *args, void *pr_ctxt)
1019 ret = proc_start(((struct process_context *)pr_ctxt)->processor);
1024 * ======== procwrap_un_map ========
1026 u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
1030 status = proc_un_map(((struct process_context *)pr_ctxt)->processor,
1031 args->args_proc_unmapmem.map_addr, pr_ctxt);
1036 * ======== procwrap_un_reserve_memory ========
1038 u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
1041 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
1043 status = proc_un_reserve_memory(hprocessor,
1044 args->args_proc_unrsvmem.rsv_addr,
1050 * ======== procwrap_stop ========
1052 u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
1056 ret = proc_stop(((struct process_context *)pr_ctxt)->processor);
1062 * ======== find_handle =========
1064 inline void find_node_handle(struct node_res_object **noderes,
1065 void *pr_ctxt, void *hnode)
1068 *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
1076 * ======== nodewrap_allocate ========
1078 u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
1081 struct dsp_uuid node_uuid;
1082 u32 cb_data_size = 0;
1083 u32 __user *psize = (u32 __user *) args->args_node_allocate.args;
1085 struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
1086 struct node_res_object *node_res;
1088 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
1090 /* Optional argument */
1092 if (get_user(cb_data_size, psize))
1095 cb_data_size += sizeof(u32);
1097 pargs = kmalloc(cb_data_size, GFP_KERNEL);
1102 CP_FM_USR(pargs, args->args_node_allocate.args, status,
1105 CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
1108 /* Optional argument */
1109 if (args->args_node_allocate.attr_in) {
1110 CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in,
1113 attr_in = &proc_attr_in;
1119 status = node_allocate(hprocessor,
1120 &node_uuid, (struct dsp_cbdata *)pargs,
1121 attr_in, &node_res, pr_ctxt);
1124 nodeid = node_res->id + 1;
1125 CP_TO_USR(args->args_node_allocate.node, &nodeid,
1129 node_delete(node_res, pr_ctxt);
1139 * ======== nodewrap_alloc_msg_buf ========
1141 u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
1144 struct dsp_bufferattr *pattr = NULL;
1145 struct dsp_bufferattr attr;
1147 struct node_res_object *node_res;
1149 find_node_handle(&node_res, pr_ctxt,
1150 args->args_node_allocmsgbuf.node);
1155 if (!args->args_node_allocmsgbuf.size)
1158 if (args->args_node_allocmsgbuf.attr) { /* Optional argument */
1159 CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1);
1165 CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1);
1167 status = node_alloc_msg_buf(node_res->node,
1168 args->args_node_allocmsgbuf.size,
1171 CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1);
1176 * ======== nodewrap_change_priority ========
1178 u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
1181 struct node_res_object *node_res;
1183 find_node_handle(&node_res, pr_ctxt,
1184 args->args_node_changepriority.node);
1189 ret = node_change_priority(node_res->node,
1190 args->args_node_changepriority.prio);
1196 * ======== nodewrap_connect ========
1198 u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
1201 struct dsp_strmattr attrs;
1202 struct dsp_strmattr *pattrs = NULL;
1204 u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
1206 struct node_res_object *node_res1, *node_res2;
1207 struct node_object *node1 = NULL, *node2 = NULL;
1209 if ((int)args->args_node_connect.node != DSP_HGPPNODE) {
1210 find_node_handle(&node_res1, pr_ctxt,
1211 args->args_node_connect.node);
1213 node1 = node_res1->node;
1215 node1 = args->args_node_connect.node;
1218 if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
1219 find_node_handle(&node_res2, pr_ctxt,
1220 args->args_node_connect.other_node);
1222 node2 = node_res2->node;
1224 node2 = args->args_node_connect.other_node;
1227 if (!node1 || !node2)
1230 /* Optional argument */
1232 if (get_user(cb_data_size, psize))
1235 cb_data_size += sizeof(u32);
1237 pargs = kmalloc(cb_data_size, GFP_KERNEL);
1238 if (pargs == NULL) {
1244 CP_FM_USR(pargs, args->args_node_connect.conn_param, status,
1249 if (args->args_node_connect.attrs) { /* Optional argument */
1250 CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1);
1256 status = node_connect(node1,
1257 args->args_node_connect.stream_id,
1259 args->args_node_connect.other_stream,
1260 pattrs, (struct dsp_cbdata *)pargs);
1269 * ======== nodewrap_create ========
1271 u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
1274 struct node_res_object *node_res;
1276 find_node_handle(&node_res, pr_ctxt, args->args_node_create.node);
1281 ret = node_create(node_res->node);
1287 * ======== nodewrap_delete ========
1289 u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
1292 struct node_res_object *node_res;
1294 find_node_handle(&node_res, pr_ctxt, args->args_node_delete.node);
1299 ret = node_delete(node_res, pr_ctxt);
1305 * ======== nodewrap_free_msg_buf ========
1307 u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
1310 struct dsp_bufferattr *pattr = NULL;
1311 struct dsp_bufferattr attr;
1312 struct node_res_object *node_res;
1314 find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node);
1319 if (args->args_node_freemsgbuf.attr) { /* Optional argument */
1320 CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1);
1326 if (!args->args_node_freemsgbuf.buffer)
1330 status = node_free_msg_buf(node_res->node,
1331 args->args_node_freemsgbuf.buffer,
1339 * ======== nodewrap_get_attr ========
1341 u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
1344 struct dsp_nodeattr attr;
1345 struct node_res_object *node_res;
1347 find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.node);
1352 status = node_get_attr(node_res->node, &attr,
1353 args->args_node_getattr.attr_size);
1354 CP_TO_USR(args->args_node_getattr.attr, &attr, status, 1);
1360 * ======== nodewrap_get_message ========
1362 u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
1366 struct node_res_object *node_res;
1368 find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.node);
1373 status = node_get_message(node_res->node, &msg,
1374 args->args_node_getmessage.timeout);
1376 CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);
1382 * ======== nodewrap_pause ========
1384 u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
1387 struct node_res_object *node_res;
1389 find_node_handle(&node_res, pr_ctxt, args->args_node_pause.node);
1394 ret = node_pause(node_res->node);
1400 * ======== nodewrap_put_message ========
1402 u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
1406 struct node_res_object *node_res;
1408 find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node);
1413 CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
1417 node_put_message(node_res->node, &msg,
1418 args->args_node_putmessage.timeout);
1425 * ======== nodewrap_register_notify ========
1427 u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
1430 struct dsp_notification notification;
1431 struct node_res_object *node_res;
1433 find_node_handle(&node_res, pr_ctxt,
1434 args->args_node_registernotify.node);
1439 /* Initialize the notification data structure */
1440 notification.name = NULL;
1441 notification.handle = NULL;
1443 if (!args->args_proc_register_notify.event_mask)
1444 CP_FM_USR(¬ification,
1445 args->args_proc_register_notify.notification,
1448 status = node_register_notify(node_res->node,
1449 args->args_node_registernotify.event_mask,
1450 args->args_node_registernotify.
1451 notify_type, ¬ification);
1452 CP_TO_USR(args->args_node_registernotify.notification, ¬ification,
1458 * ======== nodewrap_run ========
1460 u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
1463 struct node_res_object *node_res;
1465 find_node_handle(&node_res, pr_ctxt, args->args_node_run.node);
1470 ret = node_run(node_res->node);
1476 * ======== nodewrap_terminate ========
1478 u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
1482 struct node_res_object *node_res;
1484 find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.node);
1489 status = node_terminate(node_res->node, &tempstatus);
1491 CP_TO_USR(args->args_node_terminate.status, &tempstatus, status, 1);
1497 * ======== nodewrap_get_uuid_props ========
1499 u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt)
1502 struct dsp_uuid node_uuid;
1503 struct dsp_ndbprops *pnode_props = NULL;
1504 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
1506 CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status,
1510 pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL);
1511 if (pnode_props != NULL) {
1513 node_get_uuid_props(hprocessor, &node_uuid, pnode_props);
1514 CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props,
1524 * ======== find_strm_handle =========
1526 inline void find_strm_handle(struct strm_res_object **strmres,
1527 void *pr_ctxt, void *hstream)
1530 *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id,
1537 * ======== strmwrap_allocate_buffer ========
1539 u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt)
1542 u8 **ap_buffer = NULL;
1543 u32 num_bufs = args->args_strm_allocatebuffer.num_bufs;
1544 struct strm_res_object *strm_res;
1546 find_strm_handle(&strm_res, pr_ctxt,
1547 args->args_strm_allocatebuffer.stream);
1552 if (num_bufs > MAX_BUFS)
1555 ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
1556 if (ap_buffer == NULL)
1559 status = strm_allocate_buffer(strm_res,
1560 args->args_strm_allocatebuffer.size,
1561 ap_buffer, num_bufs, pr_ctxt);
1563 CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer,
1567 strm_free_buffer(strm_res,
1568 ap_buffer, num_bufs, pr_ctxt);
1577 * ======== strmwrap_close ========
1579 u32 strmwrap_close(union trapped_args *args, void *pr_ctxt)
1581 struct strm_res_object *strm_res;
1583 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.stream);
1588 return strm_close(strm_res, pr_ctxt);
1592 * ======== strmwrap_free_buffer ========
1594 u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
1597 u8 **ap_buffer = NULL;
1598 u32 num_bufs = args->args_strm_freebuffer.num_bufs;
1599 struct strm_res_object *strm_res;
1601 find_strm_handle(&strm_res, pr_ctxt,
1602 args->args_strm_freebuffer.stream);
1607 if (num_bufs > MAX_BUFS)
1610 ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
1611 if (ap_buffer == NULL)
1614 CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status,
1618 status = strm_free_buffer(strm_res,
1619 ap_buffer, num_bufs, pr_ctxt);
1621 CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status,
1629 * ======== strmwrap_get_event_handle ========
1631 u32 __deprecated strmwrap_get_event_handle(union trapped_args * args,
1634 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1639 * ======== strmwrap_get_info ========
1641 u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt)
1644 struct stream_info strm_info;
1645 struct dsp_streaminfo user;
1646 struct dsp_streaminfo *temp;
1647 struct strm_res_object *strm_res;
1649 find_strm_handle(&strm_res, pr_ctxt,
1650 args->args_strm_getinfo.stream);
1655 CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1);
1656 temp = strm_info.user_strm;
1658 strm_info.user_strm = &user;
1661 status = strm_get_info(strm_res->stream,
1663 args->args_strm_getinfo.
1666 CP_TO_USR(temp, strm_info.user_strm, status, 1);
1667 strm_info.user_strm = temp;
1668 CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1);
1673 * ======== strmwrap_idle ========
1675 u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt)
1678 struct strm_res_object *strm_res;
1680 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.stream);
1685 ret = strm_idle(strm_res->stream, args->args_strm_idle.flush_flag);
1691 * ======== strmwrap_issue ========
1693 u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt)
1696 struct strm_res_object *strm_res;
1698 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.stream);
1703 if (!args->args_strm_issue.buffer)
1706 /* No need of doing CP_FM_USR for the user buffer (pbuffer)
1707 as this is done in Bridge internal function bridge_chnl_add_io_req
1709 status = strm_issue(strm_res->stream,
1710 args->args_strm_issue.buffer,
1711 args->args_strm_issue.bytes,
1712 args->args_strm_issue.buf_size,
1713 args->args_strm_issue.arg);
1719 * ======== strmwrap_open ========
1721 u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
1724 struct strm_attr attr;
1725 struct strm_res_object *strm_res_obj;
1726 struct dsp_streamattrin strm_attr_in;
1727 struct node_res_object *node_res;
1730 find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node);
1735 CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
1737 if (attr.stream_attr_in != NULL) { /* Optional argument */
1738 CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1);
1740 attr.stream_attr_in = &strm_attr_in;
1741 if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA)
1746 status = strm_open(node_res->node,
1747 args->args_strm_open.direction,
1748 args->args_strm_open.index, &attr, &strm_res_obj,
1751 strmid = strm_res_obj->id + 1;
1752 CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1);
1758 * ======== strmwrap_reclaim ========
1760 u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt)
1767 struct strm_res_object *strm_res;
1769 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.stream);
1774 status = strm_reclaim(strm_res->stream, &buf_ptr,
1775 &ul_bytes, &ul_buf_size, &dw_arg);
1776 CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1);
1777 CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1);
1778 CP_TO_USR(args->args_strm_reclaim.arg, &dw_arg, status, 1);
1780 if (args->args_strm_reclaim.buf_size_ptr != NULL) {
1781 CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size,
1789 * ======== strmwrap_register_notify ========
1791 u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt)
1794 struct dsp_notification notification;
1795 struct strm_res_object *strm_res;
1797 find_strm_handle(&strm_res, pr_ctxt,
1798 args->args_strm_registernotify.stream);
1803 /* Initialize the notification data structure */
1804 notification.name = NULL;
1805 notification.handle = NULL;
1807 status = strm_register_notify(strm_res->stream,
1808 args->args_strm_registernotify.event_mask,
1809 args->args_strm_registernotify.
1810 notify_type, ¬ification);
1811 CP_TO_USR(args->args_strm_registernotify.notification, ¬ification,
1818 * ======== strmwrap_select ========
1820 u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
1823 struct strm_object *strm_tab[MAX_STREAMS];
1825 struct strm_res_object *strm_res;
1826 int *ids[MAX_STREAMS];
1829 if (args->args_strm_select.strm_num > MAX_STREAMS)
1832 CP_FM_USR(ids, args->args_strm_select.stream_tab, status,
1833 args->args_strm_select.strm_num);
1838 for (i = 0; i < args->args_strm_select.strm_num; i++) {
1839 find_strm_handle(&strm_res, pr_ctxt, ids[i]);
1844 strm_tab[i] = strm_res->stream;
1848 status = strm_select(strm_tab, args->args_strm_select.strm_num,
1849 &mask, args->args_strm_select.timeout);
1851 CP_TO_USR(args->args_strm_select.mask, &mask, status, 1);
1858 * ======== cmmwrap_calloc_buf ========
1860 u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
1862 /* This operation is done in kernel */
1863 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1868 * ======== cmmwrap_free_buf ========
1870 u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt)
1872 /* This operation is done in kernel */
1873 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1878 * ======== cmmwrap_get_handle ========
1880 u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt)
1883 struct cmm_object *hcmm_mgr;
1884 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
1886 status = cmm_get_handle(hprocessor, &hcmm_mgr);
1888 CP_TO_USR(args->args_cmm_gethandle.cmm_mgr, &hcmm_mgr, status, 1);
1894 * ======== cmmwrap_get_info ========
1896 u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt)
1899 struct cmm_info cmm_info_obj;
1901 status = cmm_get_info(args->args_cmm_getinfo.cmm_mgr, &cmm_info_obj);
1903 CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status,