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

📄 usbddrv.cpp

📁 cayman提供的PXA270 wince下的bsp源码包
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    break;
                }
            } else
                if (iFreePipe == gcMaxPipes)
                    iFreePipe = iPipe;
        }
        if (iFreePipe < gcMaxPipes) {
            pDev->apPipes[iFreePipe] = pPipe;
            LeaveCriticalSection(&pDev->csPipeLock);
            DEBUGMSG(ZONE_API|ZONE_PIPE, (TEXT("-USBD:OpenPipe success, hPipe = %X\n"), pPipe));
            return (USB_PIPE)pPipe;
        }
        LeaveCriticalSection(&pDev->csPipeLock);
    }
    // Some error occurred (error code set in HCD)
    FreePipeObject(pPipe);
    DEBUGMSG(ZONE_ERROR,(TEXT("!USBD:OpenPipe returning error\r\n")));
    return NULL;
}

/*
 * @func   BOOL | ClosePipe | Close an open pipe handle.
 * @rdesc  Return TRUE if successful, FALSE if error.
 * @comm   Abort and close all transfers in progress on pipe, and free all
 *         resources associated with pipe.  If transfers are in
 *         progress, will block until aborts complete.
 */
extern "C" BOOL
ClosePipe(
    USB_PIPE hPipe)  // @parm [IN] - Open pipe handle
{
    BOOL fRet = TRUE;
    SPipe * pPipe = (SPipe *)hPipe;
    if (!ReferencePipeHandle(pPipe))
    {
        DEBUGMSG(ZONE_WARNING,(TEXT("!USBD:ClosePipe - Invalid handle\r\n")));
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    SDevice * pDev = pPipe->pDevice;
    SHcd * pHcd = pDev->pHcd;
    DEBUGMSG(ZONE_API|ZONE_PIPE,(TEXT("+USBD:ClosePipe, hPipe: 0x%X\r\n"),hPipe));

    EnterCriticalSection(&pDev->csPipeLock);

#ifdef NEVER // try this with OHCI just for giggles (BUGBUG)
    // old code relied on this always being true!
    DEBUGCHK( pDev->apPipes[pPipe->iEndpointIndex] == pPipe );
#endif

    for (UINT iPipe = 0; iPipe < gcMaxPipes; ++iPipe)
        if (pDev->apPipes[iPipe] == pPipe)
            break;
    if (iPipe == gcMaxPipes) {
        DEBUGMSG(ZONE_WARNING|ZONE_API|ZONE_PIPE, (TEXT("-USBD:ClosePipe, pipe is not open.\n")));
        LeaveCriticalSection(&pDev->csPipeLock);
        DereferencePipeHandle(pPipe);
        SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }
    pDev->apPipes[iPipe] = NULL;

    LeaveCriticalSection(&pDev->csPipeLock);

    // Mark pipe as going away - this will prevent any new transfers from
    // being started, and will prevent any transfers in progress from blocking
    // (since AddTransfer() will fail, and if AddTransfer() has already been called,
    // we'll unblock the transfer in CloseTransfer()).
    EnterCriticalSection(&pPipe->csTransferLock);
    pPipe->dwSig = CLOSING_PIPE_SIG;
    LeaveCriticalSection(&pPipe->csTransferLock);

    if (pPipe->apTransfers)
    {
        for (UINT iTransfer = 0 ; iTransfer < pPipe->cAllocatedTransfers ;
            ++iTransfer)
        {
            if (pPipe->apTransfers[iTransfer])
                CloseTransfer(pPipe->apTransfers[iTransfer]);
        }

        delete [] pPipe->apTransfers; // all transfers inside should be NULL
        pPipe->apTransfers = NULL;
        pPipe->cAllocatedTransfers = 0;
    }

    // Free all transfers on our free list
    while (pPipe->pFreeTransferList)
    {
        STransfer *pTransfer = pPipe->pFreeTransferList;
        pPipe->pFreeTransferList = pTransfer->pNext;
        // Release memory and resources used by transfer struct
        FreeTransferObjectMem(pTransfer);
    }

    UINT iEp = pPipe->iEndpointIndex;

    // Put pipe struct on free list
    DereferencePipeHandle(pPipe);
    FreePipeObject(pPipe);

    // Finally, call in to the HCD to clean up.
    fRet = (*pHcd->pHcdFuncs->lpClosePipe)(pHcd->pvHcd, pDev->iDevice, iEp);

    DEBUGMSG(ZONE_API|ZONE_PIPE,(TEXT("-USBD:ClosePipe\r\n")));
    return fRet;
}

/*
 * @func   BOOL | ResetPipe | Reset an open USB pipe
 * @rdesc  Return TRUE if successful, or FALSE if error.
 * @comm   This request will clear the halted state of a pipe within the USB stack, and
 *         reset the data toggle state of the endpoint to DATA0.  It does not reset the stalled
 *         state of the endpoint on the device; the device driver must accomplish this by
 *         sending the appropriate FEATURE request on the default pipe.  To determine whether
 *         the endpoint is stalled on the device side, use the <f GetStatus> call.
 *
 * @xref   <f IsPipeHalted> <f ClearFeature> <f GetStatus>
 */
extern "C" BOOL
ResetPipe(
    USB_PIPE hPipe) // @parm [IN] - Open USB pipe handle
{
    SPipe * pPipe = (SPipe *)hPipe;
    BOOL fRet;
    if (!ReferencePipeHandle(pPipe))
    {
        DEBUGMSG(ZONE_WARNING,(TEXT("!USBD:ResetPipe - Invalid handle\r\n")));
        return FALSE;
    }
    SDevice * pDev = pPipe->pDevice;
    SHcd * pHcd = pDev->pHcd;
    LPHCD_RESET_PIPE pFunc = pHcd->pHcdFuncs->lpResetPipe;
    DEBUGMSG(ZONE_API|ZONE_PIPE,(TEXT("+USBD:ResetPipe\r\n")));

    fRet = (*pFunc)(pHcd->pvHcd, pDev->iDevice, pPipe->iEndpointIndex);
    DereferencePipeHandle(pPipe);
    return fRet;
}


/*
 * @func   BOOL | ResetDefaultPipe | Reset default (EP0) USB pipe
 * @rdesc  Return TRUE if successful, or FALSE if error.
 * @comm   This request will clear the halted state of the default pipe within the USB stack.
 *         Note: this function is only available in USBDI version 1.1 or later.
 *
 * @xref   <f IsDefaultPipeHalted>
 */
extern "C" BOOL
ResetDefaultPipe(
    USB_HANDLE hDevice) // @parm [IN] -  USB device handle
{

    SDevice *pDev = (SDevice *)hDevice;
    if (!ValidateDeviceHandle(pDev))
    {
        DEBUGMSG(ZONE_WARNING,(TEXT("!USBD:ResetDefaultPipe - Invalid device handle\r\n")));
        return FALSE;
    }
    SPipe *pDfltPipe;
    EnterCriticalSection(&pDev->csPipeLock);
    pDfltPipe = pDev->apPipes[gcEndpointZero];
    LeaveCriticalSection(&pDev->csPipeLock);

    return ResetPipe(pDfltPipe);
}

/*
 * @func   BOOL | AbortPipeTransfers | Abort all transfers on an open USB pipe
 * @rdesc  Return TRUE if successful, FALSE if error.
 * @comm   Will block until all transfers have been successfully cancelled on the
 *         endpoint, unless USB_NO_WAIT is specified, in which case, the transfers
 *         are flagged to be cancelled, but the function returns immediately.
 */
extern "C" BOOL
AbortPipeTransfers(
    USB_PIPE hPipe,  // @parm [IN] - Open USB pipe handle
    DWORD dwFlags)   // @parm [IN] - USB_NO_WAIT, or 0
{
    SPipe * pPipe = (SPipe *)hPipe;
    if (!ReferencePipeHandle(pPipe))
    {
        DEBUGMSG(ZONE_WARNING,(TEXT("!USBD:AbortPipeTransfers - Invalid handle\r\n")));
        return FALSE;
    }
    SDevice * pDev = pPipe->pDevice;
    SHcd * pHcd = pDev->pHcd;
    UINT iTransfer;
    STransfer * pTransfer;

    DEBUGMSG(ZONE_API|ZONE_PIPE,
             (TEXT("+USBD:AbortPipeTransfers, hPipe: 0x%X, flags: 0x%X, AllocatedTrans:%u\r\n"),
              hPipe,dwFlags,pPipe->cAllocatedTransfers));

    EnterCriticalSection(&pPipe->csTransferLock);
    for (iTransfer=0;iTransfer<pPipe->cAllocatedTransfers;iTransfer++) {
        pTransfer = pPipe->apTransfers[iTransfer];
        LeaveCriticalSection(&pPipe->csTransferLock);
        if (pTransfer)
            AbortTransfer(pTransfer, dwFlags);
        EnterCriticalSection(&pPipe->csTransferLock);
    }
    LeaveCriticalSection(&pPipe->csTransferLock);

    DEBUGMSG(ZONE_PIPE,(TEXT("-USBD:AbortPipeTransfers\r\n")));
    DereferencePipeHandle(pPipe);
    return TRUE;
}

/* @topic USB Transfer functions | USB client drivers communicate with devices by issuing
 *        transfers.  There are four basic type of transfers: Control, Bulk, Interrupt, and
 *        Isochronous.  Several routines are also provided to issue control transfers for common
 *        device configuration and setup requests.
 *
 *        All transfer routines have an optional callback parameter.  If specified, the transfer
 *        routine will return immediately, and the callback function will be called when
 *        the transfer has completed, or been cancelled.  If no callback is specified, then
 *        the function will block until the transfer is finished, unless the USB_NO_WAIT flag
 *        is specified.  In this case, the function will return immediately, and no indication
 *        will be given when the transfer completes. This might be used by a client driver to
 *        queue up a list of requests, and only wait for the last one.  Note that the client is
 *        still responsible for closing all transfer handles in this case.
 *
 *        All transfer routines return a handle to a transfer, or NULL if an error occurs.  In
 *        the latter case, client drivers may obtain further error information by calling the
 *        standard <f GetLastError> function.  The following Win32 error codes are applicable to
 *        the USB transfer functions: <nl>
 *
 *               ERROR_INVALID_HANDLE      -- The pipe handle is invalid <nl>
 *               ERROR_OUTOFMEMORY         -- Could not obtain required memory for operation <nl>
 *               ERROR_INVALID_USER_BUFFER -- Client buffer pointer is invalid  <nl>
 *               ERROR_INVALID_PARAMETER   -- (isoch only) The specified starting frame is invalid <nl>
 *
 *        The USB (OHCI) hardware assumes a host page size of 4K bytes.  Under Windows CE, many
 *        supported processors do not necessarily follow this assumption (1K page size is common).
 *        The issue here is that the underlying hardware can use scatter/gather DMA, but
 *        can handle at most 1 page transition per transfer.  However, client buffers on systems
 *        with smaller page sizes may be scattered across several physically disjoint pages.
 *
 *        In order to make this restriction transparent to client drivers, OHCD.DLL allocates
 *        a buffer from the system which is known to be contiguous within 4K sections.
 *        Then, DMA is done to the private buffers, and copied to the client buffer
 *        once the transfer is complete.  For some client drivers, this extra copy may
 *        impose an unacceptable performance hit, however.  So, the Windows CE transfer functions
 *        allow the client to pass in an optional physical memory address which is used directly
 *        for the DMA to/from the HC hardware.  Because the HC accesses this buffer directly,
 *        the following two restrictions must be rigidly adhered to:
 *
 *        1) Physical buffer must be contiguous within 4K segments.   How the client allocates
 *           this memory is beyond the scope of this document (e.g. may be through a platform
 *           specific call). The LockPages() call can be used to get physical page information.
 *
 *        2) Client must not access or free the buffer before the transfer has completed.
 *
 *
 * @xref  <f GetInterface> <f SetInterface> <f GetDescriptor> <f SetDescriptor> <f SetFeature>
 *        <f ClearFeature> <f GetStatus> <f SyncFrame> <f IssueVendorTransfer>
 *        <f IssueControlTransfer> <f IssueBulkTransfer> <f IssueInterruptTransfer>
 *        <f IssueIsochTransfer>
 */

/*
 * @func   USB_TRANSFER | GetInterface | Send a GET_INTERFACE request to USB device
 * @rdesc  Returns a USB_TRANSFER handle, or NULL if an error occurs.
 * @comm   Initiates a control transfer to USB device requesting the alternate
 *         setting selected for the given interface.
 * @xref   <f SetInterface> <f IsTransferComplete> <f GetTransferStatus> <f AbortTransfer>
 */
extern "C" USB_TRANSFER
GetInterface(
    USB_HANDLE hDevice,           // @parm [IN] - USB device handle
    LPTRANSFER_NOTIFY_ROUTINE lpStartAddress, // @parm [IN] - Address of callback routine (may be NULL)
    LPVOID lpvNotifyParameter,    // @parm [IN] - Parameter to pass to callback routine
    DWORD dwFlags,                // @parm [IN] - USB_NO_WAIT, or 0
    UCHAR bInterfaceNumber,       // @parm [IN] - Interface number
    PUCHAR lpbAlternateSetting)   // @parm [OUT]- Filled in with current alternate setting value
{
    USB_DEVICE_REQUEST DeviceRequest;
    DEBUGMSG(ZONE_API|ZONE_CONFIG,(TEXT("+USBD:GetInterface\r\n")));

    DeviceRequest.bmRequestType = USB_REQUEST_DEVICE_TO_HOST |
            USB_REQUEST_STANDARD | USB_REQUEST_FOR_INTERFACE;
    DeviceRequest.bRequest = USB_REQUEST_GET_INTERFACE;
    DeviceRequest.wValue = 0;
    DeviceRequest.wIndex = bInterfaceNumber;
    DeviceRequest.wLength = 1;

    dwFlags |= USB_IN_TRANSFER;
    dwFlags &= ~USB_SHORT_TRANSFER_OK;

    return IssueVendorTransfer(hDevice, lpStartAddress, lpvNotifyParameter,
            dwFlags, &DeviceRequest, lpbAlternateSetting, 0);
}

/*
 * @func   USB_TRANSFER | SetInterface | Send a SET_INTERFACE request to USB device
 * @rdesc  Returns a USB_TRANSFER handle, or NULL if an error occurs.
 * @comm   Initiates a control transfer to USB device specifying the alternate
 *         setting to use for the given interface.
 * @xref   <f GetInterface> <f IsTransferComplete> <f GetTransferStatus> <f AbortTransfer>
 */
extern "C" USB_TRANSFER
SetInterface(
    USB_HANDLE hDevice,           // @parm [IN] - USB device handle
    LPTRANSFER_NOTIFY_ROUTINE lpStartAddress, // @parm [IN] - Address of callback routine (should be NULL unless the USB_NO_WAIT flag is set)
    LPVOID lpvNotifyParameter,    // @parm [IN] - Parameter to pass to callback routine
    DWORD dwFlags,                // @parm [IN] - USB_NO_WAIT, or 0
    UCHAR bInterfaceNumber,       // @parm [IN] - Interface number
    UCHAR bAlternateSetting)      // @parm [IN] - Alternate setting number
{
    USB_DEVICE_REQUEST DeviceRequest;
    DEBUGMSG(ZONE_API|ZONE_CONFIG,(TEXT("+USBD:SetInterface\r\n")));

    DeviceRequest.bmRequestType = USB_REQUEST_HOST_TO_DEVICE |
            USB_REQUEST_STANDARD | USB_REQUEST_FOR_INTERFACE;
    DeviceRequest.bRequest = USB_REQUEST_SET_INTERFACE;
    DeviceRequest.wValue = bAlternateSetting;
    DeviceRequest.wIndex = bInterfaceNumber;
    DeviceRequest.wLength = 0;

    dwFlags &= ~USB_IN_TRANSFER;
    dwFlags &= ~USB_SHORT_TRANSFER_OK;

    return IssueVendorTransfer(hDevice, lpStartAddress, lpvNotifyParameter,
            dwFlags, &DeviceRequest, NULL, 0);
}
/*
 * @func   USB_TRANSFER | GetDescriptor | Send a GET_DESCRIPTOR request to USB device.
 * @rdesc  Returns a USB_TRANSFER handle, or NULL if an error occurs.
 * @comm   Initiates a control transfer to USB device requesting device
 *         descriptor information.  The device will return the contents of the
 *         device descriptor starting at the index specified.
 * @xref   <f SetDescriptor> <f IsTransferComplete> <f GetTransferStatus> <f AbortTransfer>
 */
extern "C" USB_TRANSFER
GetDescriptor(
    USB_HANDLE hDevice,           // @parm [IN] - USB device handle

⌨️ 快捷键说明

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