📄 usbehcdutil.c
字号:
ITD, pHead->uTransactionStatusControlList[uMicroFrameIndex], TRANSACTION_STATUS); /* get the status and update for per packet */ uStatus = USB_EHCD_GET_BITFIELD(index, ITD, pHead->uTransactionStatusControlList[uMicroFrameIndex], TRANSACTION_STATUS); if ((0 != (uStatus & USB_EHCD_ITD_STATUS_BABBLE_DETECTED))|| (0 != (uStatus & USB_EHCD_ITD_STATUS_XACTERR))) { pPacketDes[uCount].nStatus = USBHST_FAILURE; } else if (0 != (uStatus & USB_EHCD_ITD_STATUS_BUFFER_ERROR)) { pPacketDes[uCount].nStatus = USBHST_BUFFER_UNDERRUN_ERROR; } else /* Success */ { pPacketDes[uCount].nStatus = USBHST_SUCCESS; } uCount++; } /* End of if statement .... */ } /* End of for loop */ /* Move on to next TD */ pHead = pHead->pVerticalNext; }while(pHead == pTail); return; } /* End of Function usbEhcdUpdateITDData *//***************************************************************************** usbEhcdUpdateSITDData - 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 SITDS.* <pTail> - Pointer to the tail of the list of SITDS.* <pPacketDes> - Pointer to the Packet descriptor* transferred.* RETURNS: None.** ERRNO:* None.** \NOMANUAL*/VOID usbEhcdUpdateSITDData ( UINT8 index, /* index of the host controller */ pUSB_EHCD_SITD pHead, /* Pointer to the head QTD */ pUSB_EHCD_SITD pTail, /* Pointer to the tail QTD */ pUSBHST_ISO_PACKET_DESC pPacketDes /* Pointer to the Packet descriptor */ ) { UINT32 uCount = 0; UINT8 uStatus; 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_SITD)); /* Update the length of each microframe */ /*pPacketDes[uCount].uLength = pHead->dword3.total_bytes_to_transfer; */ pPacketDes[uCount].uLength = USB_EHCD_GET_BITFIELD(index, SITD, pHead->uTransferState, TRANSFER_STATE_TOTAL_BYTES_TO_TRANSFER); /* get the status and update for per packet */ uStatus = USB_EHCD_GET_BITFIELD(index, SITD, pHead->uTransferState, TRANSFER_STATE_STATUS); if (0 != (uStatus & USB_EHCD_SITD_STATUS_ERROR)) { pPacketDes[uCount].nStatus = USBHST_FAILURE; } else if (0 != (uStatus & USB_EHCD_SITD_STATUS_BUFFER_ERROR)) { pPacketDes[uCount].nStatus = USBHST_BUFFER_UNDERRUN_ERROR; } else if (0 != (uStatus & USB_EHCD_SITD_STATUS_BABBLE_DETECTED)) { pPacketDes[uCount].nStatus = USBHST_FAILURE; } else if (0 != (uStatus & USB_EHCD_SITD_STATUS_XACTERR)) { pPacketDes[uCount].nStatus = USBHST_FAILURE; } else if (0 != (uStatus & USB_EHCD_SITD_STATUS_MISSED_FRAME)) { pPacketDes[uCount].nStatus = USBHST_FAILURE; } else /* Success */ { pPacketDes[uCount].nStatus = USBHST_SUCCESS; } uCount++; /* Move on to next TD */ pHead = pHead->pVerticalNext; }while(pHead == pTail); return; } /* End of Function usbEhcdUpdateSITDData *//***************************************************************************** usbEhcdCalculateBusTime - calculates the bus time** This function is used to calculate the bus time required for the endpoint.** <uSpeed> - Speed of the device.* <uDirection> - Direction of the pipe.* <uPipeType> - Type of the endpoint.* <uDataByteCount> - maximum byte count supported by the pipe.** RETURNS: Calculated bus time in nanoseconds.** ERRNO:* None.** \NOMANUAL*/INT32 usbEhcdCalculateBusTime ( UINT32 uSpeed, /* Speed of the device */ UINT32 uDirection, /* Direction of the pipe */ UINT32 uPipeType, /* type of the pipe */ UINT32 uDataByteCount /* Maximum byte count supported by the pipe */ ) { /* Calculate the bus time for a low speed pipe */ if(USBHST_LOW_SPEED == uSpeed) { /* Calculate the bustime for an IN pipe */ if (USB_EHCD_DIR_IN == uDirection) { return (INT32)(64060+(2*USB_EHCD_HUB_LS_SETUP)+(677* (4+USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+ USB_EHCD_HOST_DELAY); } /* Calculate the bustime for an OUT pipe */ else { return (INT32)(64107+(2*USB_EHCD_HUB_LS_SETUP)+(667* (4+USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+ USB_EHCD_HOST_DELAY); } } /* End of if(Speed == USBHST_LOW_SPEED) */ /* Calculate the bus time for a Full speed pipe */ else if(USBHST_FULL_SPEED == uSpeed) { /* Calculate the bus time for a control, bulk or interrupt pipe */ if( USBHST_ISOCHRONOUS_TRANSFER != uPipeType) { return(INT32)(9107 +(84 * (4+ USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+ USB_EHCD_HOST_DELAY); } /* Calculate the bus time for an isochronous pipe */ else { /* Calculate the bus time for an IN endpoint */ if (USB_EHCD_DIR_IN == uDirection) { return (INT32)(7268+(84 * (4+ USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+ USB_EHCD_HOST_DELAY); } /* Calculate the bus time for an OUT endpoint */ else { return (INT32)(6265+(84 * (4+USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+ USB_EHCD_HOST_DELAY); } } /* End of else */ } /* End of else if(Speed == USBHST_FULL_SPEED) */ /* Calculate the bus time for a high speed pipe */ else if(USBHST_HIGH_SPEED == uSpeed) { /* Calculate the bus time for a control, bulk or interrupt pipe */ if(USBHST_ISOCHRONOUS_TRANSFER != uPipeType) { return (INT32)((55 * 8 * 2)+(3* (4 + USB_EHCD_BIT_STUFF_TIME(uDataByteCount))) + USB_EHCD_HOST_DELAY); } /* Calculate the bus time for an isochronous pipe */ else { return (INT32)((38 * 8 * 2)+(3* (4 + USB_EHCD_BIT_STUFF_TIME(uDataByteCount))) + USB_EHCD_HOST_DELAY); } } /* End of else if(Speed == USBHST_HIGH_SPEED) */ return -1; } /* End of usbEhcdCalculateBusTime() *//***************************************************************************** usbEhcdCheckBandwidth - checks the bandwidth availability** This function is used to check whether bandwidth is available and returns the* list which can hold the endpoint and also the mask value which indicates the* microframes which can hold the endpoint transfers.** <pHCDData> - Pointer to the EHCD_DATA structure.* <uBandwidth > - Bandwidth to be reserved.* <uSpeed> - Speed of the transfer.* <pEndpointDesc> - Pointer to the endpoint descriptor.* <puListIndex> - Pointer which can hold the list index which holds the endpoint* transfers* <puMicroFrameMask> - Pointer to the mask value which can hold the microframes* which can hold the endpoint transfers.* RETURNS: TRUE if the bandwidth can be accomodated.* FALSE if the bandwidth cannot be accomodated.** ERRNO:* None.** \NOMANUAL*/BOOLEAN usbEhcdCheckBandwidth ( pUSB_EHCD_DATA pHCDData, /* Pointer to the EHCD_DATA structure */ ULONG uBandwidth, /* Bandwidth to be reserved */ UINT32 uSpeed, /* Speed of the transfer */ pUSBHST_ENDPOINT_DESCRIPTOR pEndpointDesc, /* Pointer to the endpoint desc */ UINT32 * puListIndex,/* Pointer to the list index */ UINT32 * puMicroFrameMask /* Pointer to the microframe mask value */ ) { /* To hold the index into the periodic frame list */ UINT32 uCount = 0; /* To hold the no. of microframe to be reserved in a frame */ UINT32 uUFrameCount = 0; /* To hold the polling interval */ UINT32 uPollInterval = 0; /* To hold the bandwidth calculated */ UINT32 uCalculatedBandwidth = 0; /* To hold the least occupied bandwidth */ UINT32 uLeastBandwidth = 0; /* To hold the index of the frame which has the least occupied bandwidth */ UINT32 uLeastBwIndex = 0; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCheckBandwidth - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if ((NULL == pHCDData) || (0 == uBandwidth) || (NULL == pEndpointDesc) || (USBHST_HIGH_SPEED != uSpeed && USBHST_FULL_SPEED != uSpeed && USBHST_LOW_SPEED != uSpeed) || (NULL == puListIndex) || (NULL == puMicroFrameMask)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Invalid parameter\n",0,0,0,0); return FALSE; } /* Return error if the type is not a periodic endpoint type */ if ((USBHST_ISOCHRONOUS_TRANSFER != (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) && (USBHST_INTERRUPT_TRANSFER != (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK))) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Not a periodic endpoint\n",0,0,0,0); return FALSE; } /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); if (USBHST_ISOCHRONOUS_TRANSFER == (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { UINT32 uMaxBandwidth = 0; /* Starting from the leaf nodes, check whether * supplied bandwidth can be accomodated here */ for (uCount = 0; USB_EHCD_MAX_FRAMELIST_SIZE > uCount; uCount++) { uCalculatedBandwidth = 0; /* Calculate the bandwidth occupied in this frame */ USB_EHCD_CALCULATE_FRAME_BANDWIDTH(pHCDData, uCount, uCalculatedBandwidth); /* Get the maximum bandwidth used in a frame */ if (uCalculatedBandwidth > uMaxBandwidth) { uMaxBandwidth = uCalculatedBandwidth; } } /* End of for () */ /* If there is no bandwidth available, return an error */ if ((USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER) < (uMaxBandwidth + uBandwidth)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Bandwidth not available\n",0,0,0,0); /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); return FALSE; } } /* Initialize the least bandwidth to be the maximum bandwidth applicable */ uLeastBandwidth = USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER; /* Starting from the leaf nodes, check whether bandwidth is available */ for (uCount = 0; USB_EHCD_MAX_FRAMELIST_SIZE > uCount; uCount++) { /* initialize the calculated bandwidth to be 0 */ uCalculatedBandwidth = 0; /* Calculate the bandwidth occupied in this frame */ USB_EHCD_CALCULATE_FRAME_BANDWIDTH(pHCDData, uCount, uCalculatedBandwidth); /* If the bandwidth occupied is less than the previous least bandwidth, * this becomes the least bandwidth reserved. */ if (uCalculatedBandwidth < uLeastBandwidth) { uLeastBandwidth = uCalculatedBandwidth; uLeastBwIndex = uCount; } } /* End of for () */ /* If there is no bandwidth available, return an error */ if ((USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER) < (uLeastBandwidth + uBandwidth)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Bandwidth not available\n",0,0,0,0); /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); return FALSE; } /* Get the polling interval of the endpoint */ uPollInterval = pEndpointDesc->bInterval; /* Check if it is a low or full speed device endpoint */ if (USBHST_HIGH_SPEED != uSpeed) { /* No. of microframe count will be max used for full speed */ uUFrameCount = USB_EHCD_MAX_FULL_SPEED_UFRAME; /* Check if it is an interrupt endpoint */ if (USBHST_INTERRUPT_TRANSFER == (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { /* Array holding the start and complete split masks */ UINT32 uSplitMask[USB_EHCD_MAX_INT_SPLIT_MASKS] = { USB_EHCD_SPLIT_MASK_1, USB_EHCD_SPLIT_MASK_2, USB_EHCD_SPLIT_MASK_3, USB_EHCD_SPLIT_MASK_4 }; /* Identify the index of the leaf of the tree, which is to be used*/ *puListIndex = pHCDData->FrameListData[uLeastBwIndex].uNextListIndex; /* 32 is the maximum polling interval which is supported. * So if the polling interval is greater than 32, the endpoint * will be polled every 32 ms. */ if (USB_EHCD_MAX_USB11_INTERRUPT_POLL_IN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -