📄 sdbus.cpp
字号:
//
// 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 + -