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

📄 sdclient.cpp

📁 2443 wince5.0 bsp, source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
SD_API_STATUS CSDBusDriver::GetCustomRegPath(PSDCARD_DEVICE_CONTEXT pDevice,
                                             LPTSTR                 pPath,
                                             DWORD                  cchPath,
                                             BOOL                   BasePath) 
{
    SD_PARSED_REGISTER_CID  ParsedRegisters;                // parsed registers
    SD_API_STATUS           status = SD_API_STATUS_SUCCESS; // intermediate status

    PREFAST_DEBUGCHK(pDevice);
    DEBUGCHK(pPath);

    // for Memory or MMC get the CID
    if ( (Device_SD_Memory == pDevice->DeviceType) ||
         (Device_MMC == pDevice->DeviceType) ) {
        // get the parsed CID registers
        status = SDCardInfoQuery__X((SD_DEVICE_HANDLE)pDevice,
            SD_INFO_REGISTER_CID,
            &ParsedRegisters,
            sizeof(ParsedRegisters));

        if (SD_API_SUCCESS(status)) {
            // build up the string
            HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\CID-%d-%c%c-%c%c%c%c%c"),
                SDCARD_CUSTOM_DEVICE_REG_PATH,
                ParsedRegisters.ManufacturerID,
                (TCHAR)ParsedRegisters.OEMApplicationID[0],
                (TCHAR)ParsedRegisters.OEMApplicationID[1],
                (TCHAR)ParsedRegisters.ProductName[0],
                (TCHAR)ParsedRegisters.ProductName[1],
                (TCHAR)ParsedRegisters.ProductName[2],
                (TCHAR)ParsedRegisters.ProductName[3],
                (TCHAR)ParsedRegisters.ProductName[4]);
            DEBUGCHK(SUCCEEDED(hr));

            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom MMC/SD path: %s \n"),pPath));
        }
    }
    else if (Device_SD_IO == pDevice->DeviceType) {
        if (BasePath) {
            // build the custom registry path for the card as a whole
            HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X"),
                SDCARD_CUSTOM_DEVICE_REG_PATH,
                pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
                pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardID);  
            DEBUGCHK(SUCCEEDED(hr));
        } else {
            // build the custom registry path for the SDIO card function
            HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X-FUNC-%d"),
                SDCARD_CUSTOM_DEVICE_REG_PATH,
                pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
                pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardID,
                pDevice->SDCardInfo.SDIOInformation.Function);
            DEBUGCHK(SUCCEEDED(hr));
        }

        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom SDIO path: %s \n"),pPath));
    }
    else {
        DEBUG_ASSERT(FALSE);
        status = SD_API_STATUS_INVALID_PARAMETER;
    }
            
    return status;
}



