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

📄 sdhcenum.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    return DoDeregisterHostController(pHCContext, TRUE);
}

///////////////////////////////////////////////////////////////////////////////
// SDHCDIndicateSlotStateChange - indicate a change in the SD Slot 
//
// Input: pExternalHCContext - Host controller context that was previously registered
//        SlotNumber - Slot Number
//        Event      - new event
// Output:
// Return: SD_API_STATUS 
// Notes:       
//      A host controller driver calls this api when the slot changes state (i.e.
//      device insertion/deletion).
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDIndicateSlotStateChange__X(PSDCARD_HC_CONTEXT pExternalHCContext, 
                                     DWORD              SlotNumber,
                                     SD_SLOT_EVENT      Event) 
{
    PSDBUS_HC_CONTEXT   pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
    PSDBUS_HC_SLOT_CONTEXT  pSlotContext;  // the slot context
    CSDBusDriver             *pBusDriver;   // the bus driver

    if (pHCContext == NULL) {
        RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
        DEBUGCHK(FALSE);
        return;
    }

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    if (SlotNumber > pHCContext->NumberOfSlots) {
        DEBUG_CHECK(FALSE, (TEXT("SDHCDIndicateSlotStateChange, Slot number exceeds number of slots! \n")));
        return;
    }
    // get the slot context for this slot number and host controller
    pSlotContext = SDHCGetSlotContext(pHCContext, SlotNumber);

    if (DeviceEjected == Event) {
        // immediately mark the slot for ejection
        pSlotContext->SlotState = SlotDeviceEjected;

        if (NULL == pSlotContext->hDevice) {
            // This can happen on very fast suspend-resume-suspend sequence because
            // the DeviceInserted message is still in the WorkItem queue.
            DEBUGMSG(SDCARD_ZONE_WARN, (TEXT("Host Controller:%s indicated device eject on an empty slot \n"),
                SDHCDGetHCName(pHCContext)));
            return;
        }

    } else if (DeviceInterrupting == Event) {

        if (NULL == pSlotContext->hDevice) {
            DEBUG_CHECK(FALSE,(TEXT("Host Controller:%s indicated an interrupt on an empty slot \n"),
                SDHCDGetHCName(pHCContext)));
            return;
        }
    }

    // get the bus driver object
    pBusDriver = GetSDBusDriver(pHCContext);

    PREFAST_DEBUGCHK(pBusDriver != NULL);

    switch (Event) {
        case DeviceInserted:
        case DeviceEjected:
        case DeviceInterrupting:
            DEBUGCHK(pSlotContext->pWorkItem != NULL);
            // post this message to the work item for each slot
            pBusDriver->PostSlotEvent(Event, pSlotContext, (CSDWorkItem *)pSlotContext->pWorkItem);   
            break;
        case BusRequestComplete:
            // wake up bus request complete dispatcher
            pBusDriver->WakeUpBusRequestCompleteDispatcher();
            break;
        default:
            DEBUGCHK(FALSE);
    }


}


///////////////////////////////////////////////////////////////////////////////
// SDHCDIndicateBusRequestComplete - indicate to the bus driver that
//                                   the request is complete
// Input:   pExternalHCContext - host controller context
//          pRequest   - the request to indicate
//          Status     - the ending status of the request
// Output:
// Return:  
// Notes:       
//
//      
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDIndicateBusRequestComplete__X(PSDCARD_HC_CONTEXT pExternalHCContext,
                                        HBUS_REQUEST       hRequest,
                                        SD_API_STATUS      Status)
{
    PSDBUS_HC_SLOT_CONTEXT  pSlot;          // the slot
    PSDBUS_BUS_REQUEST      pNextRequest;   // the next request    
    SD_API_STATUS           submitStatus;   // intermediate status
    CSDBusDriver           *pBusDriver;
    PSDBUS_BUS_REQUEST      pRequest = (PSDBUS_BUS_REQUEST) hRequest;
    PSDBUS_HC_CONTEXT       pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    // get the slot
    PREFAST_DEBUGCHK(pRequest);
    DEBUGCHK(pRequest->dwSig == VALID_BUS_REQUEST_SIG);
    PSDCARD_DEVICE_CONTEXT pDevice = SDDCGetClientDeviceFromHandle(pRequest->hDevice);
    PREFAST_DEBUGCHK(pDevice);
    pSlot = pDevice->pSlot;
    PREFAST_DEBUGCHK(pSlot);
    pBusDriver = (CSDBusDriver *) pDevice->pSystemContext;

    // acquire the HC lock
    SDHCDAcquireHCLock(pHCContext);

    // mark that the request is non-cancelable
    SD_REQUEST_MARK_NON_CANCELABLE(pRequest);

    if (!SD_API_SUCCESS(Status)) {
        // check for retry
        if ((SD_API_STATUS_RESPONSE_TIMEOUT == Status) || 
            (SD_API_STATUS_DATA_TIMEOUT == Status) ||
            (SD_API_STATUS_CRC_ERROR == Status)) {

            // issue a retry only if the client doesn't handle them
            if (!(CLIENT_HANDLES_RETRY(pDevice))) {
                // only retry if the slot is still ready
                // a device ejection may have caused the timeout error
                if (SD_API_SUCCESS(CheckSlotReady(pSlot))) {      
                    // check retry count
                    if (SDRequestGetRetryCount(pRequest) != 0) {
                        DEBUGMSG(SDCARD_ZONE_WARN, 
                            (TEXT("SDBusDriver: Retrying request 0x%08X, Current retry count: %d \n"),
                            pRequest,SDRequestGetRetryCount(pRequest)));
                        // decrement retry count
                        SDDecrementRetryCount(pRequest);
                        pRequest->HCParam = 0;
                        // release the lock 
                        SDHCDReleaseHCLock(pHCContext);

                        // resubmit
                        if (SD_API_SUCCESS(pBusDriver->SubmitToHC(pHCContext, 
                                pSlot->SlotIndex, pRequest))) {
                            return;   
                        }

                        // acquire the HC lock
                        SDHCDAcquireHCLock(pHCContext);

                        // re-submission failed, let it fall through to completion
                        DEBUGMSG(SDCARD_ZONE_WARN, 
                            (TEXT("SDBusDriver: Could not start retry attempt for request 0x%08X\n"),
                            pRequest));
                    }
                }
            }
        }
    }

    // mark that the request is completing
    SD_REQUEST_MARK_COMPLETING(pRequest);

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

    // dequeue the current request 
    if ((SDDequeueBusRequest(&pSlot->RequestQueue)) != pRequest) {
        // the request we are completing should be the first request in the queue
        DEBUG_CHECK(FALSE,(TEXT("SDHCDCompleteRequest- the HC is completing a request that is not the current request! \n")));
        // release the lock
        SDHCDReleaseHCLock(pHCContext);
        return;

    } 
    // queue the request to the bus driver's completion queue
    pBusDriver->QueueCompletedRequest(pRequest); 

    // start up the next request(s) in the queue
    while (1) {
        // get the next request
        pNextRequest = (PSDBUS_BUS_REQUEST) SDGetCurrentRequest(&pSlot->RequestQueue);

        // release the lock 
        SDHCDReleaseHCLock(pHCContext);

        if (NULL != pNextRequest) {
            // check the slot, we might have gotten a removal
            submitStatus = CheckSlotReady(pSlot);

            if (SD_API_SUCCESS(submitStatus)) {
                // submit the next request
                submitStatus = pBusDriver->SubmitToHC(pHCContext, pSlot->SlotIndex, pNextRequest); 

            }

            // DO NOT USE pRequest after this line since it could have 
            // been freed in the above call. (Especially if the above call
            // caused an AutoCmd12 to be issued to the standard host
            // controller, since it is completed immediately.)

            if (!SD_API_SUCCESS(submitStatus)) {       
                // set the status
                pNextRequest->Status = submitStatus;
                // re-acquire the HC lock
                SDHCDAcquireHCLock(pHCContext);
                // remove this one from the queue because it failed
                SDDequeueBusRequest(&pSlot->RequestQueue);
                // queue the request for completion
                pBusDriver->QueueCompletedRequest(pNextRequest); 
                // we stay in this loop
            } else {
                // break out of the loop, we've already submitted one
                break;
            }
        } else {
            // nothing to start up
            break;
        }   
    }   

    // indicate a slot state change
    // this will signal the dispatcher to examine the slot and 
    // complete the request from the completed request queue
    SDHCDIndicateSlotStateChange__X(pHCContext, 
        pSlot->SlotIndex,
        BusRequestComplete);   

}

