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

📄 sdhc.cpp

📁 S3C2450BSP开发包,里面有很多资料。可以提供大家参考下。有什么需要解决问题。可以联系我QQ:314661
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

// SDHC controller driver implementation

#include "SDCardDDK.h"
#include "SDHC.h"


#ifndef SHIP_BUILD
#define STR_MODULE _T("CSDHCBase::")
#define SETFNAME(name) LPCTSTR pszFname = STR_MODULE name _T(":")
#else
#define SETFNAME(name)
#endif

#ifdef DEBUG
#define MAKE_OPTION_STRING(x) _T(#x)

const LPCTSTR CSDHCBase::sc_rgpszOptions[SDHCDSlotOptionCount] = {
    MAKE_OPTION_STRING(SDHCDSetSlotPower),
    MAKE_OPTION_STRING(SDHCDSetSlotInterface),
    MAKE_OPTION_STRING(SDHCDEnableSDIOInterrupts),
    MAKE_OPTION_STRING(SDHCDDisableSDIOInterrupts),
    MAKE_OPTION_STRING(SDHCDAckSDIOInterrupt),
    MAKE_OPTION_STRING(SDHCDGetWriteProtectStatus),
    MAKE_OPTION_STRING(SDHCDQueryBlockCapability),
    MAKE_OPTION_STRING(SDHCDSetClockStateDuringIdle),
    MAKE_OPTION_STRING(SDHCDSetSlotPowerState),
    MAKE_OPTION_STRING(SDHCDGetSlotPowerState),
    MAKE_OPTION_STRING(SDHCDWakeOnSDIOInterrupts),
    MAKE_OPTION_STRING(SDHCDGetSlotInfo),
    MAKE_OPTION_STRING(SDHCDSetSlotInterfaceEx),
};
#endif


CSDHCBase::CSDHCBase(
                     ) 
                     : m_regDevice()
{    
    m_hBusAccess = NULL;
    m_cSlots = 0;
    m_pSlots = NULL;
    m_pSlotInfos = NULL;
    m_pHCDContext = NULL;
    m_interfaceType = InterfaceTypeUndefined;
    m_dwBusNumber = INVALID_BUS_NUMBER;
    m_hISRHandler = NULL;
    m_dwSysIntr = SYSINTR_UNDEFINED;
    m_dwPriority = 0;
    m_hevInterrupt = NULL;
    m_htIST = NULL;
    m_cpsCurrent = D0;

    m_fHardwareInitialized = FALSE;
    m_fRegisteredWithBusDriver = FALSE;
    m_fDriverShutdown = FALSE;
    m_fInterruptInitialized = FALSE;
}


CSDHCBase::~CSDHCBase(
                      )
{
    // We call PreDeinit just in case we are not being destroyed by
    // a call to SHC_PreDeinit.
    PreDeinit();

    if (m_fHardwareInitialized) {
        DeinitializeHardware();
    }

    if (m_pHCDContext) {
        // Cleanup the host context
        SDHCDDeleteContext(m_pHCDContext);
    }

    if (m_pSlots) delete [] m_pSlots;
    if (m_pSlotInfos) LocalFree(m_pSlotInfos);
    if (m_hBusAccess) CloseBusAccessHandle(m_hBusAccess);
}


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 (!CheckSlotCount(m_cSlots)) {
        goto EXIT;
    }
    PREFAST_ASSERT(m_cSlots <= SDHC_MAX_SLOTS);

    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;
    }

    // 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);

        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);

    // 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;

EXIT:
    if (hkDevice) RegCloseKey(hkDevice);

    return fRet;
}


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
    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();
    }

    return status;
}


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;
}


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;
    }
    case SDHCDSetSlotInterfaceEx: {
        if (cbData != sizeof(SD_CARD_INTERFACE_EX)) {
            status = SD_API_STATUS_INVALID_PARAMETER;
        }
    }
    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;
}


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);
}


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();
    }
}


VOID
CSDHCBase::PreDeinit(
                     )
{
    if (m_fRegisteredWithBusDriver) {
        if (m_fDriverShutdown == FALSE) {
            // Deregister the host controller
            SDHCDDeregisterHostController(m_pHCDContext);
        }
        // else the bus driver itself already deregistered us.

        m_fRegisteredWithBusDriver = FALSE;
    }
}


BOOL 
CSDHCBase::InitializeHardware(
                              )
{
    SETFNAME(_T("InitializeHardware"));

    DEBUGCHK(m_hBusAccess);
    DEBUGCHK(m_regDevice.IsOK());
    PREFAST_DEBUGCHK(m_pSlotInfos);
    ValidateSlotCount();

    BOOL fRet = FALSE;
    PHYSICAL_ADDRESS PortAddress;
    DWORD inIoSpace = 0;

    // Read window information
    DDKWINDOWINFO wini;
    wini.cbSize = sizeof(wini);
    DWORD dwStatus = DDKReg_GetWindowInfo(m_regDevice, &wini);
    if (dwStatus != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting window information\r\n"),
            pszFname));
        goto EXIT;
    }

    // Read ISR information
    DDKISRINFO isri;
    isri.cbSize = sizeof(isri);
    dwStatus = DDKReg_GetIsrInfo(m_regDevice, &isri);
    if (dwStatus != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting ISR information\r\n"),
            pszFname));
        goto EXIT;
    }

#ifdef SET_TI_BOARD_PCI_REG
	{
		DDKPCIINFO dpi;
		dpi.cbSize = sizeof(dpi);
		DDKReg_GetPciInfo(m_regDevice, &dpi);

		DWORD RetVal;
		PCI_SLOT_NUMBER SlotNumber;
		SlotNumber.u.AsULONG = 0;

⌨️ 快捷键说明

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