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

📄 sdhcslot.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            }
            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);
#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

    RETAILMSG(0,(TEXT("-HandleInsertion\r\n"))); // jylee
 
	v_gBspArgs->g_SDCardState = CARD_INSERTED;
      	SetEvent( v_gBspArgs->g_SDCardDetectEvent );
}


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

    PSD_BUS_REQUEST pRequest;
    BOOL fRet = FALSE;
	int count = 0 ;
	RETAILMSG(CRC_DEBUG,(TEXT("CSDHCSlotBase:: +HandleCommandComplete\r\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

#if 0
		RETAILMSG(CRC_DEBUG,(TEXT("Waiting for RESPONSE_R1B_R5B\r\n")));
		BOOL fSuccess = WaitForReg<WORD>(&CSDHCSlotBase::ReadWord, SDHC_NORMAL_INT_STATUS, NORMAL_INT_STATUS_TRX_COMPLETE, NORMAL_INT_STATUS_TRX_COMPLETE, 5000);
		RETAILMSG(CRC_DEBUG, (_T("%s Go waiting for NORMAL_INT_STATUS_TRX_COMPLETE\r\n"), pszFname));

              if (!fSuccess) {
              	RETAILMSG(1, (_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")));
#endif
	  	
                // 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\r\n"),pdwResponseBuffer[1]));
            RETAILMSG(0,(TEXT("pdwResponseBuffer[2]= 0x%X\r\n"),pdwResponseBuffer[2]));
            RETAILMSG(0,(TEXT("pdwResponseBuffer[3]= 0x%X\r\n"),pdwResponseBuffer[3]));
            }
        }

        // 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
	//RETAILMSG(1,(TEXT("CSDHCSlotBase:: -HandleCommandComplete\r\n")));

    return fRet;
}


VOID
CSDHCSlotBase::HandleErrors(
                            )
{
    SD_API_STATUS status = SD_API_STATUS_SUCCESS;
    RETAILMSG(CRC_DEBUG,(TEXT("+CSDHCSlotBase:: +HandleErrors\r\n")));

// 2007.06.10
// S/W workaround for the following problem
// Problem : When the interrupt is occurred, it is late to update the interrupt status register related to the interrupt source
while((ReadWord(SDHC_ERROR_INT_STATUS) ==0));

    // get the current request
    PSD_BUS_REQUEST pRequest = GetAndLockCurrentRequest();
    RETAILMSG(1,(TEXT("[HandleErrors] CMD %d\r\n"),pRequest->CommandCode));
    WORD wErrorStatus = ReadWord(SDHC_ERROR_INT_STATUS);
    RETAILMSG(CRC_DEBUG, (TEXT("CSDHCSlotBase::HandleErrors - ERROR INT STATUS=0x%04X\n\r"), wErrorStatus));	// jylee
    DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("HandleErrors - ERROR INT STATUS=0x%02X\n"), wErrorStatus));
//2007.09.09 D.Baek
    if(pRequest != NULL)
    {
    	RETAILMSG(1,(TEXT("[HandleErrors] CMD %d\r\n"),pRequest->CommandCode));
    }else
    {
    	RETAILMSG(1,(TEXT("[HandleErrors] Invalid pRequest value.\r\n")));
    	goto HandleErrors_Exit;
    }
    
    if (pRequest) {
        DumpRequest(pRequest, SDCARD_ZONE_ERROR);
    }

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

    if (wErrorStatus) {
        if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT ) {
		    RETAILMSG(1,(TEXT("CMD Timeout  Error...\r\n")));
            status = SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_CRC ) 
	{
            	status = SD_API_STATUS_CRC_ERROR;
		RETAILMSG(1,(TEXT("CMD CRC Error...\r\n")));			

		if ( wErrorStatus & ERR_INT_STATUS_CMD_TIMEOUT )
                	status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_ENDBIT ) {
	    	RETAILMSG(1,(TEXT("CMD ENDBIT Error...\r\n")));						
            	status = SD_API_STATUS_RESPONSE_TIMEOUT;
        }

        if ( wErrorStatus & ERR_INT_STATUS_CMD_INDEX ) {
		RETAILMSG(1,(TEXT("CMD INDEX Error...\r\n")));			
            	status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_DAT_TIMEOUT ) {
		RETAILMSG(1,(TEXT("DAT Timeout Error...\r\n")));			
            	status = SD_API_STATUS_DATA_TIMEOUT;
        }

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

        if ( wErrorStatus & ERR_INT_STATUS_DAT_ENDBIT ) {
		RETAILMSG(1,(TEXT("DAT END BIT Error...\r\n")));			
            	status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_BUS_POWER ) {
		RETAILMSG(1,(TEXT("Bus Power Error...\r\n")));			
            	status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

        if ( wErrorStatus & ERR_INT_STATUS_AUTOCMD12 ) {
        	RETAILMSG(1,(TEXT("AUTOCMD12 Error...\r\n")));			
            	status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
        }

HandleErrors_Exit:
// 2007.08.31 D.Baek
        // Perform basic error recovery
        WORD wErrIntSignal = ReadWord(SDHC_ERROR_INT_SIGNAL_ENABLE);
        WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, 0);
	 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("HandleErrors - Command line error (0x%x). Resetting CMD line.\r\n"), wErrorStatus));
            RETAILMSG(1,(TEXT("CMD Line Error: 0x%x\r\n"),wErrorStatus)); // jylee
            do
            {
				WriteWord(SDHC_ERROR_INT_STATUS, wErrorStatus);
            } while(ReadWord(SDHC_ERROR_INT_STATUS));
            RETAILMSG(1,(TEXT("CMD Line Error Status : 0x%x\r\n"),ReadWord(SDHC_ERROR_INT_STATUS)));
            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));
            RETAILMSG(CRC_DEBUG,(TEXT("Data Line Error(%x). Resetting DAT line\r\n"),wErrorStatus)); // jylee
            do
            {
    		WriteWord(SDHC_ERROR_INT_STATUS,wErrorStatus);
            } while(ReadWord(SDHC_ERROR_INT_STATUS));

	       // Make sure that the value of "Normal Interrupt Status register" is zero
	       DWORD error_timeout = 5000;
	       do
	       {
		   		WriteWord(SDHC_ERROR_INT_STATUS,wErrorStatus);
				if((ReadWord(SDHC_NORMAL_INT_STATUS) & NORMAL_INT_STATUS_ERROR_INT))
				{
					error_timeout--;
				}else
				{
					break;
				}
				if(error_timeout == 0 )
				{
					RETAILMSG(1,(TEXT("[HandleErrors] Timeout...\r\n")));
				}
   	    }while(error_timeout != 0);
         SoftwareReset(SOFT_RESET_DAT);
         }
 	RETAILMSG(CRC_DEBUG,(TEXT(
"SOFT_RESET_CMD : 0x%x\r\n"),ReadByte(SDHC_SOFT_RESET)));
 
 #if 1
         // clear all error status
         do{
         	WriteWord(SDHC_ERROR_INT_STATUS, wErrorStatus);
         }while(ReadWord(SDHC_ERROR_INT_STATUS));

 #endif
         // re-enable error interrupt signals
 #if 1 // After modifying the code due to unwanted CRC Error interrupt.
         WriteWord(SDHC_ERROR_INT_STATUS_ENABLE, wErrIntStatusEn);
         WriteWord(SDHC_ERROR_INT_SIGNAL_ENABLE, wErrIntSignal);
 #endif 

         // complete the request
         if (pRequest) {
             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))); // jylee
 	 }
 
     }
     //RETAILMSG(CRC_DEBUG,(TEXT("CSDHCSlotBase:: -HandleErrors\r\n")));
 }
 
 
 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(0,(TEXT("pRequest->HCParam != TRANSFER_SIZE(pRequest)\n"))); // jylee
             DEBUGCHK(FALSE);
             status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
         }
 
         // complete the request
         if ((pRequest->Flags & SD_AUTO_ISSUE_CMD12) && *((DWORD *)(pRequest->hDevice)) != 0) {
         	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(TR

⌨️ 快捷键说明

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