📄 wmdevice.c
字号:
*/
/*
* If we've got readback, we'll need to check the chip. Otherwise we
* had better have a specific ID.
*/
if ( WM_CHIP_HAS_READBACK( chipType ) )
{
pDeviceContext->deviceType = WM_CHIP_UNKNOWN;
pDeviceContext->flags |= DEVICE_TYPE_NEEDS_CHECKING;
}
else
{
pDeviceContext->deviceType = chipType;
}
pDeviceContext->revision = WM_REV_UNKNOWN;
/*
* Set up the function pointers.
*/
#if defined( WIN32 ) && !defined( WDCL_TEST )
pDeviceContext->fnSleep = (SleepFn) Sleep;
#else
pDeviceContext->fnSleep = NULL;
#endif
pDeviceContext->fnLockGlobalData = private_WMLockGlobalData;
pDeviceContext->fnUnlockGlobalData = private_WMUnlockGlobalData;
pDeviceContext->fnAtomicIncrement = (IncrementFn) AtomicIncrement;
pDeviceContext->fnAtomicDecrement = (DecrementFn) AtomicDecrement;
if ( WM_IS_I2S_DEVICE_ID( deviceID ) )
{
#if WM_I2S
/*
* Set up the vtable for I2S.
*/
pDeviceContext->fnLinkInit = WMPlatform2WireInit;
pDeviceContext->fnLinkShutdown = WMPlatform2WireShutdown;
pDeviceContext->fnTouchInit = NULL;
pDeviceContext->fnLockLink = NULL;
pDeviceContext->fnUnlockLink = NULL;
pDeviceContext->fnInitDeviceId = NULL;
pDeviceContext->fnCodecRead = NULL;
pDeviceContext->fnCodecWrite = WM2WireWrite;
pDeviceContext->fnCodecReset = WM2WireReset;
pDeviceContext->fnCodecWake = NULL;
/*
* If we know what chip we are, look up our chipdef now.
*/
if ( WM_CHIP_UNKNOWN != pDeviceContext->deviceType )
{
status = WMGetDeviceType( hDevice, NULL, NULL );
if ( WM_ERROR( status ) )
{
goto error1;
}
}
#else /* WM_I2S */
/*
* I2S, but haven't built for I2S - something's gone wrong.
*/
WM_TRACE( hDevice, ("private_InitDeviceContext: We should never get here!"));
WM_ASSERT( hDevice, FALSE );
#endif /* WM_I2S */
}
else
{
#if WM_AC97
/*
* Set up the vtable for AC'97.
*/
pDeviceContext->fnLinkInit = WMPlatformACLinkInit;
pDeviceContext->fnLinkShutdown = WMPlatformACLinkShutdown;
#if WM_TOUCH
pDeviceContext->fnTouchInit = WM97TouchInit;
#else /* WM_TOUCH */
pDeviceContext->fnTouchInit = NULL;
#endif /* WM_TOUCH */
pDeviceContext->fnLockLink = private_WMLockLink;
pDeviceContext->fnUnlockLink = private_WMUnlockLink;
pDeviceContext->fnInitDeviceId = WMACLinkInitDeviceId;
pDeviceContext->fnCodecRead = WMPlatformACLinkRead;
pDeviceContext->fnCodecWrite = WMPlatformACLinkWrite;
pDeviceContext->fnCodecReset = WMPlatformACLinkColdReset;
pDeviceContext->fnCodecWake = WMPlatformACLinkWarmReset;
#else /* WM_AC97 */
/*
* Not I2S, but haven't built for AC'97
* - something's gone wrong.
*/
WM_TRACE( hDevice, ("private_InitDeviceContext: We should never get here!"));
WM_ASSERT( hDevice, FALSE );
#endif /* WM_AC97 */
}
/*
* Initialise our defaults to unknown.
*/
pDeviceContext->defaultOutputStream = WM_STREAM_INVALID_STREAM;
pDeviceContext->defaultInputStream = WM_STREAM_INVALID_STREAM;
/*
* Initialisation's done.
*/
pDeviceContext->flags |= DEVICE_CONTEXT_INITIALISED;
InitDone:
/*
* And return our context pointer.
*/
*ppContext = pDeviceContext;
return WMS_SUCCESS;
/*
* Error handling.
*/
error1:
private_FreeDeviceContext( hDevice );
error0:
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_FreeDeviceContext
*
* Cleans up and frees all memory associated with the device context.
*
* Parameters:
* hDevice Handle to device context.
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_FreeDeviceContext( WM_DEVICE_HANDLE hDevice )
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
WMSTATUS status;
/*
* Free platform memory.
*/
WMPlatformFreePlatformMemory( hDevice );
/*
* We're no longer initialised.
*/
pDeviceContext->flags &= ~DEVICE_CONTEXT_INITIALISED;
/*
* Release our mutexes.
*/
if ( pDeviceContext->linkMutex )
{
status = DELETE_MUTEX( pDeviceContext->linkMutex );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, ( "Couldn't delete link mutex!" ) );
}
pDeviceContext->linkMutex = NULL;
}
if ( pDeviceContext->globalsMutex )
{
status = DELETE_MUTEX( pDeviceContext->globalsMutex );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, ( "Couldn't delete globals mutex!" ) );
}
pDeviceContext->globalsMutex = NULL;
}
/*
* Free our global data.
*/
if ( pDeviceContext->v_pWMData )
{
FREE_SHARED_MEMORY( pDeviceContext->v_pWMData );
pDeviceContext->v_pWMData = NULL;
}
/*
* And finally free the device context.
*/
WMPlatformFreeDeviceContext( hDevice );
}
#if WM_AC97
/*-----------------------------------------------------------------------------
* Function: private_WMLockLink
*
* Makes sure only one thing happens on the control link at a time.
*
* NB: This function must obey WMSystemCallsAllowed. If this returns FALSE
* it should do nothing.
*
* Parameters:
* hDevice handle to the device
* file the file this was called from
* line the line in the file
*
* Returns: WM_BOOL
* TRUE if successful, FALSE if couldn't lock in timeout.
*---------------------------------------------------------------------------*/
static WM_BOOL private_WMLockLink( WM_DEVICE_HANDLE hDevice,
const char *file,
int line
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
if ( WMSystemCallsAllowed( hDevice ) )
{
if ( WM_ERROR( ACQUIRE_MUTEX( pDeviceContext->linkMutex,
LINK_LOCK_TIMEOUT
)
)
)
{
return FALSE;
}
if ( pDeviceContext->v_pWMData )
{
WM_INCREMENT_COUNTER( pDeviceContext, LinkLockCount );
WM_LOCK_TRACE( hDevice,
( "++Link Lock => %d from %s (%d)",
WM_COUNTER( pDeviceContext, LinkLockCount ),
file,
line
)
);
/*
* Check we haven't exceeded our maximum depth - this is usually a sign of
* a locking problem.
*/
WM_ASSERT( hDevice,
WM_MAX_MUTEX_LOCK_DEPTH >=
WM_COUNTER( pDeviceContext, LinkLockCount )
);
}
}
return TRUE;
}
/*-----------------------------------------------------------------------------
* Function: private_WMUnlockLink
*
* Releases the control link lock again.
*
* NB: This function must obey WMSystemCallsAllowed. If this returns FALSE
* it should do nothing.
*
* Parameters:
* hDevice handle to the device
* file the file this was called from
* line the line in the file
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_WMUnlockLink( WM_DEVICE_HANDLE hDevice,
const char *file,
int line
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
if ( WMSystemCallsAllowed( hDevice ) )
{
WMSTATUS status;
status = RELEASE_MUTEX( pDeviceContext->linkMutex );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, ( "Couldn't release link mutex!" ) );
WM_ASSERT( hDevice, WM_SUCCESS( status ) );
}
if ( pDeviceContext->v_pWMData )
{
WM_DECREMENT_COUNTER( pDeviceContext, LinkLockCount );
WM_LOCK_TRACE( hDevice,
( "--Link Lock => %d from %s (%d)",
WM_COUNTER( pDeviceContext, LinkLockCount ),
file,
line
)
);
/*
* Check we haven't gone negative - this is usually a sign of
* a locking problem.
*/
WM_ASSERT( hDevice,
WM_COUNTER( pDeviceContext, LinkLockCount ) >= 0
);
/*
* Check to make sure that when LinkLockCount goes to zero,
* GlobalLockCount is still > 0.
*/
if ( WM_COUNTER( pDeviceContext,LinkLockCount ) == 0 )
{
WM_ASSERT( hDevice,
WM_COUNTER( pDeviceContext,GlobalLockCount ) >
WM_COUNTER( pDeviceContext,LinkLockCount ) );
}
}
}
}
#endif /* WM_AC97 */
/*-----------------------------------------------------------------------------
* Function: private_WMLockGlobalData
*
* Makes sure only one thread plays around with the global data at a time.
*
* NB: This function must obey WMSystemCallsAllowed. If this returns FALSE
* it should do nothing.
*
* Parameters:
* hDevice handle to the device
* file the file this was called from
* line the line in the file
*
* Returns: WM_BOOL
* TRUE if successful, FALSE if couldn't lock in timeout.
*---------------------------------------------------------------------------*/
static WM_BOOL private_WMLockGlobalData( WM_DEVICE_HANDLE hDevice,
const char *file,
int line
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
if ( WMSystemCallsAllowed( hDevice ) )
{
if ( WM_ERROR( ACQUIRE_MUTEX( pDeviceContext->globalsMutex,
GLOBALS_LOCK_TIMEOUT
)
)
)
{
return FALSE;
}
if ( pDeviceContext->v_pWMData )
{
WM_INCREMENT_COUNTER( pDeviceContext, GlobalLockCount );
WM_LOCK_TRACE( hDevice,
( "++Global Lock => %d from %s (%d)",
WM_COUNTER( pDeviceContext, GlobalLockCount ),
file,
line
)
);
/*
* Check we haven't exceeded our maximum depth - this is usually a sign of
* a locking problem.
*/
WM_ASSERT( hDevice,
WM_MAX_MUTEX_LOCK_DEPTH >=
WM_COUNTER( pDeviceContext, GlobalLockCount )
);
/*
* Check to make sure that LinkLockCount is still zero,
* and we do not have a potential deadlock situation.
*/
if ( WM_COUNTER( pDeviceContext,GlobalLockCount ) == 1 )
{
WM_ASSERT( hDevice,
WM_COUNTER( pDeviceContext,LinkLockCount ) <
WM_COUNTER( pDeviceContext,GlobalLockCount ) );
}
}
}
return TRUE;
}
/*-----------------------------------------------------------------------------
* Function: private_WMUnlockGlobalData
*
* Releases the global data lock again.
*
* NB: This function must obey WMSystemCallsAllowed. If this returns FALSE
* it should do nothing.
*
* Parameters:
* hDevice handle to the device
* file the file this was called from
* line the line in the file
*
* Returns: void
*---------------------------------------------------------------------------*/
static void private_WMUnlockGlobalData( WM_DEVICE_HANDLE hDevice,
const char *file,
int line
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
if ( WMSystemCallsAllowed( hDevice ) )
{
WMSTATUS status;
status = RELEASE_MUTEX( pDeviceContext->globalsMutex );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, ( "Couldn't release globals mutex!" ) );
WM_ASSERT( hDevice, WM_SUCCESS( status ) );
}
if ( pDeviceContext->v_pWMData )
{
WM_DECREMENT_COUNTER( pDeviceContext, GlobalLockCount );
WM_LOCK_TRACE( hDevice,
( "--Global Lock => %d from %s (%d)",
WM_COUNTER( pDeviceContext, GlobalLockCount ),
file,
line
)
);
/*
* Check we haven't gone negative - this is usually a sign of
* a locking problem.
*/
WM_ASSERT( hDevice,
WM_COUNTER( pDeviceContext, LinkLockCount ) >= 0
);
}
}
}
/*------------------------------ END OF FILE ---------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -