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

📄 pxa25xpdd.cpp

📁 pxa25x library for windows ce
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    LOCK_ENDPOINT(peps);
    DEBUGCHK(peps->fInitialized);

    ValidateTransferDirection(pContext, peps, pTransfer);

    DEBUGCHK(pTransfer == peps->pTransfer);

    if (dwEndpoint == 0) {
        pContext->fEndpoint0AckNeeded = FALSE;
    }
    
    ResetEndpoint(pContext, peps);
    CompleteTransfer(pContext, peps, UFN_CANCELED_ERROR);

    UNLOCK_ENDPOINT(peps);

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


static
VOID
FreePxaContext(
    PCTRLR_PDD_CONTEXT pContext
    )
{
    PREFAST_DEBUGCHK(pContext);
    DEBUGCHK(!pContext->hevInterrupt);
    DEBUGCHK(!pContext->hIST);
    DEBUGCHK(!pContext->fRunning);

    pContext->dwSig = GARBAGE_DWORD;

    if (pContext->pvLibContext) Pxa25xLibDeinit(pContext->pvLibContext);

    UnmapRegisterSet();

    if (pContext->hBusAccess) CloseBusAccessHandle(pContext->hBusAccess);
    
    if (pContext->dwSysIntr) {
        KernelIoControl(IOCTL_HAL_DISABLE_WAKE, &pContext->dwSysIntr,  
    	    sizeof(pContext->dwSysIntr), NULL, 0, NULL);
    }

    if (pContext->dwIrq != IRQ_UNSPECIFIED) {
        KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pContext->dwIrq, 
            sizeof(DWORD), NULL, 0, NULL);
    }

    
    DeleteCriticalSection(&pContext->csIsrCtrlAccess);

    LocalFree(pContext);
}


// Deinitialize the device.
DWORD
WINAPI
UfnPdd_Deinit(
              PVOID pvPddContext
              )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    FreePxaContext(pContext);
    
    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


// Start the Device.
DWORD
WINAPI
UfnPdd_Start(
             PVOID        pvPddContext
             )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DWORD dwRet;
    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    FUNCTION_ENTER_MSG();

    DEBUGCHK(!pContext->fRunning);

    BOOL fIntInitialized = FALSE;

    // Create the interrupt event
    pContext->hevInterrupt = CreateEvent(0, FALSE, FALSE, NULL);
    if (pContext->hevInterrupt == NULL) {
        dwRet = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s Error creating interrupt event. Error = %d\r\n"), 
            pszFname, dwRet));
        goto EXIT;
    }

    fIntInitialized = InterruptInitialize(pContext->dwSysIntr, 
        pContext->hevInterrupt, NULL, 0);
    if (fIntInitialized == FALSE) {
        dwRet = ERROR_GEN_FAILURE;
        DEBUGMSG(ZONE_ERROR, (_T("%s  interrupt initialization failed\r\n"),
            pszFname));
        goto EXIT;
    }

    InterruptDone(pContext->dwSysIntr);

    pContext->fExitIST = FALSE;
    pContext->hIST = CreateThread(NULL, 0, ISTMain, pContext, 0, NULL);    
    if (pContext->hIST == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s IST creation failed\r\n"), pszFname));
        dwRet = GetLastError();
        goto EXIT;
    }

    pContext->fRunning = TRUE;
    
    dwRet = Pxa25xLibStart(pContext->pvLibContext);

EXIT:
    if (dwRet != ERROR_SUCCESS) {
        if (fIntInitialized) InterruptDisable(pContext->dwSysIntr);
        
        if (pContext->fRunning) {
            pContext->fExitIST = TRUE;
            InterruptDisable(pContext->dwSysIntr);
            SetEvent(pContext->hevInterrupt);
            WaitForSingleObject(pContext->hIST, INFINITE);
            CloseHandle(pContext->hIST);
            pContext->hIST = NULL;
            pContext->fRunning = FALSE;
        }

        if (pContext->hevInterrupt) CloseHandle(pContext->hevInterrupt);
        pContext->hevInterrupt = NULL;
    }

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Stop the Device
// TODO: Move to Common PDD Lib?
DWORD
WINAPI
UfnPdd_Stop(
            PVOID pvPddContext
            )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    DEBUGCHK(pContext->fRunning);

    // Stop the IST
    pContext->fExitIST = TRUE;
    InterruptDisable(pContext->dwSysIntr);
    SetEvent(pContext->hevInterrupt);
    WaitForSingleObject(pContext->hIST, INFINITE);
    CloseHandle(pContext->hevInterrupt);
    CloseHandle(pContext->hIST);
    pContext->hIST = NULL;
    pContext->hevInterrupt = NULL;

    ResetDevice(pContext);

    pContext->fRunning = FALSE;

    Pxa25xLibStop(pContext->pvLibContext);

    DEBUGMSG(ZONE_PIPE, (_T("%s Device has been disabled\r\n"), 
        pszFname));

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


DWORD 
WINAPI 
UfnPdd_IsConfigurationSupportable(
    PVOID                       pvPddContext,
    UFN_BUS_SPEED               Speed,
    PUFN_CONFIGURATION          pConfiguration
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(Speed == BS_FULL_SPEED);

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    // This PDD does not have any special requirements that cannot be 
    // handled through IsEndpointSupportable.
    DWORD dwRet = ERROR_SUCCESS;

    FUNCTION_LEAVE_MSG();

    return dwRet;
}


DWORD
WINAPI
UfnPdd_IsEndpointSupportable(
    PVOID                       pvPddContext,
    DWORD                       dwEndpoint,
    UFN_BUS_SPEED               Speed,
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDesc,
    BYTE                        bConfigurationValue,
    BYTE                        bInterfaceNumber,
    BYTE                        bAlternateSetting
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(EP_VALID(dwEndpoint));
    DWORD dwRet = ERROR_SUCCESS;
    BYTE bEndpointAddress = 0;
    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;

    ValidateContext(pContext);

    PREFAST_DEBUGCHK(pEndpointDesc);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    // Special case for endpoint 0
    if (dwEndpoint == 0) {
        DEBUGCHK(pEndpointDesc->bmAttributes == USB_ENDPOINT_TYPE_CONTROL);
    }
    else if (dwEndpoint < ENDPOINT_COUNT) {
        BYTE bTransferType = pEndpointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
        if (bTransferType != peps->dwTypeSupported) {
            DEBUGMSG(ZONE_PIPE, (_T("%s endpoint %u does not support transfer type -> %u  \r\n"), 
                pszFname, dwEndpoint, bTransferType));
            dwRet = ERROR_INVALID_PARAMETER;
            goto EXIT;
        }

        bEndpointAddress = pEndpointDesc->bEndpointAddress;

        DWORD dwDirection;
        if (USB_ENDPOINT_DIRECTION_IN(pEndpointDesc->bEndpointAddress)) {
            dwDirection = USB_IN_TRANSFER;
        }
        else {
            dwDirection = USB_OUT_TRANSFER;
        }
        
        if (peps->dwDirectionSupported == dwDirection) {
            // Change the Address
            bEndpointAddress &= USB_ENDPOINT_DIRECTION_MASK;
            bEndpointAddress |= dwEndpoint;
        }
        else {
            DEBUGMSG(ZONE_PIPE, (_T("%s endpoint %u does not support direction -> %u \r\n"), 
                pszFname, dwEndpoint, dwDirection));
            dwRet = ERROR_INVALID_PARAMETER;
            goto EXIT;
        }
    }

    // if requested size is smaller than supported then return fail
    if (peps->dwPacketSizeSupported > pEndpointDesc->wMaxPacketSize) {
        DEBUGMSG(ZONE_ERROR, (_T("%s endpoint %u does not support packet size -> %u \r\n"), 
            pszFname, dwEndpoint, pEndpointDesc->wMaxPacketSize));
        dwRet = ERROR_INVALID_PARAMETER;
        goto EXIT;
    }
    
    // If Requested Size is larger than what is supported ... change it.
    // Note only try and change it if no errors so far... meaning node is
    // Supportable.
    if (peps->dwPacketSizeSupported < pEndpointDesc->wMaxPacketSize) {
        // Change the packet Size if Necessary 
        pEndpointDesc->wMaxPacketSize &= ~USB_ENDPOINT_MAX_PACKET_SIZE_MASK;
        pEndpointDesc->wMaxPacketSize |= peps->dwPacketSizeSupported;
    }

    // Change the endpoint address if necessary
    if (pEndpointDesc->bEndpointAddress != bEndpointAddress) {
        pEndpointDesc->bEndpointAddress = bEndpointAddress;
    }

EXIT:
    FUNCTION_LEAVE_MSG();

    return dwRet;
}


// Initialize an endpoint.
DWORD
WINAPI
UfnPdd_InitEndpoint(
    PVOID                       pvPddContext,
    DWORD                       dwEndpoint,
    UFN_BUS_SPEED               Speed,
    PUSB_ENDPOINT_DESCRIPTOR    pEndpointDesc,
    PVOID                       pvReserved,
    BYTE                        bConfigurationValue,
    BYTE                        bInterfaceNumber,
    BYTE                        bAlternateSetting
    )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(EP_VALID(dwEndpoint));
    PREFAST_DEBUGCHK(pEndpointDesc);

#ifdef DEBUG
    {
        USB_ENDPOINT_DESCRIPTOR EndpointDesc;
        memcpy(&EndpointDesc, pEndpointDesc, sizeof(EndpointDesc));
        DEBUGCHK(UfnPdd_IsEndpointSupportable(pvPddContext, dwEndpoint, Speed,
            &EndpointDesc, bConfigurationValue, bInterfaceNumber, 
            bAlternateSetting) == ERROR_SUCCESS);
        DEBUGCHK(memcmp(&EndpointDesc, pEndpointDesc, sizeof(EndpointDesc)) == 0);
    }
#endif

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    DEBUGCHK(!peps->fInitialized);

    InitializeCriticalSection(&peps->cs);
    DEBUGCHK(pEndpointDesc->wMaxPacketSize == peps->dwPacketSizeSupported);

    // Endpoints are always active.
    
    peps->fInitialized = TRUE;
    peps->fInIST = FALSE;

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}

// Deinitialize an endpoint.
// TODO: Could be made to be part of Common PDD LIB 
// this
DWORD
WINAPI
UfnPdd_DeinitEndpoint(
                      PVOID pvPddContext,
                      DWORD dwEndpoint
                      )
{
    SETFNAME();
    FUNCTION_ENTER_MSG();

    DEBUGCHK(EP_VALID(dwEndpoint));

    PCTRLR_PDD_CONTEXT pContext = (PCTRLR_PDD_CONTEXT) pvPddContext;
    ValidateContext(pContext);

    PEP_STATUS peps = GetEpStatus(pContext, dwEndpoint);
    LOCK_ENDPOINT(peps);

    DEBUGCHK(peps->fInitialized);
    DEBUGCHK(peps->pTransfer == NULL);

    // Reset and disable the endpoint 
    // Mask endpoint interrupts    
    ResetEndpoint(pContext, peps);

    peps->fInitialized = FALSE;
    UNLOCK_ENDPOINT(peps);
    
    DeleteCriticalSection(&peps->cs);

    FUNCTION_LEAVE_MSG();

    return ERROR_SUCCESS;
}


// Stall an endpoint.
DWORD
WINAPI
UfnPdd_StallEndpoint(
                     PVOID pvPddContext,
                     DWORD dwEndpoint
                     )
{

    DWORD dwRet = ERR

⌨️ 快捷键说明

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