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

📄 sdbus.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// 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.
//
//
/*++
Module Name:  
    SDBus.cpp
Abstract:
    SDBus Implementation.

Notes: 
--*/

#include <windows.h>
#include <bldver.h>
#include <cesdbus.h>
#include <marshal.hpp>

#include "../HSMMCCh1/s3c6410_hsmmc_lib/sdhcd.h"

#include "sdbus.hpp"
#include "sdslot.hpp"
#include "sdbusreq.hpp"



///////////////////////////////////////////////////////////////////////////////
// DefaultChangeCardPower - Default power allocation/deallocation handler for the 
//                          bus driver.
//                             
// Input:   pHCCardContext    - host controller context   
//          Slot        - Slot number
//            CurrentDelta- Change in Slot current
// Output:
// Return:  SD_API_STATUS_INSUFFICIENT_HOST_POWER - the slot will exceeded is maximum
//                current limit.
//            SD_API_STATUS_SUCCESS - No current limit has been exceeded. 
// Notes:   If the Host Controller does not assign its own power allocation/deallocation 
//          handler.  This function is called each time a client requests a change that
//            affects the card's power state.
/////////////////////////////////////////////////////////////////////////////// 
SD_API_STATUS CSDHost::DefaultChangeCardPower(PSDCARD_HC_CONTEXT pHCCardContext,DWORD Slot,INT CurrentDelta)
{
    USHORT  SlotPower = 0;
    INT     NewSlotPower = 0;
    PREFAST_ASSERT(pHCCardContext!=NULL);
    CSDHost * pHost = (CSDHost *) pHCCardContext;
    DWORD dwHostIndex = MAXDWORD;
    SD_API_STATUS status = SD_API_STATUS_NO_SUCH_DEVICE;
    __try {
        dwHostIndex = pHost->m_dwSdHostIndex ;
    }
    __except (SDProcessException(GetExceptionInformation())) {
        dwHostIndex = MAXDWORD;
    }
    pHost = CSDHostContainer::GetSDHost(dwHostIndex);
    if (pHost && (PSDCARD_HC_CONTEXT)pHost == pHCCardContext) {
        CSDSlot *pSlot = pHost->GetSlot(Slot);
        if (pSlot) {
            SlotPower = pSlot->GetSlotPower();
            NewSlotPower = ((INT) SlotPower) + CurrentDelta;
            status = SD_API_STATUS_SUCCESS ;
            if(NewSlotPower > DEFAULT_MAX_SLOT_CURRENT) {
                DbgPrintZo(SDCARD_ZONE_WARN, 
                           (TEXT("SDBusDriver: Power change denied, current over limmit by %dmA\n"),
                                               NewSlotPower - DEFAULT_MAX_SLOT_CURRENT));
                status = SD_API_STATUS_INSUFFICIENT_HOST_POWER;
            }
            else if(NewSlotPower < 0) {
                DbgPrintZo(SDCARD_ZONE_WARN, (TEXT("SDBusDriver: Power change math issue, current under limmit by %dmA\n"), NewSlotPower));
            }
        }
    }
    if (pHost)
        pHost->DeRef();
    
    // Do not change SlotPower in this function.
    // It will be tracked by the bus driver's calling function.

    return status;
}


//------------------------------------------------------------------
CSDHost::CSDHost(DWORD dwNumSlot)
:   m_dwNumOfSlot (min(dwNumSlot,SD_MAXIMUM_SLOT_PER_SDHOST)) 
{
    m_dwSdHostIndex = MAXDWORD;
    memset((SDCARD_HC_CONTEXT *)this, 00, sizeof(SDCARD_HC_CONTEXT));
    dwVersion = SDCARD_HC_BUS_INTERFACE_VERSION;
    InitializeCriticalSection(&HCCritSection);
    
    for (DWORD dwIndex = 0; dwIndex<SD_MAXIMUM_SLOT_PER_SDHOST; dwIndex ++ )
        m_SlotArray[dwIndex] = NULL ;
    m_fIntialized = FALSE;
    m_fHostAttached = FALSE;
    m_fIntialized = FALSE;
}