///////////////////////////////////////////////////////////////////////////////
// SDHCDGetAndLockCurrentRequest - get the current request in the host controller
//                                 slot and lock it to keep it from being cancelable
// Input:   pExternalHCContext - host controller context   
//          SlotIndex  - the slot number 
// Output:
// Return: current bus request       
// Notes:
//          This function retrieves the current request and marks the
//          request as NON-cancelable.  To return the request back to the
//          cancelable state the caller must call SDHCDUnlockRequest()     
//          This function returns the current request which can be NULL if 
//          the request was previously marked cancelable and the host controller's
//          cancelIo Handler completed the request 
///////////////////////////////////////////////////////////////////////////////
HBUS_REQUEST SDHCDGetAndLockCurrentRequest__X(PSDCARD_HC_CONTEXT pExternalHCContext, DWORD SlotIndex)
{
    PSDBUS_BUS_REQUEST     pRequest;   // the current request
    PSDBUS_HC_CONTEXT      pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;

    if (pHCContext == NULL) {
        RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
        DEBUGCHK(FALSE);
        return NULL;
    }

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    SDHCDAcquireHCLock(pHCContext);

    // get the current request
    PSDBUS_HC_SLOT_CONTEXT pSlot = SDHCGetSlotContext(pHCContext, SlotIndex);
    pRequest = (PSDBUS_BUS_REQUEST) SDGetCurrentRequest(&pSlot->RequestQueue);

    if (NULL == pRequest) {
        SDHCDReleaseHCLock(pHCContext);
        return NULL; 
    }

    if (IS_REQUEST_COMPLETING(pRequest)) {
        DEBUGCHK(FALSE);
        // the current request is completing in the dispatcher, this shouldn't happen
        SDHCDReleaseHCLock(pHCContext);
        return NULL; 
    }

    // mark the request as non-cancelable
    SD_REQUEST_MARK_NON_CANCELABLE(pRequest);

    SDHCDReleaseHCLock(pHCContext);

    return (HBUS_REQUEST) pRequest;
}

///////////////////////////////////////////////////////////////////////////////
// SDHCDUnlockRequest - Unlock a request that was previous locked
//                             
// Input:   pHCContext - host controller context   
//          pRequest  - the request to lock
// Output:
// Return:      
// Notes:   This function unlocks the request that was returned from the
//          function SDHCDGetAndLockCurrentRequest()
//          
//          This request can now be cancelled from any thread context
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDUnlockRequest__X(PSDCARD_HC_CONTEXT  pExternalHCContext,
                           HBUS_REQUEST        hRequest) 
{
    PSDBUS_HC_CONTEXT  pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
    PSDBUS_BUS_REQUEST pRequest = (PSDBUS_BUS_REQUEST) hRequest;

    if (pHCContext == NULL) {
        RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
        DEBUGCHK(FALSE);
        return;
    }

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    if (pRequest == NULL) {
        RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SD_BUS_REQUEST \n")));
        DEBUGCHK(FALSE);
        return;
    }

    SDHCDAcquireHCLock(pHCContext);
    // mark the request as cancelable
    SD_REQUEST_MARK_CANCELABLE(pRequest);
    SDHCDReleaseHCLock(pHCContext);
}

///////////////////////////////////////////////////////////////////////////////
// SDHCDPowerUpDown - Indicate a power up/down event
//                             
// Input:   pHCContext - host controller context   
//          PowerUp    - set to TRUE if powering up
//          SlotKeepPower - set to TRUE if the slot maintains power to the
//                          slot during power down
// Output:
// Return:       
// Notes:   This function notifies the bus driver of a power up/down event.
//          The host controller driver can indicate to the bus driver that power
//          can be maintained for the slot.  If power is removed, the bus driver
//          will unload the device driver on the next power up event.
//          This function can only be called from the host controller's XXX_PowerOn
//          and XXX_PowerOff function.
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDPowerUpDown__X(PSDCARD_HC_CONTEXT  pExternalHCContext, 
                         BOOL                PowerUp, 
                         BOOL                SlotKeepPower,
                         DWORD               SlotIndex)
{
    PSDBUS_HC_CONTEXT  pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
    
    if (pHCContext == NULL) {
        RETAILMSG(1, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
        DEBUGCHK(FALSE);
        return;
    }

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    DEBUGCHK(SlotIndex < pHCContext->NumberOfSlots);

    CSDBusDriver *pBusDriver = GetSDBusDriver(pHCContext);
    PSDBUS_HC_SLOT_CONTEXT pSlot = SDHCGetSlotContext(pHCContext, SlotIndex);

    if (PowerUp){
        pBusDriver->PowerUp(pSlot);        
    } else {
        pBusDriver->PowerDown(pSlot, SlotKeepPower);
    }
}

// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE

⌨️ 快捷键说明

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