///////////////////////////////////////////////////////////////////////////////
//  SDLoadDevice - load the associated device driver
//  Input:  pDevice - the device instance requiring it's device driver to be loaded 
//  Output: 
//  Notes:  
//      returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::SDLoadDevice(PSDCARD_DEVICE_CONTEXT pDevice)
{
    TCHAR                   loadPath[MAX_KEY_PATH_LENGTH];  // string buffer
    TCHAR                   keyString[MAX_KEY_NAME_LENGTH]; // key string for value string
    BOOLEAN                 deviceFound = FALSE;            // device found flag
    SD_API_STATUS           status;                         // intermediate status
    HKEY                    hKey;                           // the key

    PREFAST_DEBUGCHK(pDevice);

    // clear out the device specific context, the device is 
    // now going to be loaded
    pDevice->pDeviceContext = NULL;
    
    // get the custom path for the card or function
    status = GetCustomRegPath(pDevice, loadPath, dim(loadPath), FALSE);

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

    // attempt to open the path
    if ( (RegOpenKeyEx(HKEY_LOCAL_MACHINE, loadPath, 0, KEY_ALL_ACCESS,
            &hKey) == ERROR_SUCCESS) ) {
        RegCloseKey(hKey);
        deviceFound = TRUE;
    } else {
        // no CUSTOM driver path was found so set the default path
        if (Device_SD_Memory == pDevice->DeviceType) {
            // set the default load path for SD Memory Devices
            wcscpy(loadPath, SDCARD_SDMEMORY_CLASS_REG_PATH);
            deviceFound = TRUE;
        } else if (Device_MMC == pDevice->DeviceType) {
            // set the default load path for MMC devices
            wcscpy(loadPath, SDCARD_MMC_CLASS_REG_PATH);
            deviceFound = TRUE;
        } else if (Device_SD_IO == pDevice->DeviceType) {
            if (SD_IO_NON_STANDARD_DEVICE_CODE == pDevice->SDCardInfo.SDIOInformation.DeviceCode) {
                // can't support this device, it has the non-standard device code and the registry does not
                // contain the settings for the driver
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SDIO Device class is of type UNKNOWN, no custom driver found at %s\n"), loadPath));              
            } else {
                // put back in the default device code reg path
                HRESULT hr = StringCchPrintf(loadPath, dim(loadPath), 
                    TEXT("%s\\%d"),SDCARD_SDIO_CLASS_REG_PATH,
                    pDevice->SDCardInfo.SDIOInformation.DeviceCode);
                DEBUGCHK(SUCCEEDED(hr));
                deviceFound = TRUE;
            }
        }
    }


    if (deviceFound) {
        CReg regLoadPath(HKEY_LOCAL_MACHINE, loadPath);
        if ( !regLoadPath.IsOK() || 
             !regLoadPath.ValueSZ(DEVLOAD_DLLNAME_VALNAME, keyString, dim(keyString) * sizeof(*keyString)) ) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get DLL name in path : %s \n"), loadPath));
                return SD_API_STATUS_NO_SUCH_DEVICE;
            }

            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Loading Driver : %s \n"),keyString));

            // load the DLL
            // we load it so we can save the module handle and pass it to the client driver
            // so it can register its debug zones
            pDevice->hDriver = LoadDriver(keyString);

            if (pDevice->hDriver == NULL) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to load driver DLL : %s \n"), keyString));
                return SD_API_STATUS_NO_SUCH_DEVICE;
            }

            // mark the slot as ready
            PSDBUS_HC_SLOT_CONTEXT pSlot = pDevice->pSlot;
            pSlot->SlotState = Ready;
            
            PSDBUS_HC_CONTEXT pHostController = pSlot->pHostController;

            DEBUGCHK(pDevice->pDeviceFolder == NULL);
            status = m_sdBusEnum.ActivateChild(loadPath, 
                pHostController->dwHCNumber,
                pSlot->SlotIndex,
                pDevice->SDCardInfo.SDIOInformation.Function,
                pDevice, &pDevice->pDeviceFolder);

            if ( (pDevice->DeviceType == Device_SD_IO) &&
                 pDevice->SDCardInfo.SDIOInformation.fWUS ) {
                // This SDIO function supports wake up. Tell the host to 
                // allow waking on SDIO interrupts if the client has a 
                // registry entry enabling this. It is okay if the host fails 
                // this call.
                BOOL fWakeOnSDIOInterrupts = 
                    regLoadPath.ValueDW(SDCARD_WAKE_ON_SDIO_INTERRUPTS_VALNAME);
                if (fWakeOnSDIOInterrupts) {
                    SD_API_STATUS statusHandler = 
                        pHostController->pSlotOptionHandler(pHostController,
                            pSlot->SlotIndex, SDHCDWakeOnSDIOInterrupts,
                            &fWakeOnSDIOInterrupts, sizeof(fWakeOnSDIOInterrupts));

                    if (!SD_API_SUCCESS(statusHandler)) {
                        DEBUGMSG(SDCARD_ZONE_WARN, (_T("SD: Could not enable waking on SDIO interrupts\r\n")));
                    }
                }
            }

            // free the library, the previous ActivateDevice call will keep the driver loaded
            FreeLibrary(pDevice->hDriver);
            pDevice->hDriver = NULL;

            if (!SD_API_SUCCESS(status)) {
                pDevice->pSlot->SlotState = SlotInitFailed;
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to load driver with path: %s \n"), loadPath));
                return status;
            }

            return SD_API_STATUS_SUCCESS;    
    }

        return SD_API_STATUS_NO_SUCH_DEVICE;

}


