?? sdhcslot.cpp
字號:
// 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 + -