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

📄 usbehcdutil.c

📁 usb2 driver for vxwokrs
💻 C
📖 第 1 页 / 共 5 页
字号:
     * 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(index,                          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(index,                        QTD,		 	pQTD->uBufferPagePointerList[uIndex],			(USB_EHCD_GET_BITFIELD(index,                        QTD,                        pQTD->uBufferPagePointerList[0],		        BUFFER_POINTER) + uIndex),			BUFFER_POINTER);        }    /* Return the number of bytes being transfered by this qTD */    return (pQTD->uBytesToTransfer);    }    /* 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.** <pHCDData>  - Pointer to the USB_EHCD_DATA structure* <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_DATA  pHCDData,/* Pointer to the USB_EHCD_DATA structure */     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;    /* To hold the HCD bus index */    UINT32      index = pHCDData->uBusIndex;    /* 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(pHCDData);    /* 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(index,                                      pQTD,                                      pTransferBuffer + uBytesTransfered,                                      uTransferLength - uBytesTransfered,                                      uMaximumPacketSize);        /* Update the data toggle bit */        USB_EHCD_SET_BITFIELD(index,                             QTD,                             pQTD->uTransferInfo,                             uToggle,                             TOKEN_DT);        /* Update PID field of the qTD */        USB_EHCD_SET_BITFIELD(index,                             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)            {                        /* Temporay pointer to hold the QTD next pointer */            PUCHAR          pQTDTemp = NULL;            /* Create 1 more qTD */            pQTD->pNext = usbEhcdFormEmptyQTD(pHCDData);            /* 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() */            /* Fetch the host controller accessible region */            pQTDTemp = (PUCHAR) pQTD->pNext;            pQTDTemp += USB_EHCD_QTD_HEADER_SIZE;            /* Update the HC's link pointers */            USB_EHCD_SET_BITFIELD(index,                                  QTD,                                  pQTD->uNextQTDPointer,                                  (((unsigned)USB_EHCD_CONVERT_TO_BUS_MEM(                                     index,pQTDTemp))                                   >> 5),                                  NEXTQTD_POINTER);            /* Indicate that this is not the last element in the queue */            USB_EHCD_SET_BITFIELD(index,                                  QTD,                                  pQTD->uNextQTDPointer,                                  0,                                  NEXTQTD_POINTER_T);            /* Flush the contents of the cache to the RAM */             CACHE_DMA_FLUSH(((char*)pQTD+USB_EHCD_QTD_HEADER_SIZE), sizeof(UINT32));            /* Invalidate the cache */              CACHE_DMA_INVALIDATE((char*)pQTD+USB_EHCD_QTD_HEADER_SIZE, sizeof(UINT32));            /* Update the next element as the current qTD element */            pQTD = pQTD->pNext;            /*             * There are no other elements in the queue             * after the newly created element.             */            pQTD->pNext = NULL;            }            /* End of if(uBytesTransfered < uTransferLength) */        }        /* End of while (uBytesTransfered < uTransferLength) */    /* Update the tail pointer */    *ppDataTail = pQTD;    /* Return TRUE from the function */    return TRUE;    }    /* End of function usbEhcdCreateQTDs() *//***************************************************************************** usbEhcdUpdateNonIsochStatusAndBytes - updates the status of the* transfer and the number of bytes transferred.** This function is used to update the status of the non-isochronous* transfer and the number of bytes transferred.** <pHead> - Pointer to the head of the list of QTDS.* <pTail> - Pointer to the tail of the list of QTDS.* <pUrb> - Pointer to the URB.** RETURNS: None.** ERRNO:*   None.** \NOMANUAL*/VOID usbEhcdUpdateNonIsochStatusAndBytes    (    UINT8	index, 	   /* index of the host controller */	    pUSB_EHCD_QTD pHead,   /* Pointer to the head QTD */    pUSB_EHCD_QTD pTail,   /* Pointer to the tail QTD */    pUSBHST_URB pUrb /* Pointer to the URB */    )    {    /* To hold the status of the TD */    UINT8 uStatus = 0;    /* Flag indicating that it is a control transfer request */    BOOLEAN bIsControl = FALSE;    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdUpdateNonIsochStatusAndBytes - Entry",0,0,0,0);    /* WARNING : No parameter validation is done as this function is     * used internally by the EHCD     * Assumption is that valid parameters are passed by the EHCD.     */	/* Extract the status of the qTD */	uStatus = (UINT8)USB_EHCD_GET_BITFIELD(index,                                           QTD,                                           pTail->uTransferInfo,                                           TOKEN_STATUS);    /* Update the URB status based on the status parameter  */    if (0 == uStatus)        {        pUrb->nStatus = USBHST_SUCCESS;        }    /* Data buffer error- can be underrun or overrun. Should be checked */    else if (0 != (uStatus & USB_EHCD_QTD_STATUS_DATA_BUFFER_ERROR))        {        pUrb->nStatus = USBHST_BUFFER_UNDERRUN_ERROR;        }    /*     * babble error - this is set along with halt- so this condition     * should always fail. Mentioned here for completion     */    else if (0 != (uStatus & USB_EHCD_QTD_STATUS_BABBLE_DETECTED))        {        pUrb->nStatus = USBHST_STALL_ERROR;        }    /*     * Transaction error.     * Can be Timeout, CRC or bad PID     */    else if (0 != (uStatus & USB_EHCD_QTD_STATUS_XACTERR))        {        pUrb->nStatus = USBHST_TIMEOUT;        }    /* This is set only for a full/ low speed periodic transfer */    else if (0 != (uStatus & USB_EHCD_QTD_STATUS_MISSED_UFRAME))        {        pUrb->nStatus = USBHST_FAILURE;        }    /* Halted error condition */    else if (0 != (uStatus & USB_EHCD_QTD_STATUS_HALTED))        {        pUrb->nStatus = USBHST_STALL_ERROR;        }        /* Invalidate the cache */        CACHE_DMA_INVALIDATE(pHead, sizeof(USB_EHCD_QTD));        /* If it is a SETUP PID, jump to next TD */       if(USB_EHCD_SETUP_PID == USB_EHCD_GET_BITFIELD(index,                                                      QTD,                                                      pHead->uTransferInfo,                                                      TOKEN_PID_CODE))        {		pHead = pHead->pNext;        bIsControl = TRUE;        }    /* Update the number of bytes transferred to be 0 initially */    pUrb->uTransferLength = 0;    /*     * This loop traverses the queue of requests     * and updates the number of bytes transferred     */    do        {        /* Invalidate the cache */        CACHE_DMA_INVALIDATE(pHead, sizeof(USB_EHCD_QTD));        /* Check if the TD has been processed */        if(0 == (USB_EHCD_GET_BITFIELD(index,                                       QTD,                                       pHead->uTransferInfo,                                       TOKEN_STATUS) &                                       USB_EHCD_QTD_STATUS_ACTIVE))            {            /* Check if it is a control transfer & we have reached tail */            if((TRUE == bIsControl) && (pHead == pTail))                {                break;                }            /* Update the number of bytes transfered */            pUrb->uTransferLength +=              (pHead->uBytesToTransfer -              USB_EHCD_GET_BITFIELD(index,                                    QTD,                                    pHead->uTransferInfo,                                    TOKEN_TOTAL_BYTES_TO_TRANSFER));            }            /* End of if(0 == (pHead->dword2.status & */        else            {            break;            }            /* End of else */        /* If all TDs have been processed, break */        if(pHead == pTail)            {            break;            }        /* Move on to next TD */		pHead = pHead->pNext;        }while(1);    return;    }/***************************************************************************** usbEhcdUpdateITDData - updates the number of bytes transferred.** This function is used to update the number of bytes* transferred and status in a isochronous transfer.** <index> - index of the host controller* <pHead> - Pointer to the head of the list of ITDS.* <pTail> - Pointer to the tail of the list of ITDS.* <pPacketDes> - Pointer to the Packet descriptor*                        transferred.* <uMicroFrameMask> -* RETURNS: None.** ERRNO:*   None.** \NOMANUAL*/VOID usbEhcdUpdateITDData    (    UINT8	index,	   /* index of the host controller */		    pUSB_EHCD_ITD pHead,   /* Pointer to the head QTD */    pUSB_EHCD_ITD pTail,   /* Pointer to the tail QTD */    pUSBHST_ISO_PACKET_DESC pPacketDes, /* Pointer to the Packet descriptor */    UINT8 uMicroFrameMask    )    {    UINT32 uCount = 0;    UINT8 uStatus;    UINT8 uMicroFrameIndex;    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdUpdateITDData - Entry",0,0,0,0);    /* Check the validity of the parameters */    if(NULL == pHead ||       NULL == pTail ||       NULL == pPacketDes)        {        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdUpdateITDData - parameters \                             are not valid\n",0,0,0,0);        return;        }    /*     * This loop traverses the queue of requests     * and updates the number of bytes transferred and status     */    do    {        /* Invalidate the cache */            CACHE_DMA_INVALIDATE(pHead, sizeof(USB_EHCD_ITD));        for (uMicroFrameIndex=0;           USB_EHCD_MAX_MICROFRAME_NUMBER > uMicroFrameIndex;           uMicroFrameIndex++)           {            if((uMicroFrameMask >> uMicroFrameIndex) & 0x01)            {            	/* Update the length of each microframe */				pPacketDes[uCount].uLength =                        USB_EHCD_GET_BITFIELD(index,                        ITD,                        pHead->uTransactionStatusControlList[uMicroFrameIndex],                        TRANSACTION_LENGTH);                /* Update the Status of each microframe */                pPacketDes[uCount].nStatus =                USB_EHCD_GET_BITFIELD(index,

⌨️ 快捷键说明

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