📄 usbehcdtransfermanagement.c
字号:
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 != ((uUFrameMask >> uUFrameIndex) & 0x01)) { pHCDData->TreeListData[uListIndex].uBandwidth[uUFrameIndex] += uBandwidth; } } /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Update the overall bandwidth */ bStatus = usbEhcdUpdateBandwidth(pHCDData); /* * If the bandwidth reservation is not successful, * release the bandwidth */ if (FALSE == bStatus) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCreatePipe - Bandwidth not available\n",0,0,0,0); /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* * This loop will update the tree 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 != ((uUFrameMask >> uUFrameIndex) & 0x01)) { pHCDData->TreeListData[uListIndex]. uBandwidth[uUFrameIndex] -= uBandwidth; } } /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Update the bandwidth. * Nothing can be done with the return value. So not * checking for return status. */ usbEhcdUpdateBandwidth(pHCDData); /* Free memory allocated for the USB_EHCD_PIPE */ OS_FREE(pHCDPipe); return USBHST_INSUFFICIENT_BANDWIDTH; } } /* End of if (USBHST_INTERRUPT_TRANSFER == pHCDPipe->uEndpointType) */ /* This is for the isochronous endpoint */ else { /* To hold the index into the frame list */ UINT32 uFrameIndex = 0; /* Exclusively access the list */ OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID, OS_WAIT_INFINITE); /* Add this pipe in the list of isochronous pipe maintained in HCD data */ USB_EHCD_ADD_TO_ISOCH_PIPE_LIST(pHCDData, pHCDPipe); /* Release the exclusive list access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* This loop updates the bandwidth in every frame * Note that the list index is the first index into the frame * list */ for (uFrameIndex = 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 != ((uUFrameMask >> uUFrameIndex) & 0x01)) { pHCDData->FrameListData[uFrameIndex]. uBandwidth[uUFrameIndex] += uBandwidth; pHCDData->FrameBandwidth[uFrameIndex][uUFrameIndex] += uBandwidth; } /* Check if bandwidth has exceeded the limits */ if (USB_EHCD_EIGHTY_PERCENT_BW < ((pHCDData->FrameBandwidth[uFrameIndex][uUFrameIndex]))) { OS_LOG_MESSAGE_HIGH(EHCD,"EHCD_CreatePipe - Bandwidth \ has exceeded the limits\n",0,0,0,0); /* Release the bandwidth allocated in all * the other microframes in this frame */ for (;(USB_EHCD_MAX_MICROFRAME_NUMBER > uUFrameIndex); uUFrameIndex--) { /* If bandwidth has been reserved, * unreserve the bandwidth reserved. */ if (0 != ((uUFrameMask >> uUFrameIndex) & 0x01)) { pHCDData->FrameListData[uFrameIndex]. uBandwidth[uUFrameIndex] -= uBandwidth; pHCDData-> FrameBandwidth[uFrameIndex][uUFrameIndex] -= uBandwidth; } } /* Release the bandwidth allocated in * the remaining frames */ /* If the bandwidth is being reserved for the * first time, then this condition will fail * indicating that the bandwidth has already been * released */ if (uListIndex < uFrameIndex) { /* As this frame's bandwidth has already * been released, start releasing from * the previous frame index */ uFrameIndex--; for (;(uFrameIndex >= uListIndex) && (USB_EHCD_MAX_FRAMELIST_SIZE > uFrameIndex); uFrameIndex --) { /* Release the bandwidth in all the microframes * in the frame */ for (uUFrameIndex = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uUFrameIndex; uUFrameIndex++) { pHCDData->FrameListData[uFrameIndex]. uBandwidth[uUFrameIndex] -= uBandwidth; pHCDData-> FrameBandwidth[uFrameIndex][uUFrameIndex] -= uBandwidth; } } } /* Free the memory allocated for the * EHCD_PIPE structure. */ OS_FREE(pHCDPipe); /* Release the exclusive access of the * bandwidth resource */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Return an error from the function */ return USBHST_INSUFFICIENT_BANDWIDTH; } } } /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Copy the step value and the mask values */ pHCDPipe->uUFrameMaskValue = uUFrameMask; return USBHST_SUCCESS; } } /* End of if ((USBHST_ISOCHRONOUS_TRANSFER ==... */ /* The following code will be executed for non-isochronous endpoints */ /* Create an empty QH */ pQH = usbEhcdFormEmptyQH(pHCDData); /* Check if QH is valid */ if (NULL == pQH) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCreatePipe - QH is invalid\n",0,0,0,0); Status = usbEhcdDeletePipe(uBusIndex, *puPipeHandle); if (USBHST_SUCCESS != Status) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCreatePipe - Error returned during Pipe deletion\n",0,0,0,0); return Status; } return USBHST_FAILURE; } /* Copy the QH pointer in USB_EHCD_PIPE data structure */ pHCDPipe->pQH = pQH; /* Copy the USB_EHCD_PIPE pointer in the QH */ pQH->pHCDPipe = pHCDPipe; /* Populate the fields of the QH - start */ /* Populate the device address */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, uDeviceAddress, ENDPOINT_CHARACTERISTICS_DEVICE_ADDRESS); /* Populate the endpoint number */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, ((pEndpointDesc->bEndpointAddress) & USB_EHCD_ENDPOINT_NUMBER_MASK), ENDPOINT_CHARACTERISTICS_ENDPT_NUMBER); /* Populate the device speed */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, uDeviceSpeed, ENDPOINT_CHARACTERISTICS_ENDPT_SPEED); /* * A control transfer uses different stages of transfer(atleast 2). * So if it is a control transfer, use the data toggle field * from the TD */ if (USBHST_CONTROL_TRANSFER == (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { /* pQH->dword1.dtc = USB_EHCD_DTC_RETRIEVE_FROM_QTD; */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, USB_EHCD_DTC_RETRIEVE_FROM_QTD, ENDPOINT_CHARACTERISTICS_DTC); } /* * For bulk and interrupt, use the data toggle field from QH * Note that this function is not called for isochronous */ else { /* pQH->dword1.dtc = USB_EHCD_DTC_PRESERVE_IN_QH; */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, USB_EHCD_DTC_PRESERVE_IN_QH, ENDPOINT_CHARACTERISTICS_DTC); } /* Update the maximum packet size */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, ((pEndpointDesc->wMaxPacketSize) & USB_EHCD_ENDPOINT_MAX_PACKET_SIZE_MASK), ENDPOINT_CHARACTERISTICS_MAXIMUM_PACKET_LENGTH); /* * This field is to be set if it is not a high speed device and the * endpoint is a control endpoint */ controlEndFlag = ((USBHST_CONTROL_TRANSFER == (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) && (USBHST_HIGH_SPEED != uDeviceSpeed))? 1:0; USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCharacteristics, controlEndFlag, ENDPOINT_CHARACTERISTICS_CONTROL_ENDPOINT_FLAG); /* Default set this bit to 1 (1 transaction per microframe) * For periodic high speed enpoints, mult field is calculated * accordingly *//* pQH->dword2.mult = 1;*/ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCapabilities, 1, ENDPOINT_CAPABILITIES_MULT ); /* If the pipe is to be created for a full/low speed device * then it should support split transfers. So * update the hub address to which the full/low speed device * is attached and the port number to which it is attached */ if (uDeviceSpeed != USBHST_HIGH_SPEED) { USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCapabilities, ((uHighSpeedHubInfo & USB_EHCD_PARENT_HUB_ADDRESS_MASK)>> 8), ENDPOINT_CAPABILITIES_HUB_ADDR ); USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCapabilities, (uHighSpeedHubInfo & USB_EHCD_HUB_PORT_NUMBER_MASK), ENDPOINT_CAPABILITIES_PORT_NUMBER); /* If it is an interrupt transfer, * update the start and complete split masks */ if (0 != uUFrameMask) { /* To hold temporarily the mask value */ UINT8 uTempMask = uUFrameMask; /* To hold the mask value */ UINT8 uSMask = 0x01; /* To hold the shift count */ UINT8 uShiftCount = 0; /* This loop extracts only the start split mask */ while (0 != uTempMask) { /* Update the start split mask value */ if (0 != (uTempMask & 0x01))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -