📄 config.c
字号:
if (pLsock->hOwner == pClient &&
(pLsock->fFlags & OWNER_FLAG_CONFIG) &&
!(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)) {
pClient = CARDSERV_CLIENT_HANDLE;
break;
}
}
}
for (; pPhys != NULL; pPhys = pPhys->Next) {
if (pPhys->uSock != (UINT8)uSocket) continue;
pLog = pPhys->pLog;
while (pLog) {
if ((pLog->hOwner != CARDSERV_CLIENT_HANDLE) &&
(pLog->hOwner != pClient)) {
// Check if this window is owned by a client that has requested a configuration
// on this socket
// If it hasn't, then assume that the client is active and wants the socket powered
// If it has, check if any of the configurations are still active
// If they are, then keep the socket powered
bFound = FALSE;
for (pLsock = v_Sockets[pPhys->uSock].pLsock; pLsock != NULL; pLsock = pLsock->Next) {
if (!(pLsock->fFlags & OWNER_FLAG_CONFIG) || pLsock->hOwner != pLog->hOwner)
continue;
if (!(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)) break;
bFound = TRUE;
}
if (!bFound || pLsock != NULL) {
DEBUGMSG(ZONE_POWER|ZONE_WARNING,
(TEXT("PCMCIA:PcmciaPowerOff(%u) -- Client window present, not powering down\n\r"),
uSocket));
LeaveCriticalSection(&v_WindowCrit);
LeaveCriticalSection(&v_SocketCrit);
LeaveCriticalSection(&v_PowerCrit);
return;
}
}
pLog = pLog->Next;
}
}
LeaveCriticalSection(&v_WindowCrit);
LeaveCriticalSection(&v_SocketCrit);
//
// Also, don't power down the socket if there are any CE_CARD_INSERTION
// notices for it.
//
EnterCriticalSection(&v_CallbackCrit);
pEvent = v_CallbackHead;
while (pEvent) {
if ((pEvent->MajorEvent == CE_CARD_INSERTION) &&
(pEvent->hSock.uSocket == uSocket)) {
DEBUGMSG(ZONE_POWER|ZONE_WARNING,
(TEXT("PCMCIA:PcmciaPowerOff(%u) -- more CE_CARD_INSERTIONs, not powering down\n\r"),
uSocket));
LeaveCriticalSection(&v_CallbackCrit);
LeaveCriticalSection(&v_PowerCrit);
return;
}
pEvent = pEvent->Next;
}
LeaveCriticalSection(&v_CallbackCrit);
}
//
// Disable any interrupts except card detect/lock
//
if (PDCardGetSocket(uSocket, &State) == CERR_SUCCESS) {
State.fInterruptEvents = INITIAL_SOCKET_EVENTS;
PDCardSetSocket(uSocket, &State);
}
//
// Power off the PCMCIA system
//
AdapterState = 0;
PDCardGetAdapter(uSocket, &AdapterState);
if (!(AdapterState & ADP_STATE_POWERDOWN)) {
AdapterState &= ~ADP_STATE_POWEROFF;
AdapterState |= ADP_STATE_POWERDOWN;
if ((status = PDCardSetAdapter(uSocket, &AdapterState)) == CERR_SUCCESS)
DEBUGMSG(ZONE_WARNING|ZONE_POWER,
(TEXT("PCMCIA:PcmciaPowerOff: socket %u powered down\n\r"),
uSocket));
else
DEBUGMSG(ZONE_WARNING|ZONE_ERROR,
(TEXT("PCMCIA:Error %d powering down PCMCIA socket %u\n\r"),
status,uSocket));
}
LeaveCriticalSection(&v_PowerCrit);
DEBUGMSG(ZONE_FUNCTION,(TEXT("PCMCIA:Leaving PcmciaPowerOff\n\r")));
} // PcmciaPowerOff
//
// CardAccessConfigurationRegister
//
// @func STATUS | CardAccessConfigurationRegister | Access PCMCIA function configuration
// registers.
// @rdesc Returns one of CERR_SUCCESS, CERR_BAD_HANDLE, CERR_BAD_SOCKET, CERR_IN_USE,
// CERR_BAD_OFFSET, or CERR_WRITE_FAILURE or CERR_BAD_ARGS.
//
// @comm Read or write value from/to PCMCIA function configuration registers.
// This function may be called before or after card registration, so allow
// a NULL param for the client handle. Note that cards may not support all
// of the FCRs (an unsupported register will return CERR_BAD_OFFSET).
// @xref <t CARD_CLIENT_HANDLE> <t CARD_SOCKET_HANDLE>
//
STATUS
CardAccessConfigurationRegister(
CARD_CLIENT_HANDLE hCardClient, // @parm Handle from <f CardRegisterClient> (may be NULL)
CARD_SOCKET_HANDLE hSock, // @parm Socket/function identifier
UINT8 rw_flag, // @parm Read/Write flag
UINT8 offset, // @parm Config register offset
UINT8 *pValue // @parm Address of value to read/write
)
{
PLOG_SOCKET pLsock;
STATUS status = CERR_SUCCESS;
PCLIENT_DRIVER pClient;
DEBUGMSG(ZONE_FUNCTION,
(TEXT("PCMCIA:CardAccessConfigurationRegister entered, rw: %d reg: %d val: 0x%X\r\n"),
rw_flag,offset,*pValue));
//
// Check the parameters
//
if (pValue == NULL) {
status = CERR_BAD_ARGS;
goto err_exit;
}
pLsock = I_FindSocket(hSock);
if (pLsock == NULL) {
status = CERR_BAD_SOCKET;
goto err_exit;
}
if (pLsock->hOwner && (rw_flag == CARD_FCR_WRITE)) {
if (hCardClient == NULL) {
pClient = pLsock->hOwner;
} else {
if ((pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
status = CERR_BAD_HANDLE;
goto err_exit;
} else if (pLsock->hOwner != pClient) {
status = CERR_IN_USE;
goto err_exit;
}
}
if (!IsValidClient((PCLIENT_DRIVER)pClient)) {
status = CERR_BAD_HANDLE;
goto err_exit;
}
}
// Make sure the card supports this register
#ifdef DEBUG
if (!(pLsock->fRegisters & (1 << offset))) {
// A very common use of this function is to get at registers
// which are non-standard. In that case, they won't be in fRegisters.
// So don't fail here, jsut issue a warning.
DEBUGMSG(ZONE_ERROR|ZONE_WARNING,
(TEXT("PCMCIA:Unsupported register %d (mask 0x%X)\n\r"),
offset,pLsock->fRegisters));
}
#endif
if (rw_flag == CARD_FCR_READ) {
status = CardReadAttrByte(pLsock->pRegWin,offset,pValue);
} else {
// Save our shadowed registers
if (offset >= 0 && offset < (NUM_REGISTERS + NUM_EXT_REGISTERS)) {
*((&pLsock->COR_val) + offset) = *pValue;
}
status = CardWriteAttrByte(pLsock->pRegWin,offset,*pValue);
}
err_exit:
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardAccessConfigurationRegister failed %d\r\n"),
status));
} else {
DEBUGMSG(ZONE_FUNCTION,
(TEXT("PCMCIA:CardAccessConfigurationRegister succeeded\r\n")));
}
return status;
} // CardAccessConfigurationRegister
//
// CardPowerOn
//
// @doc DRIVERS
//
// @func STATUS | CardPowerOn | Request that power be reapplied to a socket
// @rdesc Returns one of CERR_SUCCESS, CERR_BAD_SOCKET, CERR_BAD_HANDLE, or CERR_IN_USE
//
// @comm A client that has already requested a configuration can ask that power be
// reapplied to the socket. If CardPowerOff has not been called and the FCR_FCSR_POWER_DWN
// bit is not set, this function will do nothing. Otherwise it will restore any windows
// disabled during power down, and restore the configuration of the socket set by
// CardRequestConfiguration
// @xref <f CardPowerOff>
//
STATUS
CardPowerOn(
CARD_CLIENT_HANDLE hCardClient, // @parm Handle from <f CardRegisterClient> (may be NULL)
CARD_SOCKET_HANDLE hSock // @parm Socket/function identifier
)
{
PLOG_SOCKET pLsock;
STATUS status = CERR_SUCCESS;
PCLIENT_DRIVER pClient;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PCMCIA:CardPowerOn entered\r\n")));
pLsock = I_FindSocket(hSock);
if (pLsock == NULL || !(pLsock->fFlags & OWNER_FLAG_CONFIG)) {
status = CERR_BAD_SOCKET;
goto cpon_err_exit;
}
if (hCardClient == NULL ||
(pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
status = CERR_BAD_HANDLE;
goto cpon_err_exit;
} else if (pLsock->hOwner != pClient) {
status = CERR_IN_USE;
goto cpon_err_exit;
}
EnterCriticalSection(&v_PowerCrit);
if (pLsock->FCSR_val & FCR_FCSR_PWR_DOWN) {
pLsock->FCSR_val &= ~FCR_FCSR_PWR_DOWN;
EnterCriticalSection(&v_WindowCrit);
status = RestoreWindowState(hSock.uSocket);
LeaveCriticalSection(&v_WindowCrit);
if (status == CERR_SUCCESS) {
PcmciaPowerOn(hSock.uSocket);
ConfigureLogSock(pLsock);
if (pLsock->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP) {
if (!EnableCSCWake(hSock.uSocket) || !EnableIRQWake()) {
// We shouldn't get here, since both Enable() calls worked in CardModifyConfig
// ...but if we do, disable irq wakeup
pLsock->fFlags &= ~LOG_SOCK_FLAG_IRQ_WAKEUP;
DisableCSCWake();
}
}
// Resignal the IREQThread to reenable interrupts
if (pLsock->fFlags & OWNER_FLAG_INTERRUPT) {
SetEvent(v_IREQEvent);
}
}
}
LeaveCriticalSection(&v_PowerCrit);
cpon_err_exit:
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardPowerOn failed %d\r\n"), status));
} else {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardPowerOn succeeded\r\n")));
}
return status;
}
//
// CardPowerOff
//
// @doc DRIVERS
//
// @func STATUS | CardPowerOff | Request that the socket be depowered
// @rdesc Returns one of CERR_SUCCESS, CERR_BAD_SOCKET, CERR_BAD_HANDLE, or CERR_IN_USE
//
// @comm A client that has already requested a configuration can ask that a socket be
// powered down. The FCR_FCSR_POWER_DWN bit will be set, and the socket will be
// powered down if no other drivers are using it.
// @xref <f CardPowerOn>
//
STATUS
CardPowerOff(
CARD_CLIENT_HANDLE hCardClient, // @parm Handle from <f CardRegisterClient> (may be NULL)
CARD_SOCKET_HANDLE hSock // @parm Socket/function identifier
)
{
PLOG_SOCKET pLsock;
STATUS status = CERR_SUCCESS;
PCLIENT_DRIVER pClient;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PCMCIA:CardPowerOff entered\r\n")));
pLsock = I_FindSocket(hSock);
if (pLsock == NULL || !(pLsock->fFlags & OWNER_FLAG_CONFIG)) {
status = CERR_BAD_SOCKET;
goto cpoff_err_exit;
}
if (hCardClient == NULL ||
(pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
status = CERR_BAD_HANDLE;
goto cpoff_err_exit;
} else if (pLsock->hOwner != pClient) {
status = CERR_IN_USE;
goto cpoff_err_exit;
}
EnterCriticalSection(&v_PowerCrit);
if (!(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)) {
UINT8 uFSCR;
pLsock->FCSR_val |= FCR_FCSR_PWR_DOWN;
if (pLsock->pRegWin != NULL &&
(pLsock->fRegisters & CFG_REGISTER_STATUS)) {
CardReadAttrByte(
pLsock->pRegWin,
FCR_OFFSET_FCSR,
&uFSCR);
uFSCR |= FCR_FCSR_PWR_DOWN;
CardWriteAttrByte(pLsock->pRegWin,FCR_OFFSET_FCSR, uFSCR);
}
PcmciaPowerOff(hSock.uSocket, FALSE, pClient);
DisableCSCWake();
DisableIRQWake();
}
LeaveCriticalSection(&v_PowerCrit);
cpoff_err_exit:
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardPowerOff failed %d\r\n"), status));
} else {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardPowerOff succeeded\r\n")));
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -