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

📄 sdhcenum.cpp

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

// Host Controller Enumeration and APIs

#include "SDBusDriver.h"

///////////////////////////////////////////////////////////////////////////////
// SDHCDAllocateContext - Allocate an HCD Context
//
// Input: NumberOfSlots - Number of slots
// Output:
//        ppExternalHCContext - caller supplied storage for the host context
// Return: SD_API_STATUS 
// Notes:
//        Host controller drivers must allocate an HC context for the bus driver.
//        When a host controller driver is unloaded it must free this context
//        returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDAllocateContext__X(DWORD              NumberOfSlots,  
                                      PSDCARD_HC_CONTEXT *ppExternalHCContext)
{

    PSDBUS_HC_CONTEXT pHCContext;    // new host context 

    // check parameters, at least one slot must be allocated
    if ((ppExternalHCContext == NULL) || (NumberOfSlots == 0)) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCDAllocateContext: invalid parameter \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    // allocate host context
    DWORD cbHCContext = sizeof(SDBUS_HC_CONTEXT) + 
        (sizeof(SDBUS_HC_SLOT_CONTEXT)) * (NumberOfSlots - 1);
    pHCContext = (PSDBUS_HC_CONTEXT) LocalAlloc(LPTR, cbHCContext);

    if (pHCContext == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDHCDAllocateContext: Failed to allocate memory \n")));
        return SD_API_STATUS_NO_MEMORY;
    }

    pHCContext->dwSig = VALID_HC_CONTEXT_SIG;

    // set the number of slots
    pHCContext->NumberOfSlots = NumberOfSlots;
    // initialize critical section
    InitializeCriticalSection(&pHCContext->HCCritSection);

    // return the context
    *ppExternalHCContext = (PSDCARD_HC_CONTEXT) pHCContext;

    return SD_API_STATUS_SUCCESS;
}


///////////////////////////////////////////////////////////////////////////////
// SDHCDDeleteContext - Delete an HCD context
//
// Input: pExternalHCContext - Host Context to delete
// Output:
// Return: 
// Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDHCDDeleteContext__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{
    PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
    
    if (pHCContext == NULL) {
        DEBUG_CHECK(FALSE, (TEXT("SDHCDDeleteContext - NULL host context!")));
        return;
    }

    DEBUGCHK( pHCContext->dwSig == VALID_HC_CONTEXT_SIG ||
        pHCContext->dwSig == DEREGISTERED_HC_CONTEXT_SIG );

    // delete the critical section
    DeleteCriticalSection(&pHCContext->HCCritSection);

    pHCContext->dwSig = 0xbadbad;

    // free the context
    LocalFree(pHCContext);

}

///////////////////////////////////////////////////////////////////////////////
// CleanUpSlotWorkItems - Clean up slot work items
//
// Input: pExternalHCContext - host context
//
// Output:
// Return:
// Notes:     
///////////////////////////////////////////////////////////////////////////////
VOID CleanUpSlotWorkItems(PSDBUS_HC_CONTEXT pHCContext)
{
    ULONG                            ii;             // loop count
    volatile SDBUS_HC_SLOT_CONTEXT   *pSlotContext;  // slot

    // clean up work item objects
    for (ii = 0; ii < pHCContext->NumberOfSlots; ii++) {

        pSlotContext = SDHCGetSlotContext(pHCContext, ii);

        if (pSlotContext->pWorkItem != NULL) {

            // check to see if the device has been cleaned up yet
            // the work item cleans up the device in another thread
            // context
            while (pSlotContext->hDevice != NULL) {
                // sleep to allow device cleanup to proceed before we
                // kill the work item.
                // only when the work item clears this variable can
                // we cleanup the work item.
                Sleep(DEVICE_CLEANUP_POLLING_INTERVAL);
            }

            delete (CSDWorkItem *)pSlotContext->pWorkItem;
            pSlotContext->pWorkItem = NULL;
        }
    }

}

///////////////////////////////////////////////////////////////////////////////
// SDHCDRegisterHostController - Register a host controller with the bus driver
//
// Input: pExternalHCContext - Allocated Host controller context
//
// Output:
// Return: SD_API_STATUS
// Notes:
//       
//      the caller must allocate a host controller context and 
//      initialize the various parameters
//
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDRegisterHostController__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{

    SD_API_STATUS            status;                   // intermediate status
    CSDBusDriver             *pBusDriver;              // the bus driver
    PSDBUS_HC_SLOT_CONTEXT   pSlotContext;             // the slot context
    CSDWorkItem              *pDispatcher;             // new work item for each slot
    BOOL                     initFailed = FALSE;       // initialization flag
    PSDBUS_HC_CONTEXT        pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;

    status = SD_API_STATUS_UNSUCCESSFUL;

    if (pHCContext == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    if (pHCContext->dwVersion != SDCARD_HC_BUS_INTERFACE_VERSION) {
        DEBUGMSG(SDCARD_ZONE_ERROR, 
            (TEXT("SDBusDriver: Host controller interface version (%x) does not match bus driver (%x)\n"),
            pHCContext->dwVersion, SDCARD_HC_BUS_INTERFACE_VERSION));
        return SD_API_STATUS_INVALID_PARAMETER;
    }

    DEBUGCHK(pHCContext->dwSig == VALID_HC_CONTEXT_SIG);

    // set the system context
    pHCContext->pSystemContext = SDGetSystemContext();

    if (pHCContext->pSystemContext == NULL) {
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDBusDriver: No System Context, bus driver may not have started \n")));
        return SD_API_STATUS_BUS_DRIVER_NOT_READY;
    }

    pBusDriver = GetSDBusDriver(pHCContext);

    // lock the bus
    pBusDriver->AcquireLock();

    // catch any exceptions in case the caller passed a bad structure
    __try {
        DWORD dwSlot;
        
        // Note: Getting a new HC Number is protected by the critical section.
        pHCContext->dwHCNumber = pBusDriver->GetNewHCNumber();
        DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDBusDriver: Host Controller \"%s\" assigned number %d\n"), 
            pHCContext->HostControllerName, pHCContext->dwHCNumber));

        // fill in the rest of the host controller context
        for (dwSlot = 0; dwSlot < pHCContext->NumberOfSlots; dwSlot++) {
            // get the slot context for this slot number and host controller
            pSlotContext = SDHCGetSlotContext(pHCContext, dwSlot);
            pSlotContext->SlotIndex = dwSlot;
            pSlotContext->SlotState = SlotInactive;
            pSlotContext->pHostController = pHCContext;
            SDInitializeQueue(&pSlotContext->RequestQueue);

            // get the capabilities of this slot
            PSDCARD_HC_SLOT_INFO pSlotInfo = pSlotContext;
            status = pHCContext->pSlotOptionHandler(pHCContext, 
                dwSlot, SDHCDGetSlotInfo, pSlotInfo, sizeof(*pSlotInfo));
            if (!SD_API_SUCCESS(status)) {
                DEBUGMSG(SDCARD_ZONE_ERROR, 
                    (TEXT("SDBusDriver: Failed to get slot info for slot %u\n"), dwSlot));
                initFailed = TRUE;
                break;
            }

            // create work item object for each slot
            pDispatcher = new CSDWorkItem(pBusDriver, 
                (PSD_WORK_ITEM_FUNC)CSDBusDriver::SlotStatusChange, 
                pBusDriver->GetDispatchPriority() + 1,
                DEFAULT_MESSAGE_ENTRIES,
                sizeof(SDCARD_HC_SLOT_EVENT));

            if (NULL == pDispatcher) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to allocate event dispatcher \n")));
                initFailed = TRUE;
                break;
            }
            // start the work item
            status = pDispatcher->StartWorkItem();

            if (!SD_API_SUCCESS(status)){
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Dispatcher work item failed \n")));
                initFailed = TRUE;
                break;
            }

            pSlotContext->pWorkItem = (PVOID)pDispatcher;
        }

        if (initFailed) {
            // clean up what we've initialized so far
            CleanUpSlotWorkItems(pHCContext);

            status =  SD_API_STATUS_UNSUCCESSFUL;

        } else {

            // really register the host controller
            status = pBusDriver->RegisterHostController(pHCContext);
        }

        pBusDriver->ReleaseLock();

    } __except (SDProcessException(GetExceptionInformation())) {

        pBusDriver->ReleaseLock();
        // exception caught
        status = SD_API_STATUS_UNSUCCESSFUL;
    }

    if (SD_API_SUCCESS(status)) {
        // call the init handler of the host controller, now that the controller is 
        // registered

        __try {
            // call init handler
            // at this point we can receive any asynch notifications from the host
            // controller driver
            status = pHCContext->pInitHandler(pHCContext);

        } __except (SDProcessException(GetExceptionInformation())) {

            // exception caught
            status = SD_API_STATUS_UNSUCCESSFUL;
        }


        if (!SD_API_SUCCESS(status)) {

            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Host Controller: %s Init Handler failed: 0x%08X \n"), 
                SDHCDGetHCName(pHCContext), status));

            // lock the bus
            pBusDriver->AcquireLock();

            __try {
                // clean up slot work items
                CleanUpSlotWorkItems(pHCContext);
                // deregister the controller
                pBusDriver->DeregisterHostController(pHCContext);

                pBusDriver->ReleaseLock();

            } __except (SDProcessException(GetExceptionInformation())) {

                pBusDriver->ReleaseLock();
                // exception caught
                status = SD_API_STATUS_UNSUCCESSFUL;
            }
        }
    }

    return status;

}


SD_API_STATUS 
DoDeregisterHostController(PSDBUS_HC_CONTEXT pHCContext, BOOL fExternalCall) 
{
    PREFAST_DEBUGCHK(pHCContext);

    SD_API_STATUS status = SD_API_STATUS_SUCCESS;

    __try {
        // call the deinit handler of the host controller
        pHCContext->pDeinitHandler(pHCContext);
        status = SD_API_STATUS_SUCCESS;

    } __except (SDProcessException(GetExceptionInformation())) {
        // exception caught
        status = SD_API_STATUS_UNSUCCESSFUL;
    }

    if (!SD_API_SUCCESS(status)) {
        return status;
    }

    if (SDGetSystemContext() == NULL && fExternalCall) {
        // this should never happen
        DEBUG_CHECK(FALSE, (TEXT("SDBusDriver: No System Context!  \n")));
        return SD_API_STATUS_BUS_DRIVER_NOT_READY;
    }

    pHCContext->dwSig = DEREGISTERED_HC_CONTEXT_SIG;

    CSDBusDriver *pBusDriver = GetSDBusDriver(pHCContext);

    // lock the bus driver
    pBusDriver->AcquireLock();

    __try {
        // clean up slot work items
        CleanUpSlotWorkItems(pHCContext);
        status = pBusDriver->DeregisterHostController(pHCContext);

        pBusDriver->ReleaseLock();

    } __except (SDProcessException(GetExceptionInformation())) {
        pBusDriver->ReleaseLock();
        // exception caught
        status = SD_API_STATUS_UNSUCCESSFUL;
    }

    return status;
}


///////////////////////////////////////////////////////////////////////////////
// SDHCDDeregisterHostController - Deregister a host controller 
//
// Input: pExternalHCContext - Host controller context that was previously registered
//        
// Output:
// Return: SD_API_STATUS 
// Notes:       
//      A host controller must call this api before deleting the HC context
//      
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDHCDDeregisterHostController__X(PSDCARD_HC_CONTEXT pExternalHCContext)
{
    PSDBUS_HC_CONTEXT pHCContext = (PSDBUS_HC_CONTEXT) pExternalHCContext;
    
    if (pHCContext == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Passed invalid SDCARD_HC_CONTEXT \n")));
        return SD_API_STATUS_INVALID_PARAMETER;

⌨️ 快捷键说明

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