📄 sdhc.cpp
字号:
// Input: Slot - slot the request is going on
// pRequest - the request to be cancelled
//
// Output:
// Return: TRUE if I/O was cancelled
// Notes:
// the HC lock is taken before entering this cancel handler
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN CSDIOControllerBase::SDHCCancelIoHandlerImpl( UCHAR Slot, PSD_BUS_REQUEST pRequest)
{
// for now, we should never get here because all requests are non-cancelable
// the hardware supports timeouts so it is impossible for the controller to get stuck
DEBUGCHK(FALSE);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// CSDIOControllerBase::SDHCBusRequestHandlerImpl - bus request ha ndler
// Input: pRequest - the request
//
// Output:
// Return: SD_API_STATUS
// Notes: The request passed in is marked as uncancelable, this function
// has the option of making the outstanding request cancelable
// returns status pending
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::SDHCBusRequestHandlerImpl( PSD_BUS_REQUEST pRequest )
{
DEBUGCHK(pRequest);
SD_API_STATUS status;
BOOL fWriteTransferMode = FALSE;
DEBUGMSG(SHC_SEND_ZONE, (L"CSDIOControllerBase::SDHCBusRequestHandlerImpl: "
L"CMD: [%d]\r\n", pRequest->CommandCode
));
// acquire the device lock to protect from device removal
SDHCDAcquireHCLock(m_pHCContext);
if ( m_pCurrentRequest) {
IndicateBusRequestComplete(pRequest, SD_API_STATUS_CANCELED);
m_pCurrentRequest = NULL;
}
m_fCurrentRequestFastPath = FALSE;
m_pCurrentRequest = pRequest ;
// if no data transfer involved, use FAST PATH
if (pRequest->SystemFlags & SD_FAST_PATH_AVAILABLE &&
!( SD_COMMAND != pRequest->TransferClass &&
pRequest->NumBlocks * pRequest->BlockSize >= NUM_BYTE_FOR_POLLING_MODE)){ // We do fast path here.
m_fCurrentRequestFastPath = TRUE;
InterruptMask(m_dwControllerSysIntr,TRUE);
status = SendCommand(pRequest);
if ( status == SD_API_STATUS_PENDING ) { // Polling for completion.
while (m_pCurrentRequest) {
if( Read_MMC_STAT() & INREG16(&m_vpSDIOReg->MMC_IE) & (MMC_IE_EOC|MMC_STAT_CERR|MMC_STAT_CCRC|MMC_STAT_CTO)) {
CommandCompleteHandler();
}
}
status = FastPathStatus;
}
InterruptMask(m_dwControllerSysIntr,FALSE);
ASSERT(m_fCurrentRequestFastPath);
}
else
{
pRequest->SystemFlags &= ~SD_FAST_PATH_AVAILABLE ;
status = SendCommand(pRequest);
if(!SD_API_SUCCESS(status))
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::SDHCBusRequestHandlerImpl: "
L"Error sending command:0x%02x\r\n", pRequest->CommandCode
));
goto EXIT;
}
}
EXIT:
SDHCDReleaseHCLock(m_pHCContext);
return status;
}
// CommandCompleteHandler
// Input:
// Output:
// Notes:
BOOL CSDIOControllerBase::CommandCompleteHandler()
{
DWORD dwCurrentTickCount;
DWORD dwTimeout;
DWORD dwCountStart;
BOOL fTimeoutOverflow = FALSE;
PSD_BUS_REQUEST pRequest = NULL; // the request to complete
SD_API_STATUS status = SD_API_STATUS_PENDING;
DEBUGMSG(SHC_INTERRUPT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Got the command response\r\n"
));
#ifdef SDIO_INAB_INTERRUPT_WORKAROUND
if( m_fINABworkaroundEnabled )
{
if( m_CurrentState == SendingINAB )
goto PROCESS_INAB_STATE;
}
#endif
// get and lock the current bus request
if((pRequest = SDHCDGetAndLockCurrentRequest(m_pHCContext, 0)) == NULL)
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Unable to get/lock current request!\r\n"
));
status = SD_API_STATUS_INVALID_DEVICE_REQUEST;
goto TRANSFER_DONE;
}
#ifdef DEBUG
EnterCriticalSection( &m_critSec );
DEBUGMSG(SDCARD_ZONE_INIT, (L"+DebugSDHCRegs-------------------------\r\n"));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_CMD 0x%04X \r\n", m_vpSDIOReg->MMC_CMD ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_ARG1 0x%04X \r\n", m_vpSDIOReg->MMC_ARG1 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_ARG2 0x%04X \r\n", m_vpSDIOReg->MMC_ARG2 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_CON 0x%04X \r\n", m_vpSDIOReg->MMC_CON ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_STAT 0x%04X \r\n", m_vpSDIOReg->MMC_STAT ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_IE 0x%04X \r\n", m_vpSDIOReg->MMC_IE ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_CTO 0x%04X \r\n", m_vpSDIOReg->MMC_CTO ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_DTO 0x%04X \r\n", m_vpSDIOReg->MMC_DTO ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_BLEN 0x%04X \r\n", m_vpSDIOReg->MMC_BLEN ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_NBLK 0x%04X \r\n", m_vpSDIOReg->MMC_NBLK ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_BUF 0x%04X \r\n", m_vpSDIOReg->MMC_BUF ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_SDIO 0x%04X \r\n", m_vpSDIOReg->MMC_SDIO ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_REV 0x%04X \r\n", m_vpSDIOReg->MMC_REV ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP0 0x%04X \r\n", m_vpSDIOReg->MMC_RSP0 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP1 0x%04X \r\n", m_vpSDIOReg->MMC_RSP1 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP2 0x%04X \r\n", m_vpSDIOReg->MMC_RSP2 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP3 0x%04X \r\n", m_vpSDIOReg->MMC_RSP3 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP4 0x%04X \r\n", m_vpSDIOReg->MMC_RSP4 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP5 0x%04X \r\n", m_vpSDIOReg->MMC_RSP5 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP6 0x%04X \r\n", m_vpSDIOReg->MMC_RSP6 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_RSP7 0x%04X \r\n", m_vpSDIOReg->MMC_RSP7 ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_IOSR 0x%04X \r\n", m_vpSDIOReg->MMC_IOSR ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_SYSC 0x%04X \r\n", m_vpSDIOReg->MMC_SYSC ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"MMC_SISS 0x%04X \r\n", m_vpSDIOReg->MMC_SISS ));
DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_WKEN1 0x%04X \r\n", m_vpPRCMReg->ulPM_WKEN1_CORE));
DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_WKST1 0x%04X \r\n", m_vpPRCMReg->ulPM_WKST1_CORE));
DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_AUTOIDEL1 0x%04X \r\n", m_vpPRCMReg->ulCM_AUTOIDLE1_CORE));
DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_FCLKEN1 0x%04X \r\n", m_vpPRCMReg->ulCM_FCLKEN1_CORE));
DEBUGMSG(SDCARD_ZONE_INIT, (L"PRCM_PM_ICLKEN1 0x%04X \r\n", m_vpPRCMReg->ulCM_ICLKEN1_CORE));
DEBUGMSG(SDCARD_ZONE_INIT, (L"-DebugSDHCRegs-------------------------\r\n"));
LeaveCriticalSection( &m_critSec );
#endif
WORD MMC_STAT = Read_MMC_STAT();
if( MMC_STAT & MMC_STAT_CB )
{
ASSERT( pRequest->CommandResponse.ResponseType == ResponseR1b );
if( pRequest->CommandResponse.ResponseType == ResponseR1b )
{
DEBUGMSG(SHC_BUSY_STATE_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Card in busy state after command! Delaying...\r\n"));
// calculate timeout conditions
dwCountStart = GetTickCount();
dwTimeout = dwCountStart + m_dwMaxTimeout;
if( dwTimeout < dwCountStart )
fTimeoutOverflow = TRUE;
do {
MMC_STAT = Read_MMC_STAT();
// check for card ejection
if( !SDCardDetect() )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Card removed!\r\n"));
status = SD_API_STATUS_DEVICE_REMOVED;
goto TRANSFER_DONE;
}
// check for a timeout
dwCurrentTickCount = GetTickCount();
if( fTimeoutOverflow ? ( dwTimeout < dwCurrentTickCount && dwCurrentTickCount < dwCountStart )
: ( dwTimeout < dwCurrentTickCount || dwCurrentTickCount < dwCountStart ) )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Card BUSY timeout!\r\n"));
status = SD_API_STATUS_RESPONSE_TIMEOUT;
goto TRANSFER_DONE;
}
} while( !( MMC_STAT & ( MMC_STAT_EOFB | MMC_STAT_CCRC | MMC_STAT_CTO | MMC_STAT_DCRC | MMC_STAT_DTO ) ) );
DEBUGMSG(SHC_BUSY_STATE_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Card exited busy state.\r\n"));
ASSERT( MMC_STAT & MMC_STAT_EOFB );
Write_MMC_STAT( MMC_STAT_CB | MMC_STAT_EOFB );
}
}
// }
WORD MMC_STAT_OVERWRITE = 0;
if( MMC_STAT & MMC_STAT_CCRC ) // command CRC error
{
status = SD_API_STATUS_CRC_ERROR;
MMC_STAT_OVERWRITE |= MMC_STAT_CCRC;
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Got command CRC error!\r\n"));
}
if( MMC_STAT & MMC_STAT_CTO ) // command response timeout
{
status = SD_API_STATUS_RESPONSE_TIMEOUT;
MMC_STAT_OVERWRITE |= MMC_STAT_CTO;
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Got command response timeout!\r\n"));
}
if( MMC_STAT_OVERWRITE ) // clear the status error bits
{
Write_MMC_STAT(MMC_STAT_OVERWRITE);
goto TRANSFER_DONE;
}
// get the response information
if(pRequest->CommandResponse.ResponseType == NoResponse)
{
DEBUGMSG (SHC_SDBUS_INTERACT_ZONE,(L"CSDIOControllerBase::CommandCompleteHandler: "
L"GetCmdResponse returned no response (no response expected)\r\n"));
goto TRANSFER_DONE;
}
else{
status = GetCommandResponse(pRequest);
if(!SD_API_SUCCESS(status))
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Error getting response for command:0x%02x\r\n", pRequest->CommandCode
));
goto TRANSFER_DONE;
}
}
if (SD_COMMAND != pRequest->TransferClass) // data transfer
{
DWORD cbTransfer = TRANSFER_SIZE(pRequest);
BOOL fRet;
switch(pRequest->TransferClass)
{
case SD_READ:
__try {
fRet = SDIReceive(pRequest->pBlockBuffer, cbTransfer);
}
__except(SDProcessException(GetExceptionInformation())) {
fRet = FALSE;
}
if(!fRet)
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"SDIPollingReceive() failed\r\n"
));
goto TRANSFER_DONE;
}
else
{
#ifdef ENABLE_DEBUG
DWORD dwTemp = 0;
while( dwTemp < cbTransfer && (dwTemp < (HEXBUFSIZE / 2 - 1) ) )
{
szHexBuf[dwTemp*2] = pRequest->pBlockBuffer[dwTemp] / 16;
szHexBuf[dwTemp*2+1] = pRequest->pBlockBuffer[dwTemp] % 16;
if( szHexBuf[dwTemp*2] < 10 )
szHexBuf[dwTemp*2] += '0';
else
szHexBuf[dwTemp*2] += 'a' - 10;
if( szHexBuf[dwTemp*2+1] < 10 )
szHexBuf[dwTemp*2+1] += '0';
else
szHexBuf[dwTemp*2+1] += 'a' - 10;
dwTemp++;
}
szHexBuf[dwTemp*2] = 0;
DEBUGMSG (SHC_SDBUS_INTERACT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"PollingReceive succesfully received %d bytes {%S}\r\n", cbTransfer, szHexBuf
));
#endif
}
break;
case SD_WRITE:
{
#ifdef ENABLE_DEBUG
DWORD dwTemp = 0;
while( dwTemp < cbTransfer && (dwTemp < (HEXBUFSIZE / 2 - 1) ) )
{
szHexBuf[dwTemp*2] = pRequest->pBlockBuffer[dwTemp] / 16;
szHexBuf[dwTemp*2+1] = pRequest->pBlockBuffer[dwTemp] % 16;
if( szHexBuf[dwTemp*2] < 10 )
szHexBuf[dwTemp*2] += '0';
else
szHexBuf[dwTemp*2] += 'a' - 10;
if( szHexBuf[dwTemp*2+1] < 10 )
szHexBuf[dwTemp*2+1] += '0';
else
szHexBuf[dwTemp*2+1] += 'a' - 10;
dwTemp++;
}
szHexBuf[dwTemp*2] = 0;
#endif
}
__try {
fRet = SDITransmit(pRequest->pBlockBuffer, cbTransfer);
}
__except(SDProcessException(GetExceptionInformation())) {
fRet = FALSE;
}
if( !fRet )
{
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"SDIPollingTransmit() failed\r\n"));
DEBUGMSG (SHC_SDBUS_INTERACT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"PollingTransmit failed to send %d bytes {%S}\r\n", cbTransfer, szHexBuf
));
goto TRANSFER_DONE;
}
else
{
DEBUGMSG (SHC_SDBUS_INTERACT_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"PollingTransmit succesfully sent %d bytes {%S}\r\n", cbTransfer, szHexBuf
));
}
break;
}
status = SD_API_STATUS_SUCCESS;
}
TRANSFER_DONE:
if( pRequest != NULL )
{
if ( ( !( m_fAppCmdMode ) ) &&
( (pRequest->CommandCode == SD_CMD_IO_RW_DIRECT) ||
(pRequest->CommandCode == SD_CMD_IO_RW_EXTENDED) ) )
{
Write_MMC_SDIO( Read_MMC_SDIO() & ~( BIT15 | BIT6 ) );
}
if( pRequest->CommandResponse.ResponseType == ResponseR4 )
{
Write_MMC_SDIO( Read_MMC_SDIO() & ~( BIT7 ) );
}
}
if( status == SD_API_STATUS_SUCCESS )
{
if( m_fAppCmdMode )
{
m_fAppCmdMode = FALSE;
DEBUGMSG(SHC_SEND_ZONE, (L"CSDIOControllerBase::CommandCompleteHandler: "
L"Switched to Sta
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -