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

📄 sdbusrequest.cpp

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*====================================================================================================

            Fast-Path goal is to replace the overhead of interrupts, thread
            switching and thread synchronization with polling by the application
            thread.  This works well at high card clock rates when the card can
            respond faster then the interrupt overhead allows.  For this case
            only, switching from interrupt driven to polling actually reduces
            the amount of work done by the CPU to service this device.  Eliminated
            are:

            *  the thread switches required to handle the actual interrupt and
               hand it off to the interrupt thread,
            *  the setting, clearing, and waiting for the interrupt event,
            *  the setting, clearing, and waiting for the dispatcher event,
            *  the thread switch to the dispatcher, and
            *  the setting, clearing, and waiting for the I/O completion event.

            For Fast-Path, the client driver thread does all of the work to
            perform the I/O operation.

        -----------------------------------------------------------------------------------------
                                        Fast-Path
        -----------------------------------------------------------------------------------------

                                    Client Driver Thread

                                            |
                                            v
                                    calls SDSynchronousBusRequest
                            +--             |
                            |               v
                            |  D    Build Bus Request
                            |  r            |
                            |B i            v
                            |u v    Place in Bus Request Queue
                            |s e            |
                            |  r            v
                            |       Start first bus request
                            +--             |
                            |H              v
                            |o      Start I/O on controller
                            |s              |
                            |t              v
                            |       Poll for I/O Completion
                            |C              |
                            |o D            v
                            |n r    return the I/O status
                            |t i            |
                            |r v            |
                            |o e            |
                            |l r            |
                            |l              |
                            |e              |
                            |r              |
                            +               v
                            |  D    Free current request
                            |  r            |
                            |B i            v
                            |u v    Start next request
                            |s e            |
                            |  r            v
                            |       Return final status
                            +--

            The main difference above is that the starting of the next request
            is delayed until the stack is unwound.  This prevents stack overflows!

====================================================================================================*/

        //  Complete the Fast-Path processing if necessary.
    if ( SD_API_STATUS_FAST_PATH_SUCCESS == status )
    {
        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 )) != hRequest )
        {
                // 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")));
        }

        BOOL fResponseCopiedCorrectly = TRUE;

        //  Return the response data to the client driver if requested.
        if (NULL != pResponse)
        {
            // copy the response buffer
            fResponseCopiedCorrectly = 
                CeSafeCopyMemory(pResponse, &hRequest->CommandResponse, sizeof(SD_COMMAND_RESPONSE));
        }

            // free the request
        SDFreeBusRequest__X(hRequest);

			// decrement the ref count
		SDDCDecrementRefCount(SDDCGetClientDeviceFromHandle(hDevice));

            //  Start the next SDIO request and release the HCLock.
        SDHCDStartNextRequest ( pSlot->pHostController, pBusDriver, pSlot );

            //  Return a status value that existing client drivers understand.
        if (fResponseCopiedCorrectly) {
            status = SD_API_STATUS_SUCCESS;
        }
        else {
            DEBUGMSG(SDCARD_ZONE_ERROR, (_T("SDCard: Access violation while copying command response to user buffer\r\n")));
            status = SD_API_STATUS_ACCESS_VIOLATION;
        }
    }

    //pBusDriver->FreeSyncInfo(pSynchInfo);

    pDevice->syncCount--;
    LeaveCriticalSection(&pDevice->syncCritSection);
    DEBUGCELOGMSG(SDCARD_ZONESLOT_CELOG,(TEXT("-SDSynchronousBusRequest__X: status=%x\r\n"),status));
    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, 
#ifdef __MOVINAND_SUPPORT__ 
 
        // added numBlock parameter to support multi block read/write 
 
                                        DWORD                 Flags, 
                                        DWORD          numBlock) 
#else   
                                        DWORD                  Flags) 
 
#endif 
{
    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) {
 #ifdef __MOVINAND_SUPPORT__  // convert open-ended mode to pre-defined mode 
      if( (pDevice->DeviceType == Device_MMC) && pDevice->dwWhatIsCardType == 0) 
    { 
      // build a CMD23 request 
      	RETAILMSG(0,(TEXT("PREDEFIEND!!\n")));
 
              pRequest->CommandCode = SD_CMD_SET_BLOCK_COUNT; 
 
              pRequest->CommandArgument = numBlock; 
                pRequest->CommandResponse.ResponseType = ResponseR1; 
    } 
   else 
   { 
#endif             
                // build a CMD12 request
                pRequest->CommandCode = SD_CMD_STOP_TRANSMISSION;
                pRequest->CommandArgument = 0;
                pRequest->CommandResponse.ResponseType = ResponseR1b;
#ifdef __MOVINAND_SUPPORT__
    } 
#endif   

            } 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,
                              DWORD                    Argument,
                              SD_TRANSFER_CLASS        TransferClass,
                              SD_RESPONSE_TYPE         ResponseType,
                              ULONG                    NumBlocks,
                              ULONG                    BlockSize,
                              PUCHAR                   pBuffer,
                              PSD_BUS_REQUEST_CALLBACK pCallback,
                              DWORD                    RequestParam,
                              HBUS_REQUEST            *phRequest,
                              DWORD                    Flags)
{
    CSDBusDriver           *pBusDriver;    // the bus driver
    PSDBUS_BUS_REQUEST      pNewRequest;    // the new request
    SD_API_STATUS           status = SD_API_STATUS_SUCCESS; // intermediate status
    PSDBUS_BUS_REQUEST      pOptionalRequest = NULL;  // optional request to send down

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

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

    if( pCallback == NULL ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- Callback missing \n")));
        return SD_API_STATUS_INVALID_PARAMETER;;
    }

    if( phRequest == NULL ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- caller supplied storage is NULL \n")));
        return SD_API_STATUS_INVALID_PARAMETER;;
    }

    if( TransferClass == SD_READ || TransferClass == SD_WRITE ) {
        if( NumBlocks == 0 ) {

⌨️ 快捷键说明

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