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

📄 sdhc.cpp

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    BOOL               fRegisteredWithBusDriver = FALSE;
    BOOL               fHardwareInitialized = FALSE;
    PHYSICAL_ADDRESS   pa;
    
    DEBUGMSG(SDCARD_ZONE_INIT, (L"+CSDIOControllerBase::Init: "
        L"Active RegPath: %s\r\n", pszActiveKey
    ));
   
    m_pCurrentRequest = NULL;
    m_pszActiveKey = pszActiveKey; //save the activity key for power mgt
    
    hKeyDevice = OpenDeviceKey(pszActiveKey);
    if ( (hKeyDevice == NULL) || !regDevice.Open(hKeyDevice, NULL) ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Failed to open device key\r\n"
        ));
        goto EXIT;
    }

    // allocate the context - support for 2 Slots - BUT 1 controller
    status = SDHCDAllocateContext(1, &m_pHCContext);
    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Failed to allocate context : 0x%08X\r\n",
            status
        ));
        goto EXIT;
    }

    // Set our extension
    m_pHCContext->pHCSpecificContext = this;

    if( !GetRegistrySettings(&regDevice) )
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Error reading registry settings\r\n"
        ));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto EXIT;
    }

    // map hardware memory space
    pa.QuadPart = OMAP3_MMCHS1_REGS_PA;
    m_vpSDIOReg = (OMAP2420_SDIO_REGS*)MmMapIoSpace( pa, sizeof(OMAP2420_SDIO_REGS), FALSE );
    if ( !m_vpSDIOReg )
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Error allocating MMC controller register\r\n"
        ));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto EXIT;
    }

    pa.QuadPart = OMAP2420_PRCM_REGS_PA;
    m_vpPRCMReg = (OMAP2420_PRCM_REGS*)MmMapIoSpace( pa, sizeof(OMAP2420_PRCM_REGS), FALSE );
    if ( !m_vpPRCMReg )
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Error allocating Power Reset and Clock Managment Registers\r\n"
        ));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto EXIT;
    }

    
    if( !InitializeHardware() )
    {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Error allocating CD/RW GPIO registers\r\n"
        ));
        status = SD_API_STATUS_INSUFFICIENT_RESOURCES;
        goto EXIT;
    }

    // turn the SDHC controller to fully on!
    ClockOn();
    this->m_PowerState = D0;

    fHardwareInitialized = TRUE;

    // Initialize the slot
    SoftwareReset(SOFT_RESET_ALL);
    Sleep(10); // Allow time for card to power down after a device reset
    DumpRegisters();

    // Read SD Host Controller Info from register.
    if (!InterpretCapabilities()) 
    {
        goto EXIT;
    }

    // now register the host controller 
    status = SDHCDRegisterHostController(m_pHCContext);

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::Init: "
            L"Failed to register host controller: %0x08X\r\n", status
        ));
        goto EXIT;
    }

    fRegisteredWithBusDriver = TRUE;

    // return the controller context
    dwRet = (DWORD) this;

EXIT:
    if (hKeyDevice) RegCloseKey(hKeyDevice);

    if ( (dwRet == 0) && m_pHCContext ) {
        FreeHostContext( fRegisteredWithBusDriver, fHardwareInitialized );
    }

    DEBUGMSG(SDCARD_ZONE_INIT, (L"-CSDIOControllerBase::Init\r\n"));

    return dwRet;
}


// Free the host context and associated resources.
VOID CSDIOControllerBase::FreeHostContext( BOOL fRegisteredWithBusDriver, BOOL fHardwareInitialized )
{
    DEBUGCHK(m_pHCContext);
    ClockOff();

    if (fRegisteredWithBusDriver) {
        // deregister the host controller
        SDHCDDeregisterHostController(m_pHCContext);
    }

    // unmap hardware memory space

    DeinitializeHardware();
    if (m_vpSDIOReg) MmUnmapIoSpace((PVOID)m_vpSDIOReg, sizeof(OMAP2420_SDIO_REGS));
    if (m_vpPRCMReg) MmUnmapIoSpace((PVOID)m_vpPRCMReg, sizeof(OMAP2420_PRCM_REGS));

    m_PowerState = D4;
    
    // cleanup the host context
    SDHCDDeleteContext(m_pHCContext);
}    


