Home | History | Annotate | Download | only in libbridge
      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  */
     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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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