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

📄 sdbusrequest.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//
// 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.
//

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

// Bus request api implementation  

#include "SDCardDDK.h"
#include "SDbusdriver.h"


#ifdef DEBUG

// card response text look up
static const WCHAR  *SDCardResponseTypeLookUp[8] =
{{TEXT("NoResponse")},
{TEXT("R1")},
{TEXT("R1b")},
{TEXT("R2")},
{TEXT("R3")},
{TEXT("R4")},
{TEXT("R5")},
{TEXT("R6")}
};


// card state string look up
static const WCHAR  *SDCardStateStringLookUp[16] =
{{TEXT("IDLE")},
{TEXT("READY")},
{TEXT("IDENT")},
{TEXT("STBY")},
{TEXT("TRAN")},
{TEXT("DATA")},
{TEXT("RCV")},
{TEXT("PRG")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
{TEXT("UNKN")},
};

#endif

///////////////////////////////////////////////////////////////////////////////
//  SDSynchCommandCompleteCallback - synchronous completion callback
//  Input:  hDevice - the device handle
//          pRequest - the request that just completed
//          pContext - the context passed in register device
//          BusRequestParam - the optional argument
//  Output: 
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID SDSynchCommandCompleteCallback(SD_DEVICE_HANDLE hDevice,
                                    HBUS_REQUEST     hRequest,
                                    PVOID            pContext,
                                    DWORD            BusRequestParam)
{
    PSD_SYNCH_REQUEST_INFO pSynchInfo = (PSD_SYNCH_REQUEST_INFO)BusRequestParam;
    PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;

    // save off the status
    pSynchInfo->Status = pRequest->Status;

    if (NULL != pSynchInfo->pResponse) {
        BOOL fNoException;

        // we are copying data back from an arbitrary context, set access permissions
        SD_SET_PROC_PERMISSIONS_FROM_REQUEST(pRequest) {
            // copy the response buffer
            fNoException = SDPerformSafeCopy(pSynchInfo->pResponse, 
                &pRequest->CommandResponse, sizeof(SD_COMMAND_RESPONSE));
        } SD_RESTORE_PROC_PERMISSIONS();

        if (fNoException == FALSE) {
            DEBUGMSG(SDCARD_ZONE_ERROR, 
                (TEXT("SDBusDriver: Exception writing to response buffer\n")));
            pSynchInfo->Status = SD_API_STATUS_ACCESS_VIOLATION;
        }
    }

    // free this request
    SDFreeBusRequest__X(hRequest);

    // wake up the blocked thread
    SetEvent(pSynchInfo->hWaitEvent);

}

///////////////////////////////////////////////////////////////////////////////
//  SDSynchronousBusRequest__X - send an SD Bus request synchronously
//  Input:  hDevice -  device handle
//          Command - command to send
//          Argument - argument for command
//          TransferClass - Command only, or associated with read/write data
//          ResponseType - expected response
//          pResponse - buffer to hold response (OPTIONAL)
//          NumBlocks   - number of blocks
//          BlockSize   - block size
//          pBuffer     - block buffer
//          Flags       - bus request flags
//          
//  Output: pResponse - caller allocated storage for the return response 
//  Return: SD_API_STATUS
//  Notes:  
//        This function provides a synchronous (blocking) call to perform a 
//        bus request.  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDSynchronousBusRequest__X(SD_DEVICE_HANDLE       hDevice, 
                                         UCHAR                  Command,
                                         DWORD                  Argument,
                                         SD_TRANSFER_CLASS      TransferClass,
                                         SD_RESPONSE_TYPE       ResponseType,
                                         PSD_COMMAND_RESPONSE   pResponse,
                                         ULONG                  NumBlocks,
                                         ULONG                  BlockSize,
                                         PUCHAR                 pBuffer,
                                         DWORD                  Flags)
{

    SD_API_STATUS           status;             // intermediate status
    PSD_SYNCH_REQUEST_INFO  pSynchInfo;         // synch information
    HBUS_REQUEST            hRequest;           // the new request
    DWORD                   waitResult;         // wait result
    CSDBusDriver           *pBusDriver;         // the bus driver

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SendSynchCommandRequest+\n")));

    PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
    if (!ValidateClientHandle(pDevice)) {
        return SD_API_STATUS_INVALID_HANDLE;
    }

    // get the bus driver
    pBusDriver =  SDDCGetBusDriver(pDevice);
    // allocate a synch info structure, we pre-allocate event objects to
    // minimize impact of creating and deleting wait objects
    pSynchInfo = pBusDriver->AllocateSyncInfo();

    if (NULL == pSynchInfo) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SendSynchCommandRequest- failed to allocate sync info \n")));
        return SD_API_STATUS_INSUFFICIENT_RESOURCES;
    }

    // save the response 
    pSynchInfo->pResponse = pResponse;

    // send the request
    status = SDBusRequest__X(hDevice,                      // device
        Command,                      // command
        Argument,                     // command argument
        TransferClass,                //
        ResponseType,                 // response
        NumBlocks,                       // no blocks
        BlockSize,                       // 
        pBuffer,                         //    
        SDSynchCommandCompleteCallback,  // callback
        (DWORD)pSynchInfo,               // pass the synch information
        &hRequest,                       // request  
        Flags);                          // flags

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SendSynchCommandRequest-\n")));
        pBusDriver->FreeSyncInfo(pSynchInfo);
        return status;
    }

    // wait for the I/O to complete 
    waitResult = WaitForSingleObject(pSynchInfo->hWaitEvent, INFINITE);

    if (WAIT_OBJECT_0 == waitResult) {
        // the request finishes asynchronously and the callback updated the status in the synch struct
        status = pSynchInfo->Status;
    } else {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SendSynchCommandRequest - Wait Failed 0x%08x Error 0x%08x\n"),
            waitResult, GetLastError()));

        // We can only cancel the bus request if it has not already been
        // canceled in SDSynchCommandCompleteCallback. 

        DWORD dw = 1000;
        while (dw--) {
            if (pSynchInfo->Status != SD_API_STATUS_PENDING) {
                break;
            }

            Sleep(1);
        }

        if (pSynchInfo->Status == SD_API_STATUS_PENDING) {
            // The callback still has not been called. Cancel the request.
            SDCancelBusRequest__X(hRequest);
        }

        status = SD_API_STATUS_UNSUCCESSFUL;
    }

    pBusDriver->FreeSyncInfo(pSynchInfo);

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SendSynchCommandRequest-\n")));
    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  OptionalRequestCallBack - completion callback for optional request