BOOL CSDHost::Init()
{
    if (!m_fIntialized) {
        // set the number of slots
        // such that the host can detect the version of the bus driver
        StringCchCopy(HostControllerName,_countof(HostControllerName),  BUS_VER_FOR_HOST);
        // set the default power control handler function
        pChangeCardPowerHandler = DefaultChangeCardPower;
        dwVersion = SDCARD_HC_BUS_INTERFACE_VERSION ;
        
        for (DWORD dwIndex = 0;  dwIndex<m_dwNumOfSlot; dwIndex ++) {
            m_SlotArray[dwIndex] = new CSDSlot(dwIndex,*this);
            if (!(m_SlotArray[dwIndex] && m_SlotArray[dwIndex]->Init())) {
                ASSERT(FALSE);
                return FALSE;
            }
        }
        m_fIntialized = TRUE;
        return TRUE;
    }
    return FALSE;
}
CSDHost::~CSDHost()
{
    ASSERT(!m_fHostAttached);
    for (DWORD dwIndex= 0; dwIndex< m_dwNumOfSlot; dwIndex++) {
        if (m_SlotArray[ dwIndex ]) {
            delete m_SlotArray[ dwIndex ];
        }
    };
    DeleteCriticalSection(&HCCritSection);
}

BOOL CSDHost::Attach()
{
    if (m_fIntialized && !m_fHostAttached) {
        m_fHostAttached = TRUE ;
        for (DWORD dwIndex= 0; dwIndex< m_dwNumOfSlot; dwIndex++) {
            if (m_SlotArray[ dwIndex ]) {
                m_SlotArray[ dwIndex ]->Attach();
            }
        };
        return TRUE;
    }
    return FALSE;
}
BOOL CSDHost::Detach()
{
    if (m_fHostAttached) {
        m_fHostAttached = FALSE;
        for (DWORD dwIndex= 0; dwIndex< m_dwNumOfSlot; dwIndex++) {
            if (m_SlotArray[ dwIndex ]) {
                m_SlotArray[ dwIndex ]->Detach();
            }
        };
    };
    return TRUE;
}
SD_API_STATUS CSDHost::SlotSetupInterface(DWORD dwSlot, PSD_CARD_INTERFACE_EX psdCardInterfaceEx )
{
    SD_API_STATUS status = SD_API_STATUS_INVALID_PARAMETER;
    if (psdCardInterfaceEx!= NULL && dwSlot < m_dwNumOfSlot && m_SlotArray[dwSlot]!=NULL) {
        if (psdCardInterfaceEx->InterfaceModeEx.bit.sdHighSpeed == 0 ) { // we can do this on old API.
            SD_CARD_INTERFACE sdCardInterface = ConvertFromEx(*psdCardInterfaceEx);
            status = SlotOptionHandler(dwSlot, SDHCDSetSlotInterface,&sdCardInterface,sizeof(sdCardInterface));
            if (SD_API_SUCCESS(status)){
                psdCardInterfaceEx->InterfaceModeEx.bit.hsmmc8Bit = (sdCardInterface.InterfaceMode == SD_INTERFACE_MMC_8BIT? 1: 0);
                psdCardInterfaceEx->InterfaceModeEx.bit.sd4Bit = (sdCardInterface.InterfaceMode == SD_INTERFACE_SD_4BIT? 1: 0);
                psdCardInterfaceEx->ClockRate = sdCardInterface.ClockRate;
                psdCardInterfaceEx->InterfaceModeEx.bit.sdWriteProtected = (sdCardInterface.WriteProtected?1:0);
            }
        }
        else 
            status = SlotOptionHandler(dwSlot, SDHCDSetSlotInterfaceEx, psdCardInterfaceEx, sizeof(*psdCardInterfaceEx));
    }
    ASSERT(SD_API_SUCCESS(status));
    return status;
}

