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

📄 sdhcslot.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                      EnableSDIOInterrupts(FALSE);
                                      break;

        case SDHCDGetWriteProtectStatus: {
                                             DEBUGCHK(cbData == sizeof(SD_CARD_INTERFACE));
                                             PSD_CARD_INTERFACE pInterface = (PSD_CARD_INTERFACE) pData;
                                             pInterface->WriteProtected = IsWriteProtected();
                                             break;
                                         }

        case SDHCDQueryBlockCapability: {
                                            DEBUGCHK(cbData == sizeof(SD_HOST_BLOCK_CAPABILITY));
                                            PSD_HOST_BLOCK_CAPABILITY pBlockCaps = 
                                                (PSD_HOST_BLOCK_CAPABILITY)pData;

                                            DEBUGMSG(SDCARD_ZONE_INFO, 
                                                    (TEXT("CSDHCSlotBase::SlotOptionHandler: Read Block Length: %d , Read Blocks: %d\n"), 
                                                     pBlockCaps->ReadBlockSize, pBlockCaps->ReadBlocks));
                                            DEBUGMSG(SDCARD_ZONE_INFO, 
                                                    (TEXT("CSDHCSlotBase::SlotOptionHandler: Write Block Length: %d , Write Blocks: %d\n"), 
                                                     pBlockCaps->WriteBlockSize, pBlockCaps->WriteBlocks));

                                            pBlockCaps->ReadBlockSize = max(pBlockCaps->ReadBlockSize, SDHC_MIN_BLOCK_LENGTH);
                                            pBlockCaps->ReadBlockSize = min(pBlockCaps->ReadBlockSize, (USHORT) m_dwMaxBlockLen);

                                            pBlockCaps->WriteBlockSize = max(pBlockCaps->WriteBlockSize, SDHC_MIN_BLOCK_LENGTH);
                                            pBlockCaps->WriteBlockSize = min(pBlockCaps->WriteBlockSize, (USHORT) m_dwMaxBlockLen);
                                            break;
                                        }

        case SDHCDGetSlotPowerState: {
                                         DEBUGCHK(cbData == sizeof(CEDEVICE_POWER_STATE));
                                         PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
                                         *pcps = GetPowerState();
                                         break;
                                     }

        case SDHCDSetSlotPowerState: {
                                         DEBUGCHK(cbData == sizeof(CEDEVICE_POWER_STATE));
                                         PCEDEVICE_POWER_STATE pcps = (PCEDEVICE_POWER_STATE) pData;
                                         SetPowerState(*pcps);
                                         break;
                                     }

        case SDHCDWakeOnSDIOInterrupts: {
                                            DEBUGCHK(cbData == sizeof(BOOL));
                                            PBOOL pfWake = (PBOOL) pData;

                                            if (m_fCanWakeOnSDIOInterrupts) {
                                                DWORD dwWakeupControl = m_dwDefaultWakeupControl;

                                                if (*pfWake) {
                                                    dwWakeupControl |= WAKEUP_INTERRUPT;
                                                }

                                                m_bWakeupControl = (BYTE) dwWakeupControl;
                                            }
                                            else {
                                                status = SD_API_STATUS_UNSUCCESSFUL;
                                            }
                                            break;
                                        }

        case SDHCDGetSlotInfo: {
                                   DEBUGCHK(cbData == sizeof(SDCARD_HC_SLOT_INFO));
                                   PSDCARD_HC_SLOT_INFO pSlotInfo = (PSDCARD_HC_SLOT_INFO) pData;
                                   status = GetSlotInfo(pSlotInfo);
                                   break;
                               }

        case SDHCAllocateDMABuffer: {
                                        DEBUGCHK (cbData == sizeof(SD_HOST_ALLOC_FREE_DMA_BUFFER));
                                        PREFAST_ASSERT(pData!=NULL);
                                        PSD_HOST_ALLOC_FREE_DMA_BUFFER pSdDmaBuffer = (PSD_HOST_ALLOC_FREE_DMA_BUFFER)pData;
                                        pSdDmaBuffer->VirtualAddress = 
                                            SlotAllocDMABuffer(pSdDmaBuffer->Length, &pSdDmaBuffer->LogicalAddress,pSdDmaBuffer->CacheEnabled);
                                        status = (pSdDmaBuffer->VirtualAddress!=NULL? SD_API_STATUS_SUCCESS: SD_API_STATUS_BUFFER_OVERFLOW);
                                        break;
                                    }
        case SDHCFreeDMABuffer:{
                                   DEBUGCHK (cbData == sizeof(SD_HOST_ALLOC_FREE_DMA_BUFFER));
                                   PSD_HOST_ALLOC_FREE_DMA_BUFFER pSdDmaBuffer = (PSD_HOST_ALLOC_FREE_DMA_BUFFER)pData;
                                   BOOL fResult =
                                       SlotFreeDMABuffer(pSdDmaBuffer->Length, pSdDmaBuffer->LogicalAddress,pSdDmaBuffer->VirtualAddress,pSdDmaBuffer->CacheEnabled);
                                   status = (fResult? SD_API_STATUS_SUCCESS: SD_API_STATUS_INVALID_PARAMETER);
                                   break;
                               }
        default:
                               status = SD_API_STATUS_INVALID_PARAMETER;
    }
    return status;
}


