/*
* dspbridge/src/api/linux/DSPManager.c
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Copyright (C) 2007 Texas Instruments, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 of the License.
*
* This program is distributed .as is. WITHOUT ANY WARRANTY of any kind,
* whether express or implied; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
/*
* ======== DSPManager.c ========
* Description:
* This is the source for the DSP/BIOS Bridge API manager module. The
* parameters are validated at the API level, but the bulk of the
* work is done at the driver level through the RM MGR module.
*
* Public Functions:
* DSPManager_EnumNodeInfo
* DSPManager_EnumProcessorInfo
* DSPManager_Open
* DSPManager_Close
* DSPManager_WaitForEvents
*
* OEM Functions:
* DSPManager_RegisterObject
* DSPManager_UnregisterObject
*
*! Revision History
*! ================
*! 07-Jul-2003 swa: Validate arguments in RegisterObject and UnregisterObject
*! 15-Oct-2002 kc: Removed DSPManager_GetPerfData.
*! 16-Aug-2002 map: Added DSPManager_RegisterObject/UnregisterObject
*! 29-Nov-2000 rr: Use of DSP_ValidWritePtr. Code review changes incorporated.
*! 22-Nov-2000 kc: Added DSPManager_GetPerfData().
*! 25-Sep-2000 rr: Updated to Version 0.9
*! 04-Aug-2000 rr: Name changed to DSPManager.c
*! 20-Jul-2000 rr: Updated to Version 0.8
*! 27-Jun-2000 rr: Modified to call into the Class driver.
*! 12-Apr-2000 ww: Created based on DirectDSP API specification, Version 0.6.
*
*/
/* ----------------------------------- Host OS */
#include <host_os.h>
/* ----------------------------------- DSP/BIOS Bridge */
#include <dbdefs.h>
#include <errbase.h>
/* ----------------------------------- Trace & Debug */
#include <dbg.h>
#include <dbg_zones.h>
/* ----------------------------------- Others */
#include <dsptrap.h>
/* ----------------------------------- This */
#include "_dbdebug.h"
#include "_dbpriv.h"
#include <DSPManager.h>
#ifdef DEBUG_BRIDGE_PERF
#include <perfutils.h>
#endif
/* ----------------------------------- Globals */
int hMediaFile = -1; /* class driver handle */
static ULONG usage_count;
static sem_t semOpenClose;
static bool bridge_sem_initialized = false;
/* ----------------------------------- Definitions */
/* #define BRIDGE_DRIVER_NAME "/dev/dspbridge"*/
#define BRIDGE_DRIVER_NAME "/dev/DspBridge"
/*
* ======== DspManager_Open ========
* Purpose:
* Open handle to the DSP/BIOS Bridge driver
*/
DBAPI DspManager_Open(UINT argc, PVOID argp)
{
int status = 0;
if (!bridge_sem_initialized) {
if (sem_init(&semOpenClose, 0, 1) == -1) {
DEBUGMSG(DSPAPI_ZONE_ERROR,
(TEXT("MGR: Failed to Initialize"
"the bridge semaphore\n")));
return DSP_EFAIL;
} else
bridge_sem_initialized = true;
}
sem_wait(&semOpenClose);
if (usage_count == 0) { /* try opening handle to Bridge driver */
status = open(BRIDGE_DRIVER_NAME, O_RDWR);
if (status >= 0)
hMediaFile = status;
}
if (status >= 0) {
/* Success in opening handle to Bridge driver */
usage_count++;
status = DSP_SOK;
} else
status = DSP_EFAIL;
/*printf ("argc = %d, hMediaFile[%x] = %d\n", argc, &hMediaFile,
hMediaFile); */
sem_post(&semOpenClose);
return status;
}
/*
* ======== DspManager_Close ========
* Purpose: Close handle to the DSP/BIOS Bridge driver
*/
DBAPI DspManager_Close(UINT argc, PVOID argp)
{
int status = 0;
sem_wait(&semOpenClose);
if (usage_count == 1) {
status = close(hMediaFile);
if (status >= 0)
hMediaFile = -1;
}
if (status >= 0) {
/* Success in opening handle to Bridge driver */
usage_count--;
status = DSP_SOK;
} else
status = DSP_EFAIL;
sem_post(&semOpenClose);
/*printf ("close status = %d, hMediaFile[%x] = %d\n", status,
&hMediaFile, hMediaFile); */
return status;
}
/*
* ======== DSPManager_EnumNodeInfo ========
* Purpose:
* Enumerate and get configuration information about nodes configured
* in the node database.
*/
DBAPI DSPManager_EnumNodeInfo(UINT uNode, OUT struct DSP_NDBPROPS *pNDBProps,
UINT uNDBPropsSize, OUT UINT *puNumNodes)
{
DSP_STATUS status = DSP_SOK;
Trapped_Args tempStruct;
DEBUGMSG(DSPAPI_ZONE_FUNCTION,
(TEXT("MGR: DSPManager_EnumNodeInfo\r\n")));
if (!DSP_ValidWritePtr(pNDBProps, sizeof(struct DSP_NDBPROPS)) &&
!DSP_ValidWritePtr(puNumNodes, sizeof(UINT))) {
if (uNDBPropsSize >= sizeof(struct DSP_NDBPROPS)) {
/* Set up the structure */
/* Call DSP Trap */
tempStruct.ARGS_MGR_ENUMNODE_INFO.uNode = uNode;
tempStruct.ARGS_MGR_ENUMNODE_INFO.pNDBProps = pNDBProps;
tempStruct.ARGS_MGR_ENUMNODE_INFO.uNDBPropsSize =
uNDBPropsSize;
tempStruct.ARGS_MGR_ENUMNODE_INFO.puNumNodes =
puNumNodes;
status = DSPTRAP_Trap(&tempStruct,
CMD_MGR_ENUMNODE_INFO_OFFSET);
} else {
status = DSP_ESIZE;
DEBUGMSG(DSPAPI_ZONE_ERROR,
(TEXT("MGR: pNDBProps is too Small \r\n")));
}
} else {
/* Invalid pointer */
status = DSP_EPOINTER;
DEBUGMSG(DSPAPI_ZONE_ERROR,
(TEXT("MGR: pNDBProps is Invalid \r\n")));
}
return status;
}
/*
* ======== DSPManager_EnumProcessorInfo ========
* Purpose:
* Enumerate and get configuration information about available
* DSP processors.
*/
DBAPI DSPManager_EnumProcessorInfo(UINT uProcessor,
OUT struct DSP_PROCESSORINFO *pProcessorInfo,
UINT uProcessorInfoSize, OUT UINT *puNumProcs)
{
DSP_STATUS status = DSP_SOK;
Trapped_Args tempStruct;
DEBUGMSG(DSPAPI_ZONE_FUNCTION,
(TEXT("MGR: DSPManager_EnumProcessorInfo\r\n")));
if (!DSP_ValidWritePtr(pProcessorInfo, sizeof(struct DSP_PROCESSORINFO))
&& !DSP_ValidWritePtr(puNumProcs, sizeof(UINT))) {
if (uProcessorInfoSize >= sizeof(struct DSP_PROCESSORINFO)) {
/* Call DSP Trap */
tempStruct.ARGS_MGR_ENUMPROC_INFO.uProcessor =
uProcessor;
tempStruct.ARGS_MGR_ENUMPROC_INFO.pProcessorInfo =
pProcessorInfo;
tempStruct.ARGS_MGR_ENUMPROC_INFO.uProcessorInfoSize =
uProcessorInfoSize;
tempStruct.ARGS_MGR_ENUMPROC_INFO.puNumProcs =
puNumProcs;
status = DSPTRAP_Trap(&tempStruct,
CMD_MGR_ENUMPROC_INFO_OFFSET);
} else {
status = DSP_ESIZE;
DEBUGMSG(DSPAPI_ZONE_ERROR,
(TEXT("MGR: uProcessorInfoSize is too Small \r\n")));
}
} else {
/* Invalid pointer */
status = DSP_EPOINTER;
DEBUGMSG(DSPAPI_ZONE_ERROR,
(TEXT("MGR: pProcessorInfo is Invalid \r\n")));
}
return status;
}
/*
* ======== DSPManager_WaitForEvents ========
* Purpose:
* Block on Bridge event(s)
*/
DBAPI DSPManager_WaitForEvents(struct DSP_NOTIFICATION **aNotifications,
UINT uCount, OUT UINT *puIndex, UINT uTimeout)
{
DSP_STATUS status = DSP_SOK;
Trapped_Args tempStruct;
DEBUGMSG(DSPAPI_ZONE_FUNCTION,
(TEXT("MGR: DSPManager_WaitForEvents\r\n")));
if ((aNotifications) && (puIndex)) {
if (uCount) {
/* Set up the structure */
/* Call DSP Trap */
tempStruct.ARGS_MGR_WAIT.aNotifications =
aNotifications;
tempStruct.ARGS_MGR_WAIT.uCount = uCount;
tempStruct.ARGS_MGR_WAIT.puIndex = puIndex;
tempStruct.ARGS_MGR_WAIT.uTimeout = uTimeout;
status = DSPTRAP_Trap(&tempStruct, CMD_MGR_WAIT_OFFSET);
} else
/* nStreams == 0 */
*puIndex = (UINT) -1;
} else
/* Invalid pointer */
status = DSP_EPOINTER;
return status;
}
/*
* ======== DSPManager_RegisterObject ========
* Purpose:
* Register object with DCD module
*/
DBAPI DSPManager_RegisterObject(IN struct DSP_UUID *pUuid,
IN DSP_DCDOBJTYPE objType, IN CHAR *pszPathName)
{
DSP_STATUS status = DSP_SOK;
Trapped_Args tempStruct;
#ifdef DEBUG_BRIDGE_PERF
struct timeval tv_beg;
struct timeval tv_end;
struct timezone tz;
int timeRetVal = 0;
timeRetVal = getTimeStamp(&tv_beg);
#endif
DEBUGMSG(DSPAPI_ZONE_FUNCTION,
(TEXT("MGR: DSPManager_RegisterObject\r\n")));
if ((pUuid == NULL) || (objType > DSP_DCDDELETELIBTYPE) ||
(pszPathName == NULL)) {
status = DSP_EINVALIDARG;
}
if (DSP_SUCCEEDED(status)) {
/* Call DSP Trap */
tempStruct.ARGS_MGR_REGISTEROBJECT.pUuid = pUuid;
tempStruct.ARGS_MGR_REGISTEROBJECT.objType = objType;
tempStruct.ARGS_MGR_REGISTEROBJECT.pszPathName = pszPathName;
status = DSPTRAP_Trap(&tempStruct,
CMD_MGR_REGISTEROBJECT_OFFSET);
}
#ifdef DEBUG_BRIDGE_PERF
timeRetVal = getTimeStamp(&tv_end);
PrintStatistics(&tv_beg, &tv_end, "DSPManager_RegisterObject", 0);
#endif
return status;
}
/*
* ======== DSPManager_UnregisterObject ========
* Purpose:
* Unregister object with DCD module
*/
DBAPI DSPManager_UnregisterObject(IN struct DSP_UUID *pUuid,
IN DSP_DCDOBJTYPE objType)
{
DSP_STATUS status = DSP_SOK;
Trapped_Args tempStruct;
#ifdef DEBUG_BRIDGE_PERF
struct timeval tv_beg;
struct timeval tv_end;
struct timezone tz;
int timeRetVal = 0;
timeRetVal = getTimeStamp(&tv_beg);
#endif
DEBUGMSG(DSPAPI_ZONE_FUNCTION,
(TEXT("MGR: DSPManager_RegisterObject\r\n")));
if ((pUuid == NULL) || (objType > DSP_DCDDELETELIBTYPE))
status = DSP_EINVALIDARG;
if (DSP_SUCCEEDED(status)) {
/* Call DSP Trap */
tempStruct.ARGS_MGR_UNREGISTEROBJECT.pUuid = pUuid;
tempStruct.ARGS_MGR_UNREGISTEROBJECT.objType = objType;
status = DSPTRAP_Trap(&tempStruct,
CMD_MGR_UNREGISTEROBJECT_OFFSET);
}
#ifdef DEBUG_BRIDGE_PERF
timeRetVal = getTimeStamp(&tv_end);
PrintStatistics(&tv_beg, &tv_end, "DSPManager_UnregisterObject", 0);
#endif
return status;
}
#ifndef RES_CLEANUP_DISABLE
/*
* ======== DSPManager_GetProcResourceInfo ========
* Purpose:
* Get GPP process resource info
*/
DBAPI DSPManager_GetProcResourceInfo(UINT *pBuf, UINT *pSize)
{
DSP_STATUS status = DSP_SOK;
Trapped_Args tempStruct;
DEBUGMSG(DSPAPI_ZONE_FUNCTION,
(TEXT("MGR: DSPManager_RegisterObject\r\n")));
if (pBuf == NULL)
status = DSP_EINVALIDARG;
if (DSP_SUCCEEDED(status)) {
/* Call DSP Trap */
tempStruct.ARGS_PROC_GETTRACE.pBuf = (BYTE *)pBuf;
status = DSPTRAP_Trap(&tempStruct, CMD_MGR_RESOUCES_OFFSET);
}
return status;
}
#endif