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

📄 sdhcenum.cpp

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

// Host Controller Enumeration and APIs

#include "SDBusDriver.h"


SD_API_STATUS DefaultChangeCardPower(PSDCARD_HC_CONTEXT pHCContext, 
                                     DWORD              Slot, 
                                     INT                CurrentDelta);


///////////////////////////////////////////////////////////////////////////////
// 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 bus driver version via the host controller name
    // such that the host can detect the version of the bus driver
    SDHCDSetHCName(pHCContext, BUS_VER_FOR_HOST);

	// set the default power control handler function
    SDHCDSetChangePowerHandler(pHCContext, DefaultChangeCardPower);

    // 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;

			
			// ??Read Setting From Registry in future??
            //by default enable power control at the slot
            SDHCDSetSlotEnablePowerControl(pHCContext, dwSlot, TRUE);

            //reset current draw per slot
            SDHCDSetSlotPower(pHCContext, dwSlot, 0);
        }

        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

⌨️ 快捷键说明

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