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

📄 sdbusreq.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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) {

⌨️ 快捷键说明

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