?? sdbusreq.cpp
字號(hào):
//
// 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.
//
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
SDBusReq.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"
void * CSDBusRequest::operator new(size_t stSize)
{
return CSDHostContainer::AllocateBusRequest(stSize);
}
void CSDBusRequest::operator delete (void *pointer)
{
CSDHostContainer::FreeBusRequest((CSDBusRequest *)pointer);
}
DWORD CSDBusRequest::g_dwRequestIndex = 0 ;
CSDBusRequest::CSDBusRequest(CSDDevice& sdDevice, SD_BUS_REQUEST& sdBusRequest, HANDLE hCallback, CSDBusRequest * pParentBus )
: m_pParentBus(pParentBus)
, m_hCallback(hCallback)
, m_sdDevice(sdDevice)
{
m_lRefCount = 0;
m_pAsyncQueueNext = NULL;
m_pChildListNext = NULL;
m_dwRequestIndex = (SDBUS_REQUEST_INDEX_MASK & (DWORD)InterlockedIncrement((PLONG)&g_dwRequestIndex));
ListEntry.Flink = NULL;
ListEntry.Blink = NULL;
hDevice = (m_sdDevice.GetDeviceHandle()).hValue;
SystemFlags = sdBusRequest.SystemFlags;
TransferClass = sdBusRequest.TransferClass;
CommandCode = sdBusRequest.CommandCode;
CommandArgument = sdBusRequest.CommandArgument;
CommandResponse.ResponseType = sdBusRequest.CommandResponse.ResponseType;
RequestParam = sdBusRequest.RequestParam;
NumBlocks = sdBusRequest.NumBlocks;
BlockSize = sdBusRequest.BlockSize;
HCParam = 0;
pBlockBuffer = NULL ;
pCallback = sdBusRequest.pCallback;
DataAccessClocks = 0; // reset data access clocks
Flags = sdBusRequest.Flags ;
Status = SD_API_STATUS_PENDING ;
m_pOrinalAddr = sdBusRequest.pBlockBuffer;
if ((Flags & SD_BUS_REQUEST_PHYS_BUFFER) && sdBusRequest.cbSizeOfPhysList && sdBusRequest.pPhysBuffList) {
cbSizeOfPhysList = sdBusRequest.cbSizeOfPhysList/sizeof(PHYS_BUFF_LIST); // Convert to unit.
m_pOrignalPhysAddr = sdBusRequest.pPhysBuffList;
if (!SUCCEEDED(CeAllocAsynchronousBuffer((PVOID *)&pPhysBuffList,m_pOrignalPhysAddr,cbSizeOfPhysList*sizeof(PHYS_BUFF_LIST),ARG_I_PTR))) {
Flags &= ~SD_BUS_REQUEST_PHYS_BUFFER;
pPhysBuffList = NULL;
cbSizeOfPhysList = 0 ;
}
}
else {
m_pOrignalPhysAddr= pPhysBuffList = NULL;
cbSizeOfPhysList = 0;
}
if (m_pParentBus)
m_pParentBus->AddRef();
m_dwArguDesc = 0 ;
m_fCompleted = FALSE;
m_ExternalHandle = NULL;
}
CSDBusRequest::~CSDBusRequest()
{
TerminateLink();
if (m_pOrinalAddr && pBlockBuffer && m_pOrinalAddr != pBlockBuffer) {
HRESULT hResult= CeFreeAsynchronousBuffer(pBlockBuffer,m_pOrinalAddr, NumBlocks*BlockSize, m_dwArguDesc) ;
ASSERT(SUCCEEDED(hResult));
}
if ( pPhysBuffList && cbSizeOfPhysList && m_pOrignalPhysAddr && m_pOrignalPhysAddr!=pPhysBuffList) {
HRESULT hResult= CeFreeAsynchronousBuffer(pPhysBuffList,m_pOrignalPhysAddr, cbSizeOfPhysList*sizeof(PHYS_BUFF_LIST), ARG_I_PTR) ;
ASSERT(SUCCEEDED(hResult));
}
}
BOOL CSDBusRequest::Init()
{
BOOL fRet = TRUE;
if( TransferClass == SD_READ || TransferClass == SD_WRITE ) {
if( NumBlocks == 0 ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- No transfer buffers passed \n")));
Status = SD_API_STATUS_INVALID_PARAMETER;
fRet = FALSE;
}
else if( m_pOrinalAddr == NULL ) {
// check pointer to see if block array ptr is non-NULL
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- NULL buffer pointer passed \n")));
Status = SD_API_STATUS_INVALID_PARAMETER;
fRet = FALSE;
} else if ( m_pOrinalAddr && NumBlocks && BlockSize && m_hCallback ) { // External call
m_dwArguDesc = (TransferClass == SD_READ?ARG_O_PTR:ARG_I_PTR);
if (NumBlocks>=(1<<16) || BlockSize>=(1<<16) || !SUCCEEDED(CeAllocAsynchronousBuffer((PVOID *)&pBlockBuffer,m_pOrinalAddr,NumBlocks*BlockSize,m_dwArguDesc))) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest__X CeAllocAsynchronousBuffer Error (%d)\r\n"),GetLastError()));
ASSERT(FALSE);
Status = SD_API_STATUS_ACCESS_VIOLATION;
pBlockBuffer = NULL ;
fRet = FALSE;
}
}
else {
pBlockBuffer = (PUCHAR) m_pOrinalAddr ;
}
}
if (fRet) {
if ((Device_SD_Memory == m_sdDevice.GetDeviceType()) || (Device_MMC == m_sdDevice.GetDeviceType())) {
if (TransferClass == SD_READ) {
// set for read
DataAccessClocks = m_sdDevice.GetCardInfo().SDMMCInformation.DataAccessReadClocks;
} else if (TransferClass == SD_WRITE) {
// set write
DataAccessClocks = m_sdDevice.GetCardInfo().SDMMCInformation.DataAccessWriteClocks;
}
}
SystemFlags &= ~SYSTEM_FLAGS_RETRY_COUNT_MASK;
SystemFlags |= (CSDHostContainer::GetRetryCount() & SYSTEM_FLAGS_RETRY_COUNT_MASK);
SystemFlags |= ((Flags & SD_SLOTRESET_REQUEST)!=0?SD_BUS_REQUEST_SLOT_RESET:0);
if (m_pParentBus == NULL) { // This is paranet
UCHAR ucSDIOFlags = m_sdDevice.GetCardInfo().SDIOInformation.Flags;
if ((( 1 < NumBlocks ) &&
((SD_CMD_IO_RW_EXTENDED == CommandCode) &&
(((SD_READ == TransferClass) &&
(0 != (ucSDIOFlags & (SFTBLK_USE_FOR_CMD53_READ | SFTBLK_USE_ALWAYS )))) ||
((SD_WRITE == TransferClass ) &&
(0 != (ucSDIOFlags & (SFTBLK_USE_FOR_CMD53_WRITE | SFTBLK_USE_ALWAYS ))))))) ||
((SD_CMD_READ_MULTIPLE_BLOCK == CommandCode) &&
(0 != (ucSDIOFlags & (SFTBLK_USE_FOR_CMD18 | SFTBLK_USE_ALWAYS )))) ||
((SD_CMD_WRITE_MULTIPLE_BLOCK == CommandCode) &&
(0 != (ucSDIOFlags & (SFTBLK_USE_FOR_CMD25 | SFTBLK_USE_ALWAYS ))))) {
// It is really hard to seperate physical buffer. If this happen. we disable physical buffer.
Flags &= ~SD_BUS_REQUEST_PHYS_BUFFER;
fRet = BuildSoftBlock();
}
if (((SD_CMD_READ_MULTIPLE_BLOCK != CommandCode) ||
(0 == (ucSDIOFlags & (SFTBLK_USE_FOR_CMD18 | SFTBLK_USE_ALWAYS)))) &&
((SD_CMD_WRITE_MULTIPLE_BLOCK != CommandCode) ||
(0 == (ucSDIOFlags & (SFTBLK_USE_FOR_CMD25 | SFTBLK_USE_ALWAYS )))) &&
(0 == (ucSDIOFlags & SFTBLK_USE_ALWAYS))) {
// check for optional request
fRet = BuildOptionalRequest( ucSDIOFlags );
}
}
}
ASSERT(fRet);
if (!fRet)
m_fCompleted = TRUE;
return fRet;
}
BOOL CSDBusRequest::CheckForCompletion()
{
if (m_pParentBus!=NULL) {
return m_pParentBus->CheckForCompletion();
}
else if (IsComplete()) {
// This one is completed.
if (SD_API_SUCCESS(Status) && m_pChildListNext!=NULL) {
Status = m_pChildListNext->GetFirstFailedStatus();
}
#ifdef DEBUG
SD_CARD_STATUS cardStatus;
if (SDBUS_ZONE_REQUEST) {
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: CMD%d CMDArg: 0x%08X TransferClass:%d ResponseType: %s Complete\n"),
CommandCode, CommandArgument,TransferClass, SDCardResponseTypeLookUp[CommandResponse.ResponseType & 0x7]));
if (SD_API_SUCCESS(Status)) {
if ( (ResponseR1 == CommandResponse.ResponseType) || (ResponseR1b == CommandResponse.ResponseType)) {
SDGetCardStatusFromResponse(&CommandResponse, &cardStatus);
DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("--- SDBusDriver: R1,R1b Response, Card Status: 0x%08X, Last State: %s \n"),
cardStatus,
SDCardStateStringLookUp[((CommandResponse.ResponseBuffer[2] >> 1) & 0x0F)]));
}
if (NoResponse != CommandResponse.ResponseType) {
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -