DSPNode.c revision cbd96ffef4bc147078d4dafa64e27a38cba16289
1/*
2 * dspbridge/src/api/linux/DSPNode.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * Copyright (C) 2007 Texas Instruments, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published
10 * by the Free Software Foundation version 2.1 of the License.
11 *
12 * This program is distributed .as is. WITHOUT ANY WARRANTY of any kind,
13 * whether express or implied; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 */
17
18
19/*
20 *  ======== DSPNode.c ========
21 *  Description:
22 *      This is the source for the DSP/BIOS Bridge API node module. The
23 *      parameters are validated at the API level, but the bulk of the
24 *      work is done at the driver level through the RM NODE module.
25 *
26 *  Public Functions:
27 *      DSPNode_Allocate
28 *      DSPNode_AllocMsgBuf
29 *      DSPNode_ChangePriority
30 *      DSPNode_Connect
31 *      DSPNode_ConnectEx
32 *      DSPNode_Create
33 *      DSPNode_Delete
34 *      DSPNode_FreeMsgBuf
35 *      DSPNode_GetAttr
36 *      DSPNode_GetMessage
37 *      DSPNode_Pause
38 *      DSPNode_PutMessage
39 *      DSPNode_RegisterNotify
40 *      DSPNode_Run
41 *      DSPNode_Terminate
42 *
43 *! Revision History
44 *! ================
45 *! 14-Mar-2002 map Set *pBuffer to null before returning error status in
46 *!		            DSPNode_AllocMsgBuf.
47 *! 01-Oct-2001 rr  CMM error codes are converted to DSP_STATUS in
48 *!                 DSPNode_Allocate.
49 *! 11-Sep-2001 ag  Zero-copy message support.
50 *! 08-Jun-2001 jeh Fixed priority range check in DSPNode_ChangePriority.
51 *! 23-Apr-2001 jeh Added pStatus parameter to DSPNode_Terminate.
52 *! 06-Feb-2001 kc: Added check for alignment value in DSPNode_AllocMsgBuf
53 *! 08-Dec-2000 ag  Added alignment to DSPNode_AllocMsgBuf().
54 *! 05-Dec-2000 ag  Added SM support to DSPNode_[Alloc][Free]MsgBuf().
55 *! 09-Nov-2000 rr: Code cleaned up. Use of IsValidEvent/Mask Macros.
56 *! 27-Oct-2000 jeh Updated to version 0.9 of API spec.
57 *! 07-Sep-2000 jeh Changed type HANDLE in DSPNode_RegisterNotify to
58 *!                 DSP_HNOTIFICATION. Added DSP_STRMATTR param to
59 *!                 DSPNode_Connect.
60 *! 04-Aug-2000 rr: Name changed to DSPNode.c
61 *! 27-Jul-2000 rr: Types updated to ver 0.8 API.
62 *! 18-Jul-2000 rr: Node calls into the Class driver.
63 *!                 Only parameters are validated here.
64 *! 17-May-2000 rr: DSPNode_Connect checks for GHPPNODE.
65 *! 15-May-2000 gp: Made input args to DSPNode_Allocate() CONST.
66 *!                 Return DSP_ENOTIMPL from DSPNode_ChangePriority().
67 *! 02-May-2000 rr: Reg functions use SERVICES.
68 *! 12-Apr-2000 ww: Created based on DirectDSP API specification, Version 0.6.
69 *
70 */
71
72/*  ----------------------------------- Host OS */
73#include <host_os.h>
74#include <stdlib.h>
75#include <malloc.h>
76
77/*  ----------------------------------- DSP/BIOS Bridge */
78#include <dbdefs.h>
79#include <errbase.h>
80
81/*  ----------------------------------- Trace & Debug */
82#include <dbg.h>
83#include <dbg_zones.h>
84
85/*  ----------------------------------- Resource Manager */
86#include <memry.h>
87
88/*  ----------------------------------- Others */
89#include <dsptrap.h>
90
91/*  ----------------------------------- This */
92#include "_dbdebug.h"
93#include "_dbpriv.h"
94
95#include <DSPNode.h>
96
97#ifdef DEBUG_BRIDGE_PERF
98#include <perfutils.h>
99#endif
100
101/*  ----------------------------------- Globals */
102extern int hMediaFile;		/* class driver handle */
103
104/* Declared here, not to users */
105DSP_STATUS GetNodeType(DSP_HNODE hNode, DSP_NODETYPE *pNodeType);
106
107/*
108 *  ======== DSPNode_Allocate ========
109 *  Purpose:
110 *      Allocate data structures for controlling and communicating
111 *      with a node on a specific DSP processor..
112 */
113DBAPI DSPNode_Allocate(DSP_HPROCESSOR hProcessor,
114		 IN CONST struct DSP_UUID *pNodeID,
115		 IN CONST OPTIONAL struct DSP_CBDATA *pArgs,
116		 IN OPTIONAL struct DSP_NODEATTRIN *pAttrIn,
117		 OUT DSP_HNODE *phNode)
118{
119	DSP_STATUS status = DSP_SOK;
120	Trapped_Args tempStruct;
121	struct CMM_OBJECT *hCmm;		/* shared memory mngr handle */
122	struct CMM_INFO pInfo;		/* Used for virtual space allocation */
123	PVOID pVirtBase;
124	struct DSP_BUFFERATTR bufAttr;
125    DSP_NODETYPE nodeType;
126    struct DSP_NDBPROPS    nodeProps;
127    UINT            heapSize = 0;
128    PVOID           pGPPVirtAddr = NULL;
129    UINT            uProfileID;
130	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Allocate:\r\n")));
131	if (!hProcessor) {
132		status = DSP_EHANDLE;
133		DEBUGMSG(DSPAPI_ZONE_ERROR,
134			(TEXT("NODE: DSPNode_Allocate: "
135				"hProcessor is Invalid \r\n")));
136		goto func_cont;
137	}
138	if (!(pNodeID) || !(phNode)) {
139		status = DSP_EPOINTER;
140		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Allocate: "
141			"Invalid pointer in the Input\r\n")));
142		goto func_cont;
143	}
144	/* First get the NODE properties, allocate, reserve
145				memory for Node heap */
146	if (pAttrIn) {
147		status = DSPNode_GetUUIDProps(hProcessor, pNodeID, &nodeProps);
148		pAttrIn->pGPPVirtAddr = NULL;
149		if (DSP_SUCCEEDED(status)) {
150			uProfileID = pAttrIn->uProfileID;
151			DEBUGMSG(DSPAPI_ZONE_FUNCTION,
152					("DSPNodeAllocate: User requested"
153						  "node heap profile \n"));
154			if (uProfileID < nodeProps.uCountProfiles)
155				heapSize =
156				nodeProps.aProfiles[uProfileID].ulHeapSize;
157			if (heapSize) {
158				/* allocate heap memory */
159				/* Make heap size multiple of page size * */
160				heapSize = PG_ALIGN_HIGH(heapSize, PG_SIZE_4K);
161				/* align memory on cache line boundary * */
162				pGPPVirtAddr = memalign(GEM_CACHE_LINE_SIZE,
163							heapSize);
164				DEBUGMSG(DSPAPI_ZONE_FUNCTION,
165					("DSPNodeAllocate: Node heap memory"
166							  "addr, size \n"));
167				if ((pGPPVirtAddr == NULL))
168					status = DSP_EMEMORY;
169				pAttrIn->uHeapSize = heapSize;
170				pAttrIn->pGPPVirtAddr = pGPPVirtAddr;
171			}
172		} else {
173			DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT(
174				"NODE:DSPNode_Allocate: Failed to get Node "
175				"UUID properties \r\n")));
176		}
177	}
178	if (DSP_SUCCEEDED(status)) {
179		/* Set up the structure  Call DSP Trap */
180		tempStruct.ARGS_NODE_ALLOCATE.hProcessor = hProcessor;
181		tempStruct.ARGS_NODE_ALLOCATE.pNodeID =
182						(struct DSP_UUID *)pNodeID;
183		tempStruct.ARGS_NODE_ALLOCATE.pArgs =
184						(struct DSP_CBDATA *)pArgs;
185		tempStruct.ARGS_NODE_ALLOCATE.pAttrIn =
186					(struct DSP_NODEATTRIN *)pAttrIn;
187		tempStruct.ARGS_NODE_ALLOCATE.phNode = phNode;
188		status = DSPTRAP_Trap(&tempStruct, CMD_NODE_ALLOCATE_OFFSET);
189	}
190func_cont:
191	 /* If 1st SM segment is configured then allocate and map it to
192		this process.*/
193	if (!DSP_SUCCEEDED(status)) {
194		if (pGPPVirtAddr)
195			free(pGPPVirtAddr);
196		return status;
197	}
198	tempStruct.ARGS_CMM_GETHANDLE.hProcessor = hProcessor;
199	tempStruct.ARGS_CMM_GETHANDLE.phCmmMgr = &hCmm;
200	status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETHANDLE_OFFSET);
201	if (DSP_SUCCEEDED(status)) {
202		/* Get SM segment info from CMM */
203		tempStruct.ARGS_CMM_GETINFO.hCmmMgr = hCmm;
204		tempStruct.ARGS_CMM_GETINFO.pCmmInfo = &pInfo;
205		status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETINFO_OFFSET);
206		if (DSP_FAILED(status)) {
207			status = DSP_EFAIL;
208			DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT(
209			"NODE: DSPNode_Allocate: "
210			"Failed to get SM segment\r\n")));
211		} else
212			status = DSP_SOK;
213
214	} else {
215		status = DSP_EFAIL;
216		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT(
217			"NODE: DSPNode_Allocate:Failed to CMM handle\r\n")));
218	}
219	if (!DSP_SUCCEEDED(status)) {
220		free(pGPPVirtAddr);
221		return status;
222	}
223
224	GetNodeType(*phNode, &nodeType);
225	if ((nodeType != NODE_DEVICE) && (pInfo.ulNumGPPSMSegs > 0)) {
226		/* Messaging uses 1st segment */
227		if ((pInfo.segInfo[0].dwSegBasePa != 0) &&
228		    (pInfo.segInfo[0].ulTotalSegSize) > 0) {
229			pVirtBase = mmap(NULL, pInfo.segInfo[0].ulTotalSegSize,
230				 PROT_READ | PROT_WRITE, MAP_SHARED |
231				 MAP_LOCKED, hMediaFile,
232				 pInfo.segInfo[0].dwSegBasePa);
233			if (!pVirtBase) {
234				DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: "
235				"DSPNode_Allocate:Virt alloc failed\r\n")));
236				status = DSP_EMEMORY;
237				/* Clean up */
238				tempStruct.ARGS_NODE_DELETE.hNode = *phNode;
239				DSPTRAP_Trap(&tempStruct,
240					CMD_NODE_DELETE_OFFSET);
241				return status;
242			}
243			/* set node translator's virt addr range for seg */
244			bufAttr.uAlignment = 0;
245			bufAttr.uSegment = 1 | MEMRY_SETVIRTUALSEGID;
246			bufAttr.cbStruct = 0;
247			status = DSPNode_AllocMsgBuf(*phNode,
248					pInfo.segInfo[0].ulTotalSegSize,
249					&bufAttr, (BYTE **)&pVirtBase);
250			if (DSP_FAILED(status)) {
251				/* If failed to set segment, unmap */
252				munmap(pVirtBase,
253					pInfo.segInfo[0].ulTotalSegSize);
254				/* Clean up */
255				tempStruct.ARGS_NODE_DELETE.hNode = *phNode;
256				DSPTRAP_Trap(&tempStruct,
257					CMD_NODE_DELETE_OFFSET);
258			}
259		}
260	}
261    return status;
262}
263
264/*
265 *  ======== DSPNode_AllocMsgBuf ========
266 */
267DBAPI DSPNode_AllocMsgBuf(DSP_HNODE hNode, UINT uSize,
268		   IN OPTIONAL struct DSP_BUFFERATTR *pAttr, OUT BYTE **pBuffer)
269{
270	DSP_STATUS status = DSP_SOK;
271	Trapped_Args tempStruct;
272	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
273		(TEXT("NODE: DSPNode_AllocMsgBuf:\r\n")));
274
275	if (uSize == 0) {
276		status = DSP_ESIZE;
277		if (pBuffer)
278			*pBuffer = NULL;
279
280	} else if (hNode) {
281		if (pBuffer) {
282			/* Set up the structure */
283			tempStruct.ARGS_NODE_ALLOCMSGBUF.hNode = hNode;
284			tempStruct.ARGS_NODE_ALLOCMSGBUF.uSize = uSize;
285			tempStruct.ARGS_NODE_ALLOCMSGBUF.pAttr = pAttr;
286			/* Va Base */
287			tempStruct.ARGS_NODE_ALLOCMSGBUF.pBuffer = pBuffer;
288			/* Call DSP Trap */
289			status = DSPTRAP_Trap(&tempStruct,
290				CMD_NODE_ALLOCMSGBUF_OFFSET);
291			if (DSP_SUCCEEDED(status)) {
292				if (*pBuffer == NULL) {
293					DEBUGMSG(DSPAPI_ZONE_FUNCTION,
294					(TEXT("NODE: DSPNode_AllocMsgBuf: "
295					"No SM\r\n")));
296					status = DSP_EMEMORY;	/* No SM */
297				}
298			} else
299				*pBuffer = NULL;
300
301		} else {
302			/* Invalid pointer */
303			status = DSP_EPOINTER;
304			DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: "
305			"DSPNode_AllocBuf: Invalid pointer in the Input\r\n")));
306		}
307	} else {
308		/* Invalid handle */
309		status = DSP_EHANDLE;
310		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_AllocMsgBuf: "
311						"hNode is Invalid \r\n")));
312		if (pBuffer)
313			*pBuffer = NULL;
314
315	}
316
317	return status;
318}
319
320/*
321 *  ======== DSPNode_ChangePriority ========
322 *  Purpose:
323 *      Change a task node's runtime priority within the DSP RTOS.
324 */
325DBAPI DSPNode_ChangePriority(DSP_HNODE hNode, INT iPriority)
326{
327	DSP_STATUS status = DSP_SOK;
328	Trapped_Args tempStruct;
329
330	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
331			(TEXT("NODE: DSPNode_ChangePriority:\r\n")));
332
333	if (hNode) {
334		/* Set up the structure */
335		if (iPriority >= DSP_NODE_MIN_PRIORITY &&
336		    iPriority <= DSP_NODE_MAX_PRIORITY) {
337			/* Call DSP Trap */
338			tempStruct.ARGS_NODE_CHANGEPRIORITY.hNode = hNode;
339			tempStruct.ARGS_NODE_CHANGEPRIORITY.iPriority =
340							iPriority;
341			status = DSPTRAP_Trap(&tempStruct,
342					CMD_NODE_CHANGEPRIORITY_OFFSET);
343		} else
344			status = DSP_ERANGE;
345
346	} else {
347		/* Invalid pointer */
348		status = DSP_EHANDLE;
349		DEBUGMSG(DSPAPI_ZONE_ERROR,
350			(TEXT("NODE: DSPNode_ChangePriority: "
351			"hNode is Invalid \r\n")));
352	}
353
354	return status;
355}
356
357/*
358 *  ======== DSPNode_Connect ========
359 *  Purpose:
360 *      Make a stream connection, either between two nodes on a DSP,
361 *      or between a node on a DSP and the GPP.
362 */
363DBAPI DSPNode_Connect(DSP_HNODE hNode, UINT uStream, DSP_HNODE hOtherNode,
364		UINT uOtherStream, IN OPTIONAL struct DSP_STRMATTR *pAttrs)
365{
366	return DSPNode_ConnectEx(hNode, uStream, hOtherNode, uOtherStream,
367				 pAttrs, NULL);
368}
369
370/*
371 *  ======== DSPNode_ConnectEx ========
372 *  Purpose:
373 *      Make a stream connection, either between two nodes on a DSP,
374 *      or between a node on a DSP and the GPP.
375 */
376DBAPI DSPNode_ConnectEx(DSP_HNODE hNode, UINT uStream, DSP_HNODE hOtherNode,
377		  UINT uOtherStream, IN OPTIONAL struct DSP_STRMATTR *pAttrs,
378		  IN OPTIONAL struct DSP_CBDATA *pConnParam)
379{
380	DSP_STATUS status = DSP_SOK;
381	Trapped_Args tempStruct;
382
383	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_ConnectEx:\r\n")));
384
385	if ((hNode) && (hOtherNode)) {
386		/* Set up the structure */
387		/* Call DSP Trap */
388		tempStruct.ARGS_NODE_CONNECT.hNode = hNode;
389		tempStruct.ARGS_NODE_CONNECT.uStream = uStream;
390		tempStruct.ARGS_NODE_CONNECT.hOtherNode = hOtherNode;
391		tempStruct.ARGS_NODE_CONNECT.uOtherStream = uOtherStream;
392		tempStruct.ARGS_NODE_CONNECT.pAttrs = pAttrs;
393		tempStruct.ARGS_NODE_CONNECT.pConnParam = pConnParam;
394		status = DSPTRAP_Trap(&tempStruct, CMD_NODE_CONNECT_OFFSET);
395	} else {
396		/* Invalid pointer */
397		status = DSP_EHANDLE;
398		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Connect: "
399		"hNode or hOtherNode is Invalid Handle\r\n")));
400	}
401
402	return status;
403}
404
405/*
406 *  ======== DSPNode_Create ========
407 *  Purpose:
408 *      Create a node in a pre-run (i.e., inactive) state on its
409 *		DSP processor.
410 */
411DBAPI DSPNode_Create(DSP_HNODE hNode)
412{
413	DSP_STATUS status = DSP_SOK;
414	Trapped_Args tempStruct;
415#ifdef DEBUG_BRIDGE_PERF
416	struct timeval tv_beg;
417	struct timeval tv_end;
418	struct timezone tz;
419	int timeRetVal = 0;
420
421	timeRetVal = getTimeStamp(&tv_beg);
422#endif
423
424
425	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Create:\r\n")));
426
427	if (hNode) {
428		/* Set up the structure */
429		/* Call DSP Trap */
430		tempStruct.ARGS_NODE_CREATE.hNode = hNode;
431		status = DSPTRAP_Trap(&tempStruct, CMD_NODE_CREATE_OFFSET);
432	} else {
433		/* Invalid pointer */
434		status = DSP_EHANDLE;
435		DEBUGMSG(DSPAPI_ZONE_ERROR,
436		(TEXT("NODE: DSPNode_Create: hNode is Invalid Handle\r\n")));
437	}
438
439#ifdef DEBUG_BRIDGE_PERF
440	timeRetVal = getTimeStamp(&tv_end);
441	PrintStatistics(&tv_beg, &tv_end, "DSPNode_Create", 0);
442
443#endif
444
445	return status;
446}
447
448/*
449 *  ======== DSPNode_Delete ========
450 *  Purpose:
451 *      Delete all DSP-side and GPP-side resources for the node.
452 */
453DBAPI DSPNode_Delete(DSP_HNODE hNode)
454{
455	DSP_STATUS status = DSP_SOK;
456	Trapped_Args tempStruct;
457	BYTE *pVirtBase = NULL;
458	struct DSP_BUFFERATTR bufAttr;
459	struct CMM_OBJECT *hCmm;		/* shared memory mngr handle */
460	struct CMM_INFO pInfo;		/* Used for virtual space allocation */
461	DSP_NODETYPE nodeType;
462	struct DSP_NODEATTR    nodeAttr;
463#ifdef DEBUG_BRIDGE_PERF
464	struct timeval tv_beg;
465	struct timeval tv_end;
466	struct timezone tz;
467	int timeRetVal = 0;
468
469	timeRetVal = getTimeStamp(&tv_beg);
470#endif
471
472	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Delete:\r\n")));
473	if (!hNode) {
474		/* Invalid pointer */
475		status = DSP_EHANDLE;
476		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Delete: "
477					"hNode is Invalid Handle\r\n")));
478		return status;
479	}
480	/* Get segment size.
481	 >0 is SM segment. Get default SM Mgr*/
482	tempStruct.ARGS_CMM_GETHANDLE.hProcessor = NULL;
483	tempStruct.ARGS_CMM_GETHANDLE.phCmmMgr = &hCmm;
484	status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETHANDLE_OFFSET);
485	if (DSP_SUCCEEDED(status)) {
486		/* Get SM segment info from CMM */
487		tempStruct.ARGS_CMM_GETINFO.hCmmMgr = hCmm;
488		tempStruct.ARGS_CMM_GETINFO.pCmmInfo = &pInfo;
489		status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETINFO_OFFSET);
490		if (DSP_FAILED(status)) {
491			status = DSP_EFAIL;
492			DEBUGMSG(DSPAPI_ZONE_ERROR,
493				(TEXT("NODE: DSPNode_Delete:"
494					" Failed to get SM segment\r\n")));
495		} else
496			status = DSP_SOK;
497
498	} else {
499		status = DSP_EFAIL;
500		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Delete: "
501					"Failed to CMM handle\r\n")));
502	}
503	if (!DSP_SUCCEEDED(status)) {
504		status = DSP_EBADSEGID;	/* no SM segments*/
505		return status;
506	}
507    status = DSPNode_GetAttr(hNode, &nodeAttr, sizeof(nodeAttr));
508	GetNodeType(hNode, &nodeType);
509	if (nodeType != NODE_DEVICE) {
510		/*segInfo index starts at 0.These checks may not be required*/
511		if ((pInfo.segInfo[0].dwSegBasePa != 0) &&
512		    (pInfo.segInfo[0].ulTotalSegSize) > 0) {
513			/* get node translator's virtual address range
514			   so we can free it */
515			bufAttr.uAlignment = 0;
516			bufAttr.uSegment = 1 | MEMRY_GETVIRTUALSEGID;
517			DSPNode_AllocMsgBuf(hNode, 1, &bufAttr, &pVirtBase);
518			/* Free virtual space */
519			if (!pVirtBase)
520				goto loop_end;
521
522			if (munmap(pVirtBase,
523					pInfo.segInfo[0].ulTotalSegSize)) {
524				status = DSP_EFAIL;
525			}
526		}
527	}
528loop_end:
529	if (DSP_SUCCEEDED(status)) {
530		/* Set up the structure Call DSP Trap */
531		tempStruct.ARGS_NODE_DELETE.hNode = hNode;
532		status = DSPTRAP_Trap(&tempStruct, CMD_NODE_DELETE_OFFSET);
533		/* Free any node heap memory */
534		if (nodeAttr.inNodeAttrIn.pGPPVirtAddr) {
535			DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("DSPNodeDelete:"
536					"Freeing Node heap addr \n")));
537			free(nodeAttr.inNodeAttrIn.pGPPVirtAddr);
538		}
539	}
540#ifdef DEBUG_BRIDGE_PERF
541	timeRetVal = getTimeStamp(&tv_end);
542	PrintStatistics(&tv_beg, &tv_end, "DSPNode_Delete", 0);
543#endif
544
545	return status;
546}
547
548/*
549 *  ======== DSPNode_FreeMsgBuf ========
550 */
551DBAPI DSPNode_FreeMsgBuf(DSP_HNODE hNode, IN BYTE *pBuffer,
552				IN OPTIONAL struct DSP_BUFFERATTR *pAttr)
553{
554	DSP_STATUS status = DSP_SOK;
555	Trapped_Args tempStruct;
556
557	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_FreeMsgBuf:\r\n")));
558
559	if (hNode) {
560		if (pBuffer) {
561			/* Set up the structure */
562			/* Call DSP Trap */
563			tempStruct.ARGS_NODE_FREEMSGBUF.hNode = hNode;
564			tempStruct.ARGS_NODE_FREEMSGBUF.pBuffer = pBuffer;
565			tempStruct.ARGS_NODE_FREEMSGBUF.pAttr = pAttr;
566			status = DSPTRAP_Trap(&tempStruct,
567				CMD_NODE_FREEMSGBUF_OFFSET);
568			if (DSP_FAILED(status)) {
569				DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: "
570						"DSPNode_FreeMsgBuf:"
571						"Failed to Free SM buf\r\n")));
572			}
573		} else {
574			/* Invalid parameter */
575			status = DSP_EPOINTER;
576			DEBUGMSG(DSPAPI_ZONE_ERROR,
577				(TEXT("NODE: DSPNode_FreeMsgBuf: "
578				"Invalid pointer in the Input\r\n")));
579		}
580	} else {
581		/* Invalid pointer */
582		status = DSP_EHANDLE;
583		DEBUGMSG(DSPAPI_ZONE_ERROR,
584				(TEXT("NODE: DSPNode_FreeMsgBuf: "
585				"hNode is Invalid \r\n")));
586	}
587
588	return status;
589}
590
591/*
592 *  ======== DSPNode_GetAttr ========
593 *  Purpose:
594 *      Copy the current attributes of the specified node.
595 */
596DBAPI DSPNode_GetAttr(DSP_HNODE hNode, OUT struct DSP_NODEATTR *pAttr,
597		UINT uAttrSize)
598{
599	DSP_STATUS status = DSP_SOK;
600	Trapped_Args tempStruct;
601
602	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_GetAttr:\r\n")));
603
604	if (hNode) {
605		if (pAttr) {
606			if (uAttrSize >= sizeof(struct DSP_NODEATTR)) {
607				/* Set up the structure */
608				/* Call DSP Trap */
609				tempStruct.ARGS_NODE_GETATTR.hNode = hNode;
610				tempStruct.ARGS_NODE_GETATTR.pAttr = pAttr;
611				tempStruct.ARGS_NODE_GETATTR.uAttrSize =
612								uAttrSize;
613				status = DSPTRAP_Trap(&tempStruct,
614					CMD_NODE_GETATTR_OFFSET);
615			} else {
616				status = DSP_ESIZE;
617				DEBUGMSG(DSPAPI_ZONE_ERROR,
618					(TEXT("NODE: DSPNode_GetAttr: "
619					"Size is too small \r\n")));
620			}
621		} else {
622			/* Invalid parameter */
623			status = DSP_EPOINTER;
624			DEBUGMSG(DSPAPI_ZONE_ERROR,
625				(TEXT("NODE: DSPNode_GetAttr: "
626				"Invalid pointer in the Input\r\n")));
627		}
628	} else {
629		/* Invalid pointer */
630		status = DSP_EHANDLE;
631		DEBUGMSG(DSPAPI_ZONE_ERROR,
632			(TEXT("NODE: DSPNode_GetAttr: "
633			"hNode is Invalid \r\n")));
634	}
635
636	return status;
637}
638
639/*
640 *  ======== DSPNode_GetMessage ========
641 *  Purpose:
642 *      Retrieve an event message from a task node.
643 */
644DBAPI DSPNode_GetMessage(DSP_HNODE hNode, OUT struct DSP_MSG *pMessage,
645				UINT uTimeout)
646{
647	DSP_STATUS status = DSP_SOK;
648	Trapped_Args tempStruct;
649#ifdef DEBUG_BRIDGE_PERF
650	struct timeval tv_beg;
651	struct timeval tv_end;
652	struct timezone tz;
653	int timeRetVal = 0;
654
655	timeRetVal = getTimeStamp(&tv_beg);
656
657#endif
658
659	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_GetMessage:\r\n")));
660
661	if (hNode) {
662		if (pMessage) {
663			/* Set up the structure */
664			/* Call DSP Trap */
665			tempStruct.ARGS_NODE_GETMESSAGE.hNode = hNode;
666			tempStruct.ARGS_NODE_GETMESSAGE.pMessage = pMessage;
667			tempStruct.ARGS_NODE_GETMESSAGE.uTimeout = uTimeout;
668			status = DSPTRAP_Trap(&tempStruct,
669				CMD_NODE_GETMESSAGE_OFFSET);
670		} else {
671			status = DSP_EPOINTER;
672			DEBUGMSG(DSPAPI_ZONE_ERROR,
673				(TEXT("NODE: DSPNode_GetMessage:"
674				"pMessage is Invalid \r\n")));
675		}
676	} else {
677		status = DSP_EHANDLE;
678		DEBUGMSG(DSPAPI_ZONE_ERROR,
679			(TEXT("NODE: DSPNode_GetMessage: "
680			"hNode is Invalid \r\n")));
681	}
682#ifdef DEBUG_BRIDGE_PERF
683	timeRetVal = getTimeStamp(&tv_end);
684	PrintStatistics(&tv_beg, &tv_end, "DSPNode_GetMessage", 0);
685#endif
686
687
688	return status;
689}
690
691/*
692 *  ======== GetNodeType ========
693 *  Purpose:
694 *      Return the node type
695 */
696DSP_STATUS GetNodeType(DSP_HNODE hNode, DSP_NODETYPE *pNodeType)
697{
698	/*DSP_STATUS status;*/
699	DSP_STATUS status = DSP_SOK;
700	struct DSP_NODEATTR nodeAttr;
701
702	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("GetNodeType:\r\n")));
703
704	if (hNode) {
705		status = DSPNode_GetAttr(hNode, &nodeAttr, sizeof(nodeAttr));
706		if (DSP_SUCCEEDED(status)) {
707			*pNodeType =
708			nodeAttr.iNodeInfo.nbNodeDatabaseProps.uNodeType;
709		}
710	} else {
711		status = DSP_EHANDLE;
712		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("GetNodeType: "
713					"hNode is Invalid \r\n")));
714	}
715
716	return status;
717}
718
719/*
720 *  ======== DSPNode_Pause ========
721 *  Purpose:
722 *      Temporarily suspend execution of a node that is currently running
723 *      on a DSP.
724 */
725DBAPI DSPNode_Pause(DSP_HNODE hNode)
726{
727	DSP_STATUS status = DSP_SOK;
728	Trapped_Args tempStruct;
729
730	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Pause:\r\n")));
731
732	if (hNode) {
733		/* Set up the structure */
734		/* Call DSP Trap */
735		tempStruct.ARGS_NODE_PAUSE.hNode = hNode;
736		status = DSPTRAP_Trap(&tempStruct, CMD_NODE_PAUSE_OFFSET);
737	} else {
738		/* Invalid pointer */
739		status = DSP_EHANDLE;
740		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Pause: "
741				"hNode is Invalid Handle\r\n")));
742	}
743
744	return status;
745}
746
747/*
748 *  ======== DSPNode_PutMessage ========
749 *  Purpose:
750 *      Send an event message to a task node.
751 */
752DBAPI DSPNode_PutMessage(DSP_HNODE hNode, IN CONST struct DSP_MSG *pMessage,
753						UINT uTimeout)
754{
755	DSP_STATUS status = DSP_SOK;
756	Trapped_Args tempStruct;
757#ifdef DEBUG_BRIDGE_PERF
758	struct timeval tv_beg;
759	struct timeval tv_end;
760	struct timeval tz;
761	int timeRetVal = 0;
762
763	timeRetVal = getTimeStamp(&tv_beg);
764#endif
765
766	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_PutMessage:\r\n")));
767
768	if (hNode) {
769		if (pMessage) {
770			/* Set up the structure */
771			/* Call DSP Trap */
772			tempStruct.ARGS_NODE_PUTMESSAGE.hNode = hNode;
773			tempStruct.ARGS_NODE_PUTMESSAGE.pMessage =
774						(struct DSP_MSG *)pMessage;
775			tempStruct.ARGS_NODE_PUTMESSAGE.uTimeout = uTimeout;
776			status = DSPTRAP_Trap(&tempStruct,
777				CMD_NODE_PUTMESSAGE_OFFSET);
778		} else {
779			status = DSP_EPOINTER;
780			DEBUGMSG(DSPAPI_ZONE_ERROR,
781				(TEXT("NODE: DSPNode_PutMessage: "
782						"pMessage is Invalid \r\n")));
783		}
784	} else {
785		/* Invalid pointer */
786		status = DSP_EHANDLE;
787		DEBUGMSG(DSPAPI_ZONE_ERROR,
788			(TEXT("NODE: DSPNode_PutMessage: "
789					"hNode is Invalid \r\n")));
790	}
791#ifdef DEBUG_BRIDGE_PERF
792	timeRetVal = getTimeStamp(&tv_end);
793	PrintStatistics(&tv_beg, &tv_end, "DSPNode_PutMessage", 0);
794#endif
795
796
797	return status;
798}
799
800/*
801 *  ======== DSPNode_RegisterNotify ========
802 *  Purpose:
803 *      Register to be notified of specific events for this node.
804 */
805DBAPI
806DSPNode_RegisterNotify(DSP_HNODE hNode, UINT uEventMask,
807		       UINT uNotifyType, struct DSP_NOTIFICATION *hNotification)
808{
809	DSP_STATUS status = DSP_SOK;
810	Trapped_Args tempStruct;
811
812	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
813			(TEXT("NODE: DSPNode_RegisterNotify:\r\n")));
814
815	if ((hNode) && (hNotification)) {
816		if (IsValidNodeEvent(uEventMask)) {
817			if (IsValidNotifyMask(uNotifyType)) {
818				/* Set up the structure */
819				/* Call DSP Trap */
820				tempStruct.ARGS_NODE_REGISTERNOTIFY.hNode =
821							hNode;
822				tempStruct.ARGS_NODE_REGISTERNOTIFY.uEventMask =
823							uEventMask;
824				tempStruct.ARGS_NODE_REGISTERNOTIFY\
825					.uNotifyType = uNotifyType;
826				tempStruct.ARGS_NODE_REGISTERNOTIFY\
827					.hNotification = hNotification;
828
829				status = DSPTRAP_Trap(&tempStruct,
830						CMD_NODE_REGISTERNOTIFY_OFFSET);
831			} else {
832				status = DSP_ENOTIMPL;
833				DEBUGMSG(DSPAPI_ZONE_ERROR,
834					(TEXT("NODE: DSPNode_RegisterNotify: "
835					"Invalid Notification Mask \r\n")));
836			}
837		} else {
838			status = DSP_EVALUE;
839			DEBUGMSG(DSPAPI_ZONE_ERROR,
840				(TEXT("NODE: DSPNode_RegisterNotify:"
841						"Invalid Event type\r\n")));
842		}
843	} else {
844		/* Invalid pointer */
845		status = DSP_EHANDLE;
846		DEBUGMSG(DSPAPI_ZONE_ERROR,
847			(TEXT("NODE: DSPNode_RegisterNotify: "
848				"hNode is Invalid \r\n")));
849	}
850
851	return status;
852}
853
854/*
855 *  ======== DSPNode_Run ========
856 *  Purpose:
857 *      Start a task node running.
858 */
859DBAPI DSPNode_Run(DSP_HNODE hNode)
860{
861	DSP_STATUS status = DSP_SOK;
862	Trapped_Args tempStruct;
863
864	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Run:\r\n")));
865
866	if (hNode) {
867		/* Set up the structure */
868		/* Call DSP Trap */
869		tempStruct.ARGS_NODE_RUN.hNode = hNode;
870		status = DSPTRAP_Trap(&tempStruct, CMD_NODE_RUN_OFFSET);
871	} else {
872		/* Invalid pointer */
873		status = DSP_EHANDLE;
874		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Run: "
875					"hNode is Invalid Handle\r\n")));
876	}
877
878	return status;
879}
880
881/*
882 *  ======== DSPNode_Terminate ========
883 *  Purpose:
884 *      Signal a task node running on a  DSP processor that it should
885 *      exit its execute-phase function.
886 */
887DBAPI DSPNode_Terminate(DSP_HNODE hNode, DSP_STATUS *pStatus)
888{
889	DSP_STATUS status = DSP_SOK;
890	Trapped_Args tempStruct;
891
892	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Terminate:\r\n")));
893
894	if (hNode) {
895		/* !DSP_ValidWritePtr means it is a valid write ptr */
896		if (!DSP_ValidWritePtr(pStatus, sizeof(DSP_STATUS))) {
897			/* Set up the structure */
898			/* Call DSP Trap */
899			tempStruct.ARGS_NODE_TERMINATE.hNode = hNode;
900			tempStruct.ARGS_NODE_TERMINATE.pStatus = pStatus;
901			status = DSPTRAP_Trap(&tempStruct,
902				CMD_NODE_TERMINATE_OFFSET);
903		} else
904			status = DSP_EPOINTER;
905
906	} else {
907		/* Invalid pointer */
908		status = DSP_EHANDLE;
909		DEBUGMSG(DSPAPI_ZONE_ERROR,
910			(TEXT("NODE: DSPNode_Terminate: "
911					"hNode is Invalid Handle\r\n")));
912	}
913
914	return status;
915}
916
917
918/*
919 *  ======== DSPNode_GetUUIDProps ========
920 *  Purpose:
921 *      Get Node properties from DCD/DOF file given the UUID
922 */
923DBAPI DSPNode_GetUUIDProps(DSP_HPROCESSOR hProcessor,
924		IN CONST struct DSP_UUID *pNodeID,
925		 OUT struct DSP_NDBPROPS *pNodeProps)
926{
927	DSP_STATUS status = DSP_SOK;
928	Trapped_Args tempStruct;
929
930	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
931				(TEXT("NODE:DSPNode_GetUUIDProps:\r\n")));
932
933	if (hProcessor) {
934		if ((pNodeID) && (pNodeProps)) {
935			/* Set up the structure */
936			/* Call DSP Trap */
937			tempStruct.ARGS_NODE_GETUUIDPROPS.hProcessor =
938						hProcessor;
939			tempStruct.ARGS_NODE_GETUUIDPROPS.pNodeID =
940						(struct DSP_UUID *)pNodeID;
941			tempStruct.ARGS_NODE_GETUUIDPROPS.pNodeProps =
942					(struct DSP_NDBPROPS *) pNodeProps;
943			status = DSPTRAP_Trap(&tempStruct,
944				CMD_NODE_GETUUIDPROPS_OFFSET);
945		} else {
946			/* Invalid parameter */
947			status = DSP_EPOINTER;
948			DEBUGMSG(DSPAPI_ZONE_ERROR,
949				(TEXT("NODE: DSPNode_GetUUIDProps: "
950				       "Invalid pointer in the Input\r\n")));
951		}
952	} else {
953		/* Invalid pointer */
954		status = DSP_EHANDLE;
955		DEBUGMSG(DSPAPI_ZONE_ERROR,
956			(TEXT("NODE: DSPNode_GetUUIDProps: "
957					"hProcessor is Invalid \r\n")));
958	}
959
960	return status;
961}
962
963