///////////////////////////////////////////////////////////////////////////////
//  SDUnloadDevice - unload the client device
//  Input:  pDevice - the device instance requiring it's device driver to be unloaded
//  Output: 
//  Notes:  
//      returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
VOID CSDBusDriver::SDUnloadDevice(PSDCARD_DEVICE_CONTEXT pDevice)
{
    CSDBusDriver *pBusDriver = (CSDBusDriver *)pDevice->pSystemContext; // the bus driver
    LONG         refcount;         // reference count
    ULONG        maxWait;          // max wait

    PREFAST_DEBUGCHK(pBusDriver != NULL);

    // notify the client
    NotifyClient(pDevice, 
        SDCardEjected);

    maxWait = DEFAULT_MAX_WAIT_COUNT;
    // poll until all pending requests are gone
    // since the slot has been marked for device removal
    // all incomming requests and request in the slot queue will get rejected 
    // so we do not need to flush out the request queue but rather wait until request processing
    // flushes them out normally
    while (((refcount = 
        SDDCGetRefCount(((volatile SDCARD_DEVICE_CONTEXT *)pDevice))) != 0) &&
        maxWait) {
            DEBUGMSG(SDBUS_ZONE_DEVICE, 
                (TEXT("SDUnloadDevice: Device: %s has %d refcount, waitcnt:%d waiting....\n"),
                SDDCGetClientName(pDevice), refcount, maxWait));
            Sleep(DEFAULT_REFCOUNT_WAIT);
            maxWait--;
        }

        if (0 == maxWait) {
            DEBUG_CHECK(FALSE, 
                (TEXT("SDUnloadDevice: Device %s, has  %d outstanding requests that cannot be completed! \n"),
                SDDCGetClientName(pDevice), refcount));
        }

        // all requests have been flushed, deactivate the device
        if (pDevice->pDeviceFolder != NULL) {
            DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDUnloadDevice: Deactivating Device: %s \n"),SDDCGetClientName(pDevice)));
            m_sdBusEnum.DeactivateChild(pDevice->pDeviceFolder);
        }

        pBusDriver->DeleteClientDevice(pDevice);

        DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDUnloadDevice: Client Device deleted \n")));
}


///////////////////////////////////////////////////////////////////////////////
//  SDRegisterClient__X - register a client device
//  Input:  hDevice         - device handle
//          pDeviceContext  - device specific context allocated by driver
//          pInfo           - registration information
//          
//  Output: 
//  Notes:  
//      returns SD_API_STATUS_SUCCESS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDRegisterClient__X(SD_DEVICE_HANDLE                 hDevice, 
                                  PVOID                            pDeviceContext, 
                                  PSDCARD_CLIENT_REGISTRATION_INFO pInfo)
{
    SD_API_STATUS           status = SD_API_STATUS_INVALID_PARAMETER;  // intermediate status
    CSDBusDriver            *pBusDriver;                               // the bus driver

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

    if (pInfo == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDRegisterClient : Reg info is NULL!\n")));
    }
    else {
        pBusDriver = (CSDBusDriver *)pDevice->pSystemContext;
        DEBUGCHK(pBusDriver != NULL);

        if (pBusDriver != NULL) {
            status = pBusDriver->RegisterClientDevice(pDevice,
                pDeviceContext, pInfo);
            if (status != SD_API_STATUS_SUCCESS) {
                DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDRegisterClient: Failed to register client 0x%08X \n"),status));
            }
        }
    }

    return status;
}

///////////////////////////////////////////////////////////////////////////////
//  SDAcquireDeviceLock - acquire the synchronization lock for the device
//  Input:  hDevice - device handle
//                
//  Output: 
//  Notes:  
//          Caller must call SDReleaseDeviceLock to release the lock
///////////////////////////////////////////////////////////////////////////////
VOID SDAcquireDeviceLock(SD_DEVICE_HANDLE hDevice) 
{
    EnterCriticalSection(&(((PSDCARD_DEVICE_CONTEXT)hDevice)->DeviceCritSection));
}

///////////////////////////////////////////////////////////////////////////////
//  SDReleaseDeviceLock - release the synchronization lock for the device
//  Input:  hDevice - device handle
//                  
//  Output: 
//  Notes:  
//          Caller must have previously called SDAcquireDeviceLock
///////////////////////////////////////////////////////////////////////////////
VOID SDReleaseDeviceLock(SD_DEVICE_HANDLE hDevice)
{
    LeaveCriticalSection(&(((PSDCARD_DEVICE_CONTEXT)hDevice)->DeviceCritSection));
}

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

⌨️ 快捷键说明

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