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

📄 ufnmdd.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// Open a pipe.
DWORD
WINAPI
UfnMdd_OpenPipe(
    UFN_HANDLE   hDevice,
    DWORD        dwEndpointAddress,
    PUFN_PIPE    phPipe
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCPipe pPipe = NULL;
    BOOL fTookCS = FALSE;
    
    VERIFY_PCONTEXT();
    EnterCriticalSection(&pContext->csMddAccess);
    fTookCS = TRUE;
    
    VERIFY_RUNNING();

    if (phPipe == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Invalid parameter\r\n"), pszFname));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    if (!pContext->fRegistered) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Device not registered\r\n"), pszFname));
        dwRet = ERROR_INVALID_STATE;
        goto EXIT;
    }

    if (dwEndpointAddress > 0xFF) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Invalid endpoint address = 0x%x\r\n"), 
            pszFname, dwEndpointAddress));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    // Search for the target endpoint address. The endpoint address is
    // stored in the endpoint descriptor.
    pPipe = FindPipe(pContext, dwEndpointAddress);
    if (pPipe == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Invalid endpoint address = 0x%x\r\n"),
            pszFname, dwEndpointAddress));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    // Open the endpoint
    dwRet = pPipe->Open(pContext->Speed, NULL);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Error opening endpoint 0x%x\r\n"),
            pszFname, pPipe->GetEndpointAddress()));
        goto EXIT;
    }
    
    DEBUGMSG(ZONE_INIT || ZONE_PIPE, (_T("%s Opened endpoint 0x%x\r\n"),
        pszFname, pPipe->GetEndpointAddress()));

    __try {
        *phPipe = pPipe;
        dwRet = ERROR_SUCCESS;
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Exception!\r\n"), pszFname));
        dwRet = ERROR_INVALID_PARAMETER;
    }
    
EXIT:
    FUNCTION_LEAVE_MSG();
    if (fTookCS) {
        LeaveCriticalSection(&pContext->csMddAccess);
    }

    return dwRet;
}


// Close a pipe.
DWORD
WINAPI
UfnMdd_ClosePipe(
    UFN_HANDLE hDevice,
    UFN_PIPE   hPipe
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet = ERROR_INVALID_PARAMETER;;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCPipe pPipe = (PCPipe) hPipe;
    BOOL fTookCS = FALSE;
    
    VERIFY_PCONTEXT();
    VERIFY_RUNNING();

    dwRet = CPipe::ValidatePipeHandle(pPipe);
    if (dwRet != ERROR_SUCCESS) { 
        goto EXIT; 
    }

    if (pPipe->GetPhysicalEndpoint() == 0) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Cannot close endpoint 0 pipe (0x%08x)\r\n"), 
            pszFname, pPipe));
        dwRet = ERROR_INVALID_HANDLE;
        goto EXIT;
    }

    EnterCriticalSection(&pContext->csMddAccess);
    fTookCS = TRUE;
    
    dwRet = pPipe->Close();

EXIT:
    FUNCTION_LEAVE_MSG();
    if (fTookCS) {
        LeaveCriticalSection(&pContext->csMddAccess);
    }
    
    return dwRet;
}


