📄 usbehcdbandwidth.c
字号:
if(NULL == pBandwidth) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdIsBandwidthAvailable - Memory not allocated for the bandwidth\n",0,0,0,0); return USBHST_MEMORY_NOT_ALLOCATED; } /* Initialize the element of array to zero */ OS_MEMSET(pBandwidth, 0, sizeof(struct _bandwidth_)); /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* Get the bandwidth used for isochronous in frame list */ USB_EHCD_GET_ISOCH_BANDWIDTH(pHCDData, pBandwidth->IsochBW); /* Get the bandwidth used for isochronous in frame list */ USB_EHCD_GET_INTERRUPT_BANDWIDTH(pHCDData, pBandwidth->InterruptBW); /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Subtract bandwidth for each tree node */ for (uTreeNodeCount =0; USB_EHCD_MAX_TREE_NODES > uTreeNodeCount; uTreeNodeCount++) { /* Initialize the pQH */ pUSB_EHCD_QH pQH = (pUSB_EHCD_QH) ((UINT32)pHCDData->TreeListData[uTreeNodeCount].pHeadPointer - USB_EHCD_QH_HEADER_SIZE); /* If there is no QH attached here, only dummy QH present */ if((pHCDData->TreeListData[uTreeNodeCount].pTailPointer == (pVOID) ((UINT32)pQH + USB_EHCD_QH_HEADER_SIZE)) || (NULL == pQH->pNext)) { continue; } do { /* Get the first active QH pointer in first iteration thene get next pointer*/ pQH = pQH->pNext; if(uDeviceAddress == pQH->pHCDPipe->uAddress) { for (uUFrameIndex = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uUFrameIndex; uUFrameIndex++) { /* Check if bandwidth is to be updated for this * microframe and update the bandwidth */ if (0 != ((pQH->pHCDPipe->uUFrameMaskValue >> uUFrameIndex) & 0x01)) { pBandwidth->InterruptBW[uTreeNodeCount][uUFrameIndex] -= pQH->pHCDPipe->uBandwidth; } } /* End of for() */ } /* End of if (uDevice...) */ }while(pQH != (pUSB_EHCD_QH)((UINT32) pHCDData->TreeListData[uTreeNodeCount].pTailPointer - USB_EHCD_QH_HEADER_SIZE)); } /* Get pointer of the isochronous pipe list */ for (pHCDPipe = pHCDData->pIsochPipeList; NULL != pHCDPipe; pHCDPipe = pHCDPipe->pNext) { if (uDeviceAddress == pHCDPipe->uAddress) { /* This loop will remove the bandwidth * allocated in each of the frames */ for (uFrameIndex = pHCDPipe->uListIndex; USB_EHCD_MAX_FRAMELIST_SIZE > uFrameIndex; uFrameIndex++) { /* This loop will update the frame list bandwidth * for every microframe */ for (uUFrameIndex = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uUFrameIndex; uUFrameIndex++) { /* Check if bandwidth is to be updated for this * microframe and update the bandwidth */ if (0 != ((pHCDPipe->uUFrameMaskValue >> uUFrameIndex) & 0x01)) { pBandwidth->IsochBW[uFrameIndex][uUFrameIndex] -= pHCDPipe->uBandwidth; } } /* End of loop for each microframe */ } /* End of loop for each frame */ } /* End of if */ } /* End of loop for pipe search */ /* Get the bandwidth per frame in the frame list */ USB_EHCD_GET_FRAME_BANDWIDTH(pHCDData, pBandwidth->IsochBW, pBandwidth->InterruptBW, pTotalFrameBW); /* free the memory allocated */ OS_FREE(pBandwidth); return USBHST_SUCCESS; } /* End of function *//***************************************************************************** usbEhcdAddBandwidth - checks and allocate the bandwidth availability** This function is used to check whether bandwidth is available and returns the* updated bandwidth array** <uDeviceSpeed> - Device Speed of the transfer.* <pInterfaceDesc> - Pointer to the interface desc.* <pFrameBW> - Array of bandwidth list** RETURNS: TRUE if the bandwidth can be accomodated.* FALSE if the bandwidth cannot be accomodated.** ERRNO:* None.* \NOMANUAL*/BOOLEAN usbEhcdAddBandwidth ( UINT32 uDeviceSpeed, /* Device Speed of the transfer */ pUSBHST_INTERFACE_DESCRIPTOR pInterfaceDesc, /* Pointer to the interface desc */ UINT32 * pTotalFrameBW /* Array of bandwidth list */ ) { /* To hold the maximum packet size for the endpoint */ UINT32 uMaxPacketSize = 0; /* To hold the no. of micro frame in a frame */ UINT32 uMicroFrameCount = 0; /* To hold the frame index inthe frame list */ UINT32 uFrameIndex = 0, uFrameListIndex = 0; /* To hold the end point descriptor */ pUSBHST_ENDPOINT_DESCRIPTOR pEPDesc = NULL; /* To hold the count and end point count*/ UINT32 uCount, uEPCount; /* To hold the supported poll interval */ UINT32 uPollInterval = 0; /* To hold the bandwidth */ UINT32 uBandwidth = 0; /* If the device speed is high speed, the payload is * equal the maxpacketsize * number of packets that can * be sent in a microframe. * The bits 0 to 10 give the maximum packet size. The bits 11 and 12 * give the (number of packets in a microframe - 1). */ uEPCount = pInterfaceDesc->bNumEndpoints; pEPDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)((UINT8 *)(pInterfaceDesc) + pInterfaceDesc->bLength); while(USBHST_ENDPOINT_DESC!=pEPDesc->bDescriptorType) { pEPDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)((UINT8 *)(pEPDesc) + pEPDesc->bLength); } for (uCount=0; uCount < uEPCount; uCount++) { /* Get the polling interval of the endpoint */ uPollInterval = pEPDesc->bInterval; if (USBHST_HIGH_SPEED == uDeviceSpeed) { uMaxPacketSize = (OS_UINT16_LE_TO_CPU(pEPDesc->wMaxPacketSize) & USB_EHCD_ENDPOINT_MAX_PACKET_SIZE_MASK) * (((OS_UINT16_LE_TO_CPU(pEPDesc->wMaxPacketSize) & USB_EHCD_ENDPOINT_NUMBER_OF_TRANSACTIONS_MASK) >> 11) + 1); /* Get the polling interval */ uPollInterval = 1 << (uPollInterval - 1); /* Get the no. of micro frame to be scheduled in a frame */ if (0 == (uPollInterval % USB_EHCD_MAX_MICROFRAME_NUMBER)) { /* The endpoint is to be polled one microframe in the frame */ uMicroFrameCount = 1; } else { uMicroFrameCount = USB_EHCD_MAX_MICROFRAME_NUMBER/ (uPollInterval % USB_EHCD_MAX_MICROFRAME_NUMBER); } } /* If it is low or full speed, the maximum packet size is the same * as that retrieved from the endpoint descriptor */ else { uMaxPacketSize = OS_UINT16_LE_TO_CPU(pEPDesc->wMaxPacketSize); /* If it is an Out end point */ if (0 == (pEPDesc->bEndpointAddress & USB_EHCD_DIR_IN)) { if (USBHST_INTERRUPT_TRANSFER == (pEPDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { /* Only one start split and 3 complete split will be scheduled in one frame */ uMicroFrameCount = 4; } else { /* Only one start split will be scheduled in one frame */ uMicroFrameCount = 1; } } else /* If it is an In end point */ { /* Only one start split and 3 complete split will be scheduled in one frame */ uMicroFrameCount = 4; } } /* Calculate the bandwidth which is required for this pipe */ uBandwidth = usbEhcdCalculateBusTime(USBHST_HIGH_SPEED, (pEPDesc->bEndpointAddress) & USB_EHCD_DIR_IN, (pEPDesc->bmAttributes) & USB_EHCD_ENDPOINT_TYPE_MASK, uMaxPacketSize); /* Bandwidth required for each frame */ uBandwidth *= uMicroFrameCount; if (USBHST_ISOCHRONOUS_TRANSFER == (pEPDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { /* To hold the max bandwidth utilised */ UINT32 uMaxBandwidth = 0; for (uFrameIndex = 0; USB_EHCD_MAX_FRAMELIST_SIZE > uFrameIndex; uFrameIndex++) { /* Add the current BW required in each frame*/ pTotalFrameBW[uFrameIndex] += uBandwidth; /* Get the maximum bandwidth used in a frame */ if (pTotalFrameBW[uFrameIndex] > uMaxBandwidth) { uMaxBandwidth = pTotalFrameBW[uFrameIndex]; } } /* End of for () */ /* If there is no bandwidth available, return an error */ if ((USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER) < uMaxBandwidth) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Bandwidth not available\n",0,0,0,0); return FALSE; } } else if(USBHST_INTERRUPT_TRANSFER == (pEPDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { /* Initialize with the min bandwidth */ UINT32 uMinBandwidth = pTotalFrameBW[0]; if (USBHST_HIGH_SPEED == uDeviceSpeed) { /* Calculate the polling interval in terms of frames */ if (0 != (uPollInterval % USB_EHCD_MAX_MICROFRAME_NUMBER)) { uPollInterval = 1; } else { uPollInterval /= USB_EHCD_MAX_MICROFRAME_NUMBER; } } /* if the pollling intervalis greater than supported then copy the max only */ if (USB_EHCD_MAX_USB11_INTERRUPT_POLL_INTERVAL < uPollInterval) { uPollInterval = USB_EHCD_MAX_USB11_INTERRUPT_POLL_INTERVAL; } for (uFrameIndex = 0; uPollInterval > uFrameIndex; uFrameIndex++) { /* Get the minimum bandwidth used in a frame */ if (pTotalFrameBW[uFrameIndex] < uMinBandwidth) { uMinBandwidth = pTotalFrameBW[uFrameIndex]; uFrameListIndex = uFrameIndex; } } for (uFrameIndex = uFrameListIndex; USB_EHCD_MAX_FRAMELIST_SIZE > uFrameIndex; uFrameIndex+=uPollInterval) { pTotalFrameBW[uFrameIndex] += uBandwidth; /* If there is no bandwidth available, return an error */ if ((USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER) < pTotalFrameBW[uFrameIndex]) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Bandwidth not available\n",0,0,0,0); return FALSE; } } }/* end of Interrupt */ pEPDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)((UINT8 *)(pEPDesc) + pEPDesc->bLength); } /* end of loop for each endpoint */ return TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -