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

📄 sdbusrequest.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                              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 ) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- No transfer buffers passed \n")));
            return SD_API_STATUS_INVALID_PARAMETER;
        }

        // check pointer to see if block array ptr is non-NULL
        if( pBuffer == NULL ) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusRequest: SDBusRequest- NULL buffer pointer passed \n")));
            return SD_API_STATUS_INVALID_PARAMETER;
        }
    }

    // pre-increment the reference count to keep the device object alive
    SDDCIncrementRefCount(pDevice);

    __try {

        // get the bus driver
        pBusDriver =  SDDCGetBusDriver(pDevice);

        // allocate a 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 {

            pNewRequest->ListEntry.Flink = NULL;
            pNewRequest->ListEntry.Blink = NULL;
            pNewRequest->hDevice = hDevice;
            pNewRequest->SystemFlags = 0;
            pNewRequest->TransferClass = TransferClass;
            pNewRequest->CommandCode = Command;
            pNewRequest->CommandArgument = Argument;
            pNewRequest->CommandResponse.ResponseType = ResponseType;
            pNewRequest->RequestParam   = RequestParam;
            pNewRequest->NumBlocks = NumBlocks;            
            pNewRequest->BlockSize = BlockSize;
            pNewRequest->HCParam = 0;
            pNewRequest->pBlockBuffer = pBuffer;
            pNewRequest->pCallback    = pCallback;
            pNewRequest->DataAccessClocks = 0; // reset data access clocks
            pNewRequest->Flags = Flags;
            // get the current thread permissions for the block buffer
            pNewRequest->CurrentPermissions = GetCurrentPermissions();

            // only memory cards have this property
            if ((Device_SD_Memory == pDevice->DeviceType) ||
                (Device_MMC == pDevice->DeviceType)) {

                if (TransferClass == SD_READ) {
                    // set for read
                    pNewRequest->DataAccessClocks = pDevice->SDCardInfo.SDMMCInformation.DataAccessReadClocks;
                } else if (TransferClass == SD_WRITE) {
                    // set write
                    pNewRequest->DataAccessClocks = pDevice->SDCardInfo.SDMMCInformation.DataAccessWriteClocks; 
                }
            }

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

            // return the request to the caller
            DEBUGCHK(ValidateRequest(pNewRequest));
            *phRequest = pNewRequest;

            // check for optional request
            pOptionalRequest = BuildOptionalRequest(pDevice,
                pBusDriver, 
                Flags);

            if (pOptionalRequest != NULL) {
                // increment ref count for the optional request
                SDDCIncrementRefCount(pDevice);  
                // must interlock this request with the parent device 
                // so we can atomically add this in the queue
                SDDCAcquireDeviceLock(pDevice->pParentDevice);
            }

            DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDBusDriver: Submitting bus request:0x%08X to device %s \n"),pNewRequest,
                SDDCGetClientName(pDevice)));
            // submit the main request
  
            status = pBusDriver->SubmitBusRequest(pNewRequest);


            if (!SD_API_SUCCESS(status)) {
                // free the request, it did not make it down
                pBusDriver->FreeBusRequest(pNewRequest); 

                // free the optional request too
                if (pOptionalRequest != NULL) {
                    pBusDriver->FreeBusRequest(pOptionalRequest); 
                }

            } else {

                // now submit the optional request if one is required
                if (pOptionalRequest != NULL) {


                    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDBusDriver: Submitting optional request:0x%08X to device %s \n"),pOptionalRequest,
                        SDDCGetClientName(pDevice)));
                    // while we have the parent lock held add the optional
                    // request in behind this original request
                    if (!SD_API_SUCCESS(pBusDriver->SubmitBusRequest(pOptionalRequest))) {
                        // free the request, it didn't make it down
                        pBusDriver->FreeBusRequest(pOptionalRequest); 
                        // decrement ref count
                        SDDCDecrementRefCount(pDevice);
                        // we leave status alone since the previous
                        // command succeeded we let that get processed normally
                        // nothing we can really do here
                    }
                }
            }

            if (pOptionalRequest != NULL) {
                // unlock 
                SDDCReleaseDeviceLock(pDevice->pParentDevice);
            }

        }

    } __except (SDProcessException(GetExceptionInformation())) {
        status = SD_API_STATUS_UNSUCCESSFUL;
    }

    if (!SD_API_SUCCESS(status)) {
        // never made it down
        SDDCDecrementRefCount(pDevice);
        // if the main request never made it down, the optional request 
        // would not have either
        if (pOptionalRequest != NULL) {
            SDDCDecrementRefCount(pDevice);
        }
    }

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDFreeBusRequest__X - free this request
//  Input:  pRequest  - the request to free     
//  Output: 
//  Return: 
//  Notes:
//          this function returns the bus request back to the memory look aside 
//          list
///////////////////////////////////////////////////////////////////////////////
VOID SDFreeBusRequest__X(HBUS_REQUEST  hRequest)
{
    PSDBUS_BUS_REQUEST  pRequest = (PSDBUS_BUS_REQUEST) hRequest;

    if ( !ValidateRequest(pRequest) || (pRequest->hDevice == NULL) ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDFreeBusRequest: Invalid request\n")));
    }
    else {
        PSDCARD_DEVICE_CONTEXT pDevice = 
            SDDCGetClientDeviceFromHandle(pRequest->hDevice);
        DEBUGCHK(pDevice);

        CSDBusDriver *pBusDriver = SDDCGetBusDriver(pDevice);
        DEBUGCHK(pBusDriver);

        pBusDriver->FreeBusRequest(pRequest);
    }
}

///////////////////////////////////////////////////////////////////////////////
//  SDCancelBusRequest__X - Cancel an outstanding bus request
//  Input:  
//          pRequest - request to cancel (returned from SDBusRequest)
//  Output: 
//  Return: TRUE if request was cancelled , FALSE if the request is still pending
//  Notes:
//
///////////////////////////////////////////////////////////////////////////////
BOOLEAN SDCancelBusRequest__X(HBUS_REQUEST  hRequest)
{
    PSDBUS_BUS_REQUEST          pRequest = (PSDBUS_BUS_REQUEST) hRequest;
    PSDBUS_HC_SLOT_CONTEXT      pSlot;              // slot 
    PSDBUS_BUS_REQUEST          pCurrentRequest;    // current request
    BOOL                        fRet = FALSE;

    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: +SDCancelBusRequest\n")));

    if (!ValidateRequest(pRequest)) {
        goto EXIT;
    }

    // get some pointers
    PSDCARD_DEVICE_CONTEXT pDevice;
    pDevice = SDDCGetClientDeviceFromHandle(pRequest->hDevice);
    PREFAST_DEBUGCHK(pDevice != NULL);
    pSlot = pDevice->pSlot;
    PREFAST_DEBUGCHK(pSlot != NULL);

    SDHCDAcquireHCLock(pSlot->pHostController);

    if (!IS_SD_REQUEST_CANCELABLE(pRequest)) {
        // this request is not cancelable
        DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: Request 0x%08X on slot:%d is not cancelable \n"),
            pRequest, pSlot->SlotIndex));
        SDHCDReleaseHCLock(pSlot->pHostController);
        goto EXIT;
    }

    // get the current request
    pCurrentRequest = (PSDBUS_BUS_REQUEST) SDGetCurrentRequest(&pSlot->RequestQueue);

    // is this the current request?
    if (pRequest == pCurrentRequest) {
        DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: Request 0x%08X on slot:%d is the current request, calling HC to cancel \n"),
            pRequest,  pSlot->SlotIndex));
        // NOTE: DO NOT RELEASE THE HC LOCK HERE!
        // do not release the lock here, the host controller's cancel callback has to release the HC lock
        fRet = pSlot->pHostController->pCancelIOHandler(pSlot->pHostController,
            pSlot->SlotIndex, pRequest);
        goto EXIT;
    }

    // make sure the caller didn't cancel a request that wasn't in a queue
    if (NULL == pRequest->ListEntry.Flink) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCancelBusRequest: Request 0x%08X on slot:%d is not in a queue! \n"),
            pRequest, pSlot->SlotIndex ));
        SDHCDReleaseHCLock(pSlot->pHostController);
        goto EXIT;
    }

    // remove the entry
    SDRemoveEntryFromQueue(&pSlot->RequestQueue, pRequest);

    // release the lock
    SDHCDReleaseHCLock(pSlot->pHostController);

    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: Request 0x%08X on slot:%d is in the queue, removing request, completing.... \n"),
        pRequest, pSlot->SlotIndex));

    // set the status
    pRequest->Status = SD_API_STATUS_CANCELED;

    // complete the request
    SDCompleteBusRequest(pRequest);

    fRet = TRUE;

EXIT:
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("SDCard: -SDCancelBusRequest\n")));

    return fRet;
}


#if DEBUG
///////////////////////////////////////////////////////////////////////////////
//  DumpParsedCSDRegisters- dump parsed register data to the debugger
//  Input:  pParsedCSD - the Parsed CSD structure
//  Output: 
//
//  Notes:  
///////////////////////////////////////////////////////////////////////////////
VOID DumpParsedCSDRegisters(PSD_PARSED_REGISTER_CSD pParsedCSD)
{

    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT("\n\n\nSDCard: Dumping parsed Registers : \n")));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Version:%d \n"),pParsedCSD->CSDVersion)); 
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" TAAC: %f ns \n"),pParsedCSD->DataAccessTime.TAAC));  
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" NSAC: %d clocks \n"),pParsedCSD->DataAccessTime.NSAC)); 
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" MaxDataTransferRate: %d kb/s \n"),pParsedCSD->MaxDataTransferRate));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Card Command Classes: 0x%04X \n"),pParsedCSD->CardCommandClasses));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Max Read Block Length: %d bytes \n"),pParsedCSD->MaxReadBlockLength));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Read Block Partial? : %d  \n"),pParsedCSD->ReadBlockPartial));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Max Write Block Length: %d bytes \n"),pParsedCSD->MaxWriteBlockLength));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Write Block Partial? : %d  \n"),pParsedCSD->WriteBlockPartial));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Write Block Misaligned? : %d  \n"),pParsedCSD->WriteBlockMisalign));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Read Block Misaligned? : %d  \n"),pParsedCSD->ReadBlockMisalign));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" DSR Implemented? : %d  \n"),pParsedCSD->DSRImplemented));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Device Size : %d bytes  \n"),pParsedCSD->DeviceSize));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Read Current Min : %d mA \n"),pParsedCSD->VDDReadCurrentMin));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Read Current Max : %d mA \n"),pParsedCSD->VDDReadCurrentMax));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Write Current Min : %d mA \n"),pParsedCSD->VDDWriteCurrentMin));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" VDD Write Current Max : %d mA \n"),pParsedCSD->VDDWriteCurrentMax));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Erase Block Enabled?: %d  \n"),pParsedCSD->EraseBlockEnable));
    DEBUGMSG(SDBUS_ZONE_REQUEST, (TEXT(" Erase Sector Size: %d blocks \n"),pParsedCSD->EraseSectorSize));

⌨️ 快捷键说明

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