DWORD
CSDHCSlotBase::DetermineMaxClockRate(
        )
{
    DEBUGCHK(m_pregDevice->IsOK());

    // We allow the registry to override what is in the capabilities register.
    DWORD dwMaxClockRate = m_pregDevice->ValueDW(SDHC_FREQUENCY_KEY);
    if (dwMaxClockRate == 0) {
        SSDHC_CAPABILITIES caps = GetCapabilities();

        dwMaxClockRate = caps.bits.ClkFreq * 1000000;
        if (dwMaxClockRate == 0) {
            // No clock frequency specified. Use the highest possible that
            // could have been specified so that a working clock divisor 
            // will be chosen.
            dwMaxClockRate = SDHC_MAX_CLOCK_FREQUENCY;
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: No base clock frequency specified\n")));
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHC: Using default frequency of %u\n"), 
                        dwMaxClockRate));
        }
    }

    return dwMaxClockRate;
}


DWORD
CSDHCSlotBase::DetermineMaxBlockLen(
        )
{
    static const USHORT sc_rgusBlockLen[] = { 
        SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_0,
        SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_1,
        SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_2
    };

    SSDHC_CAPABILITIES caps = GetCapabilities();
    // Determine the maximum block length
    DWORD dwMaxBlockLen;
    if (caps.bits.MaxBlockLen < _countof(sc_rgusBlockLen)) {    
        dwMaxBlockLen = sc_rgusBlockLen[caps.bits.MaxBlockLen];
    }
    else { // We hit reserved bit by Standard SDHC specification. So, it is better to returns smallest one.
        ASSERT(FALSE);
        dwMaxBlockLen = SDHC_CAPABILITIES_MAX_BLOCK_LENGTH_0 ;
    }
    return dwMaxBlockLen;
}


DWORD
CSDHCSlotBase::DetermineTimeoutControl(
        )
{
    DEBUGCHK(m_pregDevice->IsOK());

    return SDHC_TIMEOUT_CONTROL_MAX;
}


DWORD 
CSDHCSlotBase::DetermineWakeupSources(
        )
{
    DEBUGCHK(m_pregDevice->IsOK());
    DWORD dwWakeupSources = m_pregDevice->ValueDW(SDHC_WAKEUP_SOURCES_KEY);
    dwWakeupSources &= WAKEUP_ALL_SOURCES;

    // Waking on SDIO interrupts must be enabled by the bus driver.
    dwWakeupSources &= ~WAKEUP_INTERRUPT; 

    return dwWakeupSources;
}


VOID
CSDHCSlotBase::SetVoltage(
        DWORD dwVddSetting
        )
{
    Validate();

    UCHAR ucVoltageSelection = SDBUS_POWER_ON;
    UCHAR ucOldVoltage;

    DEBUGCHK(dwVddSetting & m_dwVddWindows);

    if ( dwVddSetting & 
            (SD_VDD_WINDOW_3_2_TO_3_3 | SD_VDD_WINDOW_3_3_TO_3_4) ) {
        ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_3_3V;
    }
    else if ( dwVddSetting & 
            (SD_VDD_WINDOW_2_9_TO_3_0 | SD_VDD_WINDOW_3_0_TO_3_1) ) {
        ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_3_0V;
    }
    else if ( dwVddSetting & 
            (SD_VDD_WINDOW_1_7_TO_1_8 | SD_VDD_WINDOW_1_8_TO_1_9) ) {
        ucVoltageSelection |= SDBUS_VOLTAGE_SELECT_1_8V;
    }

    ucOldVoltage = ReadByte(SDHC_POWER_CONTROL);
    if (ucOldVoltage != ucVoltageSelection) {
        // SD Bus Power must be initially set to 0 when changing voltages
        WriteByte(SDHC_POWER_CONTROL, 0);
        WriteByte(SDHC_POWER_CONTROL, ucVoltageSelection);

        DEBUGMSG(SDCARD_ZONE_INFO,( 
                    TEXT("CSDHCSlotBase::SetVoltage: Set SDHC_POWER_CONTROL reg = 0x%02x\n"),
                    ucVoltageSelection));

        Sleep(GetPowerSupplyRampUpMs());
    }
}


