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

📄 sdhcslot.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            RETAILMSG(0,(TEXT("pdwResponseBuffer[2]= 0x%X\n"),pdwResponseBuffer[2]));
            RETAILMSG(0,(TEXT("pdwResponseBuffer[3]= 0x%X\n"),pdwResponseBuffer[3]));			
            }
        }

        // check for command/response only
        if (TRANSFER_IS_COMMAND_ONLY(pRequest)) {
            IndicateBusRequestComplete(pRequest, transferStatus);
            fRet = TRUE;
        } else {
            // handle data phase transfer
		//pIOPreg->GPFDAT = (0x1<<7);
            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 = GetAndLockCurrentRequest();

    WORD wErrorStatus = ReadWord(SDHC_ERROR_INT_STATUS);
    RETAILMSG(1, 
        (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));	
    DEBUGMSG(SDCARD_ZONE_ERROR, 
        (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
    if (pRequest) {
        DumpRequest(pRequest, SDCARD_ZONE_ERROR);
    }

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

    if (wErrorStatus) {
        if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT ) {
            status = SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_CRC ) {
            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 ) {
            status = SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_INDEX ) {
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_TIMEOUT ) {
            status = SD_API_STATUS_DATA_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_CRC ) {
            status = SD_API_STATUS_CRC_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_ENDBIT ) {
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_BUS_POWER ) {
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_AUTOCMD12 ) {
            status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        // Perform basic error recovery
        WORD wErrIntSignal = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
        WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, 0);

        if (IS_CMD_LINE_ERROR(wErrorStatus)) {
            // Reset CMD line
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("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("HandleErrors - Data line error (0x%x). Resetting DAT line.\r\n"),
                wErrorStatus));
            SoftwareReset(SOFT_RESET_DAT);
        }

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

        // re-enable error interrupt signals
        WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, wErrIntSignal);
	 RETAILMSG(0,(TEXT("Error Handler : 0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));
        // complete the request
        if (pRequest) {
		RETAILMSG(0,(TEXT("IndicateBusRequestComplete(pRequest, status)\n")));
            IndicateBusRequestComplete(pRequest, status);
        }
	 else
	 {
	 	WORD wIntEnable = ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE);
		wIntEnable |= NORMAL_INT_ENABLE_CMD_COMPLETE | NORMAL_INT_ENABLE_TRX_COMPLETE;
		WriteWord(SDHC_NORMAL_INT_STATUS_ENABLE,wIntEnable);
		 RETAILMSG(0,(TEXT("Error Handler : 0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));		
	 }
    }
}


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

    // get the current request  
    pRequest = GetAndLockCurrentRequest();
	RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleTransferDone\n")));
    if (pRequest) {
        if (!TRANSFER_IS_COMMAND_ONLY(pRequest)) {
            if (UseDmaForRequest(pRequest)) {
                DWORD cbTransfer = TRANSFER_SIZE(pRequest);
                DWORD cbRemainder = cbTransfer % CB_DMA_PAGE;

                if (cbRemainder == 0) {
                    cbRemainder = CB_DMA_PAGE;
                }
                pRequest->HCParam += cbRemainder;
		RETAILMSG(0,(TEXT("pRequest->HCParam=%d, cbTransfer=%d, PAGE_SIZE=%d\n"),pRequest->HCParam,cbTransfer,PAGE_SIZE));				
		//pIOPreg->GPFDAT &= ~(0x1<<7);
                if (TRANSFER_IS_READ(pRequest)) {
                    BOOL fNoException;
                    DEBUGCHK(cbTransfer <= CB_DMA_BUFFER);

                    SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {               
                        fNoException = SDPerformSafeCopy(pRequest->pBlockBuffer,
                            m_pbDmaBuffer, cbTransfer);
                    } SD_RESTORE_PROC_PERMISSIONS();

                    if (fNoException == FALSE) {
                        status = SD_API_STATUS_ACCESS_VIOLATION;
                    }
                }
            }
        }

        if (pRequest->HCParam != TRANSFER_SIZE(pRequest)) {
            // This means that a Command Complete interrupt occurred before
            // a Buffer Ready interrupt. Hardware should not allow this. 
            RETAILMSG(1,(TEXT("pRequest->HCParam != TRANSFER_SIZE(pRequest)\n")));
            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(!UseDmaForRequest(pRequest));
        DEBUGCHK(pRequest->NumBlocks > 0);
        DEBUGCHK(pRequest->HCParam < TRANSFER_SIZE(pRequest));
        DEBUGCHK(TRANSFER_IS_READ(pRequest));

#ifdef DEBUG
        ++m_dwReadyInts;
#endif

        DWORD dwOldPermissions = SetProcPermissions(pRequest->CurrentPermissions);

        __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) {
                // Buffer is not DWORD aligned so we must use an
                // intermediate buffer.
                pdwBuffer = rgdwIntermediateBuffer;
                fUsingIntermediateBuffer = TRUE;
            }

            DWORD dwDwordsRemaining = cDwords;
            pRequest->HCParam += dwDwordsRemaining * 4;

            // Read the data from the device
            while ( dwDwordsRemaining-- ) {
                *(pdwBuffer++) = ReadDword(SDHC_BUFFER_DATA_PORT_0);
            }

            if ( dwRemainder != 0 ) {
                DWORD dwLastWord = ReadDword(SDHC_BUFFER_DATA_PORT_0);
                memcpy(pdwBuffer, &dwLastWord, dwRemainder);
                pRequest->HCParam += dwRemainder;
            }

            if (fUsingIntermediateBuffer) {
                memcpy(pdwUserBuffer, rgdwIntermediateBuffer, pRequest->BlockSize);
            }

            SetProcPermissions(dwOldPermissions);
        }
        __except(SDProcessException(GetExceptionInformation())) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("Exception reading from client buffer!\r\n")));
            SetProcPermissions(dwOldPermissions);
            IndicateBusRequestComplete(pRequest, SD_API_STATUS_ACCESS_VIOLATION);
        }

        DEBUGCHK(pRequest->HCParam == (m_dwReadyInts * pRequest->BlockSize));
    }
    // else request must have been canceled due to an error
}


VOID 
CSDHCSlotBase::HandleWriteReady(
                                )
{    
    DEBUGMSG(SDHC_TRANSMIT_ZONE, (TEXT("HandleWriteReady - HandleWriteReady! \n"))); 

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

    if (pRequest) {
        DEBUGCHK(TRANSFER_IS_WRITE(pRequest));
        DEBUGCHK(!UseDmaForRequest(pRequest));
        DEBUGCHK(pRequest->NumBlocks > 0);
        DEBUGCHK(pRequest->HCParam < TRANSFER_SIZE(pRequest));

#ifdef DEBUG
        ++m_dwReadyInts;
#endif

        DWORD dwOldPermissions = SetProcPermissions(pRequest->CurrentPermissions);

        __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) {
                // Buffer is not DWORD aligned so we must use an
                // intermediate buffer.
                pdwBuffer = rgdwIntermediateBuffer;
                memcpy(rgdwIntermediateBuffer, pdwUserBuffer, pRequest->BlockSize);
            }

            DWORD dwDwordsRemaining = cDwords;
            pRequest->HCParam += dwDwordsRemaining * 4;

            // Write data to buffer data port
            while ( dwDwordsRemaining-- ) {
                WriteDword(SDHC_BUFFER_DATA_PORT_0, *(pdwBuffer++));
            }

            if ( dwRemainder != 0 ) {
                DWORD dwLastWord = 0;
                memcpy(&dwLastWord, pdwBuffer, dwRemainder);
                WriteDword(SDHC_BUFFER_DATA_PORT_0, dwLastWord);
                pRequest->HCParam += dwRemainder;
            }

            SetProcPermissions(dwOldPermissions);
        }
        __except(SDProcessException(GetExceptionInformation())) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("Exception reading from client buffer!\r\n")));
            SetProcPermissions(dwOldPermissions);
            IndicateBusRequestComplete(pRequest, SD_API_STATUS_ACCESS_VIOLATION);
        }

        DEBUGCHK(pRequest->HCParam == (m_dwReadyInts * pRequest->BlockSize));
    }
    // else request must have been canceled due to an error
}


VOID 
CSDHCSlotBase::HandleDma(
                         )
{
    // Get the current request
    PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();

    if (pRequest) {
        DEBUGCHK(pRequest->NumBlocks > 0);
        DEBUGCHK(UseDmaForRequest(pRequest));
		RETAILMSG(1,(TEXT("CSDHCSlotBase::HandleDma\n")));
		RETAILMSG(1,(TEXT("pRequest->HCParam=%d, CB_DMA_PAGE=%d, TRANSFER_SIZE(pRequest)=%d\n"),pRequest->HCParam,CB_DMA_PAGE,TRANSFER_SIZE(pRequest)));
        DWORD dwNewHCParam = pRequest->HCParam + CB_DMA_PAGE;

        // Only update our transferred count if we have not completed the
        // transfer already, since some host controllers give an extra
        // DMA interrupt after the last block transfer.
        if (dwNewHCParam < TRANSFER_SIZE(pRequest)) {
		RETAILMSG(1,(TEXT("dwNewHCParam < TRANSFER_SIZE(pRequest)\n")));			
            pRequest->HCParam = dwNewHCParam;
            DWORD paCurrDmaBuffer = m_paDmaBuffer + pRequest->HCParam;
            DEBUGCHK( paCurrDmaBuffer < (m_paDmaBuffer + CB_DMA_BUFFER) );
            DEBUGCHK( paCurrDmaBuffer < (m_paDmaBuffer + TRANSFER_SIZE(pRequest)) );
            DEBUGCHK( paCurrDmaBuffer == ReadDword(SDHC_SYSTEMADDRESS_LO) );

            WriteDword(SDHC_SYSTEMADDRESS_LO, paCurrDmaBuffer);
        }
    }
    // else request must have been canceled due to an error
}


BOOL 
CSDHCSlotBase::UseDmaForRequest(
                                PSD_BUS_REQUEST pRequest
                                )
{
    PREFAST_DEBUGCHK(pRequest);

    BOOL fRet = FALSE;
    
    if (m_pbDmaBuffer) {
        DEBUGCHK(m_paDmaBuffer);

        if ( (pRequest->BlockSize % 4 == 0) &&
             (TRANSFER_SIZE(pRequest) <= CB_DMA_BUFFER) ) {
            DEBUGCHK(m_paDmaBuffer % 4 == 0);
            DEBUGCHK(PAGE_SIZE == CB_DMA_PAGE);
            fRet = TRUE;
        }
    }
    
    return fRet;
}


PVOID
CSDHCSlotBase::AllocPhysBuffer(
                               size_t cb,
                               PDWORD pdwPhysAddr
                               )
{
    PVOID pvUncached;
    PVOID pvRet = NULL;
    DWORD dwPhysAddr;

    pvUncached = AllocPhysMem(cb, PAGE_READWRITE, 0, 0, &dwPhysAddr);

    if (pvUncached) {
        *pdwPhysAddr = dwPhysAddr;
        pvRet = pvUncached;
    }

    return pvRet;
}


VOID
CSDHCSlotBase::FreePhysBuffer(
                              PVOID pv

⌨️ 快捷键说明

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