📄 xsac97ctrl.c
字号:
// {
// // Other errors indicate a bad parameter, failure to clear any
// // existing handler by the interrupt controller driver, or
// // violation of the assumption that the AC'97 is unused by a
// // debugger. All are essentially software errors.
// // The error log, as filled in by the subroutines, should leave a
// // trace of exactly what the problem was.
//
// retVal = ERR_T_SW_INTERNAL;
// }
// LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
// ERR_S_XSAC97CTRL_HWSETUP, retVal, 0, 0, 0)
}
else
{
// No problems. Enable the AC'97 interrupts at the Int Controller
// Ignore return value, the parameter was range-checked above.
// (void) XsIcEnableIrqDeviceInt (XSIC_AC97_SGNL);
}
return (retVal);
} // End XsAc97CtrlHWSetup ()
/*
*******************************************************************************
*
* FUNCTION: XsAc97CtrlRegisterHandler
*
* DESCRIPTION: Register an interrupt handling subroutine to be called
* when a specified AC'97 interrupt type occurs. Also
* register a pointer that will be passed to that handler.
*
* Critical section is performed under interrupt protection.
*
* INPUT PARAMETERS:
* XsAc97CtrlIdT interruptTypeId - int type to register handler for
* XsAc97CtrlHandlerFnPT clientHandlerFnP - Handler to be called for int.
* void * paramP - Pointer to be passed to reg. handler
*
* RETURNS:
* Success: 0 (ERR_NONE)
* Failure: ERR_T_ILLPARAM - Interrupt type ID out of range
* ERR_T_NOT_AVAIL - Interrupt type ID unsupported
* ERR_T_REG_HANDLER - pin already has a registered handler
*
* GLOBAL EFFECTS:
* - Required for XsAc97CtrlEnableIntType().
* - Records last detected failure condition
*
* ASSUMPTIONS:
*
* CALLS:
*
* CALLED BY:
*
* Notes:
* - Does not enable the interrupt: use XsAc97CtrlEnableIntType() afterwards.
*
* PROTOTYPE: UINT32 XsAc97CtrlRegisterHandler (XsAc97CtrlIdT,
* XsAc97CtrlHandlerFnPT,
* void *)
*
*******************************************************************************
*/
/*
ErrorT XsAc97CtrlRegisterHandler ( XsAc97CtrlIntIdT interruptTypeId,
XsAc97CtrlHandlerFnPT clientHandlerFnP,
void * paramP)
{
ErrorT retVal;
UINT32 irqIntState;
XsAc97CtrlStatusEntryT* currIntTypeCfgP;
retVal = XsAc97CtrlRangeCheckIntTypeId (interruptTypeId);
irqIntState = XsIcDisableInterruptsIrq(); // Begin atomic zone.
if (!retVal)
{ // Interrupt type ID is safe. Check other conditions.
// Map interrupt type ID onto retVal IDs and get pointer into table.
currIntTypeCfgP = XsAc97CtrlStatusTable +
XsAc97CtrlIntToStatusTransTbl[interruptTypeId];
if (currIntTypeCfgP->registeredHandlerFnP)
{
retVal = ERR_T_REG_HANDLER; // Can't overwrite existing hndlr
}
}
if (retVal)
{
LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
ERR_S_XSAC97CTRL_REG_HANDLER, retVal, 0, 0, 0)
}
else // No problems, register the handler.
{
currIntTypeCfgP->registeredHandlerFnP = clientHandlerFnP;
currIntTypeCfgP->registeredParamP = paramP;
}
XsIcRestoreInterruptsIrq (irqIntState); // End atomic zone.
return (retVal);
} // XsAc97CtrlRegisterHandler ()
*/
/*
*******************************************************************************
*
* FUNCTION: XsAc97CtrlUnRegisterHandler
*
* DESCRIPTION: Disable any interrupt of the specified AC '97 Controller
* interrupt type and unregister any registered handler for it.
* The only error is out-of-range interrupt type ID;
*
* INPUT PARAMETERS: XsAc97CtrlIdT interruptTypeId - AC'97 interrupt type
* to unregister handler for
*
* RETURNS: Success: 0 (ERR_NONE)
* Failure: ERR_T_ILLPARAM - Interrupt type ID out of range
* ERR_T_NOT_AVAIL - Interrupt type ID unsupported
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS: None
*
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsAc97CtrlUnRegisterHandler (XsAc97CtrlIdT);
*
*******************************************************************************
*/
/*
ErrorT XsAc97CtrlUnRegisterHandler (XsAc97CtrlIntIdT interruptTypeId)
{
ErrorT retVal ;
UINT32 irqIntState ;
XsAc97CtrlStatusEntryT* currIntTypeCfgP ;
irqIntState = XsIcDisableInterruptsIrq(); // Begin atomic zone.
// Also checks interruptTypeId
retVal = XsAc97CtrlDisableIntType (interruptTypeId);
if (retVal)
{
LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
ERR_S_XSAC97CTRL_UNR_HANDLER, retVal, 0, 0, 0)
}
else // Interrupt disabled for interrupt type. Unregister.
{
// Map interrupt type ID onto retVal IDs and get pointer into table.
currIntTypeCfgP = XsAc97CtrlStatusTable +
XsAc97CtrlIntToStatusTransTbl[interruptTypeId];
currIntTypeCfgP->registeredHandlerFnP = NULL;
currIntTypeCfgP->registeredParamP = NULL;
}
XsIcRestoreInterruptsIrq (irqIntState); // End atomic zone.
return(retVal);
} // XsAc97CtrlUnRegisterHandler ()
*/
/*
*******************************************************************************
*
* FUNCTION: XsAc97CtrlEnableIntType
*
* DESCRIPTION: Enable interrupts for the specified AC '97 Controller
* interrupt type. An interrupt handling subroutine must
* already be registered. Performed under interrupt protection.
* Clears any existing interrupt triggering indication on
* specified interrupt type before enabling.
*
* Gracefully does nothing if already enabled.
*
* INPUT PARAMETERS: XsAc97CtrlIntIdT interruptTypeId - ID for AC '97 interrupt
* type to enable
*
* RETURNS:
* Success: 0 (ERR_NONE)
* Failure: ERR_T_ILLPARAM - Interrupt type ID out of range
* ERR_T_NOT_AVAIL - Interrupt type ID unsupported
* ERR_T_NO_HANDLER - interrupt type lacks a registered handler
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS:
*
* CALLS: XsAc97CtrlCheckStatus
* XsAc97CtrlRangeCheckIntTypeId
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsAc97CtrlEnableIntType (XsAc97CtrlIdT);
*
*******************************************************************************
*/
/*
ErrorT XsAc97CtrlEnableIntType (XsAc97CtrlIntIdT interruptTypeId)
{
ErrorT retVal ;
UINT32 irqIntState ;
XsAc97CtrlStatusEntryT* currIntTypeCfgP;
// Look for out of range IDs and non-supported IDs
retVal = XsAc97CtrlRangeCheckIntTypeId (interruptTypeId);
if (!retVal)
{ // Valid ID, type is supported.
// Map interrupt type ID onto retVal IDs and get pointer into table.
currIntTypeCfgP = XsAc97CtrlStatusTable +
XsAc97CtrlIntToStatusTransTbl[interruptTypeId];
// Only enable interrupts that have registered handlers.
if (NULL == currIntTypeCfgP->registeredHandlerFnP)
{
retVal = ERR_T_NO_HANDLER;
}
} // Finished if !retVal: all error states checked.
if (retVal)
{
LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
ERR_S_XSAC97CTRL_ENAB_INT, retVal, 0, 0, 0)
}
// Act only if currently disabled.
else if (FALSE == currIntTypeCfgP->intIsEnabled)
{
irqIntState = XsIcDisableInterruptsIrq(); // Begin atomic zone.
// Clear old indications that might trigger spurious interrupt.
// - Use side effect of status check subroutine.
(void) XsAc97CtrlGetStatus (
XsAc97CtrlIntToStatusTransTbl[interruptTypeId]);
// Enable int type: All AC '97 Controller interrupt type enables
// are active high and controlled by a single bit.
*currIntTypeCfgP->enableRegisterP |=
(1u << currIntTypeCfgP->enableBitShift);
currIntTypeCfgP->intIsEnabled = TRUE; // Record new state
XsIcRestoreInterruptsIrq (irqIntState); // End atomic zone.
} // Done else (retVal): range checked and supported, and if (not enabled).
return(retVal);
} // XsAc97CtrlEnableIntType ()
*/
/*
*******************************************************************************
*
* FUNCTION: XsAc97CtrlDisableIntType
*
* DESCRIPTION: Disable, if currently enabled, interrupts for the specified
* AC '97 Controller interrupt type. Performed under
* interrupt protection.
*
* No-ops gracefully if not enabled.
*
* INPUT PARAMETERS: XsAc97CtrlIntIdT interruptTypeId - ID for AC '97 interrupt
* type to disable
*
* RETURNS: Success: 0 (ERR_NONE)
* Failure: ERR_T_ILLPARAM - Interrupt type ID out of range
* ERR_T_NOT_AVAIL - Interrupt type ID unsupported
*
* GLOBAL EFFECTS: None
*
* ASSUMPTIONS:
* CALLS:
*
* CALLED BY:
*
* PROTOTYPE: UINT32 XsAc97CtrlDisableIntType (XsAc97CtrlIntIdT);
*
*******************************************************************************
*/
ErrorT XsAc97CtrlDisableIntType (XsAc97CtrlIntIdT interruptTypeId)
{
ErrorT retVal ;
UINT32 irqIntState;
XsAc97CtrlStatusEntryT* currIntTypeCfgP;
retVal = XsAc97CtrlRangeCheckIntTypeId (interruptTypeId);
if (retVal)
{
LOGERROR (XsAc97CtrlContext.loggedError, ERR_L_XSAC97CTRL,
ERR_S_XSAC97CTRL_DISAB_INT, retVal, 0, 0, 0)
}
else
{
// Map interrupt type ID onto retVal IDs and get pointer into table.
currIntTypeCfgP = XsAc97CtrlStatusTable +
XsAc97CtrlIntToStatusTransTbl[interruptTypeId];
irqIntState = XsIcDisableInterruptsIrq(); // Begin atomic zone.
if (TRUE == currIntTypeCfgP->intIsEnabled)
{
// All AC '97 Controller interrupt type enables are active high
// and controlled by a single bit.
*currIntTypeCfgP->enableRegisterP &=
~(1u << currIntTypeCfgP->enableBitShift);
currIntTypeCfgP->intIsEnabled = FALSE; // Record new state
} // Was enabled, so disabled it.
XsIcRestoreInterruptsIrq (irqIntState); // End atomic zone.
} // Finished else (retVal): parameter range checked
return(retVal);
} // XsAc97CtrlDisablePinInt ()
/*
*******************************************************************************
*
* FUNCTION: XsAc97CtrlGetStatus
*
* DESCRIPTION: Reports the value of the specified status indicator, as
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -