staging: tidspbridge: remove msg_mod_init() and msg_exit()
[deliverable/linux.git] / drivers / staging / tidspbridge / pmgr / dspapi.c
CommitLineData
c4ca3d5a
ORL
1/*
2 * dspapi.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Common DSP API functions, also includes the wrapper
7 * functions called directly by the DeviceIOControl interface.
8 *
9 * Copyright (C) 2005-2006 Texas Instruments, Inc.
10 *
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.
14 *
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.
18 */
2094f12d 19#include <linux/types.h>
c4ca3d5a
ORL
20
21/* ----------------------------------- Host OS */
22#include <dspbridge/host_os.h>
23
24/* ----------------------------------- DSP/BIOS Bridge */
c4ca3d5a
ORL
25#include <dspbridge/dbdefs.h>
26
c4ca3d5a 27/* ----------------------------------- OS Adaptation Layer */
c4ca3d5a 28#include <dspbridge/ntfy.h>
c4ca3d5a
ORL
29
30/* ----------------------------------- Platform Manager */
31#include <dspbridge/chnl.h>
32#include <dspbridge/dev.h>
33#include <dspbridge/drv.h>
34
35#include <dspbridge/proc.h>
36#include <dspbridge/strm.h>
37
38/* ----------------------------------- Resource Manager */
39#include <dspbridge/disp.h>
40#include <dspbridge/mgr.h>
41#include <dspbridge/node.h>
42#include <dspbridge/rmm.h>
43
44/* ----------------------------------- Others */
45#include <dspbridge/msg.h>
46#include <dspbridge/cmm.h>
47#include <dspbridge/io.h>
48
49/* ----------------------------------- This */
50#include <dspbridge/dspapi.h>
51#include <dspbridge/dbdcd.h>
52
53#include <dspbridge/resourcecleanup.h>
54
55/* ----------------------------------- Defines, Data Structures, Typedefs */
56#define MAX_TRACEBUFLEN 255
57#define MAX_LOADARGS 16
58#define MAX_NODES 64
59#define MAX_STREAMS 16
60#define MAX_BUFS 64
61
62/* Used to get dspbridge ioctl table */
63#define DB_GET_IOC_TABLE(cmd) (DB_GET_MODULE(cmd) >> DB_MODULE_SHIFT)
64
65/* Device IOCtl function pointer */
66struct api_cmd {
0cd343a4 67 u32(*fxn) (union trapped_args *args, void *pr_ctxt);
5108de0a 68 u32 index;
c4ca3d5a
ORL
69};
70
71/* ----------------------------------- Globals */
72static u32 api_c_refs;
73
74/*
75 * Function tables.
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.
79 */
80
81/* MGR wrapper functions */
82static 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 */
89};
90
91/* PROC wrapper functions */
92static 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 */
112};
113
114/* NODE wrapper functions */
115static 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 */
131};
132
133/* STRM wrapper functions */
134static 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 */
146};
147
148/* CMM wrapper functions */
149static 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 */
154};
155
156/* Array used to store ioctl table sizes. It can hold up to 8 entries */
157static u8 size_cmd[] = {
158 ARRAY_SIZE(mgr_cmd),
159 ARRAY_SIZE(proc_cmd),
160 ARRAY_SIZE(node_cmd),
161 ARRAY_SIZE(strm_cmd),
162 ARRAY_SIZE(cmm_cmd),
163};
164
165static inline void _cp_fm_usr(void *to, const void __user * from,
166 int *err, unsigned long bytes)
167{
51d5e099 168 if (*err)
c4ca3d5a
ORL
169 return;
170
171 if (unlikely(!from)) {
172 *err = -EFAULT;
173 return;
174 }
175
176 if (unlikely(copy_from_user(to, from, bytes)))
177 *err = -EFAULT;
178}
179
180#define CP_FM_USR(to, from, err, n) \
181 _cp_fm_usr(to, from, &(err), (n) * sizeof(*(to)))
182
183static inline void _cp_to_usr(void __user *to, const void *from,
184 int *err, unsigned long bytes)
185{
51d5e099 186 if (*err)
c4ca3d5a
ORL
187 return;
188
189 if (unlikely(!to)) {
190 *err = -EFAULT;
191 return;
192 }
193
194 if (unlikely(copy_to_user(to, from, bytes)))
195 *err = -EFAULT;
196}
197
198#define CP_TO_USR(to, from, err, n) \
199 _cp_to_usr(to, from, &(err), (n) * sizeof(*(from)))
200
201/*
202 * ======== api_call_dev_ioctl ========
203 * Purpose:
204 * Call the (wrapper) function for the corresponding API IOCTL.
205 */
0cd343a4 206inline int api_call_dev_ioctl(u32 cmd, union trapped_args *args,
c4ca3d5a
ORL
207 u32 *result, void *pr_ctxt)
208{
0cd343a4 209 u32(*ioctl_cmd) (union trapped_args *args, void *pr_ctxt) = NULL;
c4ca3d5a
ORL
210 int i;
211
212 if (_IOC_TYPE(cmd) != DB) {
213 pr_err("%s: Incompatible dspbridge ioctl number\n", __func__);
214 goto err;
215 }
216
217 if (DB_GET_IOC_TABLE(cmd) > ARRAY_SIZE(size_cmd)) {
218 pr_err("%s: undefined ioctl module\n", __func__);
219 goto err;
220 }
221
222 /* Check the size of the required cmd table */
223 i = DB_GET_IOC(cmd);
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));
227 goto err;
228 }
229
230 switch (DB_GET_MODULE(cmd)) {
231 case DB_MGR:
232 ioctl_cmd = mgr_cmd[i].fxn;
233 break;
234 case DB_PROC:
235 ioctl_cmd = proc_cmd[i].fxn;
236 break;
237 case DB_NODE:
238 ioctl_cmd = node_cmd[i].fxn;
239 break;
240 case DB_STRM:
241 ioctl_cmd = strm_cmd[i].fxn;
242 break;
243 case DB_CMM:
244 ioctl_cmd = cmm_cmd[i].fxn;
245 break;
246 }
247
248 if (!ioctl_cmd) {
249 pr_err("%s: requested ioctl not defined\n", __func__);
250 goto err;
251 } else {
252 *result = (*ioctl_cmd) (args, pr_ctxt);
253 }
254
255 return 0;
256
257err:
258 return -EINVAL;
259}
260
261/*
262 * ======== api_exit ========
263 */
264void api_exit(void)
265{
c4ca3d5a
ORL
266 api_c_refs--;
267
268 if (api_c_refs == 0) {
269 /* Release all modules initialized in api_init(). */
c4ca3d5a 270 dev_exit();
c4ca3d5a 271 io_exit();
c4ca3d5a 272 mgr_exit();
c4ca3d5a 273 }
c4ca3d5a
ORL
274}
275
276/*
277 * ======== api_init ========
278 * Purpose:
279 * Module initialization used by Bridge API.
280 */
281bool api_init(void)
282{
283 bool ret = true;
1471d6c6 284 bool fdev, fio;
974f9cd5 285 bool fmgr;
c4ca3d5a
ORL
286
287 if (api_c_refs == 0) {
288 /* initialize driver and other modules */
c4ca3d5a 289 fmgr = mgr_init();
c4ca3d5a
ORL
290 fio = io_init();
291 fdev = dev_init();
1471d6c6 292 ret = fdev && fio;
974f9cd5 293 ret = ret && fmgr;
c4ca3d5a 294 if (!ret) {
c4ca3d5a
ORL
295
296 if (fmgr)
297 mgr_exit();
298
c4ca3d5a
ORL
299 if (fio)
300 io_exit();
301
302 if (fdev)
303 dev_exit();
c4ca3d5a
ORL
304 }
305 }
306 if (ret)
307 api_c_refs++;
308
309 return ret;
310}
311
312/*
313 * ======== api_init_complete2 ========
314 * Purpose:
315 * Perform any required bridge initialization which cannot
316 * be performed in api_init() or dev_start_device() due
317 * to the fact that some services are not yet
318 * completely initialized.
319 * Parameters:
320 * Returns:
321 * 0: Allow this device to load
322 * -EPERM: Failure.
323 * Requires:
324 * Bridge API initialized.
325 * Ensures:
326 */
327int api_init_complete2(void)
328{
329 int status = 0;
330 struct cfg_devnode *dev_node;
331 struct dev_object *hdev_obj;
4a659562 332 struct drv_data *drv_datap;
c4ca3d5a 333 u8 dev_type;
c4ca3d5a 334
c4ca3d5a
ORL
335 /* Walk the list of DevObjects, get each devnode, and attempting to
336 * autostart the board. Note that this requires COF loading, which
337 * requires KFILE. */
338 for (hdev_obj = dev_get_first(); hdev_obj != NULL;
339 hdev_obj = dev_get_next(hdev_obj)) {
51d5e099 340 if (dev_get_dev_node(hdev_obj, &dev_node))
c4ca3d5a
ORL
341 continue;
342
51d5e099 343 if (dev_get_dev_type(hdev_obj, &dev_type))
c4ca3d5a
ORL
344 continue;
345
4a659562
IGC
346 if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
347 drv_datap = dev_get_drvdata(bridge);
348
349 if (drv_datap && drv_datap->base_img)
c4ca3d5a 350 proc_auto_start(dev_node, hdev_obj);
4a659562 351 }
c4ca3d5a
ORL
352 }
353
354 return status;
355}
356
357/* TODO: Remove deprecated and not implemented ioctl wrappers */
358
359/*
360 * ======== mgrwrap_enum_node_info ========
361 */
0cd343a4 362u32 mgrwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
363{
364 u8 *pndb_props;
365 u32 num_nodes;
366 int status = 0;
121e8f9b 367 u32 size = args->args_mgr_enumnode_info.ndb_props_size;
c4ca3d5a
ORL
368
369 if (size < sizeof(struct dsp_ndbprops))
370 return -EINVAL;
371
372 pndb_props = kmalloc(size, GFP_KERNEL);
373 if (pndb_props == NULL)
374 status = -ENOMEM;
375
157990f0 376 if (!status) {
c4ca3d5a
ORL
377 status =
378 mgr_enum_node_info(args->args_mgr_enumnode_info.node_id,
379 (struct dsp_ndbprops *)pndb_props, size,
380 &num_nodes);
381 }
121e8f9b 382 CP_TO_USR(args->args_mgr_enumnode_info.ndb_props, pndb_props, status,
c4ca3d5a 383 size);
121e8f9b 384 CP_TO_USR(args->args_mgr_enumnode_info.num_nodes, &num_nodes, status,
c4ca3d5a
ORL
385 1);
386 kfree(pndb_props);
387
388 return status;
389}
390
391/*
392 * ======== mgrwrap_enum_proc_info ========
393 */
0cd343a4 394u32 mgrwrap_enum_proc_info(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
395{
396 u8 *processor_info;
397 u8 num_procs;
398 int status = 0;
399 u32 size = args->args_mgr_enumproc_info.processor_info_size;
400
401 if (size < sizeof(struct dsp_processorinfo))
402 return -EINVAL;
403
404 processor_info = kmalloc(size, GFP_KERNEL);
405 if (processor_info == NULL)
406 status = -ENOMEM;
407
157990f0 408 if (!status) {
c4ca3d5a
ORL
409 status =
410 mgr_enum_processor_info(args->args_mgr_enumproc_info.
411 processor_id,
412 (struct dsp_processorinfo *)
413 processor_info, size, &num_procs);
414 }
415 CP_TO_USR(args->args_mgr_enumproc_info.processor_info, processor_info,
416 status, size);
121e8f9b 417 CP_TO_USR(args->args_mgr_enumproc_info.num_procs, &num_procs,
c4ca3d5a
ORL
418 status, 1);
419 kfree(processor_info);
420
421 return status;
422}
423
424#define WRAP_MAP2CALLER(x) x
425/*
426 * ======== mgrwrap_register_object ========
427 */
0cd343a4 428u32 mgrwrap_register_object(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
429{
430 u32 ret;
431 struct dsp_uuid uuid_obj;
432 u32 path_size = 0;
433 char *psz_path_name = NULL;
434 int status = 0;
435
436 CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
51d5e099 437 if (status)
c4ca3d5a
ORL
438 goto func_end;
439 /* path_size is increased by 1 to accommodate NULL */
440 path_size = strlen_user((char *)
121e8f9b 441 args->args_mgr_registerobject.sz_path_name) +
c4ca3d5a
ORL
442 1;
443 psz_path_name = kmalloc(path_size, GFP_KERNEL);
cc58cbb8
JL
444 if (!psz_path_name) {
445 status = -ENOMEM;
c4ca3d5a 446 goto func_end;
cc58cbb8 447 }
c4ca3d5a
ORL
448 ret = strncpy_from_user(psz_path_name,
449 (char *)args->args_mgr_registerobject.
121e8f9b 450 sz_path_name, path_size);
c4ca3d5a
ORL
451 if (!ret) {
452 status = -EFAULT;
453 goto func_end;
454 }
455
cc58cbb8
JL
456 if (args->args_mgr_registerobject.obj_type >= DSP_DCDMAXOBJTYPE) {
457 status = -EINVAL;
458 goto func_end;
459 }
c4ca3d5a
ORL
460
461 status = dcd_register_object(&uuid_obj,
462 args->args_mgr_registerobject.obj_type,
463 (char *)psz_path_name);
464func_end:
465 kfree(psz_path_name);
466 return status;
467}
468
469/*
470 * ======== mgrwrap_unregister_object ========
471 */
0cd343a4 472u32 mgrwrap_unregister_object(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
473{
474 int status = 0;
475 struct dsp_uuid uuid_obj;
476
477 CP_FM_USR(&uuid_obj, args->args_mgr_registerobject.uuid_obj, status, 1);
51d5e099 478 if (status)
c4ca3d5a
ORL
479 goto func_end;
480
481 status = dcd_unregister_object(&uuid_obj,
482 args->args_mgr_unregisterobject.
483 obj_type);
484func_end:
485 return status;
486
487}
488
489/*
490 * ======== mgrwrap_wait_for_bridge_events ========
491 */
0cd343a4 492u32 mgrwrap_wait_for_bridge_events(union trapped_args *args, void *pr_ctxt)
c4ca3d5a 493{
35f338e4 494 int status = 0;
c4ca3d5a
ORL
495 struct dsp_notification *anotifications[MAX_EVENTS];
496 struct dsp_notification notifications[MAX_EVENTS];
497 u32 index, i;
498 u32 count = args->args_mgr_wait.count;
499
500 if (count > MAX_EVENTS)
501 status = -EINVAL;
502
503 /* get the array of pointers to user structures */
504 CP_FM_USR(anotifications, args->args_mgr_wait.anotifications,
505 status, count);
506 /* get the events */
507 for (i = 0; i < count; i++) {
508 CP_FM_USR(&notifications[i], anotifications[i], status, 1);
35f338e4
ER
509 if (status || !notifications[i].handle) {
510 status = -EINVAL;
511 break;
c4ca3d5a 512 }
35f338e4
ER
513 /* set the array of pointers to kernel structures */
514 anotifications[i] = &notifications[i];
c4ca3d5a 515 }
157990f0 516 if (!status) {
35f338e4 517 status = mgr_wait_for_bridge_events(anotifications, count,
c4ca3d5a
ORL
518 &index,
519 args->args_mgr_wait.
a534f17b 520 timeout);
c4ca3d5a 521 }
121e8f9b 522 CP_TO_USR(args->args_mgr_wait.index, &index, status, 1);
35f338e4 523 return status;
c4ca3d5a
ORL
524}
525
526/*
527 * ======== MGRWRAP_GetProcessResourceInfo ========
528 */
0cd343a4 529u32 __deprecated mgrwrap_get_process_resources_info(union trapped_args * args,
c4ca3d5a
ORL
530 void *pr_ctxt)
531{
532 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
533 return 0;
534}
535
536/*
537 * ======== procwrap_attach ========
538 */
0cd343a4 539u32 procwrap_attach(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
540{
541 void *processor;
542 int status = 0;
543 struct dsp_processorattrin proc_attr_in, *attr_in = NULL;
544
545 /* Optional argument */
546 if (args->args_proc_attach.attr_in) {
547 CP_FM_USR(&proc_attr_in, args->args_proc_attach.attr_in, status,
548 1);
157990f0 549 if (!status)
c4ca3d5a
ORL
550 attr_in = &proc_attr_in;
551 else
552 goto func_end;
553
554 }
555 status = proc_attach(args->args_proc_attach.processor_id, attr_in,
556 &processor, pr_ctxt);
557 CP_TO_USR(args->args_proc_attach.ph_processor, &processor, status, 1);
558func_end:
559 return status;
560}
561
562/*
563 * ======== procwrap_ctrl ========
564 */
0cd343a4 565u32 procwrap_ctrl(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
566{
567 u32 cb_data_size, __user * psize = (u32 __user *)
121e8f9b 568 args->args_proc_ctrl.args;
c4ca3d5a
ORL
569 u8 *pargs = NULL;
570 int status = 0;
a534f17b 571 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
572
573 if (psize) {
574 if (get_user(cb_data_size, psize)) {
575 status = -EPERM;
576 goto func_end;
577 }
578 cb_data_size += sizeof(u32);
579 pargs = kmalloc(cb_data_size, GFP_KERNEL);
580 if (pargs == NULL) {
581 status = -ENOMEM;
582 goto func_end;
583 }
584
121e8f9b 585 CP_FM_USR(pargs, args->args_proc_ctrl.args, status,
c4ca3d5a
ORL
586 cb_data_size);
587 }
157990f0 588 if (!status) {
6bcc9bee 589 status = proc_ctrl(hprocessor,
b4da7fc3 590 args->args_proc_ctrl.cmd,
c4ca3d5a
ORL
591 (struct dsp_cbdata *)pargs);
592 }
593
121e8f9b 594 /* CP_TO_USR(args->args_proc_ctrl.args, pargs, status, 1); */
c4ca3d5a
ORL
595 kfree(pargs);
596func_end:
597 return status;
598}
599
600/*
601 * ======== procwrap_detach ========
602 */
0cd343a4 603u32 __deprecated procwrap_detach(union trapped_args * args, void *pr_ctxt)
c4ca3d5a
ORL
604{
605 /* proc_detach called at bridge_release only */
606 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
607 return 0;
608}
609
610/*
611 * ======== procwrap_enum_node_info ========
612 */
0cd343a4 613u32 procwrap_enum_node_info(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
614{
615 int status;
616 void *node_tab[MAX_NODES];
617 u32 num_nodes;
618 u32 alloc_cnt;
a534f17b 619 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
620
621 if (!args->args_proc_enumnode_info.node_tab_size)
622 return -EINVAL;
623
6bcc9bee 624 status = proc_enum_nodes(hprocessor,
c4ca3d5a
ORL
625 node_tab,
626 args->args_proc_enumnode_info.node_tab_size,
627 &num_nodes, &alloc_cnt);
628 CP_TO_USR(args->args_proc_enumnode_info.node_tab, node_tab, status,
629 num_nodes);
121e8f9b 630 CP_TO_USR(args->args_proc_enumnode_info.num_nodes, &num_nodes,
c4ca3d5a 631 status, 1);
121e8f9b 632 CP_TO_USR(args->args_proc_enumnode_info.allocated, &alloc_cnt,
c4ca3d5a
ORL
633 status, 1);
634 return status;
635}
636
0cd343a4 637u32 procwrap_end_dma(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
638{
639 int status;
640
641 if (args->args_proc_dma.dir >= DMA_NONE)
642 return -EINVAL;
643
644 status = proc_end_dma(pr_ctxt,
121e8f9b 645 args->args_proc_dma.mpu_addr,
085467b8 646 args->args_proc_dma.size,
c4ca3d5a
ORL
647 args->args_proc_dma.dir);
648 return status;
649}
650
0cd343a4 651u32 procwrap_begin_dma(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
652{
653 int status;
654
655 if (args->args_proc_dma.dir >= DMA_NONE)
656 return -EINVAL;
657
658 status = proc_begin_dma(pr_ctxt,
121e8f9b 659 args->args_proc_dma.mpu_addr,
085467b8 660 args->args_proc_dma.size,
c4ca3d5a
ORL
661 args->args_proc_dma.dir);
662 return status;
663}
664
665/*
666 * ======== procwrap_flush_memory ========
667 */
0cd343a4 668u32 procwrap_flush_memory(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
669{
670 int status;
671
fbbb4959 672 if (args->args_proc_flushmemory.flags >
c4ca3d5a
ORL
673 PROC_WRITEBACK_INVALIDATE_MEM)
674 return -EINVAL;
675
676 status = proc_flush_memory(pr_ctxt,
121e8f9b 677 args->args_proc_flushmemory.mpu_addr,
085467b8 678 args->args_proc_flushmemory.size,
fbbb4959 679 args->args_proc_flushmemory.flags);
c4ca3d5a
ORL
680 return status;
681}
682
683/*
684 * ======== procwrap_invalidate_memory ========
685 */
0cd343a4 686u32 procwrap_invalidate_memory(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
687{
688 int status;
689
690 status =
691 proc_invalidate_memory(pr_ctxt,
121e8f9b 692 args->args_proc_invalidatememory.mpu_addr,
085467b8 693 args->args_proc_invalidatememory.size);
c4ca3d5a
ORL
694 return status;
695}
696
697/*
698 * ======== procwrap_enum_resources ========
699 */
0cd343a4 700u32 procwrap_enum_resources(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
701{
702 int status = 0;
703 struct dsp_resourceinfo resource_info;
a534f17b 704 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
705
706 if (args->args_proc_enumresources.resource_info_size <
707 sizeof(struct dsp_resourceinfo))
708 return -EINVAL;
709
710 status =
6bcc9bee 711 proc_get_resource_info(hprocessor,
c4ca3d5a
ORL
712 args->args_proc_enumresources.resource_type,
713 &resource_info,
714 args->args_proc_enumresources.
715 resource_info_size);
716
717 CP_TO_USR(args->args_proc_enumresources.resource_info, &resource_info,
718 status, 1);
719
720 return status;
721
722}
723
724/*
725 * ======== procwrap_get_state ========
726 */
0cd343a4 727u32 procwrap_get_state(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
728{
729 int status;
730 struct dsp_processorstate proc_state;
a534f17b 731 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
732
733 if (args->args_proc_getstate.state_info_size <
734 sizeof(struct dsp_processorstate))
735 return -EINVAL;
736
6bcc9bee 737 status = proc_get_state(hprocessor, &proc_state,
c4ca3d5a
ORL
738 args->args_proc_getstate.state_info_size);
739 CP_TO_USR(args->args_proc_getstate.proc_state_obj, &proc_state, status,
740 1);
741 return status;
742
743}
744
745/*
746 * ======== procwrap_get_trace ========
747 */
0cd343a4 748u32 procwrap_get_trace(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
749{
750 int status;
751 u8 *pbuf;
a534f17b 752 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
753
754 if (args->args_proc_gettrace.max_size > MAX_TRACEBUFLEN)
755 return -EINVAL;
756
757 pbuf = kzalloc(args->args_proc_gettrace.max_size, GFP_KERNEL);
758 if (pbuf != NULL) {
6bcc9bee 759 status = proc_get_trace(hprocessor, pbuf,
c4ca3d5a
ORL
760 args->args_proc_gettrace.max_size);
761 } else {
762 status = -ENOMEM;
763 }
ee4317f7 764 CP_TO_USR(args->args_proc_gettrace.buf, pbuf, status,
c4ca3d5a
ORL
765 args->args_proc_gettrace.max_size);
766 kfree(pbuf);
767
768 return status;
769}
770
771/*
772 * ======== procwrap_load ========
773 */
0cd343a4 774u32 procwrap_load(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
775{
776 s32 i, len;
777 int status = 0;
778 char *temp;
779 s32 count = args->args_proc_load.argc_index;
780 u8 **argv = NULL, **envp = NULL;
a534f17b 781 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
782
783 if (count <= 0 || count > MAX_LOADARGS) {
784 status = -EINVAL;
785 goto func_cont;
786 }
787
788 argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
789 if (!argv) {
790 status = -ENOMEM;
791 goto func_cont;
792 }
793
794 CP_FM_USR(argv, args->args_proc_load.user_args, status, count);
51d5e099 795 if (status) {
c4ca3d5a
ORL
796 kfree(argv);
797 argv = NULL;
798 goto func_cont;
799 }
800
801 for (i = 0; i < count; i++) {
802 if (argv[i]) {
803 /* User space pointer to argument */
804 temp = (char *)argv[i];
805 /* len is increased by 1 to accommodate NULL */
806 len = strlen_user((char *)temp) + 1;
807 /* Kernel space pointer to argument */
808 argv[i] = kmalloc(len, GFP_KERNEL);
809 if (argv[i]) {
810 CP_FM_USR(argv[i], temp, status, len);
51d5e099 811 if (status) {
c4ca3d5a
ORL
812 kfree(argv[i]);
813 argv[i] = NULL;
814 goto func_cont;
815 }
816 } else {
817 status = -ENOMEM;
818 goto func_cont;
819 }
820 }
821 }
822 /* TODO: validate this */
823 if (args->args_proc_load.user_envp) {
824 /* number of elements in the envp array including NULL */
825 count = 0;
826 do {
b04462a1
VK
827 if (get_user(temp,
828 args->args_proc_load.user_envp + count)) {
829 status = -EFAULT;
830 goto func_cont;
831 }
c4ca3d5a
ORL
832 count++;
833 } while (temp);
834 envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL);
835 if (!envp) {
836 status = -ENOMEM;
837 goto func_cont;
838 }
839
840 CP_FM_USR(envp, args->args_proc_load.user_envp, status, count);
51d5e099 841 if (status) {
c4ca3d5a
ORL
842 kfree(envp);
843 envp = NULL;
844 goto func_cont;
845 }
846 for (i = 0; envp[i]; i++) {
847 /* User space pointer to argument */
848 temp = (char *)envp[i];
849 /* len is increased by 1 to accommodate NULL */
850 len = strlen_user((char *)temp) + 1;
851 /* Kernel space pointer to argument */
852 envp[i] = kmalloc(len, GFP_KERNEL);
853 if (envp[i]) {
854 CP_FM_USR(envp[i], temp, status, len);
51d5e099 855 if (status) {
c4ca3d5a
ORL
856 kfree(envp[i]);
857 envp[i] = NULL;
858 goto func_cont;
859 }
860 } else {
861 status = -ENOMEM;
862 goto func_cont;
863 }
864 }
865 }
866
157990f0 867 if (!status) {
6bcc9bee 868 status = proc_load(hprocessor,
c4ca3d5a 869 args->args_proc_load.argc_index,
cd4f13c0 870 (const char **)argv, (const char **)envp);
c4ca3d5a
ORL
871 }
872func_cont:
873 if (envp) {
874 i = 0;
875 while (envp[i])
876 kfree(envp[i++]);
877
878 kfree(envp);
879 }
880
881 if (argv) {
882 count = args->args_proc_load.argc_index;
883 for (i = 0; (i < count) && argv[i]; i++)
884 kfree(argv[i]);
885
886 kfree(argv);
887 }
888
889 return status;
890}
891
892/*
893 * ======== procwrap_map ========
894 */
0cd343a4 895u32 procwrap_map(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
896{
897 int status;
898 void *map_addr;
a534f17b 899 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a 900
085467b8 901 if (!args->args_proc_mapmem.size)
c4ca3d5a
ORL
902 return -EINVAL;
903
a534f17b 904 status = proc_map(args->args_proc_mapmem.processor,
121e8f9b 905 args->args_proc_mapmem.mpu_addr,
085467b8 906 args->args_proc_mapmem.size,
c4ca3d5a 907 args->args_proc_mapmem.req_addr, &map_addr,
121e8f9b 908 args->args_proc_mapmem.map_attr, pr_ctxt);
157990f0 909 if (!status) {
121e8f9b 910 if (put_user(map_addr, args->args_proc_mapmem.map_addr)) {
c4ca3d5a 911 status = -EINVAL;
6bcc9bee 912 proc_un_map(hprocessor, map_addr, pr_ctxt);
c4ca3d5a
ORL
913 }
914
915 }
916 return status;
917}
918
919/*
920 * ======== procwrap_register_notify ========
921 */
0cd343a4 922u32 procwrap_register_notify(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
923{
924 int status;
925 struct dsp_notification notification;
a534f17b 926 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
927
928 /* Initialize the notification data structure */
ee4317f7 929 notification.name = NULL;
c4ca3d5a
ORL
930 notification.handle = NULL;
931
6bcc9bee 932 status = proc_register_notify(hprocessor,
c4ca3d5a
ORL
933 args->args_proc_register_notify.event_mask,
934 args->args_proc_register_notify.notify_type,
935 &notification);
121e8f9b 936 CP_TO_USR(args->args_proc_register_notify.notification, &notification,
c4ca3d5a
ORL
937 status, 1);
938 return status;
939}
940
941/*
942 * ======== procwrap_reserve_memory ========
943 */
2fa28a51 944u32 procwrap_reserve_memory(union trapped_args *args, void *pr_ctxt)
c4ca3d5a 945{
2fa28a51
FC
946 int status;
947 void *prsv_addr;
a534f17b 948 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
2fa28a51 949
085467b8
RS
950 if ((args->args_proc_rsvmem.size <= 0) ||
951 (args->args_proc_rsvmem.size & (PG_SIZE4K - 1)) != 0)
2fa28a51
FC
952 return -EINVAL;
953
954 status = proc_reserve_memory(hprocessor,
085467b8 955 args->args_proc_rsvmem.size, &prsv_addr,
2fa28a51
FC
956 pr_ctxt);
957 if (!status) {
121e8f9b 958 if (put_user(prsv_addr, args->args_proc_rsvmem.rsv_addr)) {
2fa28a51
FC
959 status = -EINVAL;
960 proc_un_reserve_memory(args->args_proc_rsvmem.
a534f17b 961 processor, prsv_addr, pr_ctxt);
2fa28a51
FC
962 }
963 }
964 return status;
c4ca3d5a
ORL
965}
966
967/*
968 * ======== procwrap_start ========
969 */
0cd343a4 970u32 procwrap_start(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
971{
972 u32 ret;
973
a534f17b 974 ret = proc_start(((struct process_context *)pr_ctxt)->processor);
c4ca3d5a
ORL
975 return ret;
976}
977
978/*
979 * ======== procwrap_un_map ========
980 */
0cd343a4 981u32 procwrap_un_map(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
982{
983 int status;
984
a534f17b 985 status = proc_un_map(((struct process_context *)pr_ctxt)->processor,
c4ca3d5a
ORL
986 args->args_proc_unmapmem.map_addr, pr_ctxt);
987 return status;
988}
989
990/*
991 * ======== procwrap_un_reserve_memory ========
992 */
2fa28a51 993u32 procwrap_un_reserve_memory(union trapped_args *args, void *pr_ctxt)
c4ca3d5a 994{
2fa28a51 995 int status;
a534f17b 996 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
2fa28a51
FC
997
998 status = proc_un_reserve_memory(hprocessor,
121e8f9b 999 args->args_proc_unrsvmem.rsv_addr,
2fa28a51
FC
1000 pr_ctxt);
1001 return status;
c4ca3d5a
ORL
1002}
1003
1004/*
1005 * ======== procwrap_stop ========
1006 */
0cd343a4 1007u32 procwrap_stop(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1008{
1009 u32 ret;
1010
a534f17b 1011 ret = proc_stop(((struct process_context *)pr_ctxt)->processor);
c4ca3d5a
ORL
1012
1013 return ret;
1014}
1015
0624f52f
ER
1016/*
1017 * ======== find_handle =========
1018 */
1019inline void find_node_handle(struct node_res_object **noderes,
1020 void *pr_ctxt, void *hnode)
1021{
1022 rcu_read_lock();
1023 *noderes = idr_find(((struct process_context *)pr_ctxt)->node_id,
8df327c3 1024 (int)hnode - 1);
0624f52f
ER
1025 rcu_read_unlock();
1026 return;
1027}
1028
1029
c4ca3d5a
ORL
1030/*
1031 * ======== nodewrap_allocate ========
1032 */
0cd343a4 1033u32 nodewrap_allocate(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1034{
1035 int status = 0;
1036 struct dsp_uuid node_uuid;
1037 u32 cb_data_size = 0;
121e8f9b 1038 u32 __user *psize = (u32 __user *) args->args_node_allocate.args;
c4ca3d5a
ORL
1039 u8 *pargs = NULL;
1040 struct dsp_nodeattrin proc_attr_in, *attr_in = NULL;
0624f52f 1041 struct node_res_object *node_res;
8df327c3 1042 int nodeid;
a534f17b 1043 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
1044
1045 /* Optional argument */
1046 if (psize) {
1047 if (get_user(cb_data_size, psize))
1048 status = -EPERM;
1049
1050 cb_data_size += sizeof(u32);
157990f0 1051 if (!status) {
c4ca3d5a
ORL
1052 pargs = kmalloc(cb_data_size, GFP_KERNEL);
1053 if (pargs == NULL)
1054 status = -ENOMEM;
1055
1056 }
121e8f9b 1057 CP_FM_USR(pargs, args->args_node_allocate.args, status,
c4ca3d5a
ORL
1058 cb_data_size);
1059 }
1060 CP_FM_USR(&node_uuid, args->args_node_allocate.node_id_ptr, status, 1);
51d5e099 1061 if (status)
c4ca3d5a
ORL
1062 goto func_cont;
1063 /* Optional argument */
1064 if (args->args_node_allocate.attr_in) {
1065 CP_FM_USR(&proc_attr_in, args->args_node_allocate.attr_in,
1066 status, 1);
157990f0 1067 if (!status)
c4ca3d5a
ORL
1068 attr_in = &proc_attr_in;
1069 else
1070 status = -ENOMEM;
1071
1072 }
157990f0 1073 if (!status) {
6bcc9bee 1074 status = node_allocate(hprocessor,
c4ca3d5a 1075 &node_uuid, (struct dsp_cbdata *)pargs,
0624f52f 1076 attr_in, &node_res, pr_ctxt);
c4ca3d5a 1077 }
157990f0 1078 if (!status) {
8df327c3 1079 nodeid = node_res->id + 1;
fbbb4959 1080 CP_TO_USR(args->args_node_allocate.node, &nodeid,
0624f52f 1081 status, 1);
51d5e099 1082 if (status) {
c4ca3d5a 1083 status = -EFAULT;
0624f52f 1084 node_delete(node_res, pr_ctxt);
c4ca3d5a
ORL
1085 }
1086 }
1087func_cont:
1088 kfree(pargs);
1089
1090 return status;
1091}
1092
1093/*
1094 * ======== nodewrap_alloc_msg_buf ========
1095 */
0cd343a4 1096u32 nodewrap_alloc_msg_buf(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1097{
1098 int status = 0;
1099 struct dsp_bufferattr *pattr = NULL;
1100 struct dsp_bufferattr attr;
1101 u8 *pbuffer = NULL;
0624f52f
ER
1102 struct node_res_object *node_res;
1103
1104 find_node_handle(&node_res, pr_ctxt,
ee4317f7 1105 args->args_node_allocmsgbuf.node);
0624f52f
ER
1106
1107 if (!node_res)
1108 return -EFAULT;
c4ca3d5a 1109
fbbb4959 1110 if (!args->args_node_allocmsgbuf.size)
c4ca3d5a
ORL
1111 return -EINVAL;
1112
fbbb4959
RS
1113 if (args->args_node_allocmsgbuf.attr) { /* Optional argument */
1114 CP_FM_USR(&attr, args->args_node_allocmsgbuf.attr, status, 1);
157990f0 1115 if (!status)
c4ca3d5a
ORL
1116 pattr = &attr;
1117
1118 }
e6bf74f0 1119 /* argument */
ee4317f7 1120 CP_FM_USR(&pbuffer, args->args_node_allocmsgbuf.buffer, status, 1);
157990f0 1121 if (!status) {
ee4317f7 1122 status = node_alloc_msg_buf(node_res->node,
fbbb4959 1123 args->args_node_allocmsgbuf.size,
c4ca3d5a
ORL
1124 pattr, &pbuffer);
1125 }
ee4317f7 1126 CP_TO_USR(args->args_node_allocmsgbuf.buffer, &pbuffer, status, 1);
c4ca3d5a
ORL
1127 return status;
1128}
1129
1130/*
1131 * ======== nodewrap_change_priority ========
1132 */
0cd343a4 1133u32 nodewrap_change_priority(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1134{
1135 u32 ret;
0624f52f 1136 struct node_res_object *node_res;
c4ca3d5a 1137
0624f52f 1138 find_node_handle(&node_res, pr_ctxt,
ee4317f7 1139 args->args_node_changepriority.node);
0624f52f
ER
1140
1141 if (!node_res)
1142 return -EFAULT;
1143
ee4317f7 1144 ret = node_change_priority(node_res->node,
c4ca3d5a
ORL
1145 args->args_node_changepriority.prio);
1146
1147 return ret;
1148}
1149
1150/*
1151 * ======== nodewrap_connect ========
1152 */
0cd343a4 1153u32 nodewrap_connect(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1154{
1155 int status = 0;
1156 struct dsp_strmattr attrs;
1157 struct dsp_strmattr *pattrs = NULL;
1158 u32 cb_data_size;
1159 u32 __user *psize = (u32 __user *) args->args_node_connect.conn_param;
1160 u8 *pargs = NULL;
0624f52f
ER
1161 struct node_res_object *node_res1, *node_res2;
1162 struct node_object *node1 = NULL, *node2 = NULL;
1163
ee4317f7 1164 if ((int)args->args_node_connect.node != DSP_HGPPNODE) {
0624f52f 1165 find_node_handle(&node_res1, pr_ctxt,
ee4317f7 1166 args->args_node_connect.node);
0624f52f 1167 if (node_res1)
ee4317f7 1168 node1 = node_res1->node;
0624f52f 1169 } else {
ee4317f7 1170 node1 = args->args_node_connect.node;
0624f52f
ER
1171 }
1172
1173 if ((int)args->args_node_connect.other_node != DSP_HGPPNODE) {
1174 find_node_handle(&node_res2, pr_ctxt,
1175 args->args_node_connect.other_node);
1176 if (node_res2)
ee4317f7 1177 node2 = node_res2->node;
0624f52f
ER
1178 } else {
1179 node2 = args->args_node_connect.other_node;
1180 }
1181
1182 if (!node1 || !node2)
1183 return -EFAULT;
c4ca3d5a
ORL
1184
1185 /* Optional argument */
1186 if (psize) {
1187 if (get_user(cb_data_size, psize))
1188 status = -EPERM;
1189
1190 cb_data_size += sizeof(u32);
157990f0 1191 if (!status) {
c4ca3d5a
ORL
1192 pargs = kmalloc(cb_data_size, GFP_KERNEL);
1193 if (pargs == NULL) {
1194 status = -ENOMEM;
1195 goto func_cont;
1196 }
1197
1198 }
1199 CP_FM_USR(pargs, args->args_node_connect.conn_param, status,
1200 cb_data_size);
51d5e099 1201 if (status)
c4ca3d5a
ORL
1202 goto func_cont;
1203 }
fbbb4959
RS
1204 if (args->args_node_connect.attrs) { /* Optional argument */
1205 CP_FM_USR(&attrs, args->args_node_connect.attrs, status, 1);
157990f0 1206 if (!status)
c4ca3d5a
ORL
1207 pattrs = &attrs;
1208
1209 }
157990f0 1210 if (!status) {
0624f52f 1211 status = node_connect(node1,
c4ca3d5a 1212 args->args_node_connect.stream_id,
0624f52f 1213 node2,
c4ca3d5a
ORL
1214 args->args_node_connect.other_stream,
1215 pattrs, (struct dsp_cbdata *)pargs);
1216 }
1217func_cont:
1218 kfree(pargs);
1219
1220 return status;
1221}
1222
1223/*
1224 * ======== nodewrap_create ========
1225 */
0cd343a4 1226u32 nodewrap_create(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1227{
1228 u32 ret;
0624f52f
ER
1229 struct node_res_object *node_res;
1230
ee4317f7 1231 find_node_handle(&node_res, pr_ctxt, args->args_node_create.node);
c4ca3d5a 1232
0624f52f
ER
1233 if (!node_res)
1234 return -EFAULT;
1235
ee4317f7 1236 ret = node_create(node_res->node);
c4ca3d5a
ORL
1237
1238 return ret;
1239}
1240
1241/*
1242 * ======== nodewrap_delete ========
1243 */
0cd343a4 1244u32 nodewrap_delete(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1245{
1246 u32 ret;
0624f52f
ER
1247 struct node_res_object *node_res;
1248
ee4317f7 1249 find_node_handle(&node_res, pr_ctxt, args->args_node_delete.node);
0624f52f
ER
1250
1251 if (!node_res)
1252 return -EFAULT;
c4ca3d5a 1253
0624f52f 1254 ret = node_delete(node_res, pr_ctxt);
c4ca3d5a
ORL
1255
1256 return ret;
1257}
1258
1259/*
1260 * ======== nodewrap_free_msg_buf ========
1261 */
0cd343a4 1262u32 nodewrap_free_msg_buf(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1263{
1264 int status = 0;
1265 struct dsp_bufferattr *pattr = NULL;
1266 struct dsp_bufferattr attr;
0624f52f
ER
1267 struct node_res_object *node_res;
1268
ee4317f7 1269 find_node_handle(&node_res, pr_ctxt, args->args_node_freemsgbuf.node);
0624f52f
ER
1270
1271 if (!node_res)
1272 return -EFAULT;
1273
fbbb4959
RS
1274 if (args->args_node_freemsgbuf.attr) { /* Optional argument */
1275 CP_FM_USR(&attr, args->args_node_freemsgbuf.attr, status, 1);
157990f0 1276 if (!status)
c4ca3d5a
ORL
1277 pattr = &attr;
1278
1279 }
1280
ee4317f7 1281 if (!args->args_node_freemsgbuf.buffer)
c4ca3d5a
ORL
1282 return -EFAULT;
1283
157990f0 1284 if (!status) {
ee4317f7
RS
1285 status = node_free_msg_buf(node_res->node,
1286 args->args_node_freemsgbuf.buffer,
c4ca3d5a
ORL
1287 pattr);
1288 }
1289
1290 return status;
1291}
1292
1293/*
1294 * ======== nodewrap_get_attr ========
1295 */
0cd343a4 1296u32 nodewrap_get_attr(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1297{
1298 int status = 0;
1299 struct dsp_nodeattr attr;
0624f52f 1300 struct node_res_object *node_res;
c4ca3d5a 1301
ee4317f7 1302 find_node_handle(&node_res, pr_ctxt, args->args_node_getattr.node);
0624f52f
ER
1303
1304 if (!node_res)
1305 return -EFAULT;
1306
ee4317f7 1307 status = node_get_attr(node_res->node, &attr,
c4ca3d5a 1308 args->args_node_getattr.attr_size);
fbbb4959 1309 CP_TO_USR(args->args_node_getattr.attr, &attr, status, 1);
c4ca3d5a
ORL
1310
1311 return status;
1312}
1313
1314/*
1315 * ======== nodewrap_get_message ========
1316 */
0cd343a4 1317u32 nodewrap_get_message(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1318{
1319 int status;
1320 struct dsp_msg msg;
0624f52f
ER
1321 struct node_res_object *node_res;
1322
ee4317f7 1323 find_node_handle(&node_res, pr_ctxt, args->args_node_getmessage.node);
c4ca3d5a 1324
0624f52f
ER
1325 if (!node_res)
1326 return -EFAULT;
1327
ee4317f7 1328 status = node_get_message(node_res->node, &msg,
a534f17b 1329 args->args_node_getmessage.timeout);
c4ca3d5a
ORL
1330
1331 CP_TO_USR(args->args_node_getmessage.message, &msg, status, 1);
1332
1333 return status;
1334}
1335
1336/*
1337 * ======== nodewrap_pause ========
1338 */
0cd343a4 1339u32 nodewrap_pause(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1340{
1341 u32 ret;
0624f52f
ER
1342 struct node_res_object *node_res;
1343
ee4317f7 1344 find_node_handle(&node_res, pr_ctxt, args->args_node_pause.node);
0624f52f
ER
1345
1346 if (!node_res)
1347 return -EFAULT;
c4ca3d5a 1348
ee4317f7 1349 ret = node_pause(node_res->node);
c4ca3d5a
ORL
1350
1351 return ret;
1352}
1353
1354/*
1355 * ======== nodewrap_put_message ========
1356 */
0cd343a4 1357u32 nodewrap_put_message(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1358{
1359 int status = 0;
1360 struct dsp_msg msg;
0624f52f
ER
1361 struct node_res_object *node_res;
1362
ee4317f7 1363 find_node_handle(&node_res, pr_ctxt, args->args_node_putmessage.node);
0624f52f
ER
1364
1365 if (!node_res)
1366 return -EFAULT;
c4ca3d5a
ORL
1367
1368 CP_FM_USR(&msg, args->args_node_putmessage.message, status, 1);
1369
157990f0 1370 if (!status) {
c4ca3d5a 1371 status =
ee4317f7 1372 node_put_message(node_res->node, &msg,
a534f17b 1373 args->args_node_putmessage.timeout);
c4ca3d5a
ORL
1374 }
1375
1376 return status;
1377}
1378
1379/*
1380 * ======== nodewrap_register_notify ========
1381 */
0cd343a4 1382u32 nodewrap_register_notify(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1383{
1384 int status = 0;
1385 struct dsp_notification notification;
0624f52f
ER
1386 struct node_res_object *node_res;
1387
1388 find_node_handle(&node_res, pr_ctxt,
ee4317f7 1389 args->args_node_registernotify.node);
0624f52f
ER
1390
1391 if (!node_res)
1392 return -EFAULT;
c4ca3d5a
ORL
1393
1394 /* Initialize the notification data structure */
ee4317f7 1395 notification.name = NULL;
c4ca3d5a
ORL
1396 notification.handle = NULL;
1397
1398 if (!args->args_proc_register_notify.event_mask)
1399 CP_FM_USR(&notification,
121e8f9b 1400 args->args_proc_register_notify.notification,
c4ca3d5a
ORL
1401 status, 1);
1402
ee4317f7 1403 status = node_register_notify(node_res->node,
c4ca3d5a
ORL
1404 args->args_node_registernotify.event_mask,
1405 args->args_node_registernotify.
1406 notify_type, &notification);
121e8f9b 1407 CP_TO_USR(args->args_node_registernotify.notification, &notification,
c4ca3d5a
ORL
1408 status, 1);
1409 return status;
1410}
1411
1412/*
1413 * ======== nodewrap_run ========
1414 */
0cd343a4 1415u32 nodewrap_run(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1416{
1417 u32 ret;
0624f52f
ER
1418 struct node_res_object *node_res;
1419
ee4317f7 1420 find_node_handle(&node_res, pr_ctxt, args->args_node_run.node);
0624f52f
ER
1421
1422 if (!node_res)
1423 return -EFAULT;
c4ca3d5a 1424
ee4317f7 1425 ret = node_run(node_res->node);
c4ca3d5a
ORL
1426
1427 return ret;
1428}
1429
1430/*
1431 * ======== nodewrap_terminate ========
1432 */
0cd343a4 1433u32 nodewrap_terminate(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1434{
1435 int status;
1436 int tempstatus;
0624f52f 1437 struct node_res_object *node_res;
c4ca3d5a 1438
ee4317f7 1439 find_node_handle(&node_res, pr_ctxt, args->args_node_terminate.node);
0624f52f
ER
1440
1441 if (!node_res)
1442 return -EFAULT;
1443
ee4317f7 1444 status = node_terminate(node_res->node, &tempstatus);
c4ca3d5a 1445
fbbb4959 1446 CP_TO_USR(args->args_node_terminate.status, &tempstatus, status, 1);
c4ca3d5a
ORL
1447
1448 return status;
1449}
1450
1451/*
1452 * ======== nodewrap_get_uuid_props ========
1453 */
0cd343a4 1454u32 nodewrap_get_uuid_props(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1455{
1456 int status = 0;
1457 struct dsp_uuid node_uuid;
1458 struct dsp_ndbprops *pnode_props = NULL;
a534f17b 1459 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a
ORL
1460
1461 CP_FM_USR(&node_uuid, args->args_node_getuuidprops.node_id_ptr, status,
1462 1);
51d5e099 1463 if (status)
c4ca3d5a
ORL
1464 goto func_cont;
1465 pnode_props = kmalloc(sizeof(struct dsp_ndbprops), GFP_KERNEL);
1466 if (pnode_props != NULL) {
1467 status =
6bcc9bee 1468 node_get_uuid_props(hprocessor, &node_uuid, pnode_props);
c4ca3d5a
ORL
1469 CP_TO_USR(args->args_node_getuuidprops.node_props, pnode_props,
1470 status, 1);
1471 } else
1472 status = -ENOMEM;
1473func_cont:
1474 kfree(pnode_props);
1475 return status;
1476}
1477
4ec09714
ER
1478/*
1479 * ======== find_strm_handle =========
1480 */
1481inline void find_strm_handle(struct strm_res_object **strmres,
1482 void *pr_ctxt, void *hstream)
1483{
1484 rcu_read_lock();
1485 *strmres = idr_find(((struct process_context *)pr_ctxt)->stream_id,
084f70ee 1486 (int)hstream - 1);
4ec09714
ER
1487 rcu_read_unlock();
1488 return;
1489}
1490
c4ca3d5a
ORL
1491/*
1492 * ======== strmwrap_allocate_buffer ========
1493 */
0cd343a4 1494u32 strmwrap_allocate_buffer(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1495{
1496 int status;
1497 u8 **ap_buffer = NULL;
1498 u32 num_bufs = args->args_strm_allocatebuffer.num_bufs;
4ec09714
ER
1499 struct strm_res_object *strm_res;
1500
1501 find_strm_handle(&strm_res, pr_ctxt,
ee4317f7 1502 args->args_strm_allocatebuffer.stream);
4ec09714
ER
1503
1504 if (!strm_res)
1505 return -EFAULT;
c4ca3d5a
ORL
1506
1507 if (num_bufs > MAX_BUFS)
1508 return -EINVAL;
1509
1510 ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
dd85c991
KV
1511 if (ap_buffer == NULL)
1512 return -ENOMEM;
c4ca3d5a 1513
4ec09714 1514 status = strm_allocate_buffer(strm_res,
fbbb4959 1515 args->args_strm_allocatebuffer.size,
c4ca3d5a 1516 ap_buffer, num_bufs, pr_ctxt);
157990f0 1517 if (!status) {
c4ca3d5a
ORL
1518 CP_TO_USR(args->args_strm_allocatebuffer.ap_buffer, ap_buffer,
1519 status, num_bufs);
51d5e099 1520 if (status) {
c4ca3d5a 1521 status = -EFAULT;
4ec09714 1522 strm_free_buffer(strm_res,
c4ca3d5a
ORL
1523 ap_buffer, num_bufs, pr_ctxt);
1524 }
1525 }
1526 kfree(ap_buffer);
1527
1528 return status;
1529}
1530
1531/*
1532 * ======== strmwrap_close ========
1533 */
0cd343a4 1534u32 strmwrap_close(union trapped_args *args, void *pr_ctxt)
c4ca3d5a 1535{
4ec09714
ER
1536 struct strm_res_object *strm_res;
1537
ee4317f7 1538 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_close.stream);
4ec09714
ER
1539
1540 if (!strm_res)
1541 return -EFAULT;
1542
1543 return strm_close(strm_res, pr_ctxt);
c4ca3d5a
ORL
1544}
1545
1546/*
1547 * ======== strmwrap_free_buffer ========
1548 */
0cd343a4 1549u32 strmwrap_free_buffer(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1550{
1551 int status = 0;
1552 u8 **ap_buffer = NULL;
1553 u32 num_bufs = args->args_strm_freebuffer.num_bufs;
4ec09714
ER
1554 struct strm_res_object *strm_res;
1555
1556 find_strm_handle(&strm_res, pr_ctxt,
ee4317f7 1557 args->args_strm_freebuffer.stream);
4ec09714
ER
1558
1559 if (!strm_res)
1560 return -EFAULT;
c4ca3d5a
ORL
1561
1562 if (num_bufs > MAX_BUFS)
1563 return -EINVAL;
1564
1565 ap_buffer = kmalloc((num_bufs * sizeof(u8 *)), GFP_KERNEL);
dd85c991
KV
1566 if (ap_buffer == NULL)
1567 return -ENOMEM;
c4ca3d5a
ORL
1568
1569 CP_FM_USR(ap_buffer, args->args_strm_freebuffer.ap_buffer, status,
1570 num_bufs);
1571
4ec09714
ER
1572 if (!status)
1573 status = strm_free_buffer(strm_res,
c4ca3d5a 1574 ap_buffer, num_bufs, pr_ctxt);
4ec09714 1575
c4ca3d5a
ORL
1576 CP_TO_USR(args->args_strm_freebuffer.ap_buffer, ap_buffer, status,
1577 num_bufs);
1578 kfree(ap_buffer);
1579
1580 return status;
1581}
1582
1583/*
1584 * ======== strmwrap_get_event_handle ========
1585 */
0cd343a4 1586u32 __deprecated strmwrap_get_event_handle(union trapped_args * args,
c4ca3d5a
ORL
1587 void *pr_ctxt)
1588{
1589 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1590 return -ENOSYS;
1591}
1592
1593/*
1594 * ======== strmwrap_get_info ========
1595 */
0cd343a4 1596u32 strmwrap_get_info(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1597{
1598 int status = 0;
1599 struct stream_info strm_info;
1600 struct dsp_streaminfo user;
1601 struct dsp_streaminfo *temp;
4ec09714
ER
1602 struct strm_res_object *strm_res;
1603
1604 find_strm_handle(&strm_res, pr_ctxt,
ee4317f7 1605 args->args_strm_getinfo.stream);
4ec09714
ER
1606
1607 if (!strm_res)
1608 return -EFAULT;
c4ca3d5a
ORL
1609
1610 CP_FM_USR(&strm_info, args->args_strm_getinfo.stream_info, status, 1);
1611 temp = strm_info.user_strm;
1612
1613 strm_info.user_strm = &user;
1614
157990f0 1615 if (!status) {
ee4317f7 1616 status = strm_get_info(strm_res->stream,
c4ca3d5a
ORL
1617 &strm_info,
1618 args->args_strm_getinfo.
1619 stream_info_size);
1620 }
1621 CP_TO_USR(temp, strm_info.user_strm, status, 1);
1622 strm_info.user_strm = temp;
1623 CP_TO_USR(args->args_strm_getinfo.stream_info, &strm_info, status, 1);
1624 return status;
1625}
1626
1627/*
1628 * ======== strmwrap_idle ========
1629 */
0cd343a4 1630u32 strmwrap_idle(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1631{
1632 u32 ret;
4ec09714
ER
1633 struct strm_res_object *strm_res;
1634
ee4317f7 1635 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_idle.stream);
c4ca3d5a 1636
4ec09714
ER
1637 if (!strm_res)
1638 return -EFAULT;
1639
ee4317f7 1640 ret = strm_idle(strm_res->stream, args->args_strm_idle.flush_flag);
c4ca3d5a
ORL
1641
1642 return ret;
1643}
1644
1645/*
1646 * ======== strmwrap_issue ========
1647 */
0cd343a4 1648u32 strmwrap_issue(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1649{
1650 int status = 0;
4ec09714
ER
1651 struct strm_res_object *strm_res;
1652
ee4317f7 1653 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_issue.stream);
4ec09714
ER
1654
1655 if (!strm_res)
1656 return -EFAULT;
c4ca3d5a 1657
ee4317f7 1658 if (!args->args_strm_issue.buffer)
c4ca3d5a
ORL
1659 return -EFAULT;
1660
1661 /* No need of doing CP_FM_USR for the user buffer (pbuffer)
1662 as this is done in Bridge internal function bridge_chnl_add_io_req
1663 in chnl_sm.c */
ee4317f7
RS
1664 status = strm_issue(strm_res->stream,
1665 args->args_strm_issue.buffer,
fbbb4959
RS
1666 args->args_strm_issue.bytes,
1667 args->args_strm_issue.buf_size,
b4da7fc3 1668 args->args_strm_issue.arg);
c4ca3d5a
ORL
1669
1670 return status;
1671}
1672
1673/*
1674 * ======== strmwrap_open ========
1675 */
0cd343a4 1676u32 strmwrap_open(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1677{
1678 int status = 0;
1679 struct strm_attr attr;
4ec09714 1680 struct strm_res_object *strm_res_obj;
c4ca3d5a 1681 struct dsp_streamattrin strm_attr_in;
0624f52f 1682 struct node_res_object *node_res;
084f70ee 1683 int strmid;
0624f52f 1684
ee4317f7 1685 find_node_handle(&node_res, pr_ctxt, args->args_strm_open.node);
0624f52f
ER
1686
1687 if (!node_res)
1688 return -EFAULT;
c4ca3d5a
ORL
1689
1690 CP_FM_USR(&attr, args->args_strm_open.attr_in, status, 1);
1691
1692 if (attr.stream_attr_in != NULL) { /* Optional argument */
1693 CP_FM_USR(&strm_attr_in, attr.stream_attr_in, status, 1);
157990f0 1694 if (!status) {
c4ca3d5a
ORL
1695 attr.stream_attr_in = &strm_attr_in;
1696 if (attr.stream_attr_in->strm_mode == STRMMODE_LDMA)
1697 return -ENOSYS;
1698 }
1699
1700 }
ee4317f7 1701 status = strm_open(node_res->node,
c4ca3d5a 1702 args->args_strm_open.direction,
4ec09714 1703 args->args_strm_open.index, &attr, &strm_res_obj,
c4ca3d5a 1704 pr_ctxt);
084f70ee
ER
1705 if (!status) {
1706 strmid = strm_res_obj->id + 1;
fbbb4959 1707 CP_TO_USR(args->args_strm_open.stream, &strmid, status, 1);
084f70ee 1708 }
c4ca3d5a
ORL
1709 return status;
1710}
1711
1712/*
1713 * ======== strmwrap_reclaim ========
1714 */
0cd343a4 1715u32 strmwrap_reclaim(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1716{
1717 int status = 0;
1718 u8 *buf_ptr;
1719 u32 ul_bytes;
1720 u32 dw_arg;
1721 u32 ul_buf_size;
4ec09714
ER
1722 struct strm_res_object *strm_res;
1723
ee4317f7 1724 find_strm_handle(&strm_res, pr_ctxt, args->args_strm_reclaim.stream);
4ec09714
ER
1725
1726 if (!strm_res)
1727 return -EFAULT;
c4ca3d5a 1728
ee4317f7 1729 status = strm_reclaim(strm_res->stream, &buf_ptr,
c4ca3d5a
ORL
1730 &ul_bytes, &ul_buf_size, &dw_arg);
1731 CP_TO_USR(args->args_strm_reclaim.buf_ptr, &buf_ptr, status, 1);
1732 CP_TO_USR(args->args_strm_reclaim.bytes, &ul_bytes, status, 1);
fbbb4959 1733 CP_TO_USR(args->args_strm_reclaim.arg, &dw_arg, status, 1);
c4ca3d5a
ORL
1734
1735 if (args->args_strm_reclaim.buf_size_ptr != NULL) {
1736 CP_TO_USR(args->args_strm_reclaim.buf_size_ptr, &ul_buf_size,
1737 status, 1);
1738 }
1739
1740 return status;
1741}
1742
1743/*
1744 * ======== strmwrap_register_notify ========
1745 */
0cd343a4 1746u32 strmwrap_register_notify(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1747{
1748 int status = 0;
1749 struct dsp_notification notification;
4ec09714
ER
1750 struct strm_res_object *strm_res;
1751
1752 find_strm_handle(&strm_res, pr_ctxt,
ee4317f7 1753 args->args_strm_registernotify.stream);
4ec09714
ER
1754
1755 if (!strm_res)
1756 return -EFAULT;
c4ca3d5a
ORL
1757
1758 /* Initialize the notification data structure */
ee4317f7 1759 notification.name = NULL;
c4ca3d5a
ORL
1760 notification.handle = NULL;
1761
ee4317f7 1762 status = strm_register_notify(strm_res->stream,
c4ca3d5a
ORL
1763 args->args_strm_registernotify.event_mask,
1764 args->args_strm_registernotify.
1765 notify_type, &notification);
121e8f9b 1766 CP_TO_USR(args->args_strm_registernotify.notification, &notification,
c4ca3d5a
ORL
1767 status, 1);
1768
1769 return status;
1770}
1771
1772/*
1773 * ======== strmwrap_select ========
1774 */
0cd343a4 1775u32 strmwrap_select(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1776{
1777 u32 mask;
1778 struct strm_object *strm_tab[MAX_STREAMS];
1779 int status = 0;
4ec09714
ER
1780 struct strm_res_object *strm_res;
1781 int *ids[MAX_STREAMS];
1782 int i;
c4ca3d5a
ORL
1783
1784 if (args->args_strm_select.strm_num > MAX_STREAMS)
1785 return -EINVAL;
1786
4ec09714
ER
1787 CP_FM_USR(ids, args->args_strm_select.stream_tab, status,
1788 args->args_strm_select.strm_num);
1789
1790 if (status)
1791 return status;
1792
1793 for (i = 0; i < args->args_strm_select.strm_num; i++) {
1794 find_strm_handle(&strm_res, pr_ctxt, ids[i]);
1795
1796 if (!strm_res)
1797 return -EFAULT;
1798
ee4317f7 1799 strm_tab[i] = strm_res->stream;
4ec09714
ER
1800 }
1801
157990f0 1802 if (!status) {
c4ca3d5a 1803 status = strm_select(strm_tab, args->args_strm_select.strm_num,
a534f17b 1804 &mask, args->args_strm_select.timeout);
c4ca3d5a 1805 }
fbbb4959 1806 CP_TO_USR(args->args_strm_select.mask, &mask, status, 1);
c4ca3d5a
ORL
1807 return status;
1808}
1809
1810/* CMM */
1811
1812/*
1813 * ======== cmmwrap_calloc_buf ========
1814 */
0cd343a4 1815u32 __deprecated cmmwrap_calloc_buf(union trapped_args * args, void *pr_ctxt)
c4ca3d5a
ORL
1816{
1817 /* This operation is done in kernel */
1818 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1819 return -ENOSYS;
1820}
1821
1822/*
1823 * ======== cmmwrap_free_buf ========
1824 */
0cd343a4 1825u32 __deprecated cmmwrap_free_buf(union trapped_args * args, void *pr_ctxt)
c4ca3d5a
ORL
1826{
1827 /* This operation is done in kernel */
1828 pr_err("%s: deprecated dspbridge ioctl\n", __func__);
1829 return -ENOSYS;
1830}
1831
1832/*
1833 * ======== cmmwrap_get_handle ========
1834 */
0cd343a4 1835u32 cmmwrap_get_handle(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1836{
1837 int status = 0;
1838 struct cmm_object *hcmm_mgr;
a534f17b 1839 void *hprocessor = ((struct process_context *)pr_ctxt)->processor;
c4ca3d5a 1840
6bcc9bee 1841 status = cmm_get_handle(hprocessor, &hcmm_mgr);
c4ca3d5a 1842
fbbb4959 1843 CP_TO_USR(args->args_cmm_gethandle.cmm_mgr, &hcmm_mgr, status, 1);
c4ca3d5a
ORL
1844
1845 return status;
1846}
1847
1848/*
1849 * ======== cmmwrap_get_info ========
1850 */
0cd343a4 1851u32 cmmwrap_get_info(union trapped_args *args, void *pr_ctxt)
c4ca3d5a
ORL
1852{
1853 int status = 0;
1854 struct cmm_info cmm_info_obj;
1855
085467b8 1856 status = cmm_get_info(args->args_cmm_getinfo.cmm_mgr, &cmm_info_obj);
c4ca3d5a
ORL
1857
1858 CP_TO_USR(args->args_cmm_getinfo.cmm_info_obj, &cmm_info_obj, status,
1859 1);
1860
1861 return status;
1862}
This page took 0.248613 seconds and 5 git commands to generate.