//  Input:  hDevice - the device handle
//          pRequest - the request that just completed
//          pContext - the context passed in register device
//          BusRequestParam - the optional argument
//  Output: 
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID OptionalRequestCallBack(SD_DEVICE_HANDLE hDevice,
                             HBUS_REQUEST     hRequest,
                             PVOID            pContext,
                             DWORD            BusRequestParam)
{  
    // just free this request
    SDFreeBusRequest__X(hRequest);
}


///////////////////////////////////////////////////////////////////////////////
//  BuildOptionalRequest - build the optional request based on the request flags
//  Input:  pDevice - the device
//          pBusDriver - the bus driver object
//          Flags - the flags passed in from the bus request API
//  Output: 
//  Return: optional bus request
//  Notes:  
//          returns the optional request that should be inserted behind the current request
///////////////////////////////////////////////////////////////////////////////
PSDBUS_BUS_REQUEST BuildOptionalRequest(PSDCARD_DEVICE_CONTEXT pDevice,
                                        CSDBusDriver           *pBusDriver, 
                                        DWORD                  Flags)
{
    PSDBUS_BUS_REQUEST pRequest = NULL;   // optional request to return

    if (Flags & (SD_AUTO_ISSUE_CMD12 | SD_SDIO_AUTO_IO_ABORT)) {

        pRequest = pBusDriver->AllocateBusRequest();

        if (NULL != pRequest) {

            pRequest->hDevice = (SD_DEVICE_HANDLE)pDevice;
            pRequest->SystemFlags = 0;
            pRequest->HCParam = 0;
            pRequest->NumBlocks = 0;            
            pRequest->BlockSize = 0;
            pRequest->pBlockBuffer = NULL;
            pRequest->pCallback    = OptionalRequestCallBack;
            pRequest->RequestParam   = 0;
            pRequest->ListEntry.Flink = NULL;
            pRequest->ListEntry.Blink = NULL;
            pRequest->TransferClass = SD_COMMAND;

            if (Flags & SD_AUTO_ISSUE_CMD12) {
                // build a CMD12 request
                pRequest->CommandCode = SD_CMD_STOP_TRANSMISSION;
                pRequest->CommandArgument = 0;
                pRequest->CommandResponse.ResponseType = ResponseR1b;

            } else if (Flags & SD_SDIO_AUTO_IO_ABORT) {

                DEBUGCHK(pDevice->SDCardInfo.SDIOInformation.Function != 0);
                // CMD52
                pRequest->CommandCode = SD_IO_RW_DIRECT;
                // set up argument to write the function number to the I/O abort register
                pRequest->CommandArgument = BUILD_IO_RW_DIRECT_ARG(SD_IO_OP_WRITE,      
                    SD_IO_RW_NORMAL,
                    0,    // must be function 0 for access to common regs
                    SD_IO_REG_IO_ABORT,  
                    pDevice->SDCardInfo.SDIOInformation.Function);

                pRequest->CommandResponse.ResponseType = ResponseR5;
            }

            // set the retry count
            SDRequestSetRetryCount(pRequest, pBusDriver->GetRetryCount());
        }

    }

    return pRequest;
}

///////////////////////////////////////////////////////////////////////////////
//  SDBusRequest__X - send command over SD bus
//  Input:  pHandle       - SD bus device structure
//          Command       - SD command to send over bus
//          Argument      - 32 bit argument specific to the command
//          TransferClass - Command only, or associated with read/write data
//          ResponseType  - Response Type for the command
//          NumBlocks     - Number of data blocks in pBlockArray, can be zero
//                          if transfer class is not read or write
//          BlockSize     - Size of data blocks in pBlockArray. All blocks
//                          must be same size.
//          pBuffer       - Pointer to buffer containing BlockSize*NumBlocks bytes
//          pCallback     - completion callback
//          RequestParam    - optional driver specific parameter for this request
//          Flags         - bus request flags
//  Output: ppRequest     - newly allocated request
//  Return: SD_API_STATUS
//  Notes:  
///////////////////////////////////////////////////////////////////////////////


SD_API_STATUS SDBusRequest__X(SD_DEVICE_HANDLE         hDevice,
                              UCHAR                    Command,

⌨️ 快捷键说明

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