⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdhcslot.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            // with allowance for power supply ramp-up time. (SD Phys Layer 6.4)
            // Note that power supply ramp-up time occurs in SetVoltage().
            SetClockRate(&dwClockRate);
            SDClockOn();
            DWORD dwSleepMs = (74 / (dwClockRate / 1000)) + 1;
            Sleep(dwSleepMs);
            SDClockOff();
            if (m_SlotDma) {
                ASSERT(FALSE);
                delete m_SlotDma;
                m_SlotDma = NULL;
            }

            if (!m_fDisableDMA) {
                SSDHC_CAPABILITIES caps = GetCapabilities();
                if (FALSE) { // Disable ADM2 support for now    // caps.bits.ADMA2
                    m_SlotDma = new CSDHCSlotBase32BitADMA2(*this);
                }
                else if (caps.bits.SDMA) {
                    m_SlotDma = new CSDHCSlotBaseSDMA(*this);
                }

                if (m_SlotDma && !m_SlotDma->Init()) { // failed.
                    delete m_SlotDma;
                    m_SlotDma = NULL;
                }
                ASSERT(!(caps.bits.ADMA2 || caps.bits.SDMA) || m_SlotDma!=NULL);
            }

            // Interrupts are not enabled on a newly inserted card.
            EnableSDIOInterrupts(FALSE);

            // Indicate device arrival
            IndicateSlotStateChange(DeviceInserted);

            // Disable the command and data CRC error
            WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, (wErrIntSignalEn | (0x20)));
            WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, (wErrIntStatusEn | (0x20)));

             // Below code lines are needed for working as a mass storage device
            v_gBspArgs->g_SDCardState = CARD_INSERTED;
            SetEvent( v_gBspArgs->g_SDCardDetectEvent );
        }

    BOOL 
        CSDHCSlotBase::HandleCommandComplete(
                )
        {
            SETFNAME();

            PSD_BUS_REQUEST pRequest;
            BOOL fRet = FALSE;

            // get the current request  
            pRequest = GetAndLockCurrentRequest();
            DEBUGCHK(m_dwReadyInts == 0);

            if (pRequest) {
                DEBUGCHK(pRequest->HCParam == 0);
                // INT_TRX_COMPLETE is not suitable for s3c6410, so I comment out below code.
                // therefore, in order to keep fastpath status, those code like just below is needed.
                SD_API_STATUS transferStatus = (m_FastPathStatus >= SD_API_STATUS_SUCCESS) ? SD_API_STATUS_SUCCESS : m_FastPathStatus;

                if (NoResponse != pRequest->CommandResponse.ResponseType) {
                    // Copy response over to request structure. Note that this is a 
                    // bus driver buffer, so we do not need to SetProcPermissions 
                    // or __try/__except.
                    UNALIGNED DWORD *pdwResponseBuffer = 
                        (PDWORD) (pRequest->CommandResponse.ResponseBuffer + 1); // Skip CRC
                    WORD wCommand = ReadWord(SDHC_COMMAND);

                    if ((wCommand & CMD_RESPONSE_R1B_R5B) == CMD_RESPONSE_R1B_R5B) {
                        // Reset cmd and dat circuits
                        SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
                    }

                    pdwResponseBuffer[0] = ReadDword(SDHC_R0);
                    if (pRequest->CommandResponse.ResponseType == ResponseR2) {
                        pdwResponseBuffer[1] = ReadDword(SDHC_R2);
                        pdwResponseBuffer[2] = ReadDword(SDHC_R4);
                        pdwResponseBuffer[3] = ReadDword(SDHC_R6);
                    }
                }

                // check for command/response only
                if (TRANSFER_IS_COMMAND_ONLY(pRequest)) {
                    IndicateBusRequestComplete(pRequest, transferStatus);
                    fRet = TRUE;
                } else {
                    // handle data phase transfer
                    pRequest->HCParam = 0;
                    fRet = FALSE;
                }
            }
            // else request must have been canceled due to an error

            return fRet;
        }

    VOID 
        CSDHCSlotBase::HandleErrors(
                )
        {
            SD_API_STATUS status = SD_API_STATUS_SUCCESS;

            // get the current request  
            PSD_BUS_REQUEST pRequest = NULL;
            pRequest = GetAndLockCurrentRequest();

            WORD wErrorStatus = 0;
            WORD RetryCount = 100;

            do {
                wErrorStatus = ReadWord(SDHC_ERROR_INT_STATUS);
                RetryCount--;
            } while ((wErrorStatus == 0) || (RetryCount != 0));

            if (wErrorStatus == 0)
            {
                DEBUGMSG(SDCARD_ZONE_ERROR, 
                        (TEXT("[HSMMC0] HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
                return;
            }
    
            DEBUGMSG(SDCARD_ZONE_ERROR, 
                    (TEXT("[HSMMC0] HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
            if (pRequest) {
                DumpRequest(pRequest, SDCARD_ZONE_ERROR);
                // For simple debugging, we have to confirm the command number!
                RETAILMSG(TRUE, (TEXT("[HSMMC0] HandleErrors - ERR CMD:%d : "), pRequest->CommandCode));
            }

            DEBUGCHK( (wErrorStatus & ERR_INT_STATUS_VENDOR) == 0 );

            if (wErrorStatus) {
                if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT ) {
                    status = SD_API_STATUS_RESPONSE_TIMEOUT;
                    switch(pRequest->CommandCode) {
                        case 1 : RETAILMSG(TRUE, (TEXT("If the card is not a MMC, CMD 1 does not work in reason.\n")));
                            break;
                        case 5 : RETAILMSG(TRUE, (TEXT("If the card is not a SDIO, CMD 5 does not work in reason.\n")));
                            break;
                        case 8 : RETAILMSG(TRUE, (TEXT("If the card is not SD SPEC 2.0, CMD 8 does not work in reason.\n")));
                            break;
                        default :
                            RETAILMSG(TRUE, (TEXT("[HSMMC0] HandleErrors - CMD Timeout Error...\n")));
                            break;
                    }
                }

                if ( wErrorStatus & ERR_INT_STATUS_CMD_CRC ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - CMD CRC Error...\r\n")));            
                    status = SD_API_STATUS_CRC_ERROR;
                    if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT )
                        status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                }

                if ( wErrorStatus & ERR_INT_STATUS_CMD_ENDBIT ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - CMD ENDBIT Error...\r\n")));                        
                    status = SD_API_STATUS_RESPONSE_TIMEOUT;
                }

                if ( wErrorStatus & ERR_INT_STATUS_CMD_INDEX ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - CMD INDEX Error...\r\n")));            
                    status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                }

                if ( wErrorStatus & ERR_INT_STATUS_DAT_TIMEOUT ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - DAT Timeout Error...\r\n")));            
                    status = SD_API_STATUS_DATA_TIMEOUT;
                }

                if ( wErrorStatus & ERR_INT_STATUS_DAT_CRC ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - Data CRC Error...\r\n")));              
                    status = SD_API_STATUS_CRC_ERROR;
                }

                if ( wErrorStatus & ERR_INT_STATUS_DAT_ENDBIT ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - DAT END BIT Error...\r\n")));            
                    status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                }

                if ( wErrorStatus & ERR_INT_STATUS_BUS_POWER ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - Bus Power Error...\r\n")));
                    status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                }

                if ( wErrorStatus & ERR_INT_STATUS_AUTOCMD12 ) {
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - AUTOCMD12 Error...\r\n")));            
                    status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                }

                if (wErrorStatus & ERR_INT_STATUS_ADMA) { // ADMA Error
                    RETAILMSG(TRUE,(TEXT("[HSMMC0] HandleErrors - ADMA Error...\r\n")));
                    if (m_SlotDma && pRequest ) {
                        m_SlotDma->DMANotifyEvent(*pRequest, DMA_ERROR_OCCOR );
                    }
                    else {
                        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("[HSMMC0] HandleErrors - ADMA Error without DMA Enabled (0x%x). Resetting CMD line.\r\n"),
                                    wErrorStatus));
                    }
                }
                
                // Perform basic error recovery
                WORD wErrIntSignal = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
                WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, 0);
                // Make sure that the value of "Error Interrupt Status Enable" is zero
                WORD wErrIntStatusEn = ReadWord(SDHC_ERROR_INT_STATUS_ENABLE);
                WriteWord(SDHC_ERROR_INT_STATUS_ENABLE,0);

                if (IS_CMD_LINE_ERROR(wErrorStatus)) {
                    // Reset CMD line
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("[HSMMC0] HandleErrors - Command line error (0x%x). Resetting CMD line.\r\n"),
                                wErrorStatus));
                    SoftwareReset(SOFT_RESET_CMD);
                }

                if (IS_DAT_LINE_ERROR(wErrorStatus)) {
                    // Reset DAT line
                    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("[HSMMC0] HandleErrors - Data line error (0x%x). Resetting DAT line.\r\n"),
                                wErrorStatus));

                    DWORD RetryCount = 5000;

                    SoftwareReset(SOFT_RESET_DAT);
                    do {
                        WriteWord(SDHC_ERROR_INT_STATUS,wErrorStatus);

                        if ((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_ERROR_INT)) {
                            RetryCount--;
                        } else {
                            break;
                        }

                        if(RetryCount == 0) {
                            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("[HSMMC0] HandleErrors - DAT line error Recovery Timeout...\r\n")));
                        }
                    } while(RetryCount != 0);
                }

                // clear all error status
                WriteWord(SDHC_ERROR_INT_STATUS, wErrorStatus);

                // re-enable error interrupt signals
                WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, wErrIntStatusEn);
                WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, wErrIntSignal);

                // complete the request
                if (pRequest) {
                    IndicateBusRequestComplete(pRequest, status);
                } else {
                    // If there is not a current request, the initialize of normal interrupt status enable is needed.
                    WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,
                            (ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)) | NORMAL_INT_ENABLE_CMD_COMPLETE | NORMAL_INT_ENABLE_TRX_COMPLETE);
                }
            }
        }

    VOID 
        CSDHCSlotBase::HandleTransferDone(
                )
        {
            PSD_BUS_REQUEST pRequest;
            SD_API_STATUS   status = SD_API_STATUS_SUCCESS;

            // get the current request  
            pRequest = GetAndLockCurrentRequest();

            if (pRequest) {
                if (!TRANSFER_IS_COMMAND_ONLY(pRequest)) {
                    if (m_SlotDma && !m_SlotDma->IsDMACompleted()) {
                        m_SlotDma->DMANotifyEvent(*pRequest, TRANSFER_COMPLETED);
                    }
                }
                if (pRequest->HCParam != TRANSFER_SIZE(pRequest)) {
                    // This means that a Command Complete interrupt occurred before
                    // a Buffer Ready interrupt. Hardware should not allow this. 
                    DEBUGCHK(FALSE);
                    status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                }

                // complete the request
                if (pRequest->Flags & SD_AUTO_ISSUE_CMD12) {
                    m_fAutoCMD12Success = TRUE;
                }
                IndicateBusRequestComplete(pRequest, status);
            }
            // else request must have been canceled due to an error
        }


    VOID 
        CSDHCSlotBase::HandleReadReady(
                )
        {
            DEBUGMSG(SDHC_RECEIVE_ZONE, (TEXT("HandleReadReady - HandleReadReady!\n"))); 

            // get the current request  
            PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

            if (pRequest) {
                DEBUGCHK(pRequest->NumBlocks > 0);
                DEBUGCHK(pRequest->HCParam < TRANSFER_SIZE(pRequest));
                DEBUGCHK(TRANSFER_IS_READ(pRequest));

#ifdef DEBUG
                ++m_dwReadyInts;
#endif

                __try {
                    PDWORD pdwUserBuffer = (PDWORD) &pRequest->pBlockBuffer[pRequest->HCParam];
                    PDWORD pdwBuffer = pdwUserBuffer;
                    DWORD  rgdwIntermediateBuffer[SDHC_MAX_BLOCK_LENGTH / sizeof(DWORD)];
                    BOOL   fUsingIntermediateBuffer = FALSE;
                    DWORD  cDwords = pRequest->BlockSize / 4;
                    DWORD  dwRemainder = pRequest->BlockSize % 4;

                    PREFAST_DEBUGCHK(sizeof(rgdwIntermediateBuffer) >= pRequest->BlockSize);

                    if (((DWORD) pdwUserBuffer) % 4 != 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -