SD_API_STATUS CSDHCBase::Stop() { // Mark for shutdown m_fDriverShutdown = TRUE; if (m_fInterruptInitialized) { KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &m_dwSysIntr, sizeof(m_dwSysIntr), NULL, 0, NULL); InterruptDisable(m_dwSysIntr); } // Clean up controller IST if (m_htIST) { // Wake up the IST SetEvent(m_hevInterrupt); WaitForSingleObject(m_htIST, INFINITE); CloseHandle(m_htIST); m_htIST = NULL; } // free controller interrupt event if (m_hevInterrupt) { CloseHandle(m_hevInterrupt); m_hevInterrupt = NULL; } for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); pSlot->Stop(); } return SD_API_STATUS_SUCCESS; }
CEDEVICE_POWER_STATE CSDHCBase::DetermineRequiredControllerPowerState( ) { CEDEVICE_POWER_STATE cps = D4; for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); cps = min(cps, pSlot->GetPowerState()); } return cps; }
VOID CSDHCBase::PowerDown( ) { Validate(); for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); pSlot->PowerDown(); } CEDEVICE_POWER_STATE cps = DetermineRequiredControllerPowerState(); SetControllerPowerState(cps); }
SD_API_STATUS CSDHCBase::Start() { SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES; m_fDriverShutdown = FALSE; // allocate the interrupt event m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL); if (NULL == m_hevInterrupt) { goto EXIT; } // initialize the interrupt event RETAILMSG(0,(_T("CSDHCBase::Start() m_dwSysIntr = %x\r\n"), m_dwSysIntr)); // jylee if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) { goto EXIT; } m_fInterruptInitialized = TRUE; // create the interrupt thread for controller interrupts m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL); if (NULL == m_htIST) { goto EXIT; } for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); status = pSlot->Start(); if (!SD_API_SUCCESS(status)) { goto EXIT; } } // wake up the interrupt thread to check the slot ::SetInterruptEvent(m_dwSysIntr); status = SD_API_STATUS_SUCCESS; EXIT: if (!SD_API_SUCCESS(status)) { // Clean up Stop(); } RETAILMSG(0,(_T("CSDHCBase::-Start() status = %x\r\n"), status)); // jylee return status; }
VOID CSDHCBase::PowerUp( ) { Validate(); for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); CEDEVICE_POWER_STATE cpsRequired = pSlot->GetPowerUpRequirement(); if (cpsRequired < m_cpsCurrent) { // Move controller to higher power state initially since // it will need to be powered for the slot to access // registers. SetControllerPowerState(cpsRequired); } pSlot->PowerUp(); } }
// New function to Card detect thread of HSMMC ch1 on SMDK6410. DWORD CSDHControllerCh1::CardDetectThread() { BOOL bSlotStateChanged = FALSE; DWORD dwWaitResult = WAIT_TIMEOUT; PCSDHCSlotBase pSlotZero = GetSlot(0); CeSetThreadPriority(GetCurrentThread(), 100); while(1) { // Wait for the next insertion/removal interrupt dwWaitResult = WaitForSingleObject(m_hevCardDetectEvent, INFINITE); Lock(); pSlotZero->HandleInterrupt(SDSLOT_INT_CARD_DETECTED); Unlock(); InterruptDone(m_dwSDDetectSysIntr); EnableCardDetectInterrupt(); } return TRUE; }
VOID CSDHCBase::HandleInterrupt( ) { Lock(); RETAILMSG(0,(TEXT("+CSDHCBase::HandleInterrupt\r\n"))); // Use slot zero to get the shared global interrupt register PCSDHCSlotBase pSlotZero = GetSlot(0); DWORD dwIntStatus = pSlotZero->ReadControllerInterrupts(); do { DEBUGMSG(SDHC_INTERRUPT_ZONE, (TEXT("CSDHCBase::HandleInterrupt: Slot Interrupt_Status=0x%X\n"), dwIntStatus)); for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); //if ( ((1 << dwSlot) & dwIntStatus) || pSlot->NeedsServicing() ) { pSlot->HandleInterrupt(); //} } dwIntStatus = pSlotZero->ReadControllerInterrupts(); /* if(dwIntStatus == 0x2 ) RETAILMSG(1,(TEXT("dwIntStatus=0x%08X\n"),dwIntStatus)); */ if(dwIntStatus && pSlotZero->IsOnlySDIOInterrupt()) break; } while (dwIntStatus); InterruptDone(m_dwSysIntr); RETAILMSG(0,(TEXT("-CSDHCBase::HandleInterrupt\r\n"))); Unlock(); }
BOOL CSDHCBase::Init( LPCTSTR pszActiveKey ) { BOOL fRet = FALSE; SD_API_STATUS status; HKEY hkDevice = NULL; hkDevice = OpenDeviceKey(pszActiveKey); if (!hkDevice || !m_regDevice.Open(hkDevice, _T(""))) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Failed to open device key\n"))); goto EXIT; } // Get a handle to our parent bus. m_hBusAccess = CreateBusAccessHandle(pszActiveKey); if (m_hBusAccess == NULL) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Could not get handle to parent\n"))); goto EXIT; } m_cSlots = DetermineSlotCount(); if (m_cSlots == 0) { goto EXIT; } ValidateSlotCount(); RETAILMSG(0,(TEXT("CSDHCBase::Init m_cSlots=%d\n"),m_cSlots)); // jylee m_pSlotInfos = (PSDHC_SLOT_INFO) LocalAlloc(LPTR, sizeof(SDHC_SLOT_INFO) * m_cSlots); if (m_pSlotInfos == NULL) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot info objects\n"))); goto EXIT; } status = SDHCDAllocateContext(m_cSlots, &m_pHCDContext); if (!SD_API_SUCCESS(status)) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate context : 0x%08X \n"), status)); goto EXIT; } // Set our extension m_pHCDContext->pHCSpecificContext = this; if (!InitializeHardware()) { goto EXIT; } RETAILMSG(0,(TEXT("AllocateSlotObjects\n"))); // Allocate slot objects m_pSlots = AllocateSlotObjects(m_cSlots); if (m_pSlots == NULL) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to allocate slot objects\n"))); goto EXIT; } // Initialize the slots for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PSDHC_SLOT_INFO pSlotInfo = &m_pSlotInfos[dwSlot]; PCSDHCSlotBase pSlot = GetSlot(dwSlot); RETAILMSG(0,(TEXT("pSlot->Init\n"))); RETAILMSG(0,(TEXT("pSlotInfo->pucRegisters : 0x%x\r\n"),pSlotInfo->pucRegisters)); if (!pSlot->Init(dwSlot, pSlotInfo->pucRegisters, m_pHCDContext, m_dwSysIntr, m_hBusAccess, m_interfaceType, m_dwBusNumber, &m_regDevice)) { goto EXIT; } } // set the host controller name SDHCDSetHCName(m_pHCDContext, TEXT("HSMMC")); // set init handler SDHCDSetControllerInitHandler(m_pHCDContext, CSDHCBase::SDHCInitialize); // set deinit handler SDHCDSetControllerDeinitHandler(m_pHCDContext, CSDHCBase::SDHCDeinitialize); // set the Send packet handler SDHCDSetBusRequestHandler(m_pHCDContext, CSDHCBase::SDHCBusRequestHandler); // set the cancel I/O handler SDHCDSetCancelIOHandler(m_pHCDContext, CSDHCBase::SDHCCancelIoHandler); // set the slot option handler SDHCDSetSlotOptionHandler(m_pHCDContext, CSDHCBase::SDHCSlotOptionHandler); // These values must be set before calling SDHCDRegisterHostController() // because they are used during that call. m_dwPriority = m_regDevice.ValueDW(SDHC_PRIORITY_KEY, SDHC_CARD_CONTROLLER_PRIORITY); RETAILMSG(0,(TEXT("SDHCDRegisterHostController\n"))); // jylee // now register the host controller status = SDHCDRegisterHostController(m_pHCDContext); if (!SD_API_SUCCESS(status)) { DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC Failed to register host controller: %0x08X \n"), status)); goto EXIT; } m_fRegisteredWithBusDriver = TRUE; fRet = TRUE; RETAILMSG(0,(TEXT("CSDHCBase::Init Finished.\n"))); // jylee EXIT: if (hkDevice) RegCloseKey(hkDevice); return fRet; }
SD_API_STATUS CSDHCBase::SlotOptionHandler( DWORD dwSlot, SD_SLOT_OPTION_CODE sdOption, PVOID pData, DWORD cbData ) { SD_API_STATUS status = SD_API_STATUS_SUCCESS; BOOL fCallSlotsHandler = TRUE; Lock(); Validate(); PCSDHCSlotBase pSlot = GetSlot(dwSlot); DEBUGCHK(sdOption < dim(sc_rgpszOptions)); DEBUGCHK(sc_rgpszOptions[sdOption] != NULL); DEBUGMSG(SDCARD_ZONE_INFO, (_T("CSDHCBase::SlotOptionHandler(%u, %s)\n"), dwSlot, sc_rgpszOptions[sdOption])); switch (sdOption) { case SDHCDSetSlotPower: { if (cbData != sizeof(DWORD)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } case SDHCDSetSlotInterface: { if (cbData != sizeof(SD_CARD_INTERFACE)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } case SDHCDEnableSDIOInterrupts: case SDHCDDisableSDIOInterrupts: case SDHCDAckSDIOInterrupt: if (pData || cbData != 0) { status = SD_API_STATUS_INVALID_PARAMETER; } break; case SDHCDGetWriteProtectStatus: { if (cbData != sizeof(SD_CARD_INTERFACE)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } case SDHCDQueryBlockCapability: { if (cbData != sizeof(SD_HOST_BLOCK_CAPABILITY)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } case SDHCDSetSlotPowerState: { if (cbData != sizeof(CEDEVICE_POWER_STATE)) { status = SD_API_STATUS_INVALID_PARAMETER; } PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData; if (*pcps < m_cpsCurrent) { // Move controller to higher power state initially since // it will need to be powered for the slot to access // registers. SetControllerPowerState(*pcps); } status = pSlot->SlotOptionHandler(sdOption, pData, cbData); // Set the power state based on current conditions. Note that // the slot may have gone to a state different from what was // requested. CEDEVICE_POWER_STATE cps = DetermineRequiredControllerPowerState(); SetControllerPowerState(cps); fCallSlotsHandler = FALSE; break; } case SDHCDGetSlotPowerState: { if (cbData != sizeof(CEDEVICE_POWER_STATE)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } case SDHCDWakeOnSDIOInterrupts: { if (cbData != sizeof(BOOL)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } case SDHCDGetSlotInfo: { if (cbData != sizeof(SDCARD_HC_SLOT_INFO)) { status = SD_API_STATUS_INVALID_PARAMETER; } break; } default: break; } if (SD_API_SUCCESS(status) && fCallSlotsHandler) { // Call the slots handler to do the real work. status = pSlot->SlotOptionHandler(sdOption, pData, cbData); } Unlock(); return status; }
// New Start function for Card detect of HSMMC ch1 on SMDK6410. SD_API_STATUS CSDHControllerCh1::Start() { SD_API_STATUS status = SD_API_STATUS_INSUFFICIENT_RESOURCES; m_fDriverShutdown = FALSE; // allocate the interrupt event m_hevInterrupt = CreateEvent(NULL, FALSE, FALSE,NULL); if (NULL == m_hevInterrupt) { goto EXIT; } // initialize the interrupt event if (!InterruptInitialize (m_dwSysIntr, m_hevInterrupt, NULL, 0)) { goto EXIT; } m_fInterruptInitialized = TRUE; // create the interrupt thread for controller interrupts m_htIST = CreateThread(NULL, 0, ISTStub, this, 0, NULL); if (NULL == m_htIST) { goto EXIT; } // allocate the card detect event m_hevCardDetectEvent = CreateEvent(NULL, FALSE, FALSE,NULL); if (NULL == m_hevCardDetectEvent) { goto EXIT; } // initialize the interrupt event if (!InterruptInitialize (m_dwSDDetectSysIntr, m_hevCardDetectEvent, NULL, 0)) { goto EXIT; } // create the card detect interrupt thread m_htCardDetectThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SD_CardDetectThread, this, 0, NULL); if (NULL == m_htCardDetectThread) { goto EXIT; } for (DWORD dwSlot = 0; dwSlot < m_cSlots; ++dwSlot) { PCSDHCSlotBase pSlot = GetSlot(dwSlot); status = pSlot->Start(); if (!SD_API_SUCCESS(status)) { goto EXIT; } } // wake up the interrupt thread to check the slot ::SetInterruptEvent(m_dwSDDetectSysIntr); status = SD_API_STATUS_SUCCESS; EXIT: if (!SD_API_SUCCESS(status)) { // Clean up Stop(); } return status; }