1 /*
2  * dspbridge/src/api/linux/DSPManager.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  *  ======== DSPManager.c ========
20  *  Description:
21  *      This is the source for the DSP/BIOS Bridge API manager module. The
22  *      parameters are validated at the API level, but the bulk of the
23  *      work is done at the driver level through the RM MGR module.
24  *
25  *  Public Functions:
26  *      DSPManager_EnumNodeInfo
27  *      DSPManager_EnumProcessorInfo
28  *      DSPManager_Open
29  *      DSPManager_Close
30  *      DSPManager_WaitForEvents
31  *
32  *  OEM Functions:
33  *      DSPManager_RegisterObject
34  *      DSPManager_UnregisterObject
35  *
36  *! Revision History
37  *! ================
38  *! 07-Jul-2003 swa: Validate arguments in RegisterObject and UnregisterObject
39  *! 15-Oct-2002 kc: Removed DSPManager_GetPerfData.
40  *! 16-Aug-2002 map: Added DSPManager_RegisterObject/UnregisterObject
41  *! 29-Nov-2000 rr: Use of DSP_ValidWritePtr. Code review changes incorporated.
42  *! 22-Nov-2000 kc: Added DSPManager_GetPerfData().
43  *! 25-Sep-2000 rr: Updated to Version 0.9
44  *! 04-Aug-2000 rr: Name changed to DSPManager.c
45  *! 20-Jul-2000 rr: Updated to Version 0.8
46  *! 27-Jun-2000 rr: Modified to call into the Class driver.
47  *! 12-Apr-2000 ww: Created based on DirectDSP API specification, Version 0.6.
48  *
49  */
50 
51 /*  ----------------------------------- Host OS */
52 #include <host_os.h>
53 
54 /*  ----------------------------------- DSP/BIOS Bridge */
55 #include <dbdefs.h>
56 #include <errbase.h>
57 
58 /*  ----------------------------------- Trace & Debug */
59 #include <dbg.h>
60 #include <dbg_zones.h>
61 
62 /*  ----------------------------------- Others */
63 #include <dsptrap.h>
64 
65 /*  ----------------------------------- This */
66 #include "_dbdebug.h"
67 #include "_dbpriv.h"
68 
69 #include <DSPManager.h>
70 
71 #ifdef DEBUG_BRIDGE_PERF
72 #include <perfutils.h>
73 #endif
74 
75 /*  ----------------------------------- Globals */
76 int hMediaFile = -1;		/* class driver handle */
77 static ULONG usage_count;
78 static sem_t semOpenClose;
79 static bool bridge_sem_initialized = false;
80 
81 /*  ----------------------------------- Definitions */
82 /* #define BRIDGE_DRIVER_NAME  "/dev/dspbridge"*/
83 #define BRIDGE_DRIVER_NAME  "/dev/DspBridge"
84 
85 /*
86  *  ======== DspManager_Open ========
87  *  Purpose:
88  *      Open handle to the DSP/BIOS Bridge driver
89  */
DspManager_Open(UINT argc,PVOID argp)90 DBAPI DspManager_Open(UINT argc, PVOID argp)
91 {
92 	int status = 0;
93 
94 	if (!bridge_sem_initialized) {
95 		if (sem_init(&semOpenClose, 0, 1) == -1) {
96 			DEBUGMSG(DSPAPI_ZONE_ERROR,
97 				 (TEXT("MGR: Failed to Initialize"
98 					   "the bridge semaphore\n")));
99 			return DSP_EFAIL;
100 		} else
101 			bridge_sem_initialized = true;
102 	}
103 
104 	sem_wait(&semOpenClose);
105 	if (usage_count == 0) {	/* try opening handle to Bridge driver */
106 		status = open(BRIDGE_DRIVER_NAME, O_RDWR);
107 		if (status >= 0)
108 			hMediaFile = status;
109 	}
110 
111 	if (status >= 0) {
112 		/* Success in opening handle to Bridge driver */
113 		usage_count++;
114 		status = DSP_SOK;
115 	} else
116 		status = DSP_EFAIL;
117 
118 
119 	/*printf ("argc = %d, hMediaFile[%x] = %d\n", argc, &hMediaFile,
120 					hMediaFile); */
121 
122 	sem_post(&semOpenClose);
123 
124 	return status;
125 }
126 
127 /*
128  *  ======== DspManager_Close ========
129  *  Purpose:   Close handle to the DSP/BIOS Bridge driver
130  */
DspManager_Close(UINT argc,PVOID argp)131 DBAPI DspManager_Close(UINT argc, PVOID argp)
132 {
133 	int status = 0;
134 
135 	sem_wait(&semOpenClose);
136 
137 	if (usage_count == 1) {
138 		status = close(hMediaFile);
139 		if (status >= 0)
140 			hMediaFile = -1;
141 	}
142 
143 	if (status >= 0) {
144 		/* Success in opening handle to Bridge driver */
145 		usage_count--;
146 		status = DSP_SOK;
147 	} else
148 		status = DSP_EFAIL;
149 
150 	sem_post(&semOpenClose);
151 
152 	/*printf ("close status = %d, hMediaFile[%x] = %d\n", status,
153 						&hMediaFile, hMediaFile); */
154 
155 	return status;
156 }
157 
158 /*
159  *  ======== DSPManager_EnumNodeInfo ========
160  *  Purpose:
161  *      Enumerate and get configuration information about nodes configured
162  *      in the node database.
163  */
DSPManager_EnumNodeInfo(UINT uNode,OUT struct DSP_NDBPROPS * pNDBProps,UINT uNDBPropsSize,OUT UINT * puNumNodes)164 DBAPI DSPManager_EnumNodeInfo(UINT uNode, OUT struct DSP_NDBPROPS *pNDBProps,
165 			UINT uNDBPropsSize, OUT UINT *puNumNodes)
166 {
167 	DSP_STATUS status = DSP_SOK;
168 	Trapped_Args tempStruct;
169 
170 	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
171 		 (TEXT("MGR: DSPManager_EnumNodeInfo\r\n")));
172 
173 	if (!DSP_ValidWritePtr(pNDBProps, sizeof(struct DSP_NDBPROPS)) &&
174 	    !DSP_ValidWritePtr(puNumNodes, sizeof(UINT))) {
175 
176 		if (uNDBPropsSize >= sizeof(struct DSP_NDBPROPS)) {
177 			/* Set up the structure */
178 			/* Call DSP Trap */
179 			tempStruct.ARGS_MGR_ENUMNODE_INFO.uNode = uNode;
180 			tempStruct.ARGS_MGR_ENUMNODE_INFO.pNDBProps = pNDBProps;
181 			tempStruct.ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize =
182 							uNDBPropsSize;
183 			tempStruct.ARGS_MGR_ENUMNODE_INFO.puNumNodes =
184 							puNumNodes;
185 			status = DSPTRAP_Trap(&tempStruct,
186 					CMD_MGR_ENUMNODE_INFO_OFFSET);
187 		} else {
188 			status = DSP_ESIZE;
189 			DEBUGMSG(DSPAPI_ZONE_ERROR,
190 				 (TEXT("MGR: pNDBProps is too Small \r\n")));
191 		}
192 	} else {
193 		/* Invalid pointer */
194 		status = DSP_EPOINTER;
195 		DEBUGMSG(DSPAPI_ZONE_ERROR,
196 			 (TEXT("MGR: pNDBProps is Invalid \r\n")));
197 	}
198 
199 	return status;
200 }
201 
202 /*
203  *  ======== DSPManager_EnumProcessorInfo ========
204  *  Purpose:
205  *      Enumerate and get configuration information about available
206  *      DSP processors.
207  */
DSPManager_EnumProcessorInfo(UINT uProcessor,OUT struct DSP_PROCESSORINFO * pProcessorInfo,UINT uProcessorInfoSize,OUT UINT * puNumProcs)208 DBAPI DSPManager_EnumProcessorInfo(UINT uProcessor,
209 			     OUT struct DSP_PROCESSORINFO *pProcessorInfo,
210 			     UINT uProcessorInfoSize, OUT UINT *puNumProcs)
211 {
212 	DSP_STATUS status = DSP_SOK;
213 	Trapped_Args tempStruct;
214 
215 	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
216 		 (TEXT("MGR: DSPManager_EnumProcessorInfo\r\n")));
217 
218 	if (!DSP_ValidWritePtr(pProcessorInfo, sizeof(struct DSP_PROCESSORINFO))
219 		&& !DSP_ValidWritePtr(puNumProcs, sizeof(UINT))) {
220 
221 		if (uProcessorInfoSize >= sizeof(struct DSP_PROCESSORINFO)) {
222 			/* Call DSP Trap */
223 			tempStruct.ARGS_MGR_ENUMPROC_INFO.uProcessor =
224 								uProcessor;
225 			tempStruct.ARGS_MGR_ENUMPROC_INFO.pProcessorInfo =
226 								pProcessorInfo;
227 			tempStruct.ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize =
228 							uProcessorInfoSize;
229 			tempStruct.ARGS_MGR_ENUMPROC_INFO.puNumProcs =
230 								puNumProcs;
231 
232 			status = DSPTRAP_Trap(&tempStruct,
233 				CMD_MGR_ENUMPROC_INFO_OFFSET);
234 		} else {
235 			status = DSP_ESIZE;
236 			DEBUGMSG(DSPAPI_ZONE_ERROR,
237 			(TEXT("MGR: uProcessorInfoSize is too Small \r\n")));
238 		}
239 	} else {
240 		/* Invalid pointer */
241 		status = DSP_EPOINTER;
242 		DEBUGMSG(DSPAPI_ZONE_ERROR,
243 			 (TEXT("MGR: pProcessorInfo is Invalid \r\n")));
244 	}
245 
246 	return status;
247 }
248 
249 /*
250  *  ======== DSPManager_WaitForEvents ========
251  *  Purpose:
252  *      Block on Bridge event(s)
253  */
DSPManager_WaitForEvents(struct DSP_NOTIFICATION ** aNotifications,UINT uCount,OUT UINT * puIndex,UINT uTimeout)254 DBAPI DSPManager_WaitForEvents(struct DSP_NOTIFICATION **aNotifications,
255 			 UINT uCount, OUT UINT *puIndex, UINT uTimeout)
256 {
257 	DSP_STATUS status = DSP_SOK;
258 	Trapped_Args tempStruct;
259 
260 	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
261 		 (TEXT("MGR: DSPManager_WaitForEvents\r\n")));
262 
263 	if ((aNotifications) && (puIndex)) {
264 
265 		if (uCount) {
266 			/* Set up the structure */
267 			/* Call DSP Trap */
268 			tempStruct.ARGS_MGR_WAIT.aNotifications =
269 							aNotifications;
270 			tempStruct.ARGS_MGR_WAIT.uCount = uCount;
271 			tempStruct.ARGS_MGR_WAIT.puIndex = puIndex;
272 			tempStruct.ARGS_MGR_WAIT.uTimeout = uTimeout;
273 
274 			status = DSPTRAP_Trap(&tempStruct, CMD_MGR_WAIT_OFFSET);
275 		} else
276 			/* nStreams == 0 */
277 			*puIndex = (UINT) -1;
278 
279 	} else
280 		/* Invalid pointer */
281 		status = DSP_EPOINTER;
282 
283 
284 	return status;
285 }
286 
287 /*
288  *  ======== DSPManager_RegisterObject ========
289  *  Purpose:
290  *  Register object with DCD module
291  */
DSPManager_RegisterObject(IN struct DSP_UUID * pUuid,IN DSP_DCDOBJTYPE objType,IN CHAR * pszPathName)292 DBAPI DSPManager_RegisterObject(IN struct DSP_UUID *pUuid,
293 			  IN DSP_DCDOBJTYPE objType, IN CHAR *pszPathName)
294 {
295 	DSP_STATUS status = DSP_SOK;
296 	Trapped_Args tempStruct;
297 #ifdef DEBUG_BRIDGE_PERF
298 	struct timeval tv_beg;
299 	struct timeval tv_end;
300 	struct timezone tz;
301 	int timeRetVal = 0;
302 
303 	timeRetVal = getTimeStamp(&tv_beg);
304 #endif
305 
306 	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
307 		 (TEXT("MGR: DSPManager_RegisterObject\r\n")));
308 
309 	if ((pUuid == NULL) || (objType > DSP_DCDDELETELIBTYPE) ||
310 	    (pszPathName == NULL)) {
311 		status = DSP_EINVALIDARG;
312 	}
313 
314 	if (DSP_SUCCEEDED(status)) {
315 		/* Call DSP Trap */
316 		tempStruct.ARGS_MGR_REGISTEROBJECT.pUuid = pUuid;
317 		tempStruct.ARGS_MGR_REGISTEROBJECT.objType = objType;
318 		tempStruct.ARGS_MGR_REGISTEROBJECT.pszPathName = pszPathName;
319 		status = DSPTRAP_Trap(&tempStruct,
320 					CMD_MGR_REGISTEROBJECT_OFFSET);
321 	}
322 #ifdef DEBUG_BRIDGE_PERF
323 	timeRetVal = getTimeStamp(&tv_end);
324 	PrintStatistics(&tv_beg, &tv_end, "DSPManager_RegisterObject", 0);
325 #endif
326 
327 	return status;
328 }
329 
330 /*
331  *  ======== DSPManager_UnregisterObject ========
332  *  Purpose:
333  *  Unregister object with DCD module
334  */
DSPManager_UnregisterObject(IN struct DSP_UUID * pUuid,IN DSP_DCDOBJTYPE objType)335 DBAPI DSPManager_UnregisterObject(IN struct DSP_UUID *pUuid,
336 				IN DSP_DCDOBJTYPE objType)
337 {
338 	DSP_STATUS status = DSP_SOK;
339 	Trapped_Args tempStruct;
340 #ifdef DEBUG_BRIDGE_PERF
341 	struct timeval tv_beg;
342 	struct timeval tv_end;
343 	struct timezone tz;
344 	int timeRetVal = 0;
345 
346 	timeRetVal = getTimeStamp(&tv_beg);
347 #endif
348 
349 	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
350 		 (TEXT("MGR: DSPManager_RegisterObject\r\n")));
351 
352 	if ((pUuid == NULL) || (objType > DSP_DCDDELETELIBTYPE))
353 		status = DSP_EINVALIDARG;
354 
355 
356 	if (DSP_SUCCEEDED(status)) {
357 		/* Call DSP Trap */
358 		tempStruct.ARGS_MGR_UNREGISTEROBJECT.pUuid = pUuid;
359 		tempStruct.ARGS_MGR_UNREGISTEROBJECT.objType = objType;
360 		status = DSPTRAP_Trap(&tempStruct,
361 				CMD_MGR_UNREGISTEROBJECT_OFFSET);
362 	}
363 #ifdef DEBUG_BRIDGE_PERF
364 	timeRetVal = getTimeStamp(&tv_end);
365 	PrintStatistics(&tv_beg, &tv_end, "DSPManager_UnregisterObject", 0);
366 
367 #endif
368 
369 	return status;
370 }
371 
372 #ifndef RES_CLEANUP_DISABLE
373 /*
374  *  ======== DSPManager_GetProcResourceInfo ========
375  *  Purpose:
376  *  Get GPP process resource info
377  */
DSPManager_GetProcResourceInfo(UINT * pBuf,UINT * pSize)378 DBAPI DSPManager_GetProcResourceInfo(UINT *pBuf, UINT *pSize)
379 {
380     DSP_STATUS      status = DSP_SOK;
381     Trapped_Args    tempStruct;
382     DEBUGMSG(DSPAPI_ZONE_FUNCTION,
383 	(TEXT("MGR: DSPManager_RegisterObject\r\n")));
384 
385 	if (pBuf == NULL)
386 		status = DSP_EINVALIDARG;
387 
388 	if (DSP_SUCCEEDED(status)) {
389 		/* Call DSP Trap */
390 		tempStruct.ARGS_PROC_GETTRACE.pBuf = (BYTE *)pBuf;
391 		status = DSPTRAP_Trap(&tempStruct, CMD_MGR_RESOUCES_OFFSET);
392 	}
393 
394     return status;
395 }
396 #endif
397 
398