📄 sdhcslot.cpp
字号:
// Turn the LED on.
EnableLED(TRUE);
// Writing the upper byte of the command register starts the command.
// All register initialization must already be complete by this point.
WriteWord(SDHC_COMMAND, wRegCommand);
RETAILMSG(SDIO_DEBUG,(TEXT("[CMD%d] ARG : 0x%x\r\n"),pRequest->CommandCode, pRequest->CommandArgument));
status = SD_API_STATUS_PENDING;
RETAILMSG(0,(TEXT("Sending command IntStatusEn 0x%08X\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));
EXIT:
return status;
}
VOID
CSDHCSlotBase::EnableSDIOInterrupts(
BOOL fEnable
)
{
Validate();
if (fEnable) {
m_fSDIOInterruptsEnabled = TRUE;
DoEnableSDIOInterrupts(fEnable);
}
else {
DoEnableSDIOInterrupts(fEnable);
m_fSDIOInterruptsEnabled = FALSE;
}
}
VOID
CSDHCSlotBase::HandleInterrupt(
)
{
Validate();
WORD wIntStatus= ReadWord(SDHC_NORMAL_INT_STATUS);
WORD wErrIntStatus = ReadWord(SDHC_ERROR_INT_STATUS);
WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
//RETAILMSG(CRC_DEBUG,(TEXT("m_fCardPresent : %d\r\n"),m_fCardPresent));
RETAILMSG(SDIO_DEBUG,(TEXT("CSDHCSlotBase:: +HandleInterrupt\r\n")));
// 2007.06.14 D.BAek
// There is bug in the S3C6400. After the interrupt is occurred, the normal interrupt status register is updated lately.
// The following if statement is added to wait for setting the interrupt source to the "Normal Interrupt Status Register".
if(g_initialInsertion != 1)
{
while(( wIntStatus=ReadWord(SDHC_NORMAL_INT_STATUS)) == 0);
}
//2007.10.04 D.Baek
RETAILMSG(0,(TEXT("INT : 0x%x\r\n"),wIntStatus));
if (m_fFakeCardRemoval && m_fCardPresent) {
RETAILMSG(0,(TEXT("Wakeup !!!!!! m_fFakeCardRemoval && m_fCardPresent\n"))); // jylee
#ifndef NEW_POWER_MANAGEMENT
m_fFakeCardRemoval = FALSE;
#endif
HandleRemoval(TRUE);
}
if (wIntStatus != 0) {
DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("HandleInterrupt (%u) - Normal Interrupt_Status=0x%02x\n"), m_dwSlot, wIntStatus));
// Error handling. Make sure to handle errors first.
if ( wIntStatus & NORMAL_INT_STATUS_ERROR_INT ) {
HandleErrors();
}
// Command Complete handling.
else if ( wIntStatus & NORMAL_INT_STATUS_CMD_COMPLETE ) { // modifyed by JJG 06.10.11
// Clear status
m_fCommandCompleteOccurred = TRUE;
//For Check
RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_CMD_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_CMD_COMPLETE)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CMD_COMPLETE)));
do{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CMD_COMPLETE);
}while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CMD_COMPLETE));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_CMD_COMPLETE));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_CMD_COMPLETE));
RETAILMSG(CRC_DEBUG,(TEXT("After NORMAL_INT_STATUS_CMD_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
if ( HandleCommandComplete() ) {
wIntStatus &= ~NORMAL_INT_STATUS_TRX_COMPLETE; // this is command-only request.
}
}
// Sometimes at the lowest clock rate, the Read/WriteBufferReady
// interrupt actually occurs before the CommandComplete interrupt.
// This confuses our debug validation code and could potentially
// cause problems. This is why we will verify that the CommandComplete
// occurred before processing any data transfer interrupts.
if (m_fCommandCompleteOccurred) {
if (wIntStatus & NORMAL_INT_STATUS_DMA) {
RETAILMSG(0,(TEXT("Before NORMAL_INT_STATUS_DMA : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_DMA)));
do
{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_DMA);
}while(ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_DMA);
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_DMA));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_DMA));
RETAILMSG(0,(TEXT("After NORMAL_INT_STATUS_DMA : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
HandleDma();
// do not break here. Continue to check TransferComplete.
}
// Buffer Read Ready handling
if (wIntStatus & NORMAL_INT_STATUS_BUF_READ_RDY ) {
// Clear status
RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_BUF_READ_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_BUF_READ_RDY)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_BUF_READ_RDY)));
do
{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_READ_RDY);
}while((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_BUF_READ_RDY));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_BUF_READ_RDY));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_BUF_READ_RDY));
RETAILMSG(0,(TEXT("After NORMAL_INT_STATUS_BUF_READ_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
HandleReadReady();
// do not break here. Continue to check TransferComplete.
}
// Buffer Write Ready handling
if (wIntStatus & NORMAL_INT_STATUS_BUF_WRITE_RDY ) {
// Clear status
RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_BUF_WRITE_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_BUF_WRITE_RDY)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_BUF_WRITE_RDY)));
do
{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_BUF_WRITE_RDY);
}while((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_BUF_WRITE_RDY));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_BUF_WRITE_RDY));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_BUF_WRITE_RDY));
RETAILMSG(0,(TEXT("After NORMAL_INT_STATUS_BUF_WRITE_RDY : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
HandleWriteReady();
// do not break here. Continue to check TransferComplete.
}
}
else {
// We received data transfer interrupt before command
// complete interrupt. Wait for the command complete before
// processing the data interrupt.
}
// Transfer Complete handling
if ( wIntStatus & NORMAL_INT_STATUS_TRX_COMPLETE ) {
// Clear status
RETAILMSG(CRC_DEBUG,(TEXT("Before NORMAL_INT_STATUS_TRX_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_TRX_COMPLETE)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_TRX_COMPLETE)));
do
{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE | NORMAL_INT_STATUS_DMA);
}while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_TRX_COMPLETE|NORMAL_INT_STATUS_DMA));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,(ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | NORMAL_INT_STATUS_TRX_COMPLETE));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | NORMAL_INT_STATUS_TRX_COMPLETE));
RETAILMSG(CRC_DEBUG,(TEXT("After NORMAL_INT_STATUS_TRX_COMPLETE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS)));
HandleTransferDone();
}
// SDIO Interrupt Handling
if ( wIntStatus & NORMAL_INT_STATUS_CARD_INT ) {
DEBUGCHK(m_fSDIOInterruptsEnabled);
DEBUGMSG(SDHC_INTERRUPT_ZONE, (_T("SDHCControllerIst: Card interrupt!\n")));
RETAILMSG(SDIO_DEBUG, (_T("SDHCControllerIst: Card interrupt!\r\n")));
// Because SDIO Interrupt is level triggered, we are not able to clear
// the status. The status should be cleared by the card
// we just disable the interrupt from Interrupt Signal Register
// and Interrupt Status Enable register, and indicate that
// the card is interrupting
EnableSDIOInterrupts(FALSE);
IndicateSlotStateChange(DeviceInterrupting);
RETAILMSG(SDIO_DEBUG, (_T("SDHCControllerIst: Card interrupt finish!\r\n")));
}
// Card Detect Interrupt Handling
if (wIntStatus & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)) {
#if 0
if(wIntStatus & NORMAL_INT_STATUS_CARD_INSERTION)
{
// Card Insertion Interrupt Disable & Card Removal Interrupt Enable
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) & ~(NORMAL_INT_STATUS_CARD_INSERTION)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CARD_INSERTION)));
RETAILMSG(0,(TEXT("Card Inserted[NORMAL_INT_STATUS] : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
}
if(wIntStatus & NORMAL_INT_STATUS_CARD_REMOVAL)
{
// Card Insertion Interrupt Enable & Card Removal Interrupt Disable
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) &~(NORMAL_INT_STATUS_CARD_REMOVAL)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) & ~(NORMAL_INT_STATUS_CARD_REMOVAL)));
RETAILMSG(0,(TEXT("Card Removed[NORMAL_INT_STATUS] : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
}
#endif
#if 1
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) &~(NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) &~(NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
RETAILMSG(0,(TEXT("INT_STATUS_ENABLE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE))); // jylee
RETAILMSG(0,(TEXT("INT_SIGNAL_ENABLE : 0x%x\r\n"),ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE))); // jylee
#endif
do{
WriteWord(SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL);
RETAILMSG(0,(TEXT("[Card Detect INT] SDHC_NORMAL_INT_STATUS=0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS))); // jylee
}while(ReadWord(SDHC_NORMAL_INT_STATUS) & (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL));
// 2007.04.05 D.Baek
// Enable the "Signal" & "Status" interrupt enable bit
WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE, (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE) | (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
WriteWord(SDHC_NORMAL_INT_SIGNAL_ENABLE, (ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE) | (NORMAL_INT_STATUS_CARD_INSERTION | NORMAL_INT_STATUS_CARD_REMOVAL)));
m_fCheckSlot = TRUE;
}
}else
{
RETAILMSG(0,(TEXT("STATUS Error.\r\n"))); // jylee
}
if (m_fCheckSlot) {
m_fCheckSlot = FALSE;
// check card inserted or removed
DWORD dwPresentState = ReadDword(SDHC_PRESENT_STATE);
RETAILMSG(0, (TEXT("HandleInterrupt - Card Present Status : 0x%08X\n"),dwPresentState));
if (dwPresentState & STATE_CARD_INSERTED) {
RETAILMSG(1, (TEXT("[HSMMC] Card is Inserted.\n\r"))); // jylee
DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Inserted! \n")));
#ifdef NEW_POWER_MANAGEMENT
// for wakeup problem. hsjang 070823
RETAILMSG(0,(TEXT("m_fFakeCardRemoval : %d\r\n"),m_fFakeCardRemoval));
if ( m_fFakeCardRemoval)
{
m_fWhileWakeup = TRUE;
}
#endif
m_fFakeCardRemoval = FALSE; // added by JJG 06.11.13
if (m_fCardPresent == FALSE ) {
Start(); // D.Baek
HandleInsertion();
}
}
else {
RETAILMSG(1, (TEXT("[HSMMC] Card is Removed.\n\r"))); // jylee
DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("SDHCControllerIst - Card is Removed! \n")));
#ifdef NEW_POWER_MANAGEMENT
// for wakeup problem. hsjang 070823
if ( m_fFakeCardRemoval)
{
SetEvent(m_hWaitForEndofWakeup);
}
#endif
m_fFakeCardRemoval = FALSE; // added by JJG 06.11.13
if (m_fCardPresent) {
HandleRemoval(TRUE);
}
}
}
RETAILMSG(CRC_DEBUG,(TEXT("CSDHCSlotBase:: -HandleInterrupt\r\n")));
}
VOID
CSDHCSlotBase::HandleRemoval(
BOOL fCancelRequest
)
{
m_fCardPresent = FALSE;
m_fIsPowerManaged = FALSE;
m_fSleepsWithPower = FALSE;
m_fPowerUpDisabledInts = FALSE;
m_f4BitMode = FALSE;
m_cpsCurrent = D0;
//RETAILMSG(0,(TEXT("+HandleRemoval\r\n"))); // jylee
// Wake on SDIO interrupt must be set by he client
m_bWakeupControl &= ~WAKEUP_INTERRUPT;
#if 1
// To control the Data CRC error
WORD wErrIntSignalEn = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
WORD wErrIntStatus = ReadWord(SDHC_ERROR_INT_STATUS);
#endif
#if 1
WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn & ~(0x20))); //Command and Data CRC error disable
WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn & ~(0x20))); //Command and Data CRC error disable
#endif
if (m_fSDIOInterruptsEnabled) {
EnableSDIOInterrupts(FALSE);
}
IndicateSlotStateChange(DeviceEjected);
// turn off clock and remove power from the slot
SDClockOff();
WriteByte(SDHC_POWER_CONTROL, 0);
if (fCancelRequest) {
// get the current request
PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();
if (pRequest != NULL) {
DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("Card Removal Detected - Canceling current request: 0x%08X, command: %d\n"), pRequest, pRequest->CommandCode));
RETAILMSG(CRC_DEBUG, (TEXT("Card Removal Detected - Canceling current request: 0x%08X, command: %d\n"), pRequest, pRequest->CommandCode)); // jylee
DumpRequest(pRequest, SDHC_SEND_ZONE || SDHC_RECEIVE_ZONE);
IndicateBusRequestComplete(pRequest, SD_API_STATUS_DEVICE_REMOVED);
}
}
if (m_pbDmaBuffer) {
DEBUGCHK(m_paDmaBuffer);
FreePhysBuffer(m_pbDmaBuffer);
m_pbDmaBuffer = NULL;
m_paDmaBuffer = 0;
// The Pegasus requires the following so that the next
// insertion will work correctly.
RETAILMSG(CRC_DEBUG,(TEXT("[HandleRemoval] SoftwareReset is called\r\n"))); // jylee
SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
WriteDword(SDHC_SYSTEMADDRESS_LO, 0);
WriteWord(SDHC_BLOCKSIZE, 0);
WriteWord(SDHC_BLOCKCOUNT, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -