📄 intr.c
字号:
EventCode = 0;
// CallbackFlags = 0;
DEBUGMSG(ZONE_STSCHG,
(TEXT("fChanged = %x for Socket %d and fCurr = %x, PowerState = %x, fFlags = %x\r\n"),
fChanged, uSocket, fCurr, v_Sockets[uSocket].PowerState,
v_Sockets[uSocket].fFlags));
if (!(fCurr & EVENT_MASK_CARD_DETECT) &&
(v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_RESUMING)) {
DEBUGMSG(ZONE_STSCHG, (TEXT("Clearing the RESUMING flag on socket %d.\r\n"), uSocket));
v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_RESUMING;
PcmciaPowerOff(uSocket, TRUE, (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
}
//
// If this interrupt was due to a power off/on cycle, then notify
// all client drivers by sending them a CE_CARD_REMOVAL and then a
// CE_CARD_INSERTION (if a card is still inserted). CardGetStatus
// will indicate that no card is present until after the last removal
// notice has been processed by CallbackThread. When the last
// removal notice has been sent, CallbackThread will signal this
// thread which will then send card insertion notices for any cards
// that are inserted.
//
if (v_Sockets[uSocket].PowerState == POWER_OFF ||
v_Sockets[uSocket].PowerState == POWER_KEPT ||
v_Sockets[uSocket].PowerState == POWER_RESET) {
// Restore the windows to pre-suspend state
if (v_Sockets[uSocket].PowerState != POWER_RESET) {
if (RestoreWindowState(uSocket) != CERR_SUCCESS) {
for (pLsock = pPsock->pLsock; pLsock != NULL; pLsock = pLsock->Next)
pLsock->fFlags &= ~LOG_SOCK_FLAG_NO_SUSPEND_UNLOAD;
} else if (State.fNotifyEvents & EVENT_MASK_CARD_DETECT) {
for (pLsock = pPsock->pLsock; pLsock != NULL; pLsock = pLsock->Next) {
if (!(pLsock->fFlags & OWNER_FLAG_CONFIG) ||
!(pLsock->FCSR_val & FCR_FCSR_PWR_DOWN))
break;
}
if (pLsock != NULL || pPsock->pLsock == NULL)
PcmciaPowerOn(uSocket);
}
}
if ((v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_RESUMING) &&
(!(v_Sockets[uSocket].fFlags & PHYS_SOCK_FLAG_RESETTING) ||
v_Sockets[uSocket].PowerState == POWER_RESET)) {
DEBUGMSG(ZONE_STSCHG, (TEXT("PCMCIA:StatusChangeInt - back from standby incomplete\r\n")));
fChanged = 0;
} else {
DEBUGMSG(ZONE_STSCHG,
(TEXT("PCMCIA:StatusChangeInt - back from standby and fFlags = %x for Socket %d\r\n"), v_Sockets[uSocket].fFlags, uSocket));
// If there's still a card in the socket, mark the fact that we're expecting
// some more work before the card is ready to be configured.
if (fCurr & EVENT_MASK_CARD_DETECT) {
DEBUGMSG(ZONE_STSCHG, (TEXT("Marking socket %d as RESUMING.\r\n"), uSocket));
v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_RESUMING;
}
//
// If a card was inserted before suspend, then remember whether
// the user wants to use it on battery power.
//
DEBUGMSG(ZONE_STSCHG, (TEXT("v_fPrevEvents for Socket %d = %x \r\n"),uSocket,v_fPrevEvents[uSocket]));
if (v_fPrevEvents[uSocket] & EVENT_MASK_CARD_DETECT) {
v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_FROM_STANDBY;
if ((fCurr & EVENT_MASK_CARD_DETECT) && v_PowerManagerEvent != NULL)
SetEvent(v_PowerManagerEvent);
}
v_fPrevEvents[uSocket] = 0;
fChanged = EVENT_MASK_CARD_DETECT;
fCurr = 0;
v_fChangedEvents[uSocket] = 0;
for (uFunction = 0; uFunction < MAX_FUNCTIONS; uFunction++)
fEvents[uFunction] = 0;
bChanged = FALSE;
//
// Remove any existing CE_PM_RESUME callbacks so the file system
// doesn't get confused in the case where a
// removal/insert/resume sequence got interrupted by a power off
//
RemoveCallbacks(
NULL,
hSock,
CE_PM_RESUME,
REMOVE_PM_RESUME);
CallbackAll(
CE_PM_SUSPEND,
CE_PM_SUSPEND,
NULL,
hSock,
0);
}
} else {
v_fPrevEvents[uSocket] = fCurr;
DEBUGMSG(ZONE_STSCHG, (TEXT("NOT back from Standby and v_fPrevEvents for Socket %d is set to %x \r\n"),uSocket,v_fPrevEvents[uSocket]));
}
#ifdef DEBUG
if (fChanged && ZONE_STSCHG) {
OutBuf[0] = 0;
if (fChanged & EVENT_MASK_WRITE_PROTECT)
_tcscat(OutBuf, TEXT("WRITE_PROTECT "));
if (fChanged & EVENT_MASK_CARD_LOCK)
_tcscat(OutBuf, TEXT("CARD_LOCK "));
if (fChanged & EVENT_MASK_EJECT_REQ)
_tcscat(OutBuf, TEXT("EJECT_REQ "));
if (fChanged & EVENT_MASK_INSERT_REQ)
_tcscat(OutBuf, TEXT("INSERT_REQ "));
if (fChanged & EVENT_MASK_BATTERY_DEAD)
_tcscat(OutBuf, TEXT("BATTERY_DEAD "));
if (fChanged & EVENT_MASK_BATTERY_LOW)
_tcscat(OutBuf, TEXT("BATTERY_LOW "));
if (fChanged & EVENT_MASK_CARD_READY)
_tcscat(OutBuf, TEXT("CARD_READY "));
if (fChanged & EVENT_MASK_CARD_DETECT)
_tcscat(OutBuf, TEXT("CARD_DETECT "));
if (fChanged & EVENT_MASK_POWER_MGMT)
_tcscat(OutBuf, TEXT("POWER_MGMT "));
if (fChanged & EVENT_MASK_RESET)
_tcscat(OutBuf, TEXT("RESET "));
if (fChanged & EVENT_MASK_CARD_LOCK)
_tcscat(OutBuf, TEXT("CARD_LOCK "));
DEBUGMSG(ZONE_STSCHG,
(TEXT("PCMCIA:StatusChangeInt: Changes on socket %d: %s and fFlags = %x\r\n"),
uSocket, OutBuf, v_Sockets[uSocket].fFlags));
}
#endif
#ifdef SINGLE_SOCKET_ONLY_STUFF
//
// Check if the card generated the status change interrupt
//
if ((fChanged == 0) &&
(ret == WAIT_OBJECT_0) &&
(fCurr & EVENT_MASK_CARD_DETECT)) {
DEBUGMSG(ZONE_STSCHG,
(TEXT("PCMCIA:StatusChangeInt: Indicating CE_STATUS_CHANGE_INTERRUPT\r\n")));
CallbackAll(
CE_STATUS_CHANGE_INTERRUPT,
CE_STATUS_CHANGE_INTERRUPT,
NULL,
hSock,
CALLBACK_FLAG_LAST);
}
#endif
// CallbackFlags = CALLBACK_FLAG_ALL_FUNCTIONS;
fChangeBack = ~fChanged;
while (fChanged) { // Signal all events that happened
//
// Notify unlocks before removals
//
if (fChanged & EVENT_MASK_CARD_LOCK) {
if (!(fCurr & EVENT_MASK_CARD_LOCK)) {
fChanged &= ~EVENT_MASK_CARD_LOCK;
// CallbackFlags = CALLBACK_FLAG_ALL_FUNCTIONS;
EventCode = CE_CARD_UNLOCK;
goto status_callback;
}
}
if (fChanged & EVENT_MASK_CARD_DETECT) {
fChanged &= ~EVENT_MASK_CARD_DETECT;
// CallbackFlags = CALLBACK_FLAG_ALL_FUNCTIONS;
if (fCurr & EVENT_MASK_CARD_DETECT) {
CeLogMsg(L"PCMCIA Load: %d", hSock.uSocket);
if (v_PowerManagerEvent != NULL)
SetEvent(v_PowerManagerEvent);
EventCode = CE_CARD_INSERTION;
EnterCriticalSection(&v_BatteryCrit);
if (v_hBatteryThread[hSock.uSocket] != 0) {
if (v_hGwesEvent == NULL ||
WaitForSingleObject(v_hGwesEvent, INFINITE) != WAIT_OBJECT_0 ||
(NULL == v_pfnPostThreadMessageW) || !v_pfnPostThreadMessageW(
v_hBatteryThread[hSock.uSocket],
WM_QUIT, 0, 0)) {
DEBUGMSG(ZONE_WARNING|ZONE_CALLBACK|ZONE_INIT,
(TEXT("PCMCIA:EnqueueEvent:PostThreadMessage Failed (%d)\r\n"),
GetLastError()));
}
v_hBatteryThread[hSock.uSocket] = 0;
}
v_fBattery[hSock.uSocket] = FALSE;
LeaveCriticalSection(&v_BatteryCrit);
CallbackOne(CE_CARDSERV_LOAD, 0, NULL, hSock);
} else {
CeLogMsg(L"PCMCIA Unload: %d", hSock.uSocket);
EnterCriticalSection(&v_DetectCrit);
if (v_Sockets[hSock.uSocket].DetectState != DETECT_NONE)
v_Sockets[hSock.uSocket].DetectState = DETECT_QUIT;
LeaveCriticalSection(&v_DetectCrit);
if (v_PowerManagerEvent != NULL &&
v_Sockets[uSocket].PowerState != POWER_KEPT &&
v_Sockets[uSocket].PowerState != POWER_OFF)
SetEvent(v_PowerManagerEvent);
CallbackAll(
CE_CARD_REMOVAL,
CE_CARD_REMOVAL,
NULL,
hSock,
CALLBACK_FLAG_ALL_FUNCTIONS);
CallbackOne(CE_CARDSERV_UNLOAD, 0, NULL, hSock);
}
continue;
}
//
// Notify locks after insertions
//
if (fChanged & EVENT_MASK_CARD_LOCK) {
fChanged &= ~EVENT_MASK_CARD_LOCK;
if (fCurr & EVENT_MASK_CARD_LOCK) {
EventCode = CE_CARD_LOCK;
// CallbackFlags = CALLBACK_FLAG_ALL_FUNCTIONS;
goto status_callback;
}
}
//
// The following are only valid when the card is inserted
//
if ((fCurr & EVENT_MASK_CARD_DETECT)) {
if (fChanged & EVENT_MASK_CARD_READY) {
fChanged &= ~EVENT_MASK_CARD_READY;
if (fCurr & EVENT_MASK_CARD_READY) {
EventCode = CE_CARD_READY;
goto status_callback;
}
}
if (fChanged & EVENT_MASK_BATTERY_LOW) {
fChanged &= ~EVENT_MASK_BATTERY_LOW;
if (fCurr & EVENT_MASK_BATTERY_LOW) {
EventCode = CE_BATTERY_LOW;
goto status_callback;
}
}
if (fChanged & EVENT_MASK_BATTERY_DEAD) {
fChanged &= ~EVENT_MASK_BATTERY_DEAD;
if (fCurr & EVENT_MASK_BATTERY_DEAD) {
EventCode = CE_BATTERY_DEAD;
goto status_callback;
}
}
if (fChanged & EVENT_MASK_WRITE_PROTECT) {
fChanged &= ~EVENT_MASK_WRITE_PROTECT;
if (fCurr & EVENT_MASK_WRITE_PROTECT) {
EventCode = CE_WRITE_PROTECT;
goto status_callback;
}
}
} else {
//
// The card has been removed, so no other status need be reported.
//
fChanged = 0;
}
break;
status_callback:
if (EventCode) {
CallbackAll(
EventCode,
EventCode,
NULL,
hSock,
CALLBACK_FLAG_ALL_FUNCTIONS);
}
} // while (fChanged)
if ((fCurr & EVENT_MASK_CARD_DETECT) && bChanged) {
for (uFunction = 0; uFunction < MAX_FUNCTIONS; uFunction++) {
hSock.uFunction = uFunction;
if (fEvents[uFunction] & EVENT_MASK_CARD_READY & fChangeBack)
CallbackAll(CE_CARD_READY, CE_CARD_READY, NULL, hSock, 0);
if (fEvents[uFunction] & EVENT_MASK_BATTERY_LOW & fChangeBack)
CallbackAll(CE_CARD_READY, CE_BATTERY_LOW, NULL, hSock, 0);
if (fEvents[uFunction] & EVENT_MASK_BATTERY_DEAD & fChangeBack)
CallbackAll(CE_CARD_READY, CE_BATTERY_DEAD, NULL, hSock, 0);
if (fEvents[uFunction] & EVENT_MASK_WRITE_PROTECT & fChangeBack)
CallbackAll(CE_CARD_READY, CE_WRITE_PROTECT, NULL, hSock, 0);
}
}
} // for all sockets
if (ret == WAIT_OBJECT_0 && !v_bSharedIntr) {
DEBUGMSG(ZONE_STSCHG, (TEXT("PCMCIA:StatusChangeInt - Calling InterruptDone\r\n")));
InterruptDone(gIntrPcmciaState);
}
}
return 0;
} // StatusChangeThread
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -