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

📄 sdhcslot.cpp

📁 Samsung公司S3C2443芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                m_paDmaBuffer = BusAddr.LowPart;
            }
            else {
                // If we fail, we will simply fall back to PIO mode
                FreePhysBuffer(pvBuffer);
            }
        }
    }

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

    // Indicate device arrival
    IndicateSlotStateChange(DeviceInserted);
}


BOOL 
CSDHCSlotBase::HandleCommandComplete(
                                     )
{
    SETFNAME();
    
    PSD_BUS_REQUEST pRequest;
    BOOL fRet = FALSE;
	int count = 0 ;
	RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete\n")));
    // get the current request  
    pRequest = GetAndLockCurrentRequest();

    DEBUGCHK(m_dwReadyInts == 0);

    if (pRequest) {
	RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete    pRequest\n")));		
        DEBUGCHK(pRequest->HCParam == 0);
        SD_API_STATUS transferStatus = SD_API_STATUS_SUCCESS;
        
        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) {
                // wait for Transfer Complete status, which indicate the busy wait is over.
                // we should not handle this TXN_COMPLETE interrupt in IST in this case
                
		/*
		 RETAILMSG(0,(TEXT("HandleCommandComplete Status: 0x%X\n"),ReadWord(SDHC_NORMAL_INT_STATUS_ENABLE)));				
		 RETAILMSG(0,(TEXT("HandleCommandComplete Signal: 0x%X\n"),ReadWord(SDHC_NORMAL_INT_SIGNAL_ENABLE)));								
                BOOL fSuccess = WaitForReg<WORD>(ReadWord, SDHC_NORMAL_INT_STATUS, 
                    NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE, 5000);
                    RETAILMSG(0, (_T("%s Go waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                        pszFname));					
                if (!fSuccess) {
                    RETAILMSG(0, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                        pszFname));					
                    DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Timeout waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"),
                        pszFname));
                    transferStatus = SD_API_STATUS_RESPONSE_TIMEOUT;
                }*/

		   RETAILMSG(0,(TEXT("CSDHCSlotBase::HandleCommandComplete    SoftwareReset\n")));	
                // Reset cmd and dat circuits
                SoftwareReset(SOFT_RESET_CMD | SOFT_RESET_DAT);
            }
		
            pdwResponseBuffer[0] = ReadDword(SDHC_R0);
            RETAILMSG(0,(TEXT("pdwResponseBuffer[0]= 0x%X\n"),pdwResponseBuffer[0]));
            if (pRequest->CommandResponse.ResponseType == ResponseR2) {
                pdwResponseBuffer[1] = ReadDword(SDHC_R2);
                pdwResponseBuffer[2] = ReadDword(SDHC_R4);
                pdwResponseBuffer[3] = ReadDword(SDHC_R6);
            RETAILMSG(0,(TEXT("pdwResponseBuffer[1]= 0x%X\n"),pdwResponseBuffer[1]));
            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);
		//WaitForReg<WORD>(ReadWord, SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE); 

			/*
			do{
			}while ((ReadWord(SDHC_NORMAL_INT_STATUS)&NORMAL_INT_STATUS_TRX_COMPLETE) != NORMAL_INT_STATUS_TRX_COMPLETE);		 */
            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) && *((DWORD *)(pRequest->hDevice)) != 0) {
		if ((pRequest->Flags & SD_AUTO_ISSUE_CMD12)) {        
        	RETAILMSG(0,(TEXT("SDSDSDCARD\n")));
            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);

⌨️ 快捷键说明

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