DWORD
WINAPI
UfnMdd_GetTransferStatus(
    UFN_HANDLE   hDevice,
    UFN_TRANSFER hTransfer,
    PDWORD       pcbTransferred,
    PDWORD       pdwUsbError
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCUfnMddTransfer pTransfer = (PCUfnMddTransfer) hTransfer;

    VERIFY_PCONTEXT();

    if ( (pcbTransferred == NULL) || (pdwUsbError == NULL) ) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Bad parameter\r\n"), pszFname));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    dwRet = CUfnMddTransfer::ReferenceTransferHandle(pTransfer);
    if (dwRet == ERROR_SUCCESS) {
        dwRet = CPipe::GetTransferStatus(pTransfer, pcbTransferred, pdwUsbError);
        pTransfer->Release();
    }

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


DWORD
WINAPI
UfnMdd_AbortTransfer(
    UFN_HANDLE   hDevice,
    UFN_TRANSFER hTransfer
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCUfnMddTransfer pTransfer = (PCUfnMddTransfer) hTransfer;

    VERIFY_PCONTEXT();
    VERIFY_RUNNING();

    dwRet = CUfnMddTransfer::ReferenceTransferHandle(pTransfer);
    if (dwRet == ERROR_SUCCESS) {     
        PCPipe pPipe = pTransfer->GetPipe();
        dwRet = pPipe->AbortTransfer(pTransfer);
        pTransfer->Release();
    }

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


DWORD
WINAPI
UfnMdd_CloseTransfer(
    UFN_HANDLE   hDevice,
    UFN_TRANSFER hTransfer
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCUfnMddTransfer pTransfer = (PCUfnMddTransfer) hTransfer;

    VERIFY_PCONTEXT();

    dwRet = CUfnMddTransfer::ReferenceTransferHandle(pTransfer);
    if (dwRet == ERROR_SUCCESS) {
        PCPipe pPipe = pTransfer->GetPipe();
        dwRet = pPipe->CloseTransfer(pTransfer);
        pTransfer->Release();
    }

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


DWORD
WINAPI
UfnMdd_IssueTransfer(
    UFN_HANDLE                  hDevice,
    UFN_PIPE                    hPipe,
    LPTRANSFER_NOTIFY_ROUTINE   lpNotifyRoutine,
    PVOID                       pvNotifyContext,
    DWORD                       dwFlags,
    DWORD                       cbBuffer, 
    PVOID                       pvBuffer,
    DWORD                       dwBufferPhysicalAddress,
    PVOID                       pvPddTransferInfo,
    PUFN_TRANSFER               phTransfer
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCPipe pPipe = (PCPipe) hPipe;
    
    VERIFY_PCONTEXT();
    VERIFY_RUNNING();

    dwRet = CPipe::ValidatePipeHandle(pPipe);
    if (dwRet != ERROR_SUCCESS) { 
        goto EXIT; 
    }

    if ( (cbBuffer && (pvBuffer == NULL)) || (phTransfer == NULL) || 
          ( (dwFlags != USB_IN_TRANSFER) && (dwFlags != USB_OUT_TRANSFER) ) ) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Bad parameter\r\n"), pszFname));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }

    PCUfnMddTransfer *ppTransfer;
    ppTransfer = (PCUfnMddTransfer*) phTransfer;
    dwRet = pPipe->IssueTransfer(lpNotifyRoutine, 
        pvNotifyContext, dwFlags, cbBuffer, pvBuffer, 
        dwBufferPhysicalAddress, ppTransfer, pvPddTransferInfo);

#if 0
    // Verify that the transfer was assigned properly
    __try {
        if (dwRet == ERROR_SUCCESS) {
            DEBUGCHK(*phTransfer != NULL);
        }
        else {
            DEBUGCHK(*phTransfer == NULL);
        }
    }
    __except(EXCEPTION_EXECUTE_HANDLER) {
        DEBUGCHK(dwRet != ERROR_SUCCESS);
    }
#endif

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Stall a pipe.
DWORD
WINAPI
UfnMdd_StallPipe(
    UFN_HANDLE hDevice,
    UFN_PIPE   hPipe
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCPipe pPipe = (PCPipe) hPipe;
    
    VERIFY_PCONTEXT();
    VERIFY_RUNNING();
    
    dwRet = CPipe::ValidatePipeHandle(pPipe);
    if (dwRet != ERROR_SUCCESS) { 
        goto EXIT; 
    }
    dwRet = pPipe->Stall();

EXIT:
    FUNCTION_LEAVE_MSG();
    
    return dwRet;
}


// Clear a pipe stall.
DWORD
WINAPI
UfnMdd_ClearPipeStall(
    UFN_HANDLE hDevice,
    UFN_PIPE   hPipe
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCPipe pPipe = (PCPipe) hPipe;
    
    VERIFY_PCONTEXT();
    VERIFY_RUNNING();

    dwRet = CPipe::ValidatePipeHandle(pPipe);
    if (dwRet != ERROR_SUCCESS) { 
        goto EXIT; 
    }
    
    dwRet = pPipe->ClearStall();

EXIT:
    FUNCTION_LEAVE_MSG();
    
    return dwRet;
}


DWORD
WINAPI
UfnMdd_InitiateRemoteWakeup(
    UFN_HANDLE hDevice
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;

    VERIFY_PCONTEXT();
    VERIFY_RUNNING();

    if (!pContext->fRemoteWakeupEnabled) {
        DEBUGMSG(ZONE_ERROR, (_T("%s Remote wakeup has not been enabled by the host\r\n"),
            pszFname));
        dwRet = ERROR_GEN_FAILURE;
        goto EXIT;
    }

    dwRet = pContext->PddInfo.pfnInitiateRemoteWakeup(pContext->PddInfo.pvPddContext);
    
EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Send the control status handshake. Called after sending or receiving the 
// entire data transfer for a control transfer.
DWORD
WINAPI
UfnMdd_SendControlStatusHandshake(
    UFN_HANDLE hDevice
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PUFN_MDD_CONTEXT pContext = (PUFN_MDD_CONTEXT) hDevice;
    PCPipe pPipe;
    
    VERIFY_PCONTEXT();
    VERIFY_RUNNING();

    ValidateContext(pContext);
    DEBUGCHK(pContext->pPipes);
    
    pPipe = &pContext->pPipes[0];
    dwRet = pPipe->SendControlStatusHandshake();

EXIT:
    FUNCTION_LEAVE_MSG();
    
    return dwRet;
}


// Free all the context resources.
static
VOID
FreeContext(
    PUFN_MDD_CONTEXT pContext
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();
    
    PREFAST_DEBUGCHK(pContext);

    // Deinitialize the client.
    if (pContext->pUfnBus) {
        delete pContext->pUfnBus;
    }

    if (pContext->fPddInitialized) {
        // Deinitialize the PDD
        pContext->PddInfo.pfnDeinit(pContext->PddInfo.pvPddContext);
    }
    
    if (pContext->hKey) RegCloseKey(pContext->hKey);

    DEBUGCHK(pContext->hEnumTransfer == NULL);

    if (pContext->hevReadyForNotifications) CloseHandle(pContext->hevReadyForNotifications);

    DeleteCriticalSection(&pContext->csMddAccess);
    DeleteCriticalSection(&pContext->csBusIoctlAccess);
    
    pContext->dwSig = GARBAGE_DWORD;
    LocalFree(pContext);

    FUNCTION_LEAVE_MSG();
}


static
BOOL
IsPddInterfaceInfoValid(
    PUFN_PDD_INTERFACE_INFO pPddInterfaceInfo
    )
{
    BOOL fRet = TRUE;
    
    if ( !pPddInterfaceInfo ||
         pPddInterfaceInfo->dwVersion != UFN_PDD_INTERFACE_VERSION ||
         pPddInterfaceInfo->dwEndpointCount == 0 ||
         (pPddInterfaceInfo->dwCapabilities & UFN_PDD_CAPS_SUPPORTS_FULL_SPEED) == 0 ||
         !pPddInterfaceInfo->pfnDeinit || 
         !pPddInterfaceInfo->pfnIsConfigurationSupportable || 
         !pPddInterfaceInfo->pfnIsEndpointSupportable || 
         !pPddInterfaceInfo->pfnInitEndpoint ||
         !pPddInterfaceInfo->pfnRegisterDevice || 
         !pPddInterfaceInfo->pfnDeregisterDevice || 
         !pPddInterfaceInfo->pfnStart || 
         !pPddInterfaceInfo->pfnStop || 
         !pPddInterfaceInfo->pfnIssueTransfer ||
         !pPddInterfaceInfo->pfnAbortTransfer || 
         !pPddInterfaceInfo->pfnDeinitEndpoint || 
         !pPddInterfaceInfo->pfnStallEndpoint || 
         !pPddInterfaceInfo->pfnClearEndpointStall || 
         !pPddInterfaceInfo->pfnSendControlStatusHandshake ||

⌨️ 快捷键说明

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