📄 sdhc.cpp
字号:
// set the slot option handler
SDHCDSetSlotOptionHandler(m_pHCContext, CSDIOControllerBase::SDHCSlotOptionHandler);
// set maximum block length
m_usMaxBlockLen = STD_HC_MAX_BLOCK_LENGTH;
return fRet;
}
///////////////////////////////////////////////////////////////////////////////
// SDHCControllerIstThread - SDIO/controller IST thread for driver
// Input: lpParameter - pController - controller instance
// Output:
// Return: Thread exit status
// Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CSDIOControllerBase::SDHCControllerIstThread(LPVOID lpParameter)
{
CSDIOControllerBase *pController = (CSDIOControllerBase*)lpParameter;
return pController->SDHCControllerIstThreadImpl();
}
///////////////////////////////////////////////////////////////////////////////
// SDHCControllerIstThreadImpl - implementation of SDIO/controller IST thread
// for driver
// Input:
// Output:
// Return: Thread exit status
// Notes:
///////////////////////////////////////////////////////////////////////////////
DWORD CSDIOControllerBase::SDHCControllerIstThreadImpl()
{
DWORD dwWaitTime = INFINITE;
if (!CeSetThreadPriority(GetCurrentThread(), m_dwSDIOPriority)) {
DEBUGMSG(SDCARD_ZONE_WARN, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
L"Warning, failed to set CEThreadPriority\r\n"
));
}
InterruptDone( m_dwControllerSysIntr );
while (TRUE) {
// wait for the SDIO/controller interrupt
if (WAIT_OBJECT_0 != WaitForSingleObject(m_hControllerISTEvent, dwWaitTime))
{
DEBUGMSG(SDCARD_ZONE_WARN, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
L"Wait Failed!\r\n"
));
break;
}
if (m_fDriverShutdown) {
DEBUGMSG(SDCARD_ZONE_WARN, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
L"Thread exiting!\r\n"
));
break;
}
WORD wStat;
wStat = Read_MMC_STAT() & INREG16(&m_vpSDIOReg->MMC_IE) & 0x7fff;
if( wStat & (MMC_IE_EOC|MMC_STAT_CERR|MMC_STAT_CCRC|MMC_STAT_CTO) )
{
CommandCompleteHandler();
}
if( wStat & MMC_STAT_CIRQ )
{
ASSERT( m_fSDIOInterruptsEnabled );
// indicate that the card is interrupting
DEBUGMSG(SHC_INTERRUPT_ZONE, (L"CSDIOControllerBase::SDHCControllerIstThreadImpl: "
L"Receibed SDIO interrupt!\r\n"));
// disable the SDIO interrupt
CLRREG16(&m_vpSDIOReg->MMC_IE, MMC_IE_CIRQ);
// notify the SDBusDriver of the SDIO interrupt
m_fSDIOInterruptInService = TRUE;
SDHCDIndicateSlotStateChange(m_pHCContext, 0, DeviceInterrupting);
}
InterruptDone( m_dwControllerSysIntr );
}
DEBUGMSG(SDCARD_ZONE_FUNC, (L"-CSDIOControllerBase::SDHCControllerIstThreadImpl\r\n"));
return 0;
}
///////////////////////////////////////////////////////////////////////////////
// SDHCCardDetectIstThread - card detect IST thread for driver
// Input: lpParameter - pController - controller instance
// Output:
// Return: Thread exit status
///////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CSDIOControllerBase::SDHCCardDetectIstThread(LPVOID lpParameter)
{
CSDIOControllerBase *pController = (CSDIOControllerBase*)lpParameter;
return pController->SDHCCardDetectIstThreadImpl();
}
///////////////////////////////////////////////////////////////////////////////
// CSDIOControllerBase::SDHCDeinitializeImpl - Deinitialize the SDHC Controller
// Input:
// Output:
// Return: SD_API_STATUS
// Notes:
//
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::SDHCDeinitializeImpl()
{
// mark for shutdown
m_fDriverShutdown = TRUE;
if (m_fInitialized) {
if( m_dwControllerSysIntr != SYSINTR_UNDEFINED )
{
// disable wakeup on SDIO interrupt
if ( m_dwCurrentWakeupSources & WAKEUP_SDIO )
{
KernelIoControl( IOCTL_HAL_DISABLE_WAKE,
&m_dwControllerSysIntr,
sizeof( m_dwControllerSysIntr ),
NULL,
0,
NULL );
}
// disable controller interrupt
InterruptDisable(m_dwControllerSysIntr);
// release the SYSINTR value
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &m_dwControllerSysIntr, sizeof(DWORD), NULL, 0, NULL);
m_dwControllerSysIntr = SYSINTR_UNDEFINED;
}
if (m_fCardPresent) {
// remove device
HandleRemoval(FALSE);
}
}
// clean up controller IST
if (NULL != m_htControllerIST) {
// wake up the IST
SetEvent(m_hControllerISTEvent);
// wait for the thread to exit
WaitForSingleObject(m_htControllerIST, INFINITE);
CloseHandle(m_htControllerIST);
m_htControllerIST = NULL;
}
// free controller interrupt event
if (NULL != m_hControllerISTEvent) {
CloseHandle(m_hControllerISTEvent);
m_hControllerISTEvent = NULL;
}
// clean up card detect IST
if (NULL != m_htCardDetectIST) {
// wake up the IST
SetEvent(m_hCardDetectEvent);
// wait for the thread to exit
WaitForSingleObject(m_htCardDetectIST, INFINITE);
CloseHandle(m_htCardDetectIST);
m_htCardDetectIST = NULL;
}
if( m_hParentBus != NULL )
{
TWLIntrDisable(m_hParentBus, TWL_INTR_CD1);
TWLIntrDisable(m_hParentBus, TWL_INTR_DL1);
TWLIntrDisable(m_hParentBus, TWL_INTR_CD2);
TWLIntrDisable(m_hParentBus, TWL_INTR_DL2);
TWLClose(m_hParentBus);
m_hParentBus = NULL;
}
// free card detect interrupt event
if (NULL != m_hCardDetectEvent) {
CloseHandle(m_hCardDetectEvent);
m_hCardDetectEvent = NULL;
}
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// CSDIOControllerBase::SDHCInitialize - Initialize the the controller
// Input:
// Output:
// Return: SD_API_STATUS
// Notes:
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDIOControllerBase::SDHCInitializeImpl()
{
SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES; // intermediate status
DWORD threadID;
unsigned long ulLong;
WORD wRegValue;
DWORD *pdwSDIOIrq;
DWORD dwSDIOIrqLen;
m_fDriverShutdown = FALSE;
SoftwareReset(SOFT_RESET_ALL);
// activate the clock
ClockOn();
// --- Setup MMC config register ---
// Data Bus width 1 bit - MMC/SD mode - Power Up Up/Normal - Little Endian - Clock Divider
wRegValue = 0;
wRegValue |= VALUE_MMC_CON_DW_1BIT | VALUE_MMC_CON_MODE_MMCSD |
VALUE_MMC_CON_POWERUP_UP | VALUE_MMC_CON_BE_LITTLEENDIAN;
ulLong = (MMCSD_CLOCK_INPUT / MMCSD_CLOCK_INIT);
if (MMCSD_CLOCK_INPUT % MMCSD_CLOCK_INIT) ulLong++;
wRegValue |= (ulLong & MASK_MMC_CON_CLKD);
OUTREG16(&m_vpSDIOReg->MMC_CON, wRegValue);
DEBUGMSG(SDCARD_ZONE_INIT, (L"CSDIOControllerBase::SDHCInitializeImpl: "
L"MMC1_CON set value = %X\r\n", wRegValue
));
OUTREG16(&m_vpSDIOReg->MMC_IE, 0);
wRegValue = (SDMMC_DEFAULT_ALMOST_EMPTY - 1) | ((SDMMC_DEFAULT_ALMOST_FULL - 1) << 8);
OUTREG16(&m_vpSDIOReg->MMC_BUF, wRegValue);
Write_MMC_SDIO(0);
// --- Set the timeouts ----
// Set command timeout of 64 clocks, the max according to OMAP1610 and SD specs
OUTREG16(&m_vpSDIOReg->MMC_CTO, MMC_CTO_CONTROL_MAX);
OUTREG16(&m_vpSDIOReg->MMC_DTO, MMC_DTO_CONTROL_MAX);
// deactivate the clock
ClockOff();
// convert the SDIO hardware IRQ into a logical SYSINTR value
DWORD rgdwSDIOIrq[] = { IRQ_MMC1 };
pdwSDIOIrq = rgdwSDIOIrq;
dwSDIOIrqLen = sizeof(rgdwSDIOIrq);
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, pdwSDIOIrq, dwSDIOIrqLen, &m_dwControllerSysIntr, sizeof(DWORD), NULL))
{
// invalid SDIO SYSINTR value!
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::SDHCInitializeImpl: "
L"Error obtaining SDIO SYSINTR value!\r\n"
));
m_dwControllerSysIntr = SYSINTR_UNDEFINED;
status = SD_API_STATUS_UNSUCCESSFUL;
goto exitInit;
}
// allocate the interrupt event for the SDIO/controller interrupt
m_hControllerISTEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
if (NULL == m_hControllerISTEvent) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
if ( !InterruptInitialize( m_dwControllerSysIntr, m_hControllerISTEvent, NULL, 0 ) ) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
// allocate the interrupt event for card detection
m_hCardDetectEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == m_hCardDetectEvent) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
// Open parent bus - triton
m_hParentBus = TWLOpen();
if ( m_hParentBus == NULL ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
L"Failed to obtain parent bus handle\r\n"
));
goto exitInit;
}
// Associate event with TWL TWL_INTR_CD1 interrupt
if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_CD1, m_hCardDetectEvent)) {
goto exitInit;
}
// Associate event with TWL TWL_INTR_DL1 interrupt
if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_DL1, m_hCardDetectEvent)) {
goto exitInit;
}
// Associate event with TWL TWL_INTR_CD2 interrupt
if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_CD2, m_hCardDetectEvent)) {
goto exitInit;
}
// Associate event with TWL TWL_INTR_DL2 interrupt
if (!TWLSetIntrEvent(m_hParentBus, TWL_INTR_DL2, m_hCardDetectEvent)) {
goto exitInit;
}
// Enable TWL_INTR_CD1 event
if (!TWLIntrEnable(m_hParentBus, TWL_INTR_CD1)) {
goto exitInit;
}
// Enable TWL_INTR_DL1 event
if (!TWLIntrEnable(m_hParentBus, TWL_INTR_DL1)) {
goto exitInit;
}
// Enable TWL_INTR_CD2 event
if (!TWLIntrEnable(m_hParentBus, TWL_INTR_CD2)) {
goto exitInit;
}
// Enable TWL_INTR_DL2 event
if (!TWLIntrEnable(m_hParentBus, TWL_INTR_DL2)) {
goto exitInit;
}
// create the Controller IST thread
m_htControllerIST = CreateThread(NULL,
0,
CSDIOControllerBase::SDHCControllerIstThread,
this,
0,
&threadID);
if (NULL == m_htControllerIST) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
// create the card detect IST thread
m_htCardDetectIST = CreateThread(NULL,
0,
CSDIOControllerBase::SDHCCardDetectIstThread,
this,
0,
&threadID);
if (NULL == m_htCardDetectIST) {
status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
goto exitInit;
}
m_fInitialized = TRUE;
// on start we need the IST to check the slot for a card
// FIXME Menelaus should detect card SetEvent(m_hCardDetectEvent);
status = SD_API_STATUS_SUCCESS;
exitInit:
if (!SD_API_SUCCESS(status)) {
// just call the deinit handler directly to cleanup
SDHCDeinitializeImpl();
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// CSDIOControllerBase::SDHCSDCancelIoHandlerImpl - io cancel handler
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -