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

📄 usbehcdutil.c

📁 vxWorks下USB2.0中的EHCI的HCD源码,极具有参考价值
💻 C
📖 第 1 页 / 共 5 页
字号:
    	/* Free the siTD data structure */    	memPartFree(ehcdmemPartID, pHeadFreeSITD->pAllocatedMem);        }    /* Update the head and tail pointers to NULL */    pHeadFreeSITD = NULL;    pTailFreeSITD = NULL;    /* Release the event */    OS_RELEASE_EVENT(g_ListAccessEvent);    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdFreeAllLists - Exit\n",0,0,0,0);    return;    }    /* End of function usbEhcdFreeAllLists() */    /***************************************************************************** usbEhcdFormEmptyQH - forms an empty QH and populates it.** This function is checks if a QH can be retrieved from the free list. If a* QH cannot be retrieved, creates an empty QH. After retrieving a valid QH,* populates the fields of the QH.** RETURNS: Pointer to the USB_EHCD_QH data structure.** ERRNO:*   None.** \NOMANUAL*/pUSB_EHCD_QH usbEhcdFormEmptyQH(VOID)    {    /* To hold the pointer to the Queue Head */    pUSB_EHCD_QH    pQH = NULL;    /* To hold the pointer to the allocated memory */    VOID *       pAllocatedMem = NULL;    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdFormEmptyQH - Entry\n",0,0,0,0);    /* Get a free QH from the free list */    pQH = usbEhcdGetFreeQH();    /* If the free list is empty, allocate memory and align it */    if (NULL == pQH)        {    	/* Allocate memory considering that the QH is aligned to 32 bytes */        pAllocatedMem = memPartAlignedAlloc (ehcdmemPartID,        				            sizeof(USB_EHCD_QH),                                    USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT);        /* Check if memory allocation is successful */        if (NULL == pAllocatedMem)            {            OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdFormEmptyQH - memory not allocated for \                                 QH\n",0,0,0,0);            return NULL;            }        /* Align the memory */        pQH = usbEhcdAlign(pAllocatedMem, USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT);        /* Initialize all the elements of the Queue Head */        OS_MEMSET(pQH, 0, sizeof(USB_EHCD_QH));         /* Store the allocated memory in aligned QH */        pQH->pAllocatedMem = pAllocatedMem;        }    /* Populate the fields of the QH - Start */    /*     * This field indicates to the hardware that     * the item referenced by the link pointer is a QH     */    USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer,                             USB_EHCD_TYPE_QH, HORIZONTAL_LINK_POINTER_TYPE);    /*     * Indicate that there are no valid TDs     * in this queue as the QH is newly created     */    USB_EHCD_SET_BITFIELD(QH, pQH->uNextQtdPointer,                             USB_EHCD_INVALID_LINK, NEXTQTD_POINTER_T);    USB_EHCD_SET_BITFIELD(QH, pQH->uAlternateNextQtdPointer,                             USB_EHCD_INVALID_LINK, ALTERNATE_NEXTQTDPOINTER_T);    /* Populate the fields of the QH - End */    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdFormEmptyQH - Exit\n",0,0,0,0);    return pQH;    }     /* End of function usbEhcdFormEmptyQH() *//***************************************************************************** usbEhcdFormEmptyQTD - forms an empty QTD and populates it.** This function is checks if a QTD can be retrieved from the free list. If a* QTD cannot be retrieved, creates an empty QTD. After retrieving a valid QTD,* populates the fields of the QTD.** RETURNS: Pointer to the USB_EHCD_QTD data structure.** ERRNO:*   None.** \NOMANUAL*/pUSB_EHCD_QTD usbEhcdFormEmptyQTD(VOID)    {    /* To hold the pointer to the QTD */    pUSB_EHCD_QTD    pQTD = NULL;    /* To hold the pointer to the allocated memory */    VOID *       pAllocatedMem = NULL;    /* Get a free QTD from the free list */    pQTD = usbEhcdGetFreeQTD();    /* If the free list is empty, allocate memory and align it */    if (NULL == pQTD)        {    	/* Allocate memory considering that the QH is aligned to 32 bytes */        pAllocatedMem = memPartAlignedAlloc (ehcdmemPartID,        				                     sizeof(USB_EHCD_QTD),                               			     USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT);        /* Check if memory allocation is successful */        if (NULL == pAllocatedMem)            {            OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdFormEmptyQTD - memory not allocated for \                                 QTD\n",0,0,0,0);            return NULL;            }        /* Align the memory */        pQTD = usbEhcdAlign(pAllocatedMem, USB_EHCD_HC_DATA_STRUCTURE_ALIGNMENT);        /* Initialize all the elements of the Queue Head */        OS_MEMSET(pQTD, 0, sizeof(USB_EHCD_QTD));        /* Store the allocated memory in aligned QTD */        pQTD->pAllocatedMem = pAllocatedMem;        }    /* Populate the fields of the QTD - Start */    /* Invalidate Link pointer */    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uNextQTDPointer,                          USB_EHCD_INVALID_LINK,                          NEXTQTD_POINTER_T );    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uAlternateNextQTDPointer,                          USB_EHCD_INVALID_LINK,                          ALTERNATE_NEXTQTDPOINTER_T );    /* Indicate that a maximum of 2 errors is acceptable during a transfer */    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uTransferInfo,                          USB_EHCD_MAX_ERRORS,                          TOKEN_CERR );    /* Enable the HC to start executing the Transaction */    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uTransferInfo,                          USB_EHCD_QTD_STATUS_ACTIVE,                          TOKEN_STATUS);    /* Populate the fields of the QTD - End */    return pQTD;    }    /* End of usbEhcdFormEmptyQTD() *//***************************************************************************** usbEhcdFillQTDBuffer - populates the buffer pointers of the QTD.** This function is used to populate the buffer pointer fields of the QTD.** <pQTD>   - Pointer to the QTD.* <pBuffer>  - Pointer to the start of the buffer* <uSize> - Size of the data to be filled.* RETURNS: Returns the number of bytes which were filled in qTD.** ERRNO:*   None.** \NOMANUAL*/UINT32 usbEhcdFillQTDBuffer    (    pUSB_EHCD_QTD    pQTD, /* Pointer to the QTD */    VOID *        pBuffer,  /* Pointer to the start of the buffer */    UINT32       uSize,     /* Size of the buffer to be filled */    UINT32          uMaxPacketSize /* Maximum packet size */    )    {    /* To hold the index into the buffer pointers of the qTD */    UINT32 uIndex;    UINT32 actualSize;    /* Check the validity of the parameters */    if(NULL == pQTD ||       NULL == pBuffer ||       0 == uSize)        {        return 0;        }    /* Fill qTD's buffer pointer */    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uBufferPagePointerList[0],                          (((unsigned)USB_EHCD_CONVERT_TO_PCI(pBuffer)) >> 12),                          BUFFER_POINTER);    /* Fill qTD's current offset into the buffer pointer */    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uBufferPagePointerList[0],                          ((unsigned)USB_EHCD_CONVERT_TO_PCI(pBuffer) & 0xFFF),                          BUFFERPOINTER_CURRENT_OFFSET);    /* Fill the number of bytes to transfer -     * Totally 5 * 4K bytes can be     * transferred using 1 qTD.     */    actualSize = (uSize <= (USB_EHCD_QTD_MAX_TRANSFER_SIZE -                      USB_EHCD_GET_BITFIELD(QTD,                                            pQTD->uBufferPagePointerList[0],                                            BUFFERPOINTER_CURRENT_OFFSET)))    ? uSize:(USB_EHCD_QTD_MAX_TRANSFER_SIZE -                      USB_EHCD_GET_BITFIELD(QTD,                                            pQTD->uBufferPagePointerList[0],                                            BUFFERPOINTER_CURRENT_OFFSET));    pQTD->uBytesToTransfer = actualSize;    /* If uSize is more than BytesToTransfer for this QTD     * and BytesToTransfer is not multiple of maximum packet      * size supported by endpoint, then for IN transaction     * BytesToTransfer should change to next multiple of     * maximum packet size     */    if ((uSize > pQTD->uBytesToTransfer) &&         (pQTD->uBytesToTransfer % uMaxPacketSize))        {        pQTD->uBytesToTransfer = pQTD->uBytesToTransfer - (pQTD->uBytesToTransfer % uMaxPacketSize);        }    USB_EHCD_SET_BITFIELD(QTD,                          pQTD->uTransferInfo,                          pQTD->uBytesToTransfer,                          TOKEN_TOTAL_BYTES_TO_TRANSFER);    /* Update other buffer pointer fields of the qTD .     * Each buffer pointer will be pointing to a different page     */    for(uIndex = 1; 5 > uIndex; ++uIndex)        {        USB_EHCD_SET_BITFIELD(                        QTD,		 	pQTD->uBufferPagePointerList[uIndex],			(USB_EHCD_GET_BITFIELD(QTD,                        pQTD->uBufferPagePointerList[0],		        BUFFER_POINTER) + uIndex),			BUFFER_POINTER);        }    /* Return the number of bytes being transfered by this qTD */    return (USB_EHCD_GET_BITFIELD(QTD,                                  pQTD->uTransferInfo,                                  TOKEN_TOTAL_BYTES_TO_TRANSFER));    }    /* End of usbEhcdFillQTDBuffer() */    /***************************************************************************** usbEhcdCreateQTDs - creates TDs and populates them.** This function is used to create TDs for a data transfer and to populate the* fields of the TDs.** <ppDataHead> - Pointer holding the pointer to the*               head of the list of QTDS.* <ppDataTail> - Pointer holding the pointer to the*               tail of the list of QTDS.* <pTransferBuffer> - Data buffer* <uTransferLength> - length of the data buffer* <uToggle>  - initial toggle value* <uPID>  - PID value* RETURNS: Returns TRUE if the QTDs are created successfully.*          Returns FALSE if the QTDs are not created successfully.** ERRNO:*   None.** \NOMANUAL*/BOOLEAN usbEhcdCreateQTDs    (    pUSB_EHCD_QTD *ppDataHead,/* Pointer to the head QTD */    pUSB_EHCD_QTD *ppDataTail,/* Pointer to the tail QTD */    UCHAR  *   pTransferBuffer,/* Transfer buffer */    UINT32     uTransferLength,/* Transfer length */    UINT32     uMaximumPacketSize, /* Maximum packet size */    UINT8      uToggle,  /* Initial toggle value */    UINT8      uPID     /* PID value */    )    {    /* Pointer to the current qTD */    pUSB_EHCD_QTD pQTD = NULL;    /* To hold the temporary pointer to the qTD */    pUSB_EHCD_QTD pTempQTD = NULL;    /* To hold the number of bytes transferred */    UINT32 uBytesTransfered = 0;    /* Check the validity of the parameters */    if (NULL == ppDataHead ||        NULL == ppDataTail ||        NULL == pTransferBuffer)        {        OS_LOG_MESSAGE_HIGH(EHCD,"Parameters are not valid\n",0,0,0,0);        return FALSE;        }    /* Create the 1st TD needed for the transfer */    pQTD = *ppDataHead = usbEhcdFormEmptyQTD();    /* If unable to create the TD, return FALSE */    if(NULL == pQTD)        {        return FALSE;        }    /* This loop gets executed till all the TDs are created */    while (uBytesTransfered < uTransferLength)        {        /* Populate the TD's buffer pointers */        uBytesTransfered +=                   usbEhcdFillQTDBuffer(pQTD,                                      pTransferBuffer + uBytesTransfered,                                      uTransferLength - uBytesTransfered,                                      uMaximumPacketSize);        /* Update the data toggle bit */        USB_EHCD_SET_BITFIELD(QTD,                             pQTD->uTransferInfo,                             uToggle,                             TOKEN_DT);        /* Update PID field of the qTD */        USB_EHCD_SET_BITFIELD(QTD,                             pQTD->uTransferInfo,                             uPID,                             TOKEN_PID_CODE);        /* Flush the contents of the cache to the RAM */        CACHE_DMA_FLUSH(pQTD, sizeof(USB_EHCD_QTD));        /* Invalidate the cache */        CACHE_DMA_INVALIDATE(pQTD, sizeof(USB_EHCD_QTD));        /* If the bytes transfered is less than the total transfer size */        if(uBytesTransfered < uTransferLength)            {            /* Create 1 more qTD */            pQTD->pNext = usbEhcdFormEmptyQTD();            /* Check if memory allocation is a failure */            if(NULL == pQTD->pNext)                {                /* Free up all the TDs created */                for(pQTD = *ppDataHead;                    NULL != pQTD;                    pQTD = pQTD->pNext)                    {                    pTempQTD = pQTD->pNext;                    OS_ASSERT(NULL != pQTD->pAllocatedMem);                    OS_FREE(pQTD->pAllocatedMem);                    pQTD = pTempQTD;                    }                /* Return FALSE */                return FALSE;                }/* End of if() */            /* Flush the contents of the cache to the RAM */              CACHE_DMA_FLUSH((char*)pQTD+pUSB_EHCD_QTD_pNext_OFFSET, sizeof(UINT32));            /* Invalidate the cache */              CACHE_DMA_INVALIDATE((char*)pQTD+pUSB_EHCD_QTD_pNext_OFFSET, sizeof(UINT32));                          /* Update the HC's link pointers */            USB_EHCD_SET_BITFIELD(QTD,                                  pQTD->uNextQTDPointer,                                  (((unsigned)USB_EHCD_CONVERT_TO_PCI(pQTD->pNext))                                   >> 5),                                  NEXTQTD_POINTER);            /* Indicate that this is not the last element in the queue */            USB_EHCD_SET_BITFIELD(QTD,                                  pQTD->uNextQTDPointer,                                  0,                                  NEXTQTD_POINTER_T);            /* Flush the contents of the cache to the RAM */

⌨️ 快捷键说明

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