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