BOOL CSDIOControllerBase::IOControl(
   DWORD dwCode, 
   BYTE *pInBuffer, 
   DWORD inSize, 
   BYTE *pOutBuffer, 
   DWORD outSize, 
   DWORD *pOutSize)
{
    BOOL bRetVal = FALSE;
    
    DEBUGMSG(SDCARD_ZONE_FUNC, (L"+CSDIOControllerBase::IOControl(0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x)\r\n",
        dwCode, pInBuffer, inSize, pOutBuffer, outSize, pOutSize
    ));

    switch (dwCode) {
    // Power management functions.
    // Return device specific power capabilities.
    case IOCTL_POWER_CAPABILITIES:
    {
        POWER_CAPABILITIES pc;

        // Check arguments.
        if ( pOutBuffer == NULL || outSize < sizeof(POWER_CAPABILITIES))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
                L"IOCTL_POWER_CAPABILITIES Invalid parameter.\r\n"
            ));
            break;
        }

        // Clear capabilities structure.
        memset(&pc, 0, sizeof(POWER_CAPABILITIES));

        // Set power capabilities. Supports D0 and D4.
        pc.DeviceDx = DX_MASK(D0)|DX_MASK(D4);

        DEBUGMSG(SDCARD_ZONE_POWER, (L"CSDIOControllerBase::IOControl: "
            L"IOCTL_POWER_CAPABILITIES = 0x%x\r\n", pc.DeviceDx
        ));

        if (CeSafeCopyMemory(pOutBuffer, &pc, sizeof(pc)) == 0)
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
                L"CeSafeCopyMemory Failed\r\n"
            ));
            break;
        }

        // Update returned data size.
        if (pOutSize)
        {
            *pOutSize = sizeof(pc);
        }
        bRetVal = TRUE;
        break;
    }

    // Indicate if the device is ready to enter a new device power state.
    case IOCTL_POWER_QUERY:
    {
        DEBUGMSG(SDCARD_ZONE_POWER, (L"CSDIOControllerBase::IOControl: "
            L"IOCTL_POWER_QUERY Deprecated Function Called\r\n"
        ));
        bRetVal = FALSE;
        break;
    }

    // Request a change from one device power state to another
    // This driver self-manages it's internal power state by controlling
    // functional and interface clocks as needed in the Read and Write
    // functions rather than waiting for PM to tell it to save power
    // So the set calls below just update the power state variable
    case IOCTL_POWER_SET:
    {
        CEDEVICE_POWER_STATE dxState;

        // Check arguments.
        if (pOutBuffer == NULL || outSize < sizeof(CEDEVICE_POWER_STATE))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
                L"IOCTL_POWER_SET Invalid parameter.\r\n"
            ));
            break;
        }

        if (CeSafeCopyMemory(&dxState, pOutBuffer, sizeof(dxState)) == 0) break;

        DEBUGMSG(SDCARD_ZONE_POWER, (L"CSDIOControllerBase::IOControl: "
            L"IOCTL_POWER_SET = %d.\r\n", dxState
        ));

        // Check for any valid power state.
        if (VALID_DX(dxState))
        {
            // Power off
            if ( dxState == D4 )
            {
                DEBUGMSG(SDCARD_ZONE_POWER, (L"CSDIOControllerBase::IOControl: "
                    L"IOCTL_POWER_set PowerDown\r\n"
                ));
                
                //SDHCDPowerUpDown(m_pHCContext, FALSE, FALSE, 0);
                this->m_PowerState = dxState;
                this->FreeHostContext(TRUE, TRUE);        
            }
            // Power on.
            else
            {
                DEBUGMSG(SDCARD_ZONE_POWER, (L"CSDIOControllerBase::IOControl: "
                    L"IOCTL_POWER_set PowerUp\r\n"
                ));
                
                this->m_PowerState = dxState;
                this->Init(m_pszActiveKey);
                
                // Notify the SD Bus driver of the PowerUp event
                //SDHCDPowerUpDown(m_pHCContext, TRUE, FALSE, 0);
            }
            bRetVal = TRUE;
        }
        else
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
                L"IOCTL_POWER_SET invalid power state.\r\n"
            ));
        }
        break;
    }

    // Return the current device power state.
    case IOCTL_POWER_GET:
    {
        // Check arguments.
        if (pOutBuffer == NULL || outSize < sizeof(CEDEVICE_POWER_STATE))
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
                L"IOCTL_POWER_GET Invalid parameter.\r\n"
            ));
            break;
        }

        //Copy current state
        if (CeSafeCopyMemory(pOutBuffer, &this->m_PowerState, sizeof(this->m_PowerState)) == 0)
        {
            DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
                L"CeSafeCopyMemory Failed\r\n"
            ));
            break;
        }

        // Update returned data size.
        if (pOutSize)
        {
            *pOutSize = sizeof(this->m_PowerState);
        }

        DEBUGMSG(SDCARD_ZONE_POWER, (L"CSDIOControllerBase::IOControl: "
            L"IOCTL_POWER_GET: %d\r\n", this->m_PowerState
        ));
        bRetVal = TRUE;
        break;
    }

    default:
        DEBUGMSG(SDCARD_ZONE_ERROR, (L"CSDIOControllerBase::IOControl: "
            L"Unknown IOCTL_xxx(0x%0.8X)\r\n", dwCode
        ));
        break;

    }

    DEBUGMSG(SDCARD_ZONE_FUNC, (L"-CSDIOControllerBase::IOControl(rc = %d)\r\n", bRetVal));
    return bRetVal;    
}