// Set up the controller according to the interface parameters.
VOID 
CSDHCSlotBase::SetInterface(
        PSD_CARD_INTERFACE_EX pInterface
        )
{
    PREFAST_DEBUGCHK(pInterface);
    Validate();

    BYTE bHostCtr = 0;
#ifdef _MMC_SPEC_42_
    if (0 != pInterface->InterfaceModeEx.bit.hsmmc8Bit) {
        DEBUGMSG(SDCARD_ZONE_INIT, 
                (TEXT("SHCSDSlotOptionHandler - Setting for 8 bit mode\n")));
        RETAILMSG(TRUE, 
                (TEXT("[HSMMC1] Setting for 8 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));
        bHostCtr |= HOSTCTL_DAT_WIDTH_8BIT;
        m_f4BitMode = TRUE;
    } else if (SD_INTERFACE_SD_MMC_1BIT == pInterface->InterfaceModeEx.bit.sd4Bit) {
        DEBUGMSG(SDCARD_ZONE_INIT, 
                (TEXT("SHCSDSlotOptionHandler - Setting for 1 bit mode\n")));
        RETAILMSG(TRUE, 
                (TEXT("[HSMMC1] Setting for 1 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));        
        bHostCtr = 0;
        m_f4BitMode = FALSE;
    } else if (SD_INTERFACE_SD_4BIT == pInterface->InterfaceModeEx.bit.sd4Bit) {
        DEBUGMSG(SDCARD_ZONE_INIT, 
                (TEXT("SHCSDSlotOptionHandler - Setting for 4 bit mode\n")));
        RETAILMSG(TRUE, 
                (TEXT("[HSMMC1] Setting for 4 bit mode , Clock Rate = %d Hz\n"),pInterface->ClockRate));
        bHostCtr |= HOSTCTL_DAT_WIDTH;
        m_f4BitMode = TRUE;
    }

#else
    m_f4BitMode = (pInterface->InterfaceModeEx.bit.sd4Bit!=0);
    bHostCtr |= (m_f4BitMode?HOSTCTL_DAT_WIDTH:0);
    bHostCtr |= (pInterface->InterfaceModeEx.bit.sdHighSpeed!=0?HOSTCTL_HIGH_SPEED:0);
#endif

    if (m_SlotDma) {
        bHostCtr |= (m_SlotDma->DmaSelectBit()<<3);
    }
    DEBUGMSG(SDCARD_ZONE_INIT, 
            (TEXT("SHCSDSlotOptionHandler - Setting Host Control Register %x \n"),bHostCtr));
    WriteByte(SDHC_HOST_CONTROL, bHostCtr);

    SetClockRate(&pInterface->ClockRate);
}


VOID
CSDHCSlotBase::SetPowerState(
        CEDEVICE_POWER_STATE cpsNew
        )
{
    DEBUGCHK(VALID_DX(cpsNew));

    m_fIsPowerManaged = TRUE;

    if (DX_D1_OR_D2(cpsNew)) {
        cpsNew = D0;
    }

    if (m_cpsCurrent != cpsNew) {
        SetHardwarePowerState(cpsNew);
    }
}


VOID
CSDHCSlotBase::PowerDown(
        )
{
    Validate();

    m_cpsAtPowerDown = m_cpsCurrent;

    if (!m_fIsPowerManaged) {
        CEDEVICE_POWER_STATE cps;

        if (m_bWakeupControl) {
            cps = D3;
        }
        else {
            cps = D4;
        }

        SetHardwarePowerState(cps);
    }

    BOOL fKeepPower = FALSE;
    if (m_fSleepsWithPower || m_cpsCurrent == D0) {
        DEBUGCHK(!m_fSleepsWithPower || m_cpsCurrent == D3);
        fKeepPower = TRUE;
    }
    else
        m_fFakeCardRemoval = TRUE;

    PowerUpDown(FALSE, fKeepPower);
}


VOID 
CSDHCSlotBase::PowerUp(
        )
{
    Validate();

    if (!m_fIsPowerManaged) {
        SetHardwarePowerState(m_cpsAtPowerDown);
    }
    else if (m_fSleepsWithPower) {
        WORD wIntStatus = ReadWord(SDHC_NORMAL_INT_STATUS);
        if (wIntStatus == NORMAL_INT_STATUS_CARD_INT) {
            // We woke system through a card interrupt. We need to clear
            // this so that the IST will not be signalled.
            EnableSDIOInterrupts(FALSE);
            m_fPowerUpDisabledInts = TRUE;
        }
    }

    PowerUpDown(TRUE, TRUE);
    if (m_fFakeCardRemoval){
        Start();
        SetInterruptEvent();
    }
}
//
// For BC, 
// 1. Returns SD_API_STATUS_FAST_PATH_SUCCESS, callback is NOT called. Fastpass only.
// 2. Return !SD_API_SUCCESS(status). callback is NOT called.
// 3. Return SD_API_STATUS_SUCCESS, callback is called
// 4. Return SD_API_STATUS_PENDING, callback is NOT call Yet.
//
    SD_API_STATUS
CSDHCSlotBase::BusRequestHandler( PSD_BUS_REQUEST pRequest)
{
    SETFNAME();
    SD_API_STATUS status;
    PREFAST_DEBUGCHK(pRequest);
    Validate();
    DEBUGMSG(SDHC_SEND_ZONE, (TEXT("%s CMD:%d\n"), pszFname, pRequest->CommandCode));

    if (m_pCurrentRequest) { // We have outstand request.
        ASSERT(FALSE);
        IndicateBusRequestComplete(pRequest, SD_API_STATUS_CANCELED);
        m_pCurrentRequest = NULL;

⌨️ 快捷键说明

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