//---------------------- Bus Container ----------------------------------------
CSDHostContainer * CSDHostContainer::g_pSdContainer = NULL;
CSDHostContainer::CSDHostContainer(LPCTSTR pszActiveKey)
:   DefaultBusDriver(pszActiveKey)
,   m_deviceKey(pszActiveKey)
{
    m_pFreeBusRequestSpace = NULL ;
    m_dwMinSize=0;
    m_szSubBusNamePrefix[0] = 0 ;
    DWORD dwType;
    DWORD dwDataLen = sizeof(m_szSubBusNamePrefix) ;
    if (m_deviceKey.IsKeyOpened() && 
            m_deviceKey.RegQueryValueEx(SD_SUB_BUSNAME_VALNAME,&dwType,(PBYTE)m_szSubBusNamePrefix,&dwDataLen) &&
            dwType == SD_SUB_BUSNAME_VALTYPE ) {
        m_szSubBusNamePrefix[_countof(m_szSubBusNamePrefix)-1] = 0 ;
    }
    else 
        m_szSubBusNamePrefix[0] = 0 ;
}
CSDHostContainer::~CSDHostContainer()
{
    ((CStaticContainer *)this)->Lock();
    while (m_pFreeBusRequestSpace) {
        PFREE_BUS_REQUEST_SPACE pNext = m_pFreeBusRequestSpace->pNextFreeTransfer ;
        free(m_pFreeBusRequestSpace);
        m_pFreeBusRequestSpace = pNext;
    }
    ((CStaticContainer *)this)->Unlock();
}
BOOL CSDHostContainer::Init()
{
    if (DefaultBusDriver::Init() && m_deviceKey.IsKeyOpened()) {
        m_BusRequestRetryCount = RegValueDWORD (SDCARD_REQUEST_RETRY_KEY, DEFAULT_BUS_REQUEST_RETRY_COUNT);
        return TRUE;
    }
    else
        return FALSE;
}
#define SD_BUS_PREFIX TEXT("SDBUS")
DWORD CSDHostContainer::GetBusNamePrefix(__out_ecount(dwSizeInUnit) LPTSTR lpReturnBusName,DWORD dwSizeInUnit)
{
    DWORD dwUnitCopy = min(dwSizeInUnit,sizeof(SD_BUS_PREFIX)/sizeof(TCHAR));
    if ( lpReturnBusName && dwUnitCopy) {
        HRESULT hr = StringCchCopy( lpReturnBusName, dwSizeInUnit, SD_BUS_PREFIX);
        if ( !SUCCEEDED(hr)) {
            lpReturnBusName[0]=0; // Terminate it.
            dwUnitCopy = 0 ;
        }
        return dwUnitCopy;
    }
    else
        return 0;
}
PVOID CSDHostContainer::AllocateBusRequestImp(size_t stSize)
{
    PVOID pReturn = NULL ;
    ((CStaticContainer *)this)->Lock();
    if (stSize> m_dwMinSize) {
        DEBUGMSG(SDCARD_ZONE_WARN && m_dwMinSize!=0,(L"AllocateBusRequest Changed From %d, to %d",m_dwMinSize,stSize) );
        DeleteAllTransferSpace();
        m_dwMinSize= stSize;
    }
    if (m_pFreeBusRequestSpace==NULL) {
        m_pFreeBusRequestSpace =(PFREE_BUS_REQUEST_SPACE) malloc(sizeof(FREE_BUS_REQUEST_SPACE)+m_dwMinSize);
        if (m_pFreeBusRequestSpace) {
            m_pFreeBusRequestSpace->dwFreeSpaceTag = BUS_REQUEST_FREE_SPACE_TAG;
            m_pFreeBusRequestSpace->dwSpaceSize = m_dwMinSize;
            m_pFreeBusRequestSpace->pNextFreeTransfer = NULL;
        }
    }
    if (m_pFreeBusRequestSpace) {
        ASSERT(m_pFreeBusRequestSpace->dwFreeSpaceTag == BUS_REQUEST_FREE_SPACE_TAG);
        ASSERT(m_pFreeBusRequestSpace->dwSpaceSize>=stSize);
        pReturn = (PVOID)(m_pFreeBusRequestSpace+1);
        m_pFreeBusRequestSpace = m_pFreeBusRequestSpace->pNextFreeTransfer ;
    };
    ((CStaticContainer *)this)->Unlock();
    return pReturn;
}
CSDHost * CSDHostContainer::GetSDHost(CSDHost * pUnknowHost)
{
    DWORD dwIndex = MAXDWORD;
    if (pUnknowHost) {
        __try { dwIndex = pUnknowHost->GetIndex(); }
        __except(SDProcessException(GetExceptionInformation())) {
            dwIndex = MAXDWORD;
        }
    }
    return GetSDHost(dwIndex);
    
}

///////////////////////////////////////////////////////////////////////////////
//  GetSlotInfo - get slot information for all slots in the system
//  Input:  pBuffer - buffer to hold the slot information
//          Length  - length of the buffer
//  Output: 
//  Notes:  
//      returns the number of slots or zero on error
///////////////////////////////////////////////////////////////////////////////
DWORD CSDHostContainer::GetSlotInfo(PBUS_DRIVER_SLOT_INFO pslotInfoArray, DWORD Length) 
{
    ULONG                   slotCount = 0;          // running slot count

    ((CStaticContainer *)this)->Lock();
    for (DWORD dwIndex = 0 ; dwIndex < m_dwArraySize; dwIndex++) {
        if (m_rgObjectArray[dwIndex]!=NULL) {
            slotCount += m_rgObjectArray[dwIndex]->GetSlotCount();
        }
    };
    if (pslotInfoArray!=NULL && Length!=0) { // We need file out the information.
        // check the buffer
        if (Length < slotCount * (sizeof(BUS_DRIVER_SLOT_INFO))) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: GetSlotInfo : insufficient buffer  \n")));    
            slotCount = 0;
        }

⌨️ 快捷键说明

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