// Read the registry settings
BOOL CSDIOControllerBase::GetRegistrySettings( CReg *pReg )
{
    BOOL fRet = TRUE;

    DEBUGCHK(pReg);

    // get the controller IST thread priority
    m_dwSDIOPriority = pReg->ValueDW(SHC_SDIO_PRIORITY_KEY, SHC_CARD_CONTROLLER_PRIORITY);

    // get the card detect IST thread priority
    m_dwCDPriority = pReg->ValueDW(SHC_CD_PRIORITY_KEY, SHC_CARD_DETECT_PRIORITY);

    // get the max clock frequency from the registry (we allow the registry to override)
    m_dwMaxClockRate = pReg->ValueDW(SHC_FREQUENCY_KEY);
    if (m_dwMaxClockRate == 0) 
    {
        // No clock frequency specified. Use the highest possible that
        // could have been specified so that a working clock divisor 
        // will be chosen.
        m_dwMaxClockRate = STD_HC_MAX_CLOCK_FREQUENCY;
    }
    else 
    {
        m_dwMaxClockRate = min(m_dwMaxClockRate, 
            STD_HC_MAX_CLOCK_FREQUENCY);
    }

    // get the read/write timeout value
    m_dwMaxTimeout = pReg->ValueDW(SHC_RW_TIMEOUT_KEY, DEFAULT_TIMEOUT_VALUE);

    // get the wakeup sources
    m_dwWakeupSources = pReg->ValueDW(SHC_WAKEUP_SOURCES_KEY, 0);
    m_dwCurrentWakeupSources = m_dwWakeupSources & (~WAKEUP_SDIO);

    return fRet;
}

// Process the capabilities register
BOOL CSDIOControllerBase::InterpretCapabilities()
{
    BOOL fRet = TRUE;

    // set the host controller name
    SDHCDSetHCName(m_pHCContext, L"SDHC");

    // set init handler
    SDHCDSetControllerInitHandler(m_pHCContext, CSDIOControllerBase::SDHCInitialize);

    // set deinit handler    
    SDHCDSetControllerDeinitHandler(m_pHCContext, CSDIOControllerBase::SDHCDeinitialize);

    // set the Send packet handler
    SDHCDSetBusRequestHandler(m_pHCContext, CSDIOControllerBase::SDHCBusRequestHandler);

    // set the cancel I/O handler
    SDHCDSetCancelIOHandler(m_pHCContext, CSDIOControllerBase::SDHCCancelIoHandler);

⌨️ 快捷键说明

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