📄 config.c
字号:
status = PDCardGetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardGetSocket failed %d\r\n"),
status));
return status;
}
State.fIREQRouting |= SOCK_IREQ_WAKEUP;
status = PDCardSetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardSetSocket failed %d\r\n"),
status));
return status;
}
if (pLsock->FCSR_val & FCR_FCSR_PWR_DOWN)
bCSC = bIRQ = TRUE;
}
} else {
if (pLsock->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP) {
bCSC = bIRQ = TRUE;
pLsock->fFlags &= ~LOG_SOCK_FLAG_IRQ_WAKEUP;
EnterCriticalSection(&v_SocketCrit);
for (pTmp = v_Sockets[pLsock->hSock.uSocket].pLsock; pTmp != NULL; pTmp = pTmp->Next) {
if (pTmp->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP)
break;
}
LeaveCriticalSection(&v_SocketCrit);
if (pTmp == NULL) {
status = PDCardGetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardGetSocket failed %d\r\n"),
status));
return status;
}
State.fIREQRouting &= ~SOCK_IREQ_WAKEUP;
status = PDCardSetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardSetSocket failed %d\r\n"),
status));
return status;
}
}
}
}
mod_cfg_irqw1:
//
// Do not power down during suspend
//
if ((*fAttributes & CFG_ATTR_KEEP_POWERED) ||
(pLsock->fFlags & LOG_SOCK_FLAG_IRQ_WAKEUP)) {
if (!(pLsock->fFlags & LOG_SOCK_FLAG_KEEP_POWERED)) {
status = PDCardGetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardGetSocket failed %d\r\n"),
status));
return status;
}
State.fSocketCaps |= SOCK_CAP_KEEP_POWERED;
status = PDCardSetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardSetSocket failed %d\r\n"),
status));
return status;
}
pLsock->fFlags |= LOG_SOCK_FLAG_KEEP_POWERED;
}
} else {
if (pLsock->fFlags & LOG_SOCK_FLAG_KEEP_POWERED) {
pLsock->fFlags &= ~LOG_SOCK_FLAG_KEEP_POWERED;
EnterCriticalSection(&v_SocketCrit);
for (pTmp = v_Sockets[pLsock->hSock.uSocket].pLsock; pTmp != NULL; pTmp = pTmp->Next) {
if (pTmp->fFlags & LOG_SOCK_FLAG_KEEP_POWERED)
break;
}
LeaveCriticalSection(&v_SocketCrit);
if (pTmp == NULL) {
status = PDCardGetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardGetSocket failed %d\r\n"),
status));
return status;
}
State.fSocketCaps &= ~SOCK_CAP_KEEP_POWERED;
status = PDCardSetSocket(pLsock->hSock.uSocket, &State);
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardModifyConfiguration PDCardSetSocket failed %d\r\n"),
status));
return status;
}
}
}
}
//
// Use no unloading during suspend if requested
//
if (*fAttributes & CFG_ATTR_NO_SUSPEND_UNLOAD) {
pLsock->fFlags |= LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD;
// Try to make insertion/removal a wake source if it isn't already,
// and the socket is user accessible
if (!EnableCSCWake(hSock.uSocket)) {
pLsock->fFlags &= ~LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD;
*fAttributes &= ~CFG_ATTR_NO_SUSPEND_UNLOAD;
}
} else {
if (pLsock->fFlags & LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD) {
bCSC = TRUE;
}
pLsock->fFlags &= ~LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD;
}
// If CSC interrupts are a wake source, and the socket is user accessible
// check if we need to maintain the wake source
if (bCSC && !(v_Sockets[hSock.uSocket].fFlags & PHYS_SOCK_FLAG_NOT_USER_ACCESS)) {
DisableCSCWake();
}
if (bIRQ) {
DisableIRQWake();
}
mod_cfg_err_exit:
if (status != CERR_SUCCESS) {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardModifyConfiguration failed %d\r\n"), status));
} else {
DEBUGMSG(ZONE_FUNCTION|ZONE_ERROR,
(TEXT("PCMCIA:CardModifyConfiguration succeeded\r\n")));
}
return status;
}
//
// CardRequestConfiguration
//
// @doc DRIVERS
//
// @func STATUS | CardRequestConfiguration | Configure socket and PC card interface type and voltage.
// @rdesc Returns one of CERR_SUCCESS, CERR_BAD_HANDLE, CERR_BAD_ARGS, CERR_BAD_SOCKET,
// CERR_IN_USE, CERR_BAD_VCC, CERR_BAD_VPP or CERR_WRITE_FAILURE.
//
// @comm Configure socket and PC card for interface type and voltage settings.
// Power will be applied to the socket if it is currently off. The values
// specified in the parameter structure will be written to the card's
// configuration registers.
// @xref <t CARD_CONFIG_INFO> <f CardModifyConfiguration> <f CardReleaseConfiguration>
//
STATUS
CardRequestConfiguration(
CARD_CLIENT_HANDLE hCardClient, // @parm Handle from <f CardRegisterClient>
PCARD_CONFIG_INFO pParms // @parm pointer to a <t CARD_CONFIG_INFO> structure.
)
{
PCLIENT_DRIVER pClient;
PLOG_SOCKET pLsock;
STATUS status;
UINT8 uPIndex;
PUINT8 pRegVal, pRegStr;
UINT i;
UINT8 uStatusReg;
PPHYS_WINDOW pPhys;
PLOG_WINDOW pLog;
DEBUGMSG(ZONE_FUNCTION,
(TEXT("PCMCIA:CardRequestConfiguration entered\r\n")));
//
// Perform some parameter checks first
//
if (pParms == NULL) {
status = CERR_BAD_ARGS;
goto req_cfg_exit;
}
if ((pClient = FindClient(hCardClient, TRUE, TRUE)) == NULL) {
status = CERR_BAD_HANDLE;
goto req_cfg_exit;
}
//
// The socket being requested must already exist and not be in use by
// someone else.
//
pLsock = I_FindSocket(pParms->hSocket);
if (pLsock == NULL) {
status = CERR_BAD_SOCKET;
goto req_cfg_exit;
}
if ((pLsock->hOwner != 0) &&
(pLsock->hOwner != pClient)) {
status = CERR_IN_USE;
goto req_cfg_exit;
}
pLsock->fCfgRegisters = 0; // Clear configed registers
pRegVal = &(pParms->uConfigReg);
pRegStr = &(pLsock->COR_val);
for (i = 0; i < NUM_REGISTERS; i++) {
if (pParms->fRegisters & (1 << i)) {
pLsock->fCfgRegisters |= (1 << i);
*pRegStr = *pRegVal;
}
pRegStr++; pRegVal++;
}
pRegVal = &(pParms->IOBase[0]);
if (pParms->fRegisters & CFG_REGISTER_EXREG) {
for (i = 0; i < NUM_EXT_REGISTERS; i++) {
if (pParms->fExtRegisters & (1 << i)) {
pLsock->fCfgRegisters |= (1 << (i + NUM_REGISTERS));
*pRegStr = *pRegVal;
}
pRegStr++; pRegVal++;
}
}
// Power adapter back up
PcmciaPowerOn(pParms->hSocket.uSocket);
#ifdef EDGE_INTR
pLsock->COR_val = pParms->uConfigReg &= ~FCR_COR_LEVEL_IREQ; // used by CardResetFunction
#else
pLsock->COR_val = pParms->uConfigReg |= FCR_COR_LEVEL_IREQ; // used by CardResetFunction
#endif
uStatusReg = FCR_FCSR_INTR_ACK; // used by ISR
//
// Set the FCR_FCSR_IO_IS_8 bit according to the data path width of this
// client's windows.
//
EnterCriticalSection(&v_WindowCrit);
pPhys = v_pWinList;
while (pPhys) {
if (pPhys->uSock == pParms->hSocket.uSocket) {
pLog = pPhys->pLog;
while (pLog) {
if (pLog->hOwner == pClient) {
if (pPhys->fFlags & PHYS_WIN_FLAG_16BIT_MODE) {
DEBUGMSG(ZONE_MEM,
(TEXT("PCMCIA:CardRequestConfiguration - assuming 16 bit I/O\r\n")));
goto req_cfg_16bit;
}
}
pLog = pLog->Next;
}
}
pPhys = pPhys->Next;
}
//
// No 16 bit windows used by this client, assume using 8 bit.
//
if (!(pParms->fAttributes & CFG_ATTR_NO_IO_IS_8))
uStatusReg |= FCR_FCSR_IO_IS_8;
DEBUGMSG(ZONE_MEM,
(TEXT("PCMCIA:CardRequestConfiguration - assuming 8 bit I/O\r\n")));
req_cfg_16bit:
LeaveCriticalSection(&v_WindowCrit);
pLsock->FCSR_val = pParms->uStatusReg |= uStatusReg;
//
// Map voltages to power entry indexes
//
uPIndex = FindPowerEntry(PWR_SUPPLY_VCC, pParms->uVcc);
if (uPIndex == BAD_VOLTAGE_INDEX) {
status = CERR_BAD_VCC;
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardRequestConfiguration bad VCC specified\r\n")));
goto req_cfg_exit;
}
pLsock->fVcc = uPIndex & SOCK_VCC_LEVEL_MASK;
uPIndex = FindPowerEntry(PWR_SUPPLY_VPP1, pParms->uVpp1);
if (uPIndex == BAD_VOLTAGE_INDEX) {
status = CERR_BAD_VPP;
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardRequestConfiguration bad VPP1 specified\r\n")));
goto req_cfg_exit;
}
pLsock->uVpp1 = uPIndex;
uPIndex = FindPowerEntry(PWR_SUPPLY_VPP2, pParms->uVpp2);
if (uPIndex == BAD_VOLTAGE_INDEX) {
status = CERR_BAD_VPP;
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardRequestConfiguration bad VPP2 specified\r\n")));
goto req_cfg_exit;
}
pLsock->uVpp2 = uPIndex;
pLsock->fInterfaceType = pParms->fInterfaceType;
//
// Use the configuration register values that are present in the client's
// config info to update the card.
//
if (pLsock->pRegWin == NULL) {
DEBUGMSG(ZONE_WARNING,
(TEXT("PCMCIA:CardRequestConfiguration no config register window\r\n")));
if (pParms->fInterfaceType & CFG_IFACE_MEMORY_IO) {
status = CERR_WRITE_FAILURE;
goto req_cfg_exit;
// } else {
// goto req_cfg_no_reg; // allow memory only to set state
}
}
//req_cfg_no_reg:
//
// Enable SPKR out on the socket controller if requested
//
pLsock->fControlCaps = 0;
if ((pParms->fRegisters & CFG_REGISTER_STATUS) &&
(pParms->uStatusReg & FCR_FCSR_AUDIO)) {
pLsock->fControlCaps |= SOCK_ENABLE_SPEAKER;
}
pLsock->fFlags |= OWNER_FLAG_CONFIG;
pLsock->hOwner = pClient;
CardModifyConfiguration(hCardClient, pLsock->hSock, &pParms->fAttributes);
status = ConfigureLogSock(pLsock);
// Make sure to configure the socket first, else the IREQ thread may stomp on power settings
if ((pParms->fAttributes & CFG_ATTR_IRQ_STEERING) &&
(pLsock->fFlags & OWNER_FLAG_INTERRUPT)) {
SetEvent(v_IREQEvent);
}
status = CardReadAttrByte(pLsock->pRegWin,1,&uPIndex);
if (status == CERR_SUCCESS) {
status = CardReadAttrByte(pLsock->pRegWin,0,&uPIndex);
} if (status == CERR_SUCCESS) {
DEBUGMSG(ZONE_WARNING,
(TEXT("CardRequestConfiguration COR = 0x%x, expected 0x%x\r\n"),
uPIndex, pParms->uConfigReg));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -