1/*
2 * node.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * DSP/BIOS Bridge Node Manager.
7 *
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19#include <linux/types.h>
20#include <linux/bitmap.h>
21#include <linux/list.h>
22
23/*  ----------------------------------- Host OS */
24#include <dspbridge/host_os.h>
25
26/*  ----------------------------------- DSP/BIOS Bridge */
27#include <dspbridge/dbdefs.h>
28
29/*  ----------------------------------- OS Adaptation Layer */
30#include <dspbridge/memdefs.h>
31#include <dspbridge/proc.h>
32#include <dspbridge/strm.h>
33#include <dspbridge/sync.h>
34#include <dspbridge/ntfy.h>
35
36/*  ----------------------------------- Platform Manager */
37#include <dspbridge/cmm.h>
38#include <dspbridge/cod.h>
39#include <dspbridge/dev.h>
40#include <dspbridge/msg.h>
41
42/*  ----------------------------------- Resource Manager */
43#include <dspbridge/dbdcd.h>
44#include <dspbridge/disp.h>
45#include <dspbridge/rms_sh.h>
46
47/*  ----------------------------------- Link Driver */
48#include <dspbridge/dspdefs.h>
49#include <dspbridge/dspioctl.h>
50
51/*  ----------------------------------- Others */
52#include <dspbridge/uuidutil.h>
53
54/*  ----------------------------------- This */
55#include <dspbridge/nodepriv.h>
56#include <dspbridge/node.h>
57#include <dspbridge/dmm.h>
58
59/* Static/Dynamic Loader includes */
60#include <dspbridge/dbll.h>
61#include <dspbridge/nldr.h>
62
63#include <dspbridge/drv.h>
64#include <dspbridge/resourcecleanup.h>
65#include <_tiomap.h>
66
67#include <dspbridge/dspdeh.h>
68
69#define HOSTPREFIX	  "/host"
70#define PIPEPREFIX	  "/dbpipe"
71
72#define MAX_INPUTS(h)  \
73		((h)->dcd_props.obj_data.node_obj.ndb_props.num_input_streams)
74#define MAX_OUTPUTS(h) \
75		((h)->dcd_props.obj_data.node_obj.ndb_props.num_output_streams)
76
77#define NODE_GET_PRIORITY(h) ((h)->prio)
78#define NODE_SET_PRIORITY(hnode, prio) ((hnode)->prio = prio)
79#define NODE_SET_STATE(hnode, state) ((hnode)->node_state = state)
80
81#define MAXPIPES	100	/* Max # of /pipe connections (CSL limit) */
82#define MAXDEVSUFFIXLEN 2	/* Max(Log base 10 of MAXPIPES, MAXSTREAMS) */
83
84#define PIPENAMELEN     (sizeof(PIPEPREFIX) + MAXDEVSUFFIXLEN)
85#define HOSTNAMELEN     (sizeof(HOSTPREFIX) + MAXDEVSUFFIXLEN)
86
87#define MAXDEVNAMELEN	32	/* dsp_ndbprops.ac_name size */
88#define CREATEPHASE	1
89#define EXECUTEPHASE	2
90#define DELETEPHASE	3
91
92/* Define default STRM parameters */
93/*
94 *  TBD: Put in header file, make global DSP_STRMATTRS with defaults,
95 *  or make defaults configurable.
96 */
97#define DEFAULTBUFSIZE		32
98#define DEFAULTNBUFS		2
99#define DEFAULTSEGID		0
100#define DEFAULTALIGNMENT	0
101#define DEFAULTTIMEOUT		10000
102
103#define RMSQUERYSERVER		0
104#define RMSCONFIGURESERVER	1
105#define RMSCREATENODE		2
106#define RMSEXECUTENODE		3
107#define RMSDELETENODE		4
108#define RMSCHANGENODEPRIORITY	5
109#define RMSREADMEMORY		6
110#define RMSWRITEMEMORY		7
111#define RMSCOPY			8
112#define MAXTIMEOUT		2000
113
114#define NUMRMSFXNS		9
115
116#define PWR_TIMEOUT		500	/* default PWR timeout in msec */
117
118#define STACKSEGLABEL "L1DSRAM_HEAP"	/* Label for DSP Stack Segment Addr */
119
120/*
121 *  ======== node_mgr ========
122 */
123struct node_mgr {
124	struct dev_object *dev_obj;	/* Device object */
125	/* Function interface to Bridge driver */
126	struct bridge_drv_interface *intf_fxns;
127	struct dcd_manager *dcd_mgr;	/* Proc/Node data manager */
128	struct disp_object *disp_obj;	/* Node dispatcher */
129	struct list_head node_list;	/* List of all allocated nodes */
130	u32 num_nodes;		/* Number of nodes in node_list */
131	u32 num_created;	/* Number of nodes *created* on DSP */
132	DECLARE_BITMAP(pipe_map, MAXPIPES); /* Pipe connection bitmap */
133	DECLARE_BITMAP(pipe_done_map, MAXPIPES); /* Pipes that are half free */
134	/* Channel allocation bitmap */
135	DECLARE_BITMAP(chnl_map, CHNL_MAXCHANNELS);
136	/* DMA Channel allocation bitmap */
137	DECLARE_BITMAP(dma_chnl_map, CHNL_MAXCHANNELS);
138	/* Zero-Copy Channel alloc bitmap */
139	DECLARE_BITMAP(zc_chnl_map, CHNL_MAXCHANNELS);
140	struct ntfy_object *ntfy_obj;	/* Manages registered notifications */
141	struct mutex node_mgr_lock;	/* For critical sections */
142	u32 fxn_addrs[NUMRMSFXNS];	/* RMS function addresses */
143	struct msg_mgr *msg_mgr_obj;
144
145	/* Processor properties needed by Node Dispatcher */
146	u32 num_chnls;		/* Total number of channels */
147	u32 chnl_offset;	/* Offset of chnl ids rsvd for RMS */
148	u32 chnl_buf_size;	/* Buffer size for data to RMS */
149	int proc_family;	/* eg, 5000 */
150	int proc_type;		/* eg, 5510 */
151	u32 dsp_word_size;	/* Size of DSP word on host bytes */
152	u32 dsp_data_mau_size;	/* Size of DSP data MAU */
153	u32 dsp_mau_size;	/* Size of MAU */
154	s32 min_pri;		/* Minimum runtime priority for node */
155	s32 max_pri;		/* Maximum runtime priority for node */
156
157	struct strm_mgr *strm_mgr_obj;	/* STRM manager */
158
159	/* Loader properties */
160	struct nldr_object *nldr_obj;	/* Handle to loader */
161	struct node_ldr_fxns nldr_fxns;	/* Handle to loader functions */
162};
163
164/*
165 *  ======== connecttype ========
166 */
167enum connecttype {
168	NOTCONNECTED = 0,
169	NODECONNECT,
170	HOSTCONNECT,
171	DEVICECONNECT,
172};
173
174/*
175 *  ======== stream_chnl ========
176 */
177struct stream_chnl {
178	enum connecttype type;	/* Type of stream connection */
179	u32 dev_id;		/* pipe or channel id */
180};
181
182/*
183 *  ======== node_object ========
184 */
185struct node_object {
186	struct list_head list_elem;
187	struct node_mgr *node_mgr;	/* The manager of this node */
188	struct proc_object *processor;	/* Back pointer to processor */
189	struct dsp_uuid node_uuid;	/* Node's ID */
190	s32 prio;		/* Node's current priority */
191	u32 timeout;		/* Timeout for blocking NODE calls */
192	u32 heap_size;		/* Heap Size */
193	u32 dsp_heap_virt_addr;	/* Heap Size */
194	u32 gpp_heap_virt_addr;	/* Heap Size */
195	enum node_type ntype;	/* Type of node: message, task, etc */
196	enum node_state node_state;	/* NODE_ALLOCATED, NODE_CREATED, ... */
197	u32 num_inputs;		/* Current number of inputs */
198	u32 num_outputs;	/* Current number of outputs */
199	u32 max_input_index;	/* Current max input stream index */
200	u32 max_output_index;	/* Current max output stream index */
201	struct stream_chnl *inputs;	/* Node's input streams */
202	struct stream_chnl *outputs;	/* Node's output streams */
203	struct node_createargs create_args;	/* Args for node create func */
204	nodeenv node_env;	/* Environment returned by RMS */
205	struct dcd_genericobj dcd_props;	/* Node properties from DCD */
206	struct dsp_cbdata *args;	/* Optional args to pass to node */
207	struct ntfy_object *ntfy_obj;	/* Manages registered notifications */
208	char *str_dev_name;	/* device name, if device node */
209	struct sync_object *sync_done;	/* Synchronize node_terminate */
210	s32 exit_status;	/* execute function return status */
211
212	/* Information needed for node_get_attr() */
213	void *device_owner;	/* If dev node, task that owns it */
214	u32 num_gpp_inputs;	/* Current # of from GPP streams */
215	u32 num_gpp_outputs;	/* Current # of to GPP streams */
216	/* Current stream connections */
217	struct dsp_streamconnect *stream_connect;
218
219	/* Message queue */
220	struct msg_queue *msg_queue_obj;
221
222	/* These fields used for SM messaging */
223	struct cmm_xlatorobject *xlator;	/* Node's SM addr translator */
224
225	/* Handle to pass to dynamic loader */
226	struct nldr_nodeobject *nldr_node_obj;
227	bool loaded;		/* Code is (dynamically) loaded */
228	bool phase_split;	/* Phases split in many libs or ovly */
229
230};
231
232/* Default buffer attributes */
233static struct dsp_bufferattr node_dfltbufattrs = {
234	.cb_struct = 0,
235	.segment_id = 1,
236	.buf_alignment = 0,
237};
238
239static void delete_node(struct node_object *hnode,
240			struct process_context *pr_ctxt);
241static void delete_node_mgr(struct node_mgr *hnode_mgr);
242static void fill_stream_connect(struct node_object *node1,
243				struct node_object *node2, u32 stream1,
244				u32 stream2);
245static void fill_stream_def(struct node_object *hnode,
246			    struct node_strmdef *pstrm_def,
247			    struct dsp_strmattr *pattrs);
248static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream);
249static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr,
250				  u32 phase);
251static int get_node_props(struct dcd_manager *hdcd_mgr,
252				 struct node_object *hnode,
253				 const struct dsp_uuid *node_uuid,
254				 struct dcd_genericobj *dcd_prop);
255static int get_proc_props(struct node_mgr *hnode_mgr,
256				 struct dev_object *hdev_obj);
257static int get_rms_fxns(struct node_mgr *hnode_mgr);
258static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
259		u32 ul_num_bytes, u32 mem_space);
260static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
261		     u32 ul_num_bytes, u32 mem_space);
262
263/* Dynamic loader functions. */
264static struct node_ldr_fxns nldr_fxns = {
265	nldr_allocate,
266	nldr_create,
267	nldr_delete,
268	nldr_get_fxn_addr,
269	nldr_load,
270	nldr_unload,
271};
272
273enum node_state node_get_state(void *hnode)
274{
275	struct node_object *pnode = (struct node_object *)hnode;
276	if (!pnode)
277		return -1;
278	return pnode->node_state;
279}
280
281/*
282 *  ======== node_allocate ========
283 *  Purpose:
284 *      Allocate GPP resources to manage a node on the DSP.
285 */
286int node_allocate(struct proc_object *hprocessor,
287			const struct dsp_uuid *node_uuid,
288			const struct dsp_cbdata *pargs,
289			const struct dsp_nodeattrin *attr_in,
290			struct node_res_object **noderes,
291			struct process_context *pr_ctxt)
292{
293	struct node_mgr *hnode_mgr;
294	struct dev_object *hdev_obj;
295	struct node_object *pnode = NULL;
296	enum node_type node_type = NODE_TASK;
297	struct node_msgargs *pmsg_args;
298	struct node_taskargs *ptask_args;
299	u32 num_streams;
300	struct bridge_drv_interface *intf_fxns;
301	int status = 0;
302	struct cmm_object *hcmm_mgr = NULL;	/* Shared memory manager hndl */
303	u32 proc_id;
304	u32 pul_value;
305	u32 dynext_base;
306	u32 off_set = 0;
307	u32 ul_stack_seg_addr, ul_stack_seg_val;
308	u32 ul_gpp_mem_base;
309	struct cfg_hostres *host_res;
310	struct bridge_dev_context *pbridge_context;
311	u32 mapped_addr = 0;
312	u32 map_attrs = 0x0;
313	struct dsp_processorstate proc_state;
314#ifdef DSP_DMM_DEBUG
315	struct dmm_object *dmm_mgr;
316	struct proc_object *p_proc_object = (struct proc_object *)hprocessor;
317#endif
318
319	void *node_res;
320
321	*noderes = NULL;
322
323	status = proc_get_processor_id(hprocessor, &proc_id);
324
325	if (proc_id != DSP_UNIT)
326		goto func_end;
327
328	status = proc_get_dev_object(hprocessor, &hdev_obj);
329	if (!status) {
330		status = dev_get_node_manager(hdev_obj, &hnode_mgr);
331		if (hnode_mgr == NULL)
332			status = -EPERM;
333
334	}
335
336	if (status)
337		goto func_end;
338
339	status = dev_get_bridge_context(hdev_obj, &pbridge_context);
340	if (!pbridge_context) {
341		status = -EFAULT;
342		goto func_end;
343	}
344
345	status = proc_get_state(hprocessor, &proc_state,
346				sizeof(struct dsp_processorstate));
347	if (status)
348		goto func_end;
349	/* If processor is in error state then don't attempt
350	   to send the message */
351	if (proc_state.proc_state == PROC_ERROR) {
352		status = -EPERM;
353		goto func_end;
354	}
355
356	/* Assuming that 0 is not a valid function address */
357	if (hnode_mgr->fxn_addrs[0] == 0) {
358		/* No RMS on target - we currently can't handle this */
359		pr_err("%s: Failed, no RMS in base image\n", __func__);
360		status = -EPERM;
361	} else {
362		/* Validate attr_in fields, if non-NULL */
363		if (attr_in) {
364			/* Check if attr_in->prio is within range */
365			if (attr_in->prio < hnode_mgr->min_pri ||
366			    attr_in->prio > hnode_mgr->max_pri)
367				status = -EDOM;
368		}
369	}
370	/* Allocate node object and fill in */
371	if (status)
372		goto func_end;
373
374	pnode = kzalloc(sizeof(struct node_object), GFP_KERNEL);
375	if (pnode == NULL) {
376		status = -ENOMEM;
377		goto func_end;
378	}
379	pnode->node_mgr = hnode_mgr;
380	/* This critical section protects get_node_props */
381	mutex_lock(&hnode_mgr->node_mgr_lock);
382
383	/* Get dsp_ndbprops from node database */
384	status = get_node_props(hnode_mgr->dcd_mgr, pnode, node_uuid,
385				&(pnode->dcd_props));
386	if (status)
387		goto func_cont;
388
389	pnode->node_uuid = *node_uuid;
390	pnode->processor = hprocessor;
391	pnode->ntype = pnode->dcd_props.obj_data.node_obj.ndb_props.ntype;
392	pnode->timeout = pnode->dcd_props.obj_data.node_obj.ndb_props.timeout;
393	pnode->prio = pnode->dcd_props.obj_data.node_obj.ndb_props.prio;
394
395	/* Currently only C64 DSP builds support Node Dynamic * heaps */
396	/* Allocate memory for node heap */
397	pnode->create_args.asa.task_arg_obj.heap_size = 0;
398	pnode->create_args.asa.task_arg_obj.dsp_heap_addr = 0;
399	pnode->create_args.asa.task_arg_obj.dsp_heap_res_addr = 0;
400	pnode->create_args.asa.task_arg_obj.gpp_heap_addr = 0;
401	if (!attr_in)
402		goto func_cont;
403
404	/* Check if we have a user allocated node heap */
405	if (!(attr_in->pgpp_virt_addr))
406		goto func_cont;
407
408	/* check for page aligned Heap size */
409	if (((attr_in->heap_size) & (PG_SIZE4K - 1))) {
410		pr_err("%s: node heap size not aligned to 4K, size = 0x%x \n",
411		       __func__, attr_in->heap_size);
412		status = -EINVAL;
413	} else {
414		pnode->create_args.asa.task_arg_obj.heap_size =
415		    attr_in->heap_size;
416		pnode->create_args.asa.task_arg_obj.gpp_heap_addr =
417		    (u32) attr_in->pgpp_virt_addr;
418	}
419	if (status)
420		goto func_cont;
421
422	status = proc_reserve_memory(hprocessor,
423				     pnode->create_args.asa.task_arg_obj.
424				     heap_size + PAGE_SIZE,
425				     (void **)&(pnode->create_args.asa.
426					task_arg_obj.dsp_heap_res_addr),
427				     pr_ctxt);
428	if (status) {
429		pr_err("%s: Failed to reserve memory for heap: 0x%x\n",
430		       __func__, status);
431		goto func_cont;
432	}
433#ifdef DSP_DMM_DEBUG
434	status = dmm_get_handle(p_proc_object, &dmm_mgr);
435	if (!dmm_mgr) {
436		status = DSP_EHANDLE;
437		goto func_cont;
438	}
439
440	dmm_mem_map_dump(dmm_mgr);
441#endif
442
443	map_attrs |= DSP_MAPLITTLEENDIAN;
444	map_attrs |= DSP_MAPELEMSIZE32;
445	map_attrs |= DSP_MAPVIRTUALADDR;
446	status = proc_map(hprocessor, (void *)attr_in->pgpp_virt_addr,
447			  pnode->create_args.asa.task_arg_obj.heap_size,
448			  (void *)pnode->create_args.asa.task_arg_obj.
449			  dsp_heap_res_addr, (void **)&mapped_addr, map_attrs,
450			  pr_ctxt);
451	if (status)
452		pr_err("%s: Failed to map memory for Heap: 0x%x\n",
453		       __func__, status);
454	else
455		pnode->create_args.asa.task_arg_obj.dsp_heap_addr =
456		    (u32) mapped_addr;
457
458func_cont:
459	mutex_unlock(&hnode_mgr->node_mgr_lock);
460	if (attr_in != NULL) {
461		/* Overrides of NBD properties */
462		pnode->timeout = attr_in->timeout;
463		pnode->prio = attr_in->prio;
464	}
465	/* Create object to manage notifications */
466	if (!status) {
467		pnode->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
468							GFP_KERNEL);
469		if (pnode->ntfy_obj)
470			ntfy_init(pnode->ntfy_obj);
471		else
472			status = -ENOMEM;
473	}
474
475	if (!status) {
476		node_type = node_get_type(pnode);
477		/*  Allocate dsp_streamconnect array for device, task, and
478		 *  dais socket nodes. */
479		if (node_type != NODE_MESSAGE) {
480			num_streams = MAX_INPUTS(pnode) + MAX_OUTPUTS(pnode);
481			pnode->stream_connect = kzalloc(num_streams *
482					sizeof(struct dsp_streamconnect),
483					GFP_KERNEL);
484			if (num_streams > 0 && pnode->stream_connect == NULL)
485				status = -ENOMEM;
486
487		}
488		if (!status && (node_type == NODE_TASK ||
489					      node_type == NODE_DAISSOCKET)) {
490			/* Allocate arrays for maintainig stream connections */
491			pnode->inputs = kzalloc(MAX_INPUTS(pnode) *
492					sizeof(struct stream_chnl), GFP_KERNEL);
493			pnode->outputs = kzalloc(MAX_OUTPUTS(pnode) *
494					sizeof(struct stream_chnl), GFP_KERNEL);
495			ptask_args = &(pnode->create_args.asa.task_arg_obj);
496			ptask_args->strm_in_def = kzalloc(MAX_INPUTS(pnode) *
497						sizeof(struct node_strmdef),
498						GFP_KERNEL);
499			ptask_args->strm_out_def = kzalloc(MAX_OUTPUTS(pnode) *
500						sizeof(struct node_strmdef),
501						GFP_KERNEL);
502			if ((MAX_INPUTS(pnode) > 0 && (pnode->inputs == NULL ||
503						       ptask_args->strm_in_def
504						       == NULL))
505			    || (MAX_OUTPUTS(pnode) > 0
506				&& (pnode->outputs == NULL
507				    || ptask_args->strm_out_def == NULL)))
508				status = -ENOMEM;
509		}
510	}
511	if (!status && (node_type != NODE_DEVICE)) {
512		/* Create an event that will be posted when RMS_EXIT is
513		 * received. */
514		pnode->sync_done = kzalloc(sizeof(struct sync_object),
515								GFP_KERNEL);
516		if (pnode->sync_done)
517			sync_init_event(pnode->sync_done);
518		else
519			status = -ENOMEM;
520
521		if (!status) {
522			/*Get the shared mem mgr for this nodes dev object */
523			status = cmm_get_handle(hprocessor, &hcmm_mgr);
524			if (!status) {
525				/* Allocate a SM addr translator for this node
526				 * w/ deflt attr */
527				status = cmm_xlator_create(&pnode->xlator,
528							   hcmm_mgr, NULL);
529			}
530		}
531		if (!status) {
532			/* Fill in message args */
533			if ((pargs != NULL) && (pargs->cb_data > 0)) {
534				pmsg_args =
535				    &(pnode->create_args.asa.node_msg_args);
536				pmsg_args->pdata = kzalloc(pargs->cb_data,
537								GFP_KERNEL);
538				if (pmsg_args->pdata == NULL) {
539					status = -ENOMEM;
540				} else {
541					pmsg_args->arg_length = pargs->cb_data;
542					memcpy(pmsg_args->pdata,
543					       pargs->node_data,
544					       pargs->cb_data);
545				}
546			}
547		}
548	}
549
550	if (!status && node_type != NODE_DEVICE) {
551		/* Create a message queue for this node */
552		intf_fxns = hnode_mgr->intf_fxns;
553		status =
554		    (*intf_fxns->msg_create_queue) (hnode_mgr->msg_mgr_obj,
555							&pnode->msg_queue_obj,
556							0,
557							pnode->create_args.asa.
558							node_msg_args.max_msgs,
559							pnode);
560	}
561
562	if (!status) {
563		/* Create object for dynamic loading */
564
565		status = hnode_mgr->nldr_fxns.allocate(hnode_mgr->nldr_obj,
566							   (void *)pnode,
567							   &pnode->dcd_props.
568							   obj_data.node_obj,
569							   &pnode->
570							   nldr_node_obj,
571							   &pnode->phase_split);
572	}
573
574	/* Compare value read from Node Properties and check if it is same as
575	 * STACKSEGLABEL, if yes read the Address of STACKSEGLABEL, calculate
576	 * GPP Address, Read the value in that address and override the
577	 * stack_seg value in task args */
578	if (!status &&
579	    (char *)pnode->dcd_props.obj_data.node_obj.ndb_props.
580	    stack_seg_name != NULL) {
581		if (strcmp((char *)
582			   pnode->dcd_props.obj_data.node_obj.ndb_props.
583			   stack_seg_name, STACKSEGLABEL) == 0) {
584			status =
585			    hnode_mgr->nldr_fxns.
586			    get_fxn_addr(pnode->nldr_node_obj, "DYNEXT_BEG",
587					     &dynext_base);
588			if (status)
589				pr_err("%s: Failed to get addr for DYNEXT_BEG"
590				       " status = 0x%x\n", __func__, status);
591
592			status =
593			    hnode_mgr->nldr_fxns.
594			    get_fxn_addr(pnode->nldr_node_obj,
595					     "L1DSRAM_HEAP", &pul_value);
596
597			if (status)
598				pr_err("%s: Failed to get addr for L1DSRAM_HEAP"
599				       " status = 0x%x\n", __func__, status);
600
601			host_res = pbridge_context->resources;
602			if (!host_res)
603				status = -EPERM;
604
605			if (status) {
606				pr_err("%s: Failed to get host resource, status"
607				       " = 0x%x\n", __func__, status);
608				goto func_end;
609			}
610
611			ul_gpp_mem_base = (u32) host_res->mem_base[1];
612			off_set = pul_value - dynext_base;
613			ul_stack_seg_addr = ul_gpp_mem_base + off_set;
614			ul_stack_seg_val = readl(ul_stack_seg_addr);
615
616			dev_dbg(bridge, "%s: StackSegVal = 0x%x, StackSegAddr ="
617				" 0x%x\n", __func__, ul_stack_seg_val,
618				ul_stack_seg_addr);
619
620			pnode->create_args.asa.task_arg_obj.stack_seg =
621			    ul_stack_seg_val;
622
623		}
624	}
625
626	if (!status) {
627		/* Add the node to the node manager's list of allocated
628		 * nodes. */
629		NODE_SET_STATE(pnode, NODE_ALLOCATED);
630
631		mutex_lock(&hnode_mgr->node_mgr_lock);
632
633		list_add_tail(&pnode->list_elem, &hnode_mgr->node_list);
634		++(hnode_mgr->num_nodes);
635
636		/* Exit critical section */
637		mutex_unlock(&hnode_mgr->node_mgr_lock);
638
639		/* Preset this to assume phases are split
640		 * (for overlay and dll) */
641		pnode->phase_split = true;
642
643		/* Notify all clients registered for DSP_NODESTATECHANGE. */
644		proc_notify_all_clients(hprocessor, DSP_NODESTATECHANGE);
645	} else {
646		/* Cleanup */
647		if (pnode)
648			delete_node(pnode, pr_ctxt);
649
650	}
651
652	if (!status) {
653		status = drv_insert_node_res_element(pnode, &node_res, pr_ctxt);
654		if (status) {
655			delete_node(pnode, pr_ctxt);
656			goto func_end;
657		}
658
659		*noderes = (struct node_res_object *)node_res;
660		drv_proc_node_update_heap_status(node_res, true);
661		drv_proc_node_update_status(node_res, true);
662	}
663func_end:
664	dev_dbg(bridge, "%s: hprocessor: %p pNodeId: %p pargs: %p attr_in: %p "
665		"node_res: %p status: 0x%x\n", __func__, hprocessor,
666		node_uuid, pargs, attr_in, noderes, status);
667	return status;
668}
669
670/*
671 *  ======== node_alloc_msg_buf ========
672 *  Purpose:
673 *      Allocates buffer for zero copy messaging.
674 */
675DBAPI node_alloc_msg_buf(struct node_object *hnode, u32 usize,
676			 struct dsp_bufferattr *pattr,
677			 u8 **pbuffer)
678{
679	struct node_object *pnode = (struct node_object *)hnode;
680	int status = 0;
681	bool va_flag = false;
682	bool set_info;
683	u32 proc_id;
684
685	if (!pnode)
686		status = -EFAULT;
687	else if (node_get_type(pnode) == NODE_DEVICE)
688		status = -EPERM;
689
690	if (status)
691		goto func_end;
692
693	if (pattr == NULL)
694		pattr = &node_dfltbufattrs;	/* set defaults */
695
696	status = proc_get_processor_id(pnode->processor, &proc_id);
697	if (proc_id != DSP_UNIT) {
698		goto func_end;
699	}
700	/*  If segment ID includes MEM_SETVIRTUALSEGID then pbuffer is a
701	 *  virt  address, so set this info in this node's translator
702	 *  object for  future ref. If MEM_GETVIRTUALSEGID then retrieve
703	 *  virtual address  from node's translator. */
704	if ((pattr->segment_id & MEM_SETVIRTUALSEGID) ||
705	    (pattr->segment_id & MEM_GETVIRTUALSEGID)) {
706		va_flag = true;
707		set_info = (pattr->segment_id & MEM_SETVIRTUALSEGID) ?
708		    true : false;
709		/* Clear mask bits */
710		pattr->segment_id &= ~MEM_MASKVIRTUALSEGID;
711		/* Set/get this node's translators virtual address base/size */
712		status = cmm_xlator_info(pnode->xlator, pbuffer, usize,
713					 pattr->segment_id, set_info);
714	}
715	if (!status && (!va_flag)) {
716		if (pattr->segment_id != 1) {
717			/* Node supports single SM segment only. */
718			status = -EBADR;
719		}
720		/*  Arbitrary SM buffer alignment not supported for host side
721		 *  allocs, but guaranteed for the following alignment
722		 *  values. */
723		switch (pattr->buf_alignment) {
724		case 0:
725		case 1:
726		case 2:
727		case 4:
728			break;
729		default:
730			/* alignment value not suportted */
731			status = -EPERM;
732			break;
733		}
734		if (!status) {
735			/* allocate physical buffer from seg_id in node's
736			 * translator */
737			(void)cmm_xlator_alloc_buf(pnode->xlator, pbuffer,
738						   usize);
739			if (*pbuffer == NULL) {
740				pr_err("%s: error - Out of shared memory\n",
741				       __func__);
742				status = -ENOMEM;
743			}
744		}
745	}
746func_end:
747	return status;
748}
749
750/*
751 *  ======== node_change_priority ========
752 *  Purpose:
753 *      Change the priority of a node in the allocated state, or that is
754 *      currently running or paused on the target.
755 */
756int node_change_priority(struct node_object *hnode, s32 prio)
757{
758	struct node_object *pnode = (struct node_object *)hnode;
759	struct node_mgr *hnode_mgr = NULL;
760	enum node_type node_type;
761	enum node_state state;
762	int status = 0;
763	u32 proc_id;
764
765	if (!hnode || !hnode->node_mgr) {
766		status = -EFAULT;
767	} else {
768		hnode_mgr = hnode->node_mgr;
769		node_type = node_get_type(hnode);
770		if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
771			status = -EPERM;
772		else if (prio < hnode_mgr->min_pri || prio > hnode_mgr->max_pri)
773			status = -EDOM;
774	}
775	if (status)
776		goto func_end;
777
778	/* Enter critical section */
779	mutex_lock(&hnode_mgr->node_mgr_lock);
780
781	state = node_get_state(hnode);
782	if (state == NODE_ALLOCATED || state == NODE_PAUSED) {
783		NODE_SET_PRIORITY(hnode, prio);
784	} else {
785		if (state != NODE_RUNNING) {
786			status = -EBADR;
787			goto func_cont;
788		}
789		status = proc_get_processor_id(pnode->processor, &proc_id);
790		if (proc_id == DSP_UNIT) {
791			status =
792			    disp_node_change_priority(hnode_mgr->disp_obj,
793						      hnode,
794						      hnode_mgr->fxn_addrs
795						      [RMSCHANGENODEPRIORITY],
796						      hnode->node_env, prio);
797		}
798		if (status >= 0)
799			NODE_SET_PRIORITY(hnode, prio);
800
801	}
802func_cont:
803	/* Leave critical section */
804	mutex_unlock(&hnode_mgr->node_mgr_lock);
805func_end:
806	return status;
807}
808
809/*
810 *  ======== node_connect ========
811 *  Purpose:
812 *      Connect two nodes on the DSP, or a node on the DSP to the GPP.
813 */
814int node_connect(struct node_object *node1, u32 stream1,
815			struct node_object *node2,
816			u32 stream2, struct dsp_strmattr *pattrs,
817			struct dsp_cbdata *conn_param)
818{
819	struct node_mgr *hnode_mgr;
820	char *pstr_dev_name = NULL;
821	enum node_type node1_type = NODE_TASK;
822	enum node_type node2_type = NODE_TASK;
823	enum dsp_strmmode strm_mode;
824	struct node_strmdef *pstrm_def;
825	struct node_strmdef *input = NULL;
826	struct node_strmdef *output = NULL;
827	struct node_object *dev_node_obj;
828	struct node_object *hnode;
829	struct stream_chnl *pstream;
830	u32 pipe_id;
831	u32 chnl_id;
832	s8 chnl_mode;
833	u32 dw_length;
834	int status = 0;
835
836	if (!node1 || !node2)
837		return -EFAULT;
838
839	/* The two nodes must be on the same processor */
840	if (node1 != (struct node_object *)DSP_HGPPNODE &&
841			node2 != (struct node_object *)DSP_HGPPNODE &&
842			node1->node_mgr != node2->node_mgr)
843		return -EPERM;
844
845	/* Cannot connect a node to itself */
846	if (node1 == node2)
847		return -EPERM;
848
849	/* node_get_type() will return NODE_GPP if hnode =  DSP_HGPPNODE. */
850	node1_type = node_get_type(node1);
851	node2_type = node_get_type(node2);
852	/* Check stream indices ranges */
853	if ((node1_type != NODE_GPP && node1_type != NODE_DEVICE &&
854				stream1 >= MAX_OUTPUTS(node1)) ||
855			(node2_type != NODE_GPP && node2_type != NODE_DEVICE &&
856			 stream2 >= MAX_INPUTS(node2)))
857		return -EINVAL;
858
859	/*
860	 *  Only the following types of connections are allowed:
861	 *      task/dais socket < == > task/dais socket
862	 *      task/dais socket < == > device
863	 *      task/dais socket < == > GPP
864	 *
865	 *  ie, no message nodes, and at least one task or dais
866	 *  socket node.
867	 */
868	if (node1_type == NODE_MESSAGE || node2_type == NODE_MESSAGE ||
869			(node1_type != NODE_TASK &&
870			 node1_type != NODE_DAISSOCKET &&
871			 node2_type != NODE_TASK &&
872			 node2_type != NODE_DAISSOCKET))
873		return -EPERM;
874	/*
875	 * Check stream mode. Default is STRMMODE_PROCCOPY.
876	 */
877	if (pattrs && pattrs->strm_mode != STRMMODE_PROCCOPY)
878		return -EPERM;	/* illegal stream mode */
879
880	if (node1_type != NODE_GPP) {
881		hnode_mgr = node1->node_mgr;
882	} else {
883		hnode_mgr = node2->node_mgr;
884	}
885
886	/* Enter critical section */
887	mutex_lock(&hnode_mgr->node_mgr_lock);
888
889	/* Nodes must be in the allocated state */
890	if (node1_type != NODE_GPP &&
891			node_get_state(node1) != NODE_ALLOCATED) {
892		status = -EBADR;
893		goto out_unlock;
894	}
895
896	if (node2_type != NODE_GPP &&
897			node_get_state(node2) != NODE_ALLOCATED) {
898		status = -EBADR;
899		goto out_unlock;
900	}
901
902	/*
903	 *  Check that stream indices for task and dais socket nodes
904	 *  are not already be used. (Device nodes checked later)
905	 */
906	if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) {
907		output = &(node1->create_args.asa.
908				task_arg_obj.strm_out_def[stream1]);
909		if (output->sz_device) {
910			status = -EISCONN;
911			goto out_unlock;
912		}
913
914	}
915	if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) {
916		input = &(node2->create_args.asa.
917				task_arg_obj.strm_in_def[stream2]);
918		if (input->sz_device) {
919			status = -EISCONN;
920			goto out_unlock;
921		}
922
923	}
924	/* Connecting two task nodes? */
925	if ((node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) &&
926				(node2_type == NODE_TASK ||
927				 node2_type == NODE_DAISSOCKET)) {
928		/* Find available pipe */
929		pipe_id = find_first_zero_bit(hnode_mgr->pipe_map, MAXPIPES);
930		if (pipe_id == MAXPIPES) {
931			status = -ECONNREFUSED;
932			goto out_unlock;
933		}
934		set_bit(pipe_id, hnode_mgr->pipe_map);
935		node1->outputs[stream1].type = NODECONNECT;
936		node2->inputs[stream2].type = NODECONNECT;
937		node1->outputs[stream1].dev_id = pipe_id;
938		node2->inputs[stream2].dev_id = pipe_id;
939		output->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL);
940		input->sz_device = kzalloc(PIPENAMELEN + 1, GFP_KERNEL);
941		if (!output->sz_device || !input->sz_device) {
942			/* Undo the connection */
943			kfree(output->sz_device);
944			kfree(input->sz_device);
945			clear_bit(pipe_id, hnode_mgr->pipe_map);
946			status = -ENOMEM;
947			goto out_unlock;
948		}
949		/* Copy "/dbpipe<pipId>" name to device names */
950		sprintf(output->sz_device, "%s%d", PIPEPREFIX, pipe_id);
951		strcpy(input->sz_device, output->sz_device);
952	}
953	/* Connecting task node to host? */
954	if (node1_type == NODE_GPP || node2_type == NODE_GPP) {
955		pstr_dev_name = kzalloc(HOSTNAMELEN + 1, GFP_KERNEL);
956		if (!pstr_dev_name) {
957			status = -ENOMEM;
958			goto out_unlock;
959		}
960
961		chnl_mode = (node1_type == NODE_GPP) ?
962			CHNL_MODETODSP : CHNL_MODEFROMDSP;
963
964		/*
965		 *  Reserve a channel id. We need to put the name "/host<id>"
966		 *  in the node's create_args, but the host
967		 *  side channel will not be opened until DSPStream_Open is
968		 *  called for this node.
969		 */
970		strm_mode = pattrs ? pattrs->strm_mode : STRMMODE_PROCCOPY;
971		switch (strm_mode) {
972		case STRMMODE_RDMA:
973			chnl_id = find_first_zero_bit(hnode_mgr->dma_chnl_map,
974					CHNL_MAXCHANNELS);
975			if (chnl_id < CHNL_MAXCHANNELS) {
976				set_bit(chnl_id, hnode_mgr->dma_chnl_map);
977				/* dma chans are 2nd transport chnl set
978				 * ids(e.g. 16-31) */
979				chnl_id = chnl_id + hnode_mgr->num_chnls;
980			}
981			break;
982		case STRMMODE_ZEROCOPY:
983			chnl_id = find_first_zero_bit(hnode_mgr->zc_chnl_map,
984					CHNL_MAXCHANNELS);
985			if (chnl_id < CHNL_MAXCHANNELS) {
986				set_bit(chnl_id, hnode_mgr->zc_chnl_map);
987				/* zero-copy chans are 3nd transport set
988				 * (e.g. 32-47) */
989				chnl_id = chnl_id +
990					(2 * hnode_mgr->num_chnls);
991			}
992			break;
993		case STRMMODE_PROCCOPY:
994			chnl_id = find_first_zero_bit(hnode_mgr->chnl_map,
995					CHNL_MAXCHANNELS);
996			if (chnl_id < CHNL_MAXCHANNELS)
997				set_bit(chnl_id, hnode_mgr->chnl_map);
998			break;
999		default:
1000			status = -EINVAL;
1001			goto out_unlock;
1002		}
1003		if (chnl_id == CHNL_MAXCHANNELS) {
1004			status = -ECONNREFUSED;
1005			goto out_unlock;
1006		}
1007
1008		if (node1 == (struct node_object *)DSP_HGPPNODE) {
1009			node2->inputs[stream2].type = HOSTCONNECT;
1010			node2->inputs[stream2].dev_id = chnl_id;
1011			input->sz_device = pstr_dev_name;
1012		} else {
1013			node1->outputs[stream1].type = HOSTCONNECT;
1014			node1->outputs[stream1].dev_id = chnl_id;
1015			output->sz_device = pstr_dev_name;
1016		}
1017		sprintf(pstr_dev_name, "%s%d", HOSTPREFIX, chnl_id);
1018	}
1019	/* Connecting task node to device node? */
1020	if ((node1_type == NODE_DEVICE) || (node2_type == NODE_DEVICE)) {
1021		if (node2_type == NODE_DEVICE) {
1022			/* node1 == > device */
1023			dev_node_obj = node2;
1024			hnode = node1;
1025			pstream = &(node1->outputs[stream1]);
1026			pstrm_def = output;
1027		} else {
1028			/* device == > node2 */
1029			dev_node_obj = node1;
1030			hnode = node2;
1031			pstream = &(node2->inputs[stream2]);
1032			pstrm_def = input;
1033		}
1034		/* Set up create args */
1035		pstream->type = DEVICECONNECT;
1036		dw_length = strlen(dev_node_obj->str_dev_name);
1037		if (conn_param)
1038			pstrm_def->sz_device = kzalloc(dw_length + 1 +
1039					conn_param->cb_data,
1040					GFP_KERNEL);
1041		else
1042			pstrm_def->sz_device = kzalloc(dw_length + 1,
1043					GFP_KERNEL);
1044		if (!pstrm_def->sz_device) {
1045			status = -ENOMEM;
1046			goto out_unlock;
1047		}
1048		/* Copy device name */
1049		strncpy(pstrm_def->sz_device,
1050				dev_node_obj->str_dev_name, dw_length);
1051		if (conn_param)
1052			strncat(pstrm_def->sz_device,
1053					(char *)conn_param->node_data,
1054					(u32) conn_param->cb_data);
1055		dev_node_obj->device_owner = hnode;
1056	}
1057	/* Fill in create args */
1058	if (node1_type == NODE_TASK || node1_type == NODE_DAISSOCKET) {
1059		node1->create_args.asa.task_arg_obj.num_outputs++;
1060		fill_stream_def(node1, output, pattrs);
1061	}
1062	if (node2_type == NODE_TASK || node2_type == NODE_DAISSOCKET) {
1063		node2->create_args.asa.task_arg_obj.num_inputs++;
1064		fill_stream_def(node2, input, pattrs);
1065	}
1066	/* Update node1 and node2 stream_connect */
1067	if (node1_type != NODE_GPP && node1_type != NODE_DEVICE) {
1068		node1->num_outputs++;
1069		if (stream1 > node1->max_output_index)
1070			node1->max_output_index = stream1;
1071
1072	}
1073	if (node2_type != NODE_GPP && node2_type != NODE_DEVICE) {
1074		node2->num_inputs++;
1075		if (stream2 > node2->max_input_index)
1076			node2->max_input_index = stream2;
1077
1078	}
1079	fill_stream_connect(node1, node2, stream1, stream2);
1080	/* end of sync_enter_cs */
1081	/* Exit critical section */
1082out_unlock:
1083	if (status && pstr_dev_name)
1084		kfree(pstr_dev_name);
1085	mutex_unlock(&hnode_mgr->node_mgr_lock);
1086	dev_dbg(bridge, "%s: node1: %p stream1: %d node2: %p stream2: %d"
1087			"pattrs: %p status: 0x%x\n", __func__, node1,
1088			stream1, node2, stream2, pattrs, status);
1089	return status;
1090}
1091
1092/*
1093 *  ======== node_create ========
1094 *  Purpose:
1095 *      Create a node on the DSP by remotely calling the node's create function.
1096 */
1097int node_create(struct node_object *hnode)
1098{
1099	struct node_object *pnode = (struct node_object *)hnode;
1100	struct node_mgr *hnode_mgr;
1101	struct bridge_drv_interface *intf_fxns;
1102	u32 ul_create_fxn;
1103	enum node_type node_type;
1104	int status = 0;
1105	int status1 = 0;
1106	struct dsp_cbdata cb_data;
1107	u32 proc_id = 255;
1108	struct dsp_processorstate proc_state;
1109	struct proc_object *hprocessor;
1110#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1111	struct dspbridge_platform_data *pdata =
1112	    omap_dspbridge_dev->dev.platform_data;
1113#endif
1114
1115	if (!pnode) {
1116		status = -EFAULT;
1117		goto func_end;
1118	}
1119	hprocessor = hnode->processor;
1120	status = proc_get_state(hprocessor, &proc_state,
1121				sizeof(struct dsp_processorstate));
1122	if (status)
1123		goto func_end;
1124	/* If processor is in error state then don't attempt to create
1125	   new node */
1126	if (proc_state.proc_state == PROC_ERROR) {
1127		status = -EPERM;
1128		goto func_end;
1129	}
1130	/* create struct dsp_cbdata struct for PWR calls */
1131	cb_data.cb_data = PWR_TIMEOUT;
1132	node_type = node_get_type(hnode);
1133	hnode_mgr = hnode->node_mgr;
1134	intf_fxns = hnode_mgr->intf_fxns;
1135	/* Get access to node dispatcher */
1136	mutex_lock(&hnode_mgr->node_mgr_lock);
1137
1138	/* Check node state */
1139	if (node_get_state(hnode) != NODE_ALLOCATED)
1140		status = -EBADR;
1141
1142	if (!status)
1143		status = proc_get_processor_id(pnode->processor, &proc_id);
1144
1145	if (status)
1146		goto func_cont2;
1147
1148	if (proc_id != DSP_UNIT)
1149		goto func_cont2;
1150
1151	/* Make sure streams are properly connected */
1152	if ((hnode->num_inputs && hnode->max_input_index >
1153	     hnode->num_inputs - 1) ||
1154	    (hnode->num_outputs && hnode->max_output_index >
1155	     hnode->num_outputs - 1))
1156		status = -ENOTCONN;
1157
1158	if (!status) {
1159		/* If node's create function is not loaded, load it */
1160		/* Boost the OPP level to max level that DSP can be requested */
1161#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1162		if (pdata->cpu_set_freq)
1163			(*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP3]);
1164#endif
1165		status = hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj,
1166						       NLDR_CREATE);
1167		/* Get address of node's create function */
1168		if (!status) {
1169			hnode->loaded = true;
1170			if (node_type != NODE_DEVICE) {
1171				status = get_fxn_address(hnode, &ul_create_fxn,
1172							 CREATEPHASE);
1173			}
1174		} else {
1175			pr_err("%s: failed to load create code: 0x%x\n",
1176			       __func__, status);
1177		}
1178		/* Request the lowest OPP level */
1179#if defined(CONFIG_TIDSPBRIDGE_DVFS) && !defined(CONFIG_CPU_FREQ)
1180		if (pdata->cpu_set_freq)
1181			(*pdata->cpu_set_freq) (pdata->mpu_speed[VDD1_OPP1]);
1182#endif
1183		/* Get address of iAlg functions, if socket node */
1184		if (!status) {
1185			if (node_type == NODE_DAISSOCKET) {
1186				status = hnode_mgr->nldr_fxns.get_fxn_addr
1187				    (hnode->nldr_node_obj,
1188				     hnode->dcd_props.obj_data.node_obj.
1189				     str_i_alg_name,
1190				     &hnode->create_args.asa.
1191				     task_arg_obj.dais_arg);
1192			}
1193		}
1194	}
1195	if (!status) {
1196		if (node_type != NODE_DEVICE) {
1197			status = disp_node_create(hnode_mgr->disp_obj, hnode,
1198						  hnode_mgr->fxn_addrs
1199						  [RMSCREATENODE],
1200						  ul_create_fxn,
1201						  &(hnode->create_args),
1202						  &(hnode->node_env));
1203			if (status >= 0) {
1204				/* Set the message queue id to the node env
1205				 * pointer */
1206				intf_fxns = hnode_mgr->intf_fxns;
1207				(*intf_fxns->msg_set_queue_id) (hnode->
1208							msg_queue_obj,
1209							hnode->node_env);
1210			}
1211		}
1212	}
1213	/*  Phase II/Overlays: Create, execute, delete phases  possibly in
1214	 *  different files/sections. */
1215	if (hnode->loaded && hnode->phase_split) {
1216		/* If create code was dynamically loaded, we can now unload
1217		 * it. */
1218		status1 = hnode_mgr->nldr_fxns.unload(hnode->nldr_node_obj,
1219							  NLDR_CREATE);
1220		hnode->loaded = false;
1221	}
1222	if (status1)
1223		pr_err("%s: Failed to unload create code: 0x%x\n",
1224		       __func__, status1);
1225func_cont2:
1226	/* Update node state and node manager state */
1227	if (status >= 0) {
1228		NODE_SET_STATE(hnode, NODE_CREATED);
1229		hnode_mgr->num_created++;
1230		goto func_cont;
1231	}
1232	if (status != -EBADR) {
1233		/* Put back in NODE_ALLOCATED state if error occurred */
1234		NODE_SET_STATE(hnode, NODE_ALLOCATED);
1235	}
1236func_cont:
1237	/* Free access to node dispatcher */
1238	mutex_unlock(&hnode_mgr->node_mgr_lock);
1239func_end:
1240	if (status >= 0) {
1241		proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE);
1242		ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
1243	}
1244
1245	dev_dbg(bridge, "%s: hnode: %p status: 0x%x\n", __func__,
1246		hnode, status);
1247	return status;
1248}
1249
1250/*
1251 *  ======== node_create_mgr ========
1252 *  Purpose:
1253 *      Create a NODE Manager object.
1254 */
1255int node_create_mgr(struct node_mgr **node_man,
1256			   struct dev_object *hdev_obj)
1257{
1258	u32 i;
1259	struct node_mgr *node_mgr_obj = NULL;
1260	struct disp_attr disp_attr_obj;
1261	char *sz_zl_file = "";
1262	struct nldr_attrs nldr_attrs_obj;
1263	int status = 0;
1264	u8 dev_type;
1265
1266	*node_man = NULL;
1267	/* Allocate Node manager object */
1268	node_mgr_obj = kzalloc(sizeof(struct node_mgr), GFP_KERNEL);
1269	if (!node_mgr_obj)
1270		return -ENOMEM;
1271
1272	node_mgr_obj->dev_obj = hdev_obj;
1273
1274	node_mgr_obj->ntfy_obj = kmalloc(sizeof(struct ntfy_object),
1275			GFP_KERNEL);
1276	if (!node_mgr_obj->ntfy_obj) {
1277		status = -ENOMEM;
1278		goto out_err;
1279	}
1280	ntfy_init(node_mgr_obj->ntfy_obj);
1281
1282	INIT_LIST_HEAD(&node_mgr_obj->node_list);
1283
1284	dev_get_dev_type(hdev_obj, &dev_type);
1285
1286	status = dcd_create_manager(sz_zl_file, &node_mgr_obj->dcd_mgr);
1287	if (status)
1288		goto out_err;
1289
1290	status = get_proc_props(node_mgr_obj, hdev_obj);
1291	if (status)
1292		goto out_err;
1293
1294	/* Create NODE Dispatcher */
1295	disp_attr_obj.chnl_offset = node_mgr_obj->chnl_offset;
1296	disp_attr_obj.chnl_buf_size = node_mgr_obj->chnl_buf_size;
1297	disp_attr_obj.proc_family = node_mgr_obj->proc_family;
1298	disp_attr_obj.proc_type = node_mgr_obj->proc_type;
1299
1300	status = disp_create(&node_mgr_obj->disp_obj, hdev_obj, &disp_attr_obj);
1301	if (status)
1302		goto out_err;
1303
1304	/* Create a STRM Manager */
1305	status = strm_create(&node_mgr_obj->strm_mgr_obj, hdev_obj);
1306	if (status)
1307		goto out_err;
1308
1309	dev_get_intf_fxns(hdev_obj, &node_mgr_obj->intf_fxns);
1310	/* Get msg_ctrl queue manager */
1311	dev_get_msg_mgr(hdev_obj, &node_mgr_obj->msg_mgr_obj);
1312	mutex_init(&node_mgr_obj->node_mgr_lock);
1313
1314	/* Block out reserved channels */
1315	for (i = 0; i < node_mgr_obj->chnl_offset; i++)
1316		set_bit(i, node_mgr_obj->chnl_map);
1317
1318	/* Block out channels reserved for RMS */
1319	set_bit(node_mgr_obj->chnl_offset, node_mgr_obj->chnl_map);
1320	set_bit(node_mgr_obj->chnl_offset + 1, node_mgr_obj->chnl_map);
1321
1322	/* NO RM Server on the IVA */
1323	if (dev_type != IVA_UNIT) {
1324		/* Get addresses of any RMS functions loaded */
1325		status = get_rms_fxns(node_mgr_obj);
1326		if (status)
1327			goto out_err;
1328	}
1329
1330	/* Get loader functions and create loader */
1331	node_mgr_obj->nldr_fxns = nldr_fxns;	/* Dyn loader funcs */
1332
1333	nldr_attrs_obj.ovly = ovly;
1334	nldr_attrs_obj.write = mem_write;
1335	nldr_attrs_obj.dsp_word_size = node_mgr_obj->dsp_word_size;
1336	nldr_attrs_obj.dsp_mau_size = node_mgr_obj->dsp_mau_size;
1337	status = node_mgr_obj->nldr_fxns.create(&node_mgr_obj->nldr_obj,
1338			hdev_obj,
1339			&nldr_attrs_obj);
1340	if (status)
1341		goto out_err;
1342
1343	*node_man = node_mgr_obj;
1344
1345	return status;
1346out_err:
1347	delete_node_mgr(node_mgr_obj);
1348	return status;
1349}
1350
1351/*
1352 *  ======== node_delete ========
1353 *  Purpose:
1354 *      Delete a node on the DSP by remotely calling the node's delete function.
1355 *      Loads the node's delete function if necessary. Free GPP side resources
1356 *      after node's delete function returns.
1357 */
1358int node_delete(struct node_res_object *noderes,
1359		       struct process_context *pr_ctxt)
1360{
1361	struct node_object *pnode = noderes->node;
1362	struct node_mgr *hnode_mgr;
1363	struct proc_object *hprocessor;
1364	struct disp_object *disp_obj;
1365	u32 ul_delete_fxn;
1366	enum node_type node_type;
1367	enum node_state state;
1368	int status = 0;
1369	int status1 = 0;
1370	struct dsp_cbdata cb_data;
1371	u32 proc_id;
1372	struct bridge_drv_interface *intf_fxns;
1373
1374	void *node_res = noderes;
1375
1376	struct dsp_processorstate proc_state;
1377
1378	if (!pnode) {
1379		status = -EFAULT;
1380		goto func_end;
1381	}
1382	/* create struct dsp_cbdata struct for PWR call */
1383	cb_data.cb_data = PWR_TIMEOUT;
1384	hnode_mgr = pnode->node_mgr;
1385	hprocessor = pnode->processor;
1386	disp_obj = hnode_mgr->disp_obj;
1387	node_type = node_get_type(pnode);
1388	intf_fxns = hnode_mgr->intf_fxns;
1389	/* Enter critical section */
1390	mutex_lock(&hnode_mgr->node_mgr_lock);
1391
1392	state = node_get_state(pnode);
1393	/*  Execute delete phase code for non-device node in all cases
1394	 *  except when the node was only allocated. Delete phase must be
1395	 *  executed even if create phase was executed, but failed.
1396	 *  If the node environment pointer is non-NULL, the delete phase
1397	 *  code must be  executed. */
1398	if (!(state == NODE_ALLOCATED && pnode->node_env == (u32) NULL) &&
1399	    node_type != NODE_DEVICE) {
1400		status = proc_get_processor_id(pnode->processor, &proc_id);
1401		if (status)
1402			goto func_cont1;
1403
1404		if (proc_id == DSP_UNIT || proc_id == IVA_UNIT) {
1405			/*  If node has terminated, execute phase code will
1406			 *  have already been unloaded in node_on_exit(). If the
1407			 *  node is PAUSED, the execute phase is loaded, and it
1408			 *  is now ok to unload it. If the node is running, we
1409			 *  will unload the execute phase only after deleting
1410			 *  the node. */
1411			if (state == NODE_PAUSED && pnode->loaded &&
1412			    pnode->phase_split) {
1413				/* Ok to unload execute code as long as node
1414				 * is not * running */
1415				status1 =
1416				    hnode_mgr->nldr_fxns.
1417				    unload(pnode->nldr_node_obj,
1418					       NLDR_EXECUTE);
1419				pnode->loaded = false;
1420				NODE_SET_STATE(pnode, NODE_DONE);
1421			}
1422			/* Load delete phase code if not loaded or if haven't
1423			 * * unloaded EXECUTE phase */
1424			if ((!(pnode->loaded) || (state == NODE_RUNNING)) &&
1425			    pnode->phase_split) {
1426				status =
1427				    hnode_mgr->nldr_fxns.
1428				    load(pnode->nldr_node_obj, NLDR_DELETE);
1429				if (!status)
1430					pnode->loaded = true;
1431				else
1432					pr_err("%s: fail - load delete code:"
1433					       " 0x%x\n", __func__, status);
1434			}
1435		}
1436func_cont1:
1437		if (!status) {
1438			/* Unblock a thread trying to terminate the node */
1439			(void)sync_set_event(pnode->sync_done);
1440			if (proc_id == DSP_UNIT) {
1441				/* ul_delete_fxn = address of node's delete
1442				 * function */
1443				status = get_fxn_address(pnode, &ul_delete_fxn,
1444							 DELETEPHASE);
1445			} else if (proc_id == IVA_UNIT)
1446				ul_delete_fxn = (u32) pnode->node_env;
1447			if (!status) {
1448				status = proc_get_state(hprocessor,
1449						&proc_state,
1450						sizeof(struct
1451						       dsp_processorstate));
1452				if (proc_state.proc_state != PROC_ERROR) {
1453					status =
1454					    disp_node_delete(disp_obj, pnode,
1455							     hnode_mgr->
1456							     fxn_addrs
1457							     [RMSDELETENODE],
1458							     ul_delete_fxn,
1459							     pnode->node_env);
1460				} else
1461					NODE_SET_STATE(pnode, NODE_DONE);
1462
1463				/* Unload execute, if not unloaded, and delete
1464				 * function */
1465				if (state == NODE_RUNNING &&
1466				    pnode->phase_split) {
1467					status1 =
1468					    hnode_mgr->nldr_fxns.
1469					    unload(pnode->nldr_node_obj,
1470						       NLDR_EXECUTE);
1471				}
1472				if (status1)
1473					pr_err("%s: fail - unload execute code:"
1474					       " 0x%x\n", __func__, status1);
1475
1476				status1 =
1477				    hnode_mgr->nldr_fxns.unload(pnode->
1478							    nldr_node_obj,
1479							    NLDR_DELETE);
1480				pnode->loaded = false;
1481				if (status1)
1482					pr_err("%s: fail - unload delete code: "
1483					       "0x%x\n", __func__, status1);
1484			}
1485		}
1486	}
1487	/* Free host side resources even if a failure occurred */
1488	/* Remove node from hnode_mgr->node_list */
1489	list_del(&pnode->list_elem);
1490	hnode_mgr->num_nodes--;
1491	/* Decrement count of nodes created on DSP */
1492	if ((state != NODE_ALLOCATED) || ((state == NODE_ALLOCATED) &&
1493					  (pnode->node_env != (u32) NULL)))
1494		hnode_mgr->num_created--;
1495	/*  Free host-side resources allocated by node_create()
1496	 *  delete_node() fails if SM buffers not freed by client! */
1497	drv_proc_node_update_status(node_res, false);
1498	delete_node(pnode, pr_ctxt);
1499
1500	/*
1501	 * Release all Node resources and its context
1502	 */
1503	idr_remove(pr_ctxt->node_id, ((struct node_res_object *)node_res)->id);
1504	kfree(node_res);
1505
1506	/* Exit critical section */
1507	mutex_unlock(&hnode_mgr->node_mgr_lock);
1508	proc_notify_clients(hprocessor, DSP_NODESTATECHANGE);
1509func_end:
1510	dev_dbg(bridge, "%s: pnode: %p status 0x%x\n", __func__, pnode, status);
1511	return status;
1512}
1513
1514/*
1515 *  ======== node_delete_mgr ========
1516 *  Purpose:
1517 *      Delete the NODE Manager.
1518 */
1519int node_delete_mgr(struct node_mgr *hnode_mgr)
1520{
1521	if (!hnode_mgr)
1522		return -EFAULT;
1523
1524	delete_node_mgr(hnode_mgr);
1525
1526	return 0;
1527}
1528
1529/*
1530 *  ======== node_enum_nodes ========
1531 *  Purpose:
1532 *      Enumerate currently allocated nodes.
1533 */
1534int node_enum_nodes(struct node_mgr *hnode_mgr, void **node_tab,
1535			   u32 node_tab_size, u32 *pu_num_nodes,
1536			   u32 *pu_allocated)
1537{
1538	struct node_object *hnode;
1539	u32 i = 0;
1540	int status = 0;
1541
1542	if (!hnode_mgr) {
1543		status = -EFAULT;
1544		goto func_end;
1545	}
1546	/* Enter critical section */
1547	mutex_lock(&hnode_mgr->node_mgr_lock);
1548
1549	if (hnode_mgr->num_nodes > node_tab_size) {
1550		*pu_allocated = hnode_mgr->num_nodes;
1551		*pu_num_nodes = 0;
1552		status = -EINVAL;
1553	} else {
1554		list_for_each_entry(hnode, &hnode_mgr->node_list, list_elem)
1555			node_tab[i++] = hnode;
1556		*pu_allocated = *pu_num_nodes = hnode_mgr->num_nodes;
1557	}
1558	/* end of sync_enter_cs */
1559	/* Exit critical section */
1560	mutex_unlock(&hnode_mgr->node_mgr_lock);
1561func_end:
1562	return status;
1563}
1564
1565/*
1566 *  ======== node_free_msg_buf ========
1567 *  Purpose:
1568 *      Frees the message buffer.
1569 */
1570int node_free_msg_buf(struct node_object *hnode, u8 * pbuffer,
1571			     struct dsp_bufferattr *pattr)
1572{
1573	struct node_object *pnode = (struct node_object *)hnode;
1574	int status = 0;
1575	u32 proc_id;
1576
1577	if (!hnode) {
1578		status = -EFAULT;
1579		goto func_end;
1580	}
1581	status = proc_get_processor_id(pnode->processor, &proc_id);
1582	if (proc_id == DSP_UNIT) {
1583		if (!status) {
1584			if (pattr == NULL) {
1585				/* set defaults */
1586				pattr = &node_dfltbufattrs;
1587			}
1588			/* Node supports single SM segment only */
1589			if (pattr->segment_id != 1)
1590				status = -EBADR;
1591
1592			/* pbuffer is clients Va. */
1593			status = cmm_xlator_free_buf(pnode->xlator, pbuffer);
1594		}
1595	} else {
1596	}
1597func_end:
1598	return status;
1599}
1600
1601/*
1602 *  ======== node_get_attr ========
1603 *  Purpose:
1604 *      Copy the current attributes of the specified node into a dsp_nodeattr
1605 *      structure.
1606 */
1607int node_get_attr(struct node_object *hnode,
1608			 struct dsp_nodeattr *pattr, u32 attr_size)
1609{
1610	struct node_mgr *hnode_mgr;
1611
1612	if (!hnode)
1613		return -EFAULT;
1614
1615	hnode_mgr = hnode->node_mgr;
1616	/* Enter hnode_mgr critical section (since we're accessing
1617	 * data that could be changed by node_change_priority() and
1618	 * node_connect(). */
1619	mutex_lock(&hnode_mgr->node_mgr_lock);
1620	pattr->cb_struct = sizeof(struct dsp_nodeattr);
1621	/* dsp_nodeattrin */
1622	pattr->in_node_attr_in.cb_struct =
1623		sizeof(struct dsp_nodeattrin);
1624	pattr->in_node_attr_in.prio = hnode->prio;
1625	pattr->in_node_attr_in.timeout = hnode->timeout;
1626	pattr->in_node_attr_in.heap_size =
1627		hnode->create_args.asa.task_arg_obj.heap_size;
1628	pattr->in_node_attr_in.pgpp_virt_addr = (void *)
1629		hnode->create_args.asa.task_arg_obj.gpp_heap_addr;
1630	pattr->node_attr_inputs = hnode->num_gpp_inputs;
1631	pattr->node_attr_outputs = hnode->num_gpp_outputs;
1632	/* dsp_nodeinfo */
1633	get_node_info(hnode, &(pattr->node_info));
1634	/* end of sync_enter_cs */
1635	/* Exit critical section */
1636	mutex_unlock(&hnode_mgr->node_mgr_lock);
1637
1638	return 0;
1639}
1640
1641/*
1642 *  ======== node_get_channel_id ========
1643 *  Purpose:
1644 *      Get the channel index reserved for a stream connection between the
1645 *      host and a node.
1646 */
1647int node_get_channel_id(struct node_object *hnode, u32 dir, u32 index,
1648			       u32 *chan_id)
1649{
1650	enum node_type node_type;
1651	int status = -EINVAL;
1652
1653	if (!hnode) {
1654		status = -EFAULT;
1655		return status;
1656	}
1657	node_type = node_get_type(hnode);
1658	if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET) {
1659		status = -EPERM;
1660		return status;
1661	}
1662	if (dir == DSP_TONODE) {
1663		if (index < MAX_INPUTS(hnode)) {
1664			if (hnode->inputs[index].type == HOSTCONNECT) {
1665				*chan_id = hnode->inputs[index].dev_id;
1666				status = 0;
1667			}
1668		}
1669	} else {
1670		if (index < MAX_OUTPUTS(hnode)) {
1671			if (hnode->outputs[index].type == HOSTCONNECT) {
1672				*chan_id = hnode->outputs[index].dev_id;
1673				status = 0;
1674			}
1675		}
1676	}
1677	return status;
1678}
1679
1680/*
1681 *  ======== node_get_message ========
1682 *  Purpose:
1683 *      Retrieve a message from a node on the DSP.
1684 */
1685int node_get_message(struct node_object *hnode,
1686			    struct dsp_msg *message, u32 utimeout)
1687{
1688	struct node_mgr *hnode_mgr;
1689	enum node_type node_type;
1690	struct bridge_drv_interface *intf_fxns;
1691	int status = 0;
1692	void *tmp_buf;
1693	struct dsp_processorstate proc_state;
1694	struct proc_object *hprocessor;
1695
1696	if (!hnode) {
1697		status = -EFAULT;
1698		goto func_end;
1699	}
1700	hprocessor = hnode->processor;
1701	status = proc_get_state(hprocessor, &proc_state,
1702				sizeof(struct dsp_processorstate));
1703	if (status)
1704		goto func_end;
1705	/* If processor is in error state then don't attempt to get the
1706	   message */
1707	if (proc_state.proc_state == PROC_ERROR) {
1708		status = -EPERM;
1709		goto func_end;
1710	}
1711	hnode_mgr = hnode->node_mgr;
1712	node_type = node_get_type(hnode);
1713	if (node_type != NODE_MESSAGE && node_type != NODE_TASK &&
1714	    node_type != NODE_DAISSOCKET) {
1715		status = -EPERM;
1716		goto func_end;
1717	}
1718	/*  This function will block unless a message is available. Since
1719	 *  DSPNode_RegisterNotify() allows notification when a message
1720	 *  is available, the system can be designed so that
1721	 *  DSPNode_GetMessage() is only called when a message is
1722	 *  available. */
1723	intf_fxns = hnode_mgr->intf_fxns;
1724	status =
1725	    (*intf_fxns->msg_get) (hnode->msg_queue_obj, message, utimeout);
1726	/* Check if message contains SM descriptor */
1727	if (status || !(message->cmd & DSP_RMSBUFDESC))
1728		goto func_end;
1729
1730	/* Translate DSP byte addr to GPP Va. */
1731	tmp_buf = cmm_xlator_translate(hnode->xlator,
1732				       (void *)(message->arg1 *
1733						hnode->node_mgr->
1734						dsp_word_size), CMM_DSPPA2PA);
1735	if (tmp_buf != NULL) {
1736		/* now convert this GPP Pa to Va */
1737		tmp_buf = cmm_xlator_translate(hnode->xlator, tmp_buf,
1738					       CMM_PA2VA);
1739		if (tmp_buf != NULL) {
1740			/* Adjust SM size in msg */
1741			message->arg1 = (u32) tmp_buf;
1742			message->arg2 *= hnode->node_mgr->dsp_word_size;
1743		} else {
1744			status = -ESRCH;
1745		}
1746	} else {
1747		status = -ESRCH;
1748	}
1749func_end:
1750	dev_dbg(bridge, "%s: hnode: %p message: %p utimeout: 0x%x\n", __func__,
1751		hnode, message, utimeout);
1752	return status;
1753}
1754
1755/*
1756 *   ======== node_get_nldr_obj ========
1757 */
1758int node_get_nldr_obj(struct node_mgr *hnode_mgr,
1759			     struct nldr_object **nldr_ovlyobj)
1760{
1761	int status = 0;
1762	struct node_mgr *node_mgr_obj = hnode_mgr;
1763
1764	if (!hnode_mgr)
1765		status = -EFAULT;
1766	else
1767		*nldr_ovlyobj = node_mgr_obj->nldr_obj;
1768
1769	return status;
1770}
1771
1772/*
1773 *  ======== node_get_strm_mgr ========
1774 *  Purpose:
1775 *      Returns the Stream manager.
1776 */
1777int node_get_strm_mgr(struct node_object *hnode,
1778			     struct strm_mgr **strm_man)
1779{
1780	int status = 0;
1781
1782	if (!hnode)
1783		status = -EFAULT;
1784	else
1785		*strm_man = hnode->node_mgr->strm_mgr_obj;
1786
1787	return status;
1788}
1789
1790/*
1791 *  ======== node_get_load_type ========
1792 */
1793enum nldr_loadtype node_get_load_type(struct node_object *hnode)
1794{
1795	if (!hnode) {
1796		dev_dbg(bridge, "%s: Failed. hnode: %p\n", __func__, hnode);
1797		return -1;
1798	} else {
1799		return hnode->dcd_props.obj_data.node_obj.load_type;
1800	}
1801}
1802
1803/*
1804 *  ======== node_get_timeout ========
1805 *  Purpose:
1806 *      Returns the timeout value for this node.
1807 */
1808u32 node_get_timeout(struct node_object *hnode)
1809{
1810	if (!hnode) {
1811		dev_dbg(bridge, "%s: failed. hnode: %p\n", __func__, hnode);
1812		return 0;
1813	} else {
1814		return hnode->timeout;
1815	}
1816}
1817
1818/*
1819 *  ======== node_get_type ========
1820 *  Purpose:
1821 *      Returns the node type.
1822 */
1823enum node_type node_get_type(struct node_object *hnode)
1824{
1825	enum node_type node_type;
1826
1827	if (hnode == (struct node_object *)DSP_HGPPNODE)
1828		node_type = NODE_GPP;
1829	else {
1830		if (!hnode)
1831			node_type = -1;
1832		else
1833			node_type = hnode->ntype;
1834	}
1835	return node_type;
1836}
1837
1838/*
1839 *  ======== node_on_exit ========
1840 *  Purpose:
1841 *      Gets called when RMS_EXIT is received for a node.
1842 */
1843void node_on_exit(struct node_object *hnode, s32 node_status)
1844{
1845	if (!hnode)
1846		return;
1847
1848	/* Set node state to done */
1849	NODE_SET_STATE(hnode, NODE_DONE);
1850	hnode->exit_status = node_status;
1851	if (hnode->loaded && hnode->phase_split) {
1852		(void)hnode->node_mgr->nldr_fxns.unload(hnode->
1853							     nldr_node_obj,
1854							     NLDR_EXECUTE);
1855		hnode->loaded = false;
1856	}
1857	/* Unblock call to node_terminate */
1858	(void)sync_set_event(hnode->sync_done);
1859	/* Notify clients */
1860	proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE);
1861	ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
1862}
1863
1864/*
1865 *  ======== node_pause ========
1866 *  Purpose:
1867 *      Suspend execution of a node currently running on the DSP.
1868 */
1869int node_pause(struct node_object *hnode)
1870{
1871	struct node_object *pnode = (struct node_object *)hnode;
1872	enum node_type node_type;
1873	enum node_state state;
1874	struct node_mgr *hnode_mgr;
1875	int status = 0;
1876	u32 proc_id;
1877	struct dsp_processorstate proc_state;
1878	struct proc_object *hprocessor;
1879
1880	if (!hnode) {
1881		status = -EFAULT;
1882	} else {
1883		node_type = node_get_type(hnode);
1884		if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
1885			status = -EPERM;
1886	}
1887	if (status)
1888		goto func_end;
1889
1890	status = proc_get_processor_id(pnode->processor, &proc_id);
1891
1892	if (proc_id == IVA_UNIT)
1893		status = -ENOSYS;
1894
1895	if (!status) {
1896		hnode_mgr = hnode->node_mgr;
1897
1898		/* Enter critical section */
1899		mutex_lock(&hnode_mgr->node_mgr_lock);
1900		state = node_get_state(hnode);
1901		/* Check node state */
1902		if (state != NODE_RUNNING)
1903			status = -EBADR;
1904
1905		if (status)
1906			goto func_cont;
1907		hprocessor = hnode->processor;
1908		status = proc_get_state(hprocessor, &proc_state,
1909				sizeof(struct dsp_processorstate));
1910		if (status)
1911			goto func_cont;
1912		/* If processor is in error state then don't attempt
1913		   to send the message */
1914		if (proc_state.proc_state == PROC_ERROR) {
1915			status = -EPERM;
1916			goto func_cont;
1917		}
1918
1919		status = disp_node_change_priority(hnode_mgr->disp_obj, hnode,
1920			hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY],
1921			hnode->node_env, NODE_SUSPENDEDPRI);
1922
1923		/* Update state */
1924		if (status >= 0)
1925			NODE_SET_STATE(hnode, NODE_PAUSED);
1926
1927func_cont:
1928		/* End of sync_enter_cs */
1929		/* Leave critical section */
1930		mutex_unlock(&hnode_mgr->node_mgr_lock);
1931		if (status >= 0) {
1932			proc_notify_clients(hnode->processor,
1933					    DSP_NODESTATECHANGE);
1934			ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
1935		}
1936	}
1937func_end:
1938	dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
1939	return status;
1940}
1941
1942/*
1943 *  ======== node_put_message ========
1944 *  Purpose:
1945 *      Send a message to a message node, task node, or XDAIS socket node. This
1946 *      function will block until the message stream can accommodate the
1947 *      message, or a timeout occurs.
1948 */
1949int node_put_message(struct node_object *hnode,
1950			    const struct dsp_msg *pmsg, u32 utimeout)
1951{
1952	struct node_mgr *hnode_mgr = NULL;
1953	enum node_type node_type;
1954	struct bridge_drv_interface *intf_fxns;
1955	enum node_state state;
1956	int status = 0;
1957	void *tmp_buf;
1958	struct dsp_msg new_msg;
1959	struct dsp_processorstate proc_state;
1960	struct proc_object *hprocessor;
1961
1962	if (!hnode) {
1963		status = -EFAULT;
1964		goto func_end;
1965	}
1966	hprocessor = hnode->processor;
1967	status = proc_get_state(hprocessor, &proc_state,
1968				sizeof(struct dsp_processorstate));
1969	if (status)
1970		goto func_end;
1971	/* If processor is in bad state then don't attempt sending the
1972	   message */
1973	if (proc_state.proc_state == PROC_ERROR) {
1974		status = -EPERM;
1975		goto func_end;
1976	}
1977	hnode_mgr = hnode->node_mgr;
1978	node_type = node_get_type(hnode);
1979	if (node_type != NODE_MESSAGE && node_type != NODE_TASK &&
1980	    node_type != NODE_DAISSOCKET)
1981		status = -EPERM;
1982
1983	if (!status) {
1984		/*  Check node state. Can't send messages to a node after
1985		 *  we've sent the RMS_EXIT command. There is still the
1986		 *  possibility that node_terminate can be called after we've
1987		 *  checked the state. Could add another SYNC object to
1988		 *  prevent this (can't use node_mgr_lock, since we don't
1989		 *  want to block other NODE functions). However, the node may
1990		 *  still exit on its own, before this message is sent. */
1991		mutex_lock(&hnode_mgr->node_mgr_lock);
1992		state = node_get_state(hnode);
1993		if (state == NODE_TERMINATING || state == NODE_DONE)
1994			status = -EBADR;
1995
1996		/* end of sync_enter_cs */
1997		mutex_unlock(&hnode_mgr->node_mgr_lock);
1998	}
1999	if (status)
2000		goto func_end;
2001
2002	/* assign pmsg values to new msg */
2003	new_msg = *pmsg;
2004	/* Now, check if message contains a SM buffer descriptor */
2005	if (pmsg->cmd & DSP_RMSBUFDESC) {
2006		/* Translate GPP Va to DSP physical buf Ptr. */
2007		tmp_buf = cmm_xlator_translate(hnode->xlator,
2008					       (void *)new_msg.arg1,
2009					       CMM_VA2DSPPA);
2010		if (tmp_buf != NULL) {
2011			/* got translation, convert to MAUs in msg */
2012			if (hnode->node_mgr->dsp_word_size != 0) {
2013				new_msg.arg1 =
2014				    (u32) tmp_buf /
2015				    hnode->node_mgr->dsp_word_size;
2016				/* MAUs */
2017				new_msg.arg2 /= hnode->node_mgr->
2018				    dsp_word_size;
2019			} else {
2020				pr_err("%s: dsp_word_size is zero!\n",
2021				       __func__);
2022				status = -EPERM;	/* bad DSPWordSize */
2023			}
2024		} else {	/* failed to translate buffer address */
2025			status = -ESRCH;
2026		}
2027	}
2028	if (!status) {
2029		intf_fxns = hnode_mgr->intf_fxns;
2030		status = (*intf_fxns->msg_put) (hnode->msg_queue_obj,
2031						    &new_msg, utimeout);
2032	}
2033func_end:
2034	dev_dbg(bridge, "%s: hnode: %p pmsg: %p utimeout: 0x%x, "
2035		"status 0x%x\n", __func__, hnode, pmsg, utimeout, status);
2036	return status;
2037}
2038
2039/*
2040 *  ======== node_register_notify ========
2041 *  Purpose:
2042 *      Register to be notified on specific events for this node.
2043 */
2044int node_register_notify(struct node_object *hnode, u32 event_mask,
2045				u32 notify_type,
2046				struct dsp_notification *hnotification)
2047{
2048	struct bridge_drv_interface *intf_fxns;
2049	int status = 0;
2050
2051	if (!hnode) {
2052		status = -EFAULT;
2053	} else {
2054		/* Check if event mask is a valid node related event */
2055		if (event_mask & ~(DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY))
2056			status = -EINVAL;
2057
2058		/* Check if notify type is valid */
2059		if (notify_type != DSP_SIGNALEVENT)
2060			status = -EINVAL;
2061
2062		/* Only one Notification can be registered at a
2063		 * time - Limitation */
2064		if (event_mask == (DSP_NODESTATECHANGE | DSP_NODEMESSAGEREADY))
2065			status = -EINVAL;
2066	}
2067	if (!status) {
2068		if (event_mask == DSP_NODESTATECHANGE) {
2069			status = ntfy_register(hnode->ntfy_obj, hnotification,
2070					       event_mask & DSP_NODESTATECHANGE,
2071					       notify_type);
2072		} else {
2073			/* Send Message part of event mask to msg_ctrl */
2074			intf_fxns = hnode->node_mgr->intf_fxns;
2075			status = (*intf_fxns->msg_register_notify)
2076			    (hnode->msg_queue_obj,
2077			     event_mask & DSP_NODEMESSAGEREADY, notify_type,
2078			     hnotification);
2079		}
2080
2081	}
2082	dev_dbg(bridge, "%s: hnode: %p event_mask: 0x%x notify_type: 0x%x "
2083		"hnotification: %p status 0x%x\n", __func__, hnode,
2084		event_mask, notify_type, hnotification, status);
2085	return status;
2086}
2087
2088/*
2089 *  ======== node_run ========
2090 *  Purpose:
2091 *      Start execution of a node's execute phase, or resume execution of a node
2092 *      that has been suspended (via NODE_NodePause()) on the DSP. Load the
2093 *      node's execute function if necessary.
2094 */
2095int node_run(struct node_object *hnode)
2096{
2097	struct node_object *pnode = (struct node_object *)hnode;
2098	struct node_mgr *hnode_mgr;
2099	enum node_type node_type;
2100	enum node_state state;
2101	u32 ul_execute_fxn;
2102	u32 ul_fxn_addr;
2103	int status = 0;
2104	u32 proc_id;
2105	struct bridge_drv_interface *intf_fxns;
2106	struct dsp_processorstate proc_state;
2107	struct proc_object *hprocessor;
2108
2109	if (!hnode) {
2110		status = -EFAULT;
2111		goto func_end;
2112	}
2113	hprocessor = hnode->processor;
2114	status = proc_get_state(hprocessor, &proc_state,
2115				sizeof(struct dsp_processorstate));
2116	if (status)
2117		goto func_end;
2118	/* If processor is in error state then don't attempt to run the node */
2119	if (proc_state.proc_state == PROC_ERROR) {
2120		status = -EPERM;
2121		goto func_end;
2122	}
2123	node_type = node_get_type(hnode);
2124	if (node_type == NODE_DEVICE)
2125		status = -EPERM;
2126	if (status)
2127		goto func_end;
2128
2129	hnode_mgr = hnode->node_mgr;
2130	if (!hnode_mgr) {
2131		status = -EFAULT;
2132		goto func_end;
2133	}
2134	intf_fxns = hnode_mgr->intf_fxns;
2135	/* Enter critical section */
2136	mutex_lock(&hnode_mgr->node_mgr_lock);
2137
2138	state = node_get_state(hnode);
2139	if (state != NODE_CREATED && state != NODE_PAUSED)
2140		status = -EBADR;
2141
2142	if (!status)
2143		status = proc_get_processor_id(pnode->processor, &proc_id);
2144
2145	if (status)
2146		goto func_cont1;
2147
2148	if ((proc_id != DSP_UNIT) && (proc_id != IVA_UNIT))
2149		goto func_cont1;
2150
2151	if (state == NODE_CREATED) {
2152		/* If node's execute function is not loaded, load it */
2153		if (!(hnode->loaded) && hnode->phase_split) {
2154			status =
2155			    hnode_mgr->nldr_fxns.load(hnode->nldr_node_obj,
2156							  NLDR_EXECUTE);
2157			if (!status) {
2158				hnode->loaded = true;
2159			} else {
2160				pr_err("%s: fail - load execute code: 0x%x\n",
2161				       __func__, status);
2162			}
2163		}
2164		if (!status) {
2165			/* Get address of node's execute function */
2166			if (proc_id == IVA_UNIT)
2167				ul_execute_fxn = (u32) hnode->node_env;
2168			else {
2169				status = get_fxn_address(hnode, &ul_execute_fxn,
2170							 EXECUTEPHASE);
2171			}
2172		}
2173		if (!status) {
2174			ul_fxn_addr = hnode_mgr->fxn_addrs[RMSEXECUTENODE];
2175			status =
2176			    disp_node_run(hnode_mgr->disp_obj, hnode,
2177					  ul_fxn_addr, ul_execute_fxn,
2178					  hnode->node_env);
2179		}
2180	} else if (state == NODE_PAUSED) {
2181		ul_fxn_addr = hnode_mgr->fxn_addrs[RMSCHANGENODEPRIORITY];
2182		status = disp_node_change_priority(hnode_mgr->disp_obj, hnode,
2183						   ul_fxn_addr, hnode->node_env,
2184						   NODE_GET_PRIORITY(hnode));
2185	} else {
2186		/* We should never get here */
2187	}
2188func_cont1:
2189	/* Update node state. */
2190	if (status >= 0)
2191		NODE_SET_STATE(hnode, NODE_RUNNING);
2192	else			/* Set state back to previous value */
2193		NODE_SET_STATE(hnode, state);
2194	/*End of sync_enter_cs */
2195	/* Exit critical section */
2196	mutex_unlock(&hnode_mgr->node_mgr_lock);
2197	if (status >= 0) {
2198		proc_notify_clients(hnode->processor, DSP_NODESTATECHANGE);
2199		ntfy_notify(hnode->ntfy_obj, DSP_NODESTATECHANGE);
2200	}
2201func_end:
2202	dev_dbg(bridge, "%s: hnode: %p status 0x%x\n", __func__, hnode, status);
2203	return status;
2204}
2205
2206/*
2207 *  ======== node_terminate ========
2208 *  Purpose:
2209 *      Signal a node running on the DSP that it should exit its execute phase
2210 *      function.
2211 */
2212int node_terminate(struct node_object *hnode, int *pstatus)
2213{
2214	struct node_object *pnode = (struct node_object *)hnode;
2215	struct node_mgr *hnode_mgr = NULL;
2216	enum node_type node_type;
2217	struct bridge_drv_interface *intf_fxns;
2218	enum node_state state;
2219	struct dsp_msg msg, killmsg;
2220	int status = 0;
2221	u32 proc_id, kill_time_out;
2222	struct deh_mgr *hdeh_mgr;
2223	struct dsp_processorstate proc_state;
2224
2225	if (!hnode || !hnode->node_mgr) {
2226		status = -EFAULT;
2227		goto func_end;
2228	}
2229	if (pnode->processor == NULL) {
2230		status = -EFAULT;
2231		goto func_end;
2232	}
2233	status = proc_get_processor_id(pnode->processor, &proc_id);
2234
2235	if (!status) {
2236		hnode_mgr = hnode->node_mgr;
2237		node_type = node_get_type(hnode);
2238		if (node_type != NODE_TASK && node_type != NODE_DAISSOCKET)
2239			status = -EPERM;
2240	}
2241	if (!status) {
2242		/* Check node state */
2243		mutex_lock(&hnode_mgr->node_mgr_lock);
2244		state = node_get_state(hnode);
2245		if (state != NODE_RUNNING) {
2246			status = -EBADR;
2247			/* Set the exit status if node terminated on
2248			 * its own. */
2249			if (state == NODE_DONE)
2250				*pstatus = hnode->exit_status;
2251
2252		} else {
2253			NODE_SET_STATE(hnode, NODE_TERMINATING);
2254		}
2255		/* end of sync_enter_cs */
2256		mutex_unlock(&hnode_mgr->node_mgr_lock);
2257	}
2258	if (!status) {
2259		/*
2260		 *  Send exit message. Do not change state to NODE_DONE
2261		 *  here. That will be done in callback.
2262		 */
2263		status = proc_get_state(pnode->processor, &proc_state,
2264					sizeof(struct dsp_processorstate));
2265		if (status)
2266			goto func_cont;
2267		/* If processor is in error state then don't attempt to send
2268		 * A kill task command */
2269		if (proc_state.proc_state == PROC_ERROR) {
2270			status = -EPERM;
2271			goto func_cont;
2272		}
2273
2274		msg.cmd = RMS_EXIT;
2275		msg.arg1 = hnode->node_env;
2276		killmsg.cmd = RMS_KILLTASK;
2277		killmsg.arg1 = hnode->node_env;
2278		intf_fxns = hnode_mgr->intf_fxns;
2279
2280		if (hnode->timeout > MAXTIMEOUT)
2281			kill_time_out = MAXTIMEOUT;
2282		else
2283			kill_time_out = (hnode->timeout) * 2;
2284
2285		status = (*intf_fxns->msg_put) (hnode->msg_queue_obj, &msg,
2286						    hnode->timeout);
2287		if (status)
2288			goto func_cont;
2289
2290		/*
2291		 * Wait on synchronization object that will be
2292		 * posted in the callback on receiving RMS_EXIT
2293		 * message, or by node_delete. Check for valid hnode,
2294		 * in case posted by node_delete().
2295		 */
2296		status = sync_wait_on_event(hnode->sync_done,
2297					    kill_time_out / 2);
2298		if (status != ETIME)
2299			goto func_cont;
2300
2301		status = (*intf_fxns->msg_put)(hnode->msg_queue_obj,
2302						&killmsg, hnode->timeout);
2303		if (status)
2304			goto func_cont;
2305		status = sync_wait_on_event(hnode->sync_done,
2306					     kill_time_out / 2);
2307		if (status) {
2308			/*
2309			 * Here it goes the part of the simulation of
2310			 * the DSP exception.
2311			 */
2312			dev_get_deh_mgr(hnode_mgr->dev_obj, &hdeh_mgr);
2313			if (!hdeh_mgr)
2314				goto func_cont;
2315
2316			bridge_deh_notify(hdeh_mgr, DSP_SYSERROR, DSP_EXCEPTIONABORT);
2317		}
2318	}
2319func_cont:
2320	if (!status) {
2321		/* Enter CS before getting exit status, in case node was
2322		 * deleted. */
2323		mutex_lock(&hnode_mgr->node_mgr_lock);
2324		/* Make sure node wasn't deleted while we blocked */
2325		if (!hnode) {
2326			status = -EPERM;
2327		} else {
2328			*pstatus = hnode->exit_status;
2329			dev_dbg(bridge, "%s: hnode: %p env 0x%x status 0x%x\n",
2330				__func__, hnode, hnode->node_env, status);
2331		}
2332		mutex_unlock(&hnode_mgr->node_mgr_lock);
2333	}			/*End of sync_enter_cs */
2334func_end:
2335	return status;
2336}
2337
2338/*
2339 *  ======== delete_node ========
2340 *  Purpose:
2341 *      Free GPP resources allocated in node_allocate() or node_connect().
2342 */
2343static void delete_node(struct node_object *hnode,
2344			struct process_context *pr_ctxt)
2345{
2346	struct node_mgr *hnode_mgr;
2347	struct bridge_drv_interface *intf_fxns;
2348	u32 i;
2349	enum node_type node_type;
2350	struct stream_chnl stream;
2351	struct node_msgargs node_msg_args;
2352	struct node_taskargs task_arg_obj;
2353#ifdef DSP_DMM_DEBUG
2354	struct dmm_object *dmm_mgr;
2355	struct proc_object *p_proc_object =
2356	    (struct proc_object *)hnode->processor;
2357#endif
2358	int status;
2359	if (!hnode)
2360		goto func_end;
2361	hnode_mgr = hnode->node_mgr;
2362	if (!hnode_mgr)
2363		goto func_end;
2364
2365	node_type = node_get_type(hnode);
2366	if (node_type != NODE_DEVICE) {
2367		node_msg_args = hnode->create_args.asa.node_msg_args;
2368		kfree(node_msg_args.pdata);
2369
2370		/* Free msg_ctrl queue */
2371		if (hnode->msg_queue_obj) {
2372			intf_fxns = hnode_mgr->intf_fxns;
2373			(*intf_fxns->msg_delete_queue) (hnode->
2374							    msg_queue_obj);
2375			hnode->msg_queue_obj = NULL;
2376		}
2377
2378		kfree(hnode->sync_done);
2379
2380		/* Free all stream info */
2381		if (hnode->inputs) {
2382			for (i = 0; i < MAX_INPUTS(hnode); i++) {
2383				stream = hnode->inputs[i];
2384				free_stream(hnode_mgr, stream);
2385			}
2386			kfree(hnode->inputs);
2387			hnode->inputs = NULL;
2388		}
2389		if (hnode->outputs) {
2390			for (i = 0; i < MAX_OUTPUTS(hnode); i++) {
2391				stream = hnode->outputs[i];
2392				free_stream(hnode_mgr, stream);
2393			}
2394			kfree(hnode->outputs);
2395			hnode->outputs = NULL;
2396		}
2397		task_arg_obj = hnode->create_args.asa.task_arg_obj;
2398		if (task_arg_obj.strm_in_def) {
2399			for (i = 0; i < MAX_INPUTS(hnode); i++) {
2400				kfree(task_arg_obj.strm_in_def[i].sz_device);
2401				task_arg_obj.strm_in_def[i].sz_device = NULL;
2402			}
2403			kfree(task_arg_obj.strm_in_def);
2404			task_arg_obj.strm_in_def = NULL;
2405		}
2406		if (task_arg_obj.strm_out_def) {
2407			for (i = 0; i < MAX_OUTPUTS(hnode); i++) {
2408				kfree(task_arg_obj.strm_out_def[i].sz_device);
2409				task_arg_obj.strm_out_def[i].sz_device = NULL;
2410			}
2411			kfree(task_arg_obj.strm_out_def);
2412			task_arg_obj.strm_out_def = NULL;
2413		}
2414		if (task_arg_obj.dsp_heap_res_addr) {
2415			status = proc_un_map(hnode->processor, (void *)
2416					     task_arg_obj.dsp_heap_addr,
2417					     pr_ctxt);
2418
2419			status = proc_un_reserve_memory(hnode->processor,
2420							(void *)
2421							task_arg_obj.
2422							dsp_heap_res_addr,
2423							pr_ctxt);
2424#ifdef DSP_DMM_DEBUG
2425			status = dmm_get_handle(p_proc_object, &dmm_mgr);
2426			if (dmm_mgr)
2427				dmm_mem_map_dump(dmm_mgr);
2428			else
2429				status = DSP_EHANDLE;
2430#endif
2431		}
2432	}
2433	if (node_type != NODE_MESSAGE) {
2434		kfree(hnode->stream_connect);
2435		hnode->stream_connect = NULL;
2436	}
2437	kfree(hnode->str_dev_name);
2438	hnode->str_dev_name = NULL;
2439
2440	if (hnode->ntfy_obj) {
2441		ntfy_delete(hnode->ntfy_obj);
2442		kfree(hnode->ntfy_obj);
2443		hnode->ntfy_obj = NULL;
2444	}
2445
2446	/* These were allocated in dcd_get_object_def (via node_allocate) */
2447	kfree(hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn);
2448	hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn = NULL;
2449
2450	kfree(hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn);
2451	hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn = NULL;
2452
2453	kfree(hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn);
2454	hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn = NULL;
2455
2456	kfree(hnode->dcd_props.obj_data.node_obj.str_i_alg_name);
2457	hnode->dcd_props.obj_data.node_obj.str_i_alg_name = NULL;
2458
2459	/* Free all SM address translator resources */
2460	kfree(hnode->xlator);
2461	kfree(hnode->nldr_node_obj);
2462	hnode->nldr_node_obj = NULL;
2463	hnode->node_mgr = NULL;
2464	kfree(hnode);
2465	hnode = NULL;
2466func_end:
2467	return;
2468}
2469
2470/*
2471 *  ======== delete_node_mgr ========
2472 *  Purpose:
2473 *      Frees the node manager.
2474 */
2475static void delete_node_mgr(struct node_mgr *hnode_mgr)
2476{
2477	struct node_object *hnode, *tmp;
2478
2479	if (hnode_mgr) {
2480		/* Free resources */
2481		if (hnode_mgr->dcd_mgr)
2482			dcd_destroy_manager(hnode_mgr->dcd_mgr);
2483
2484		/* Remove any elements remaining in lists */
2485		list_for_each_entry_safe(hnode, tmp, &hnode_mgr->node_list,
2486				list_elem) {
2487			list_del(&hnode->list_elem);
2488			delete_node(hnode, NULL);
2489		}
2490		mutex_destroy(&hnode_mgr->node_mgr_lock);
2491		if (hnode_mgr->ntfy_obj) {
2492			ntfy_delete(hnode_mgr->ntfy_obj);
2493			kfree(hnode_mgr->ntfy_obj);
2494		}
2495
2496		if (hnode_mgr->disp_obj)
2497			disp_delete(hnode_mgr->disp_obj);
2498
2499		if (hnode_mgr->strm_mgr_obj)
2500			strm_delete(hnode_mgr->strm_mgr_obj);
2501
2502		/* Delete the loader */
2503		if (hnode_mgr->nldr_obj)
2504			hnode_mgr->nldr_fxns.delete(hnode_mgr->nldr_obj);
2505
2506		kfree(hnode_mgr);
2507	}
2508}
2509
2510/*
2511 *  ======== fill_stream_connect ========
2512 *  Purpose:
2513 *      Fills stream information.
2514 */
2515static void fill_stream_connect(struct node_object *node1,
2516				struct node_object *node2,
2517				u32 stream1, u32 stream2)
2518{
2519	u32 strm_index;
2520	struct dsp_streamconnect *strm1 = NULL;
2521	struct dsp_streamconnect *strm2 = NULL;
2522	enum node_type node1_type = NODE_TASK;
2523	enum node_type node2_type = NODE_TASK;
2524
2525	node1_type = node_get_type(node1);
2526	node2_type = node_get_type(node2);
2527	if (node1 != (struct node_object *)DSP_HGPPNODE) {
2528
2529		if (node1_type != NODE_DEVICE) {
2530			strm_index = node1->num_inputs +
2531			    node1->num_outputs - 1;
2532			strm1 = &(node1->stream_connect[strm_index]);
2533			strm1->cb_struct = sizeof(struct dsp_streamconnect);
2534			strm1->this_node_stream_index = stream1;
2535		}
2536
2537		if (node2 != (struct node_object *)DSP_HGPPNODE) {
2538			/* NODE == > NODE */
2539			if (node1_type != NODE_DEVICE) {
2540				strm1->connected_node = node2;
2541				strm1->ui_connected_node_id = node2->node_uuid;
2542				strm1->connected_node_stream_index = stream2;
2543				strm1->connect_type = CONNECTTYPE_NODEOUTPUT;
2544			}
2545			if (node2_type != NODE_DEVICE) {
2546				strm_index = node2->num_inputs +
2547				    node2->num_outputs - 1;
2548				strm2 = &(node2->stream_connect[strm_index]);
2549				strm2->cb_struct =
2550				    sizeof(struct dsp_streamconnect);
2551				strm2->this_node_stream_index = stream2;
2552				strm2->connected_node = node1;
2553				strm2->ui_connected_node_id = node1->node_uuid;
2554				strm2->connected_node_stream_index = stream1;
2555				strm2->connect_type = CONNECTTYPE_NODEINPUT;
2556			}
2557		} else if (node1_type != NODE_DEVICE)
2558			strm1->connect_type = CONNECTTYPE_GPPOUTPUT;
2559	} else {
2560		/* GPP == > NODE */
2561		strm_index = node2->num_inputs + node2->num_outputs - 1;
2562		strm2 = &(node2->stream_connect[strm_index]);
2563		strm2->cb_struct = sizeof(struct dsp_streamconnect);
2564		strm2->this_node_stream_index = stream2;
2565		strm2->connect_type = CONNECTTYPE_GPPINPUT;
2566	}
2567}
2568
2569/*
2570 *  ======== fill_stream_def ========
2571 *  Purpose:
2572 *      Fills Stream attributes.
2573 */
2574static void fill_stream_def(struct node_object *hnode,
2575			    struct node_strmdef *pstrm_def,
2576			    struct dsp_strmattr *pattrs)
2577{
2578	struct node_mgr *hnode_mgr = hnode->node_mgr;
2579
2580	if (pattrs != NULL) {
2581		pstrm_def->num_bufs = pattrs->num_bufs;
2582		pstrm_def->buf_size =
2583		    pattrs->buf_size / hnode_mgr->dsp_data_mau_size;
2584		pstrm_def->seg_id = pattrs->seg_id;
2585		pstrm_def->buf_alignment = pattrs->buf_alignment;
2586		pstrm_def->timeout = pattrs->timeout;
2587	} else {
2588		pstrm_def->num_bufs = DEFAULTNBUFS;
2589		pstrm_def->buf_size =
2590		    DEFAULTBUFSIZE / hnode_mgr->dsp_data_mau_size;
2591		pstrm_def->seg_id = DEFAULTSEGID;
2592		pstrm_def->buf_alignment = DEFAULTALIGNMENT;
2593		pstrm_def->timeout = DEFAULTTIMEOUT;
2594	}
2595}
2596
2597/*
2598 *  ======== free_stream ========
2599 *  Purpose:
2600 *      Updates the channel mask and frees the pipe id.
2601 */
2602static void free_stream(struct node_mgr *hnode_mgr, struct stream_chnl stream)
2603{
2604	/* Free up the pipe id unless other node has not yet been deleted. */
2605	if (stream.type == NODECONNECT) {
2606		if (test_bit(stream.dev_id, hnode_mgr->pipe_done_map)) {
2607			/* The other node has already been deleted */
2608			clear_bit(stream.dev_id, hnode_mgr->pipe_done_map);
2609			clear_bit(stream.dev_id, hnode_mgr->pipe_map);
2610		} else {
2611			/* The other node has not been deleted yet */
2612			set_bit(stream.dev_id, hnode_mgr->pipe_done_map);
2613		}
2614	} else if (stream.type == HOSTCONNECT) {
2615		if (stream.dev_id < hnode_mgr->num_chnls) {
2616			clear_bit(stream.dev_id, hnode_mgr->chnl_map);
2617		} else if (stream.dev_id < (2 * hnode_mgr->num_chnls)) {
2618			/* dsp-dma */
2619			clear_bit(stream.dev_id - (1 * hnode_mgr->num_chnls),
2620					hnode_mgr->dma_chnl_map);
2621		} else if (stream.dev_id < (3 * hnode_mgr->num_chnls)) {
2622			/* zero-copy */
2623			clear_bit(stream.dev_id - (2 * hnode_mgr->num_chnls),
2624					hnode_mgr->zc_chnl_map);
2625		}
2626	}
2627}
2628
2629/*
2630 *  ======== get_fxn_address ========
2631 *  Purpose:
2632 *      Retrieves the address for create, execute or delete phase for a node.
2633 */
2634static int get_fxn_address(struct node_object *hnode, u32 * fxn_addr,
2635				  u32 phase)
2636{
2637	char *pstr_fxn_name = NULL;
2638	struct node_mgr *hnode_mgr = hnode->node_mgr;
2639	int status = 0;
2640
2641	switch (phase) {
2642	case CREATEPHASE:
2643		pstr_fxn_name =
2644		    hnode->dcd_props.obj_data.node_obj.str_create_phase_fxn;
2645		break;
2646	case EXECUTEPHASE:
2647		pstr_fxn_name =
2648		    hnode->dcd_props.obj_data.node_obj.str_execute_phase_fxn;
2649		break;
2650	case DELETEPHASE:
2651		pstr_fxn_name =
2652		    hnode->dcd_props.obj_data.node_obj.str_delete_phase_fxn;
2653		break;
2654	default:
2655		/* Should never get here */
2656		break;
2657	}
2658
2659	status =
2660	    hnode_mgr->nldr_fxns.get_fxn_addr(hnode->nldr_node_obj,
2661						  pstr_fxn_name, fxn_addr);
2662
2663	return status;
2664}
2665
2666/*
2667 *  ======== get_node_info ========
2668 *  Purpose:
2669 *      Retrieves the node information.
2670 */
2671void get_node_info(struct node_object *hnode, struct dsp_nodeinfo *node_info)
2672{
2673	u32 i;
2674
2675	node_info->cb_struct = sizeof(struct dsp_nodeinfo);
2676	node_info->nb_node_database_props =
2677	    hnode->dcd_props.obj_data.node_obj.ndb_props;
2678	node_info->execution_priority = hnode->prio;
2679	node_info->device_owner = hnode->device_owner;
2680	node_info->number_streams = hnode->num_inputs + hnode->num_outputs;
2681	node_info->node_env = hnode->node_env;
2682
2683	node_info->ns_execution_state = node_get_state(hnode);
2684
2685	/* Copy stream connect data */
2686	for (i = 0; i < hnode->num_inputs + hnode->num_outputs; i++)
2687		node_info->sc_stream_connection[i] = hnode->stream_connect[i];
2688
2689}
2690
2691/*
2692 *  ======== get_node_props ========
2693 *  Purpose:
2694 *      Retrieve node properties.
2695 */
2696static int get_node_props(struct dcd_manager *hdcd_mgr,
2697				 struct node_object *hnode,
2698				 const struct dsp_uuid *node_uuid,
2699				 struct dcd_genericobj *dcd_prop)
2700{
2701	u32 len;
2702	struct node_msgargs *pmsg_args;
2703	struct node_taskargs *task_arg_obj;
2704	enum node_type node_type = NODE_TASK;
2705	struct dsp_ndbprops *pndb_props =
2706	    &(dcd_prop->obj_data.node_obj.ndb_props);
2707	int status = 0;
2708	char sz_uuid[MAXUUIDLEN];
2709
2710	status = dcd_get_object_def(hdcd_mgr, (struct dsp_uuid *)node_uuid,
2711				    DSP_DCDNODETYPE, dcd_prop);
2712
2713	if (!status) {
2714		hnode->ntype = node_type = pndb_props->ntype;
2715
2716		/* Create UUID value to set in registry. */
2717		uuid_uuid_to_string((struct dsp_uuid *)node_uuid, sz_uuid,
2718				    MAXUUIDLEN);
2719		dev_dbg(bridge, "(node) UUID: %s\n", sz_uuid);
2720
2721		/* Fill in message args that come from NDB */
2722		if (node_type != NODE_DEVICE) {
2723			pmsg_args = &(hnode->create_args.asa.node_msg_args);
2724			pmsg_args->seg_id =
2725			    dcd_prop->obj_data.node_obj.msg_segid;
2726			pmsg_args->notify_type =
2727			    dcd_prop->obj_data.node_obj.msg_notify_type;
2728			pmsg_args->max_msgs = pndb_props->message_depth;
2729			dev_dbg(bridge, "(node) Max Number of Messages: 0x%x\n",
2730				pmsg_args->max_msgs);
2731		} else {
2732			/* Copy device name */
2733			len = strlen(pndb_props->ac_name);
2734			hnode->str_dev_name = kzalloc(len + 1, GFP_KERNEL);
2735			if (hnode->str_dev_name == NULL) {
2736				status = -ENOMEM;
2737			} else {
2738				strncpy(hnode->str_dev_name,
2739					pndb_props->ac_name, len);
2740			}
2741		}
2742	}
2743	if (!status) {
2744		/* Fill in create args that come from NDB */
2745		if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
2746			task_arg_obj = &(hnode->create_args.asa.task_arg_obj);
2747			task_arg_obj->prio = pndb_props->prio;
2748			task_arg_obj->stack_size = pndb_props->stack_size;
2749			task_arg_obj->sys_stack_size =
2750			    pndb_props->sys_stack_size;
2751			task_arg_obj->stack_seg = pndb_props->stack_seg;
2752			dev_dbg(bridge, "(node) Priority: 0x%x Stack Size: "
2753				"0x%x words System Stack Size: 0x%x words "
2754				"Stack Segment: 0x%x profile count : 0x%x\n",
2755				task_arg_obj->prio, task_arg_obj->stack_size,
2756				task_arg_obj->sys_stack_size,
2757				task_arg_obj->stack_seg,
2758				pndb_props->count_profiles);
2759		}
2760	}
2761
2762	return status;
2763}
2764
2765/*
2766 *  ======== get_proc_props ========
2767 *  Purpose:
2768 *      Retrieve the processor properties.
2769 */
2770static int get_proc_props(struct node_mgr *hnode_mgr,
2771				 struct dev_object *hdev_obj)
2772{
2773	struct cfg_hostres *host_res;
2774	struct bridge_dev_context *pbridge_context;
2775	int status = 0;
2776
2777	status = dev_get_bridge_context(hdev_obj, &pbridge_context);
2778	if (!pbridge_context)
2779		status = -EFAULT;
2780
2781	if (!status) {
2782		host_res = pbridge_context->resources;
2783		if (!host_res)
2784			return -EPERM;
2785		hnode_mgr->chnl_offset = host_res->chnl_offset;
2786		hnode_mgr->chnl_buf_size = host_res->chnl_buf_size;
2787		hnode_mgr->num_chnls = host_res->num_chnls;
2788
2789		/*
2790		 *  PROC will add an API to get dsp_processorinfo.
2791		 *  Fill in default values for now.
2792		 */
2793		/* TODO -- Instead of hard coding, take from registry */
2794		hnode_mgr->proc_family = 6000;
2795		hnode_mgr->proc_type = 6410;
2796		hnode_mgr->min_pri = DSP_NODE_MIN_PRIORITY;
2797		hnode_mgr->max_pri = DSP_NODE_MAX_PRIORITY;
2798		hnode_mgr->dsp_word_size = DSPWORDSIZE;
2799		hnode_mgr->dsp_data_mau_size = DSPWORDSIZE;
2800		hnode_mgr->dsp_mau_size = 1;
2801
2802	}
2803	return status;
2804}
2805
2806/*
2807 *  ======== node_get_uuid_props ========
2808 *  Purpose:
2809 *      Fetch Node UUID properties from DCD/DOF file.
2810 */
2811int node_get_uuid_props(void *hprocessor,
2812			       const struct dsp_uuid *node_uuid,
2813			       struct dsp_ndbprops *node_props)
2814{
2815	struct node_mgr *hnode_mgr = NULL;
2816	struct dev_object *hdev_obj;
2817	int status = 0;
2818	struct dcd_nodeprops dcd_node_props;
2819	struct dsp_processorstate proc_state;
2820
2821	if (hprocessor == NULL || node_uuid == NULL) {
2822		status = -EFAULT;
2823		goto func_end;
2824	}
2825	status = proc_get_state(hprocessor, &proc_state,
2826				sizeof(struct dsp_processorstate));
2827	if (status)
2828		goto func_end;
2829	/* If processor is in error state then don't attempt
2830	   to send the message */
2831	if (proc_state.proc_state == PROC_ERROR) {
2832		status = -EPERM;
2833		goto func_end;
2834	}
2835
2836	status = proc_get_dev_object(hprocessor, &hdev_obj);
2837	if (hdev_obj) {
2838		status = dev_get_node_manager(hdev_obj, &hnode_mgr);
2839		if (hnode_mgr == NULL) {
2840			status = -EFAULT;
2841			goto func_end;
2842		}
2843	}
2844
2845	/*
2846	 * Enter the critical section. This is needed because
2847	 * dcd_get_object_def will ultimately end up calling dbll_open/close,
2848	 * which needs to be protected in order to not corrupt the zlib manager
2849	 * (COD).
2850	 */
2851	mutex_lock(&hnode_mgr->node_mgr_lock);
2852
2853	dcd_node_props.str_create_phase_fxn = NULL;
2854	dcd_node_props.str_execute_phase_fxn = NULL;
2855	dcd_node_props.str_delete_phase_fxn = NULL;
2856	dcd_node_props.str_i_alg_name = NULL;
2857
2858	status = dcd_get_object_def(hnode_mgr->dcd_mgr,
2859		(struct dsp_uuid *)node_uuid, DSP_DCDNODETYPE,
2860		(struct dcd_genericobj *)&dcd_node_props);
2861
2862	if (!status) {
2863		*node_props = dcd_node_props.ndb_props;
2864		kfree(dcd_node_props.str_create_phase_fxn);
2865
2866		kfree(dcd_node_props.str_execute_phase_fxn);
2867
2868		kfree(dcd_node_props.str_delete_phase_fxn);
2869
2870		kfree(dcd_node_props.str_i_alg_name);
2871	}
2872	/*  Leave the critical section, we're done. */
2873	mutex_unlock(&hnode_mgr->node_mgr_lock);
2874func_end:
2875	return status;
2876}
2877
2878/*
2879 *  ======== get_rms_fxns ========
2880 *  Purpose:
2881 *      Retrieve the RMS functions.
2882 */
2883static int get_rms_fxns(struct node_mgr *hnode_mgr)
2884{
2885	s32 i;
2886	struct dev_object *dev_obj = hnode_mgr->dev_obj;
2887	int status = 0;
2888
2889	static char *psz_fxns[NUMRMSFXNS] = {
2890		"RMS_queryServer",	/* RMSQUERYSERVER */
2891		"RMS_configureServer",	/* RMSCONFIGURESERVER */
2892		"RMS_createNode",	/* RMSCREATENODE */
2893		"RMS_executeNode",	/* RMSEXECUTENODE */
2894		"RMS_deleteNode",	/* RMSDELETENODE */
2895		"RMS_changeNodePriority",	/* RMSCHANGENODEPRIORITY */
2896		"RMS_readMemory",	/* RMSREADMEMORY */
2897		"RMS_writeMemory",	/* RMSWRITEMEMORY */
2898		"RMS_copy",	/* RMSCOPY */
2899	};
2900
2901	for (i = 0; i < NUMRMSFXNS; i++) {
2902		status = dev_get_symbol(dev_obj, psz_fxns[i],
2903					&(hnode_mgr->fxn_addrs[i]));
2904		if (status) {
2905			if (status == -ESPIPE) {
2906				/*
2907				 *  May be loaded dynamically (in the future),
2908				 *  but return an error for now.
2909				 */
2910				dev_dbg(bridge, "%s: RMS function: %s currently"
2911					" not loaded\n", __func__, psz_fxns[i]);
2912			} else {
2913				dev_dbg(bridge, "%s: Symbol not found: %s "
2914					"status = 0x%x\n", __func__,
2915					psz_fxns[i], status);
2916				break;
2917			}
2918		}
2919	}
2920
2921	return status;
2922}
2923
2924/*
2925 *  ======== ovly ========
2926 *  Purpose:
2927 *      Called during overlay.Sends command to RMS to copy a block of data.
2928 */
2929static u32 ovly(void *priv_ref, u32 dsp_run_addr, u32 dsp_load_addr,
2930		u32 ul_num_bytes, u32 mem_space)
2931{
2932	struct node_object *hnode = (struct node_object *)priv_ref;
2933	struct node_mgr *hnode_mgr;
2934	u32 ul_bytes = 0;
2935	u32 ul_size;
2936	u32 ul_timeout;
2937	int status = 0;
2938	struct bridge_dev_context *hbridge_context;
2939	/* Function interface to Bridge driver*/
2940	struct bridge_drv_interface *intf_fxns;
2941
2942	hnode_mgr = hnode->node_mgr;
2943
2944	ul_size = ul_num_bytes / hnode_mgr->dsp_word_size;
2945	ul_timeout = hnode->timeout;
2946
2947	/* Call new MemCopy function */
2948	intf_fxns = hnode_mgr->intf_fxns;
2949	status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context);
2950	if (!status) {
2951		status =
2952		    (*intf_fxns->brd_mem_copy) (hbridge_context,
2953						dsp_run_addr, dsp_load_addr,
2954						ul_num_bytes, (u32) mem_space);
2955		if (!status)
2956			ul_bytes = ul_num_bytes;
2957		else
2958			pr_debug("%s: failed to copy brd memory, status 0x%x\n",
2959				 __func__, status);
2960	} else {
2961		pr_debug("%s: failed to get Bridge context, status 0x%x\n",
2962			 __func__, status);
2963	}
2964
2965	return ul_bytes;
2966}
2967
2968/*
2969 *  ======== mem_write ========
2970 */
2971static u32 mem_write(void *priv_ref, u32 dsp_add, void *pbuf,
2972		     u32 ul_num_bytes, u32 mem_space)
2973{
2974	struct node_object *hnode = (struct node_object *)priv_ref;
2975	struct node_mgr *hnode_mgr;
2976	u16 mem_sect_type;
2977	u32 ul_timeout;
2978	int status = 0;
2979	struct bridge_dev_context *hbridge_context;
2980	/* Function interface to Bridge driver */
2981	struct bridge_drv_interface *intf_fxns;
2982
2983	hnode_mgr = hnode->node_mgr;
2984
2985	ul_timeout = hnode->timeout;
2986	mem_sect_type = (mem_space & DBLL_CODE) ? RMS_CODE : RMS_DATA;
2987
2988	/* Call new MemWrite function */
2989	intf_fxns = hnode_mgr->intf_fxns;
2990	status = dev_get_bridge_context(hnode_mgr->dev_obj, &hbridge_context);
2991	status = (*intf_fxns->brd_mem_write) (hbridge_context, pbuf,
2992					dsp_add, ul_num_bytes, mem_sect_type);
2993
2994	return ul_num_bytes;
2995}
2996
2997#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
2998/*
2999 *  ======== node_find_addr ========
3000 */
3001int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
3002		u32 offset_range, void *sym_addr_output, char *sym_name)
3003{
3004	struct node_object *node_obj;
3005	int status = -ENOENT;
3006
3007	pr_debug("%s(0x%x, 0x%x, 0x%x, 0x%x,  %s)\n", __func__,
3008			(unsigned int) node_mgr,
3009			sym_addr, offset_range,
3010			(unsigned int) sym_addr_output, sym_name);
3011
3012	list_for_each_entry(node_obj, &node_mgr->node_list, list_elem) {
3013		status = nldr_find_addr(node_obj->nldr_node_obj, sym_addr,
3014			offset_range, sym_addr_output, sym_name);
3015		if (!status)
3016			break;
3017	}
3018
3019	return status;
3020}
3021#endif
3022