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

📄 sdcardio.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// 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.
//

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

// SD Bus driver Card I/O request implementation

#include <SDCardDDK.h>
#include "SDbusdriver.h"
#include <celog.h>

#define SD_GET_IO_RW_DIRECT_RESPONSE_FLAGS(pResponse) (pResponse)->ResponseBuffer[SD_IO_R5_RESPONSE_FLAGS_BYTE_OFFSET]   
#define SD_GET_IO_RW_DIRECT_DATA(pResponse)           (pResponse)->ResponseBuffer[SD_IO_R5_RESPONSE_DATA_BYTE_OFFSET]  


SD_API_STATUS SetCardInterface(PSDCARD_DEVICE_CONTEXT pDevice, PSD_CARD_INTERFACE pInterface); 

///////////////////////////////////////////////////////////////////////////////
//  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 SDReadWriteRegistersCompleteCallback(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;
    // wake up the blocked thread
    SetEvent(pSynchInfo->hWaitEvent);
}

///////////////////////////////////////////////////////////////////////////////
//  SDReadWriteRegistersDirect - Read/Write I/O register(s) direct
//  Input:  hDevice     - the device
//          ReadWrite   - read write flag 
//          Function    - Function number
//          Address     -  starting address
//          ReadAfterWrite - flag to instruct card to read after write
//          pBuffer      -   buffer to hold value of registers
//          BufferLength - number of bytes to read/write
//      
//  Output: 
//  Return: SD_API_STATUS code
//  Notes:  
//          This function can be called to read or write multiple contigous registers synchronously
//          using the SDIO RW_DIRECT command. This function issues multiple commands to transfer
//          to or from the user's buffer
//          If ReadAfterWrite is set to 1, the operation will instruct the card
//          to return the new value of the register in the response.  
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDReadWriteRegistersDirect__X(SD_DEVICE_HANDLE       hDevice,
                                            SD_IO_TRANSFER_TYPE    ReadWrite,
                                            UCHAR                  Function,
                                            DWORD                  Address,
                                            BOOLEAN                ReadAfterWrite,
                                            PUCHAR                 pBuffer,
                                            ULONG                  BufferLength)
{
    SD_API_STATUS   status = SD_API_STATUS_SUCCESS; // intermediate status
    CSDBusDriver    *pBusDriver;        // the bus driver
    UCHAR           responseStatus;     // IO response status
    ULONG           ii;                 // loop count

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SDReadWriteRegistersDirect+\n")));
    DEBUGCELOGMSG(SDCARD_ZONESLOT_CELOG,(TEXT("+SDReadWriteRegistersDirect__X(ReadWrite=%x,Function=%x,Address=%x,BufferLength=%x\r\n"),
        (DWORD)ReadWrite,Function,Address,BufferLength));

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

    if (NULL == pBuffer) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect- NULL buffer passed \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    // get the bus driver
    pBusDriver =  SDDCGetBusDriver(pDevice);
    PREFAST_DEBUGCHK(pBusDriver);
    PSDBUS_BUS_REQUEST    pNewRequest = pBusDriver->AllocateBusRequest();

    if (pNewRequest == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- failed to allocate bus request \n")));
        status = SD_API_STATUS_UNSUCCESSFUL;
    }
    else {

        EnterCriticalSection(&pDevice->syncCritSection);
        ASSERT(pDevice->syncCount==0);
        pDevice->syncCount++;
        
        for (ii = 0; ii < BufferLength; ii++) {
            
            ResetEvent(pDevice->synchInfo.hWaitEvent);
            pDevice->synchInfo.pResponse = NULL; // Don't need copy response.
            
            pNewRequest->ListEntry.Flink = pNewRequest->ListEntry.Blink = NULL;
            pNewRequest->hDevice = hDevice;
            pNewRequest->SystemFlags = pNewRequest->Flags = 0;
            pNewRequest->TransferClass = SD_COMMAND;
            pNewRequest->CommandCode = SD_IO_RW_DIRECT;
            pNewRequest->CommandArgument = BUILD_IO_RW_DIRECT_ARG((UCHAR)ReadWrite,ReadAfterWrite,Function,(Address + ii),
                (ReadWrite==SD_IO_READ)? 0: pBuffer[ii]);

            pNewRequest->CommandResponse.ResponseType = ResponseR5;
            pNewRequest->RequestParam   = (DWORD)&pDevice->synchInfo;
            pNewRequest->NumBlocks =  pNewRequest->BlockSize = pNewRequest->HCParam = 0;
            pNewRequest->pCallback = SDReadWriteRegistersCompleteCallback,  // callback

            pNewRequest->DataAccessClocks = 0; // reset data access clocks

            if (( pDevice->SDCardInfo.SDIOInformation.Flags & FSTPTH_DISABLE ) == 0 ) {
                pNewRequest->Flags = SD_SYNCHRONOUS_REQUEST ;
                pNewRequest->SystemFlags = SD_FAST_PATH_AVAILABLE;
            }

            pNewRequest->pBlockBuffer = 0;
            
            SDDCIncrementRefCount(pDevice);

            status = pBusDriver->SubmitBusRequest(pNewRequest);

            if (!SD_API_SUCCESS(status)){
                ASSERT(FALSE);
                break;
            }
            else if (status == SD_API_STATUS_FAST_PATH_SUCCESS) { 
                PSDBUS_HC_SLOT_CONTEXT pSlot;

                    //  The bus request queue is synchronized using the HCLock.  The first
                    //  entry on the queue is always active on the Host Controller.  Proper
                    //  queue maintenance requires holding the HCLock while removing the
                    //  completed entry from the queue and starting the next entry on the
                    //  queue.  Releasing the lock between these two operations enables
                    //  situations where the request at the head of the queue is started
                    //  (passed to the host controller's bus request handler) twice, breaking
                    //  the design critiera for the host controller driver.

                    //  Synchronize with the request handling.

                pSlot = (SDDCGetClientDeviceFromHandle(hDevice))->pSlot;
                SDHCDAcquireHCLock(pSlot->pHostController);  // SDHCDStartNextRequest releases the lock!!!

                    // dequeue the current request
                if (( SDDequeueBusRequest ( & pSlot->RequestQueue )) != pNewRequest )
                {
                        // the request we are completing should be the first request in the queue
                    DEBUG_CHECK(FALSE,(TEXT("SDSynchronousBusRequest__X - the HC is completing a request that is not the current request! \n")));
                }
                // decrement the ref count
                SDDCDecrementRefCount(pDevice);
                SDHCDStartNextRequest ( pSlot->pHostController, pBusDriver, pSlot );
            }
            else {
                // wait for the I/O to complete
                DWORD waitResult = WaitForSingleObject(pDevice->synchInfo.hWaitEvent, INFINITE);

                if (WAIT_OBJECT_0 == waitResult) {
                    // the request finishes asynchronously and the callback updated the status in the synch struct
                    status = pDevice->synchInfo.Status;
                    
                } 
                else {
                    ASSERT(FALSE);
                    DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SDReadWriteRegistersDirect__X - Wait Failed 0x%08X \n"),waitResult));
                        // cancel the bus request
                    SDCancelBusRequest__X(pNewRequest);
                    status = SD_API_STATUS_UNSUCCESSFUL;
                    break;
                }
            }
            responseStatus = SD_GET_IO_RW_DIRECT_RESPONSE_FLAGS(&pNewRequest->CommandResponse);

            // mask out the previous CRC error, the command is retried on CRC errors
            // so this bit will reflect the previous command instead
            responseStatus &= ~SD_IO_COM_CRC_ERROR;

            if (!SD_IO_R5_RESPONSE_ERROR(responseStatus)) {
                status = SD_API_STATUS_SUCCESS;
                // check to see if read after write or just a read
                if (ReadAfterWrite || (SD_IO_READ == ReadWrite)) {
                    pBuffer[ii] = SD_GET_IO_RW_DIRECT_DATA(&pNewRequest->CommandResponse);
                }

            } else {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect- R5 response returned error code : 0x%02X \n"),responseStatus));
                status = SD_API_STATUS_DEVICE_RESPONSE_ERROR;
                break;
            }
        }
        // free the request
        pBusDriver->FreeBusRequest(pNewRequest);
        pDevice->syncCount--;
        LeaveCriticalSection(&pDevice->syncCritSection);
    }

    DEBUGMSG(SDCARD_ZONE_FUNC, (TEXT("SDCard: SDReadWriteRegistersDirect-\n")));

    if (!SD_API_SUCCESS(status)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDReadWriteRegistersDirect: Request Failed at address : 0x%08X status:0x%08X \n"),(Address + ii), status));
    }
    DEBUGCELOGMSG(SDCARD_ZONESLOT_CELOG,(TEXT("-SDReadWriteRegistersDirect__X: status=%x\r\n"),status));
    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDIOConnectDisconnectInterrupt  - connect/disconnect an interrupt service routine 
//                                    for an SDIO peripheral interrupt
//                                    
//  Input:  hDevice   - SD device handle
//          pIsrFunction - the interrupt service routine 
//          Connect - connect , if TRUE, pIsrFunction must not be NULL
//  Output: 
//  Return: SD_API_STATUS code
//          
//  Notes: 
///////////////////////////////////////////////////////////////////////////////
static
SD_API_STATUS SDIOConnectDisconnectInterrupt(SD_DEVICE_HANDLE         hDevice, 
                                             PSD_INTERRUPT_CALLBACK   pIsrFunction,
                                             BOOL                     Connect)
{
    PSDCARD_DEVICE_CONTEXT      pParentDevice;      // parent device
    UCHAR                       regValue;           // intermediate register value
    SD_API_STATUS               status;             // intermediate status

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

    if (Device_SD_IO != pDevice->DeviceType) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDIOConnectDisconnectInterrupt: device is not SDIO ! \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    if ( Connect && (NULL == pIsrFunction) ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: SDIOConnectInterrupt: callback function is NULL \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    // get the parent device
    pParentDevice = pDevice->pParentDevice;

    if (NULL == pParentDevice) {
        DEBUGCHK(FALSE);
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    DEBUGCHK(0 != pDevice->SDCardInfo.SDIOInformation.Function);

    // must interlock this request with the parent device to update the shadow register
    SDDCAcquireDeviceLock(pParentDevice);

    if (Connect) {
        // set the interrupt function
        pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack = pIsrFunction;
        // update shadow register , we automatically enable the master interrupt enable bit
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable |= 
            ((1 << pDevice->SDCardInfo.SDIOInformation.Function) | SD_IO_INT_ENABLE_MASTER_ENABLE);
    } else {
        DEBUGCHK(pIsrFunction == NULL);
        pDevice->SDCardInfo.SDIOInformation.pInterruptCallBack = NULL;
        // mask out this function
        pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIntEnable &= 
            ~(1 << pDevice->SDCardInfo.SDIOInformation.Function);
    }

⌨️ 快捷键说明

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