📄 usbehcdtransfermanagement.c
字号:
{ /* To hold the bandwidth reservation status */ BOOLEAN bStatus = FALSE; /* To hold the microframe index */ UINT8 uUFrameIndex = 0; /* Check if it is an interrupt endpoint */ if (USBHST_INTERRUPT_TRANSFER == pHCDPipe->uEndpointType) { /* Pointer to the tail of the list */ pUSB_EHCD_QH pTempQH = NULL; /* Copy the first element of the list */ pTempQH = (pUSB_EHCD_QH) pHCDData->TreeListData[pHCDPipe->uListIndex].pHeadPointer; /* This loop searches for the QH which needs to be removed */ while ((pTempQH != (pUSB_EHCD_QH)pHCDData-> TreeListData[pHCDPipe->uListIndex].pTailPointer) && (NULL != pTempQH)) { /* Retrieve the HCD accessible pointer */ pTempQH = (pUSB_EHCD_QH)((UINT32)pTempQH - USB_EHCD_QH_HEADER_SIZE); /* * If the next element is the same QH * which is being removed, break from the loop. */ if (pTempQH->pNext == pHCDPipe->pQH) break; /* If the next element is not NULL, update the temp pointer */ if (pTempQH->pNext != NULL) pTempQH = (pUSB_EHCD_QH)((UINT32)pTempQH->pNext + USB_EHCD_QH_HEADER_SIZE); else pTempQH = NULL; } /* Check if the loop has exited as the QH is not found * Note that 'pTempQH' points to the previous QH always */ if ((pTempQH == (pUSB_EHCD_QH)pHCDData-> TreeListData[pHCDPipe->uListIndex].pTailPointer) || (NULL == pTempQH)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDeletePipe - QH is not found\n",0,0,0,0); return USBHST_FAILURE; } /* Update the next pointers */ pTempQH->pNext = pHCDPipe->pQH->pNext; /* If the pointer is the tail, update the tail pointer */ if (pHCDData->TreeListData[pHCDPipe->uListIndex].pTailPointer == (pVOID)((UINT32)pHCDPipe->pQH + USB_EHCD_QH_HEADER_SIZE)) { pHCDData->TreeListData[pHCDPipe->uListIndex].pTailPointer = (pVOID)((UINT32)pTempQH + USB_EHCD_QH_HEADER_SIZE); } /* Copy the t bits */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pTempQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_GET_BITFIELD(uBusIndex, QH, pHCDPipe->pQH->uQueueHeadHorizontalLinkPointer, HORIZONTAL_LINK_POINTER_T), HORIZONTAL_LINK_POINTER_T); /* If the QH's next pointer is valid, update the previous head's * next pointer */ if (NULL != pHCDPipe->pQH->pNext) { /* * Fetch the address of the host controller accessable region * by adding the offest USB_EHCD_QH_HEADER_SIZE to queue head */ pQHTemp = (PUCHAR)pHCDPipe->pQH->pNext; pQHTemp += USB_EHCD_QH_HEADER_SIZE; USB_EHCD_SET_BITFIELD(uBusIndex, QH, pTempQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex,pQHTemp) >> 5), HORIZONTAL_LINK_POINTER); } /* The next pointer is not valid, update the next link pointer * to point to an invalid link address */ else { USB_EHCD_SET_BITFIELD(uBusIndex, QH, pTempQH->uQueueHeadHorizontalLinkPointer, ((unsigned)NULL), HORIZONTAL_LINK_POINTER ); } /* Release the resource access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* This loop will update the tree node 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)) { pHCDData->TreeListData[pHCDPipe->uListIndex]. uBandwidth[uUFrameIndex] -= pHCDPipe->uBandwidth; } } /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Update the bandwidth */ bStatus = usbEhcdUpdateBandwidth(pHCDData); /* Check if bandwidth updation is successful */ if (FALSE == bStatus) { OS_ASSERT(FALSE); } }/* End of if ((USBHST_INTERRUPT_TRANSFER == */ /* Isochronous endpoint removal */ else { /* To hold the pointer to the request information */ pUSB_EHCD_REQUEST_INFO pRequestInfo = NULL; /* To hold the frame index */ UINT16 uFrameIndex = 0; /* Remove pipe from isoch list maintained in the HCD data */ USB_EHCD_REMOVE_ISOCH_PIPE(pHCDData, pHCDPipe); /* Extract the first request element */ for ((pRequestInfo = pHCDPipe->pRequestQueueHead); (NULL != pRequestInfo); (pRequestInfo = pRequestInfo->pNext)) { /* Unlink all the isoch TDs associated with this request */ USB_EHCD_UNLINK_ISOCH_REQ(pHCDData, pRequestInfo, pHCDPipe->uSpeed); } /* Release the exclusive access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* 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)) { pHCDData->FrameListData[uFrameIndex]. uBandwidth[uUFrameIndex] -= pHCDPipe->uBandwidth; pHCDData->FrameBandwidth[uFrameIndex][uUFrameIndex] -= pHCDPipe->uBandwidth; } } } /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Update the bandwidth */ bStatus = usbEhcdUpdateBandwidth(pHCDData); /* Check if bandwidth updation is successful */ if (FALSE == bStatus) { OS_ASSERT(FALSE); } }/* End of isochronous endpoint removal request handling */ /* Create a synchronisation event*/ if (NULL == (pHCDPipe->DeleteSynchEventID = OS_CREATE_EVENT(OS_EVENT_NON_SIGNALED))) { OS_ASSERT(FALSE); } /* Add to the reclamation list */ USB_EHCD_ADD_TO_PERIODIC_RECLAMATION_LIST(pHCDData, pHCDPipe);#ifndef USB_EHCD_ENABLE_POLLING /* Enable the interrupt to be generated on a frame list rollover */ USB_EHCD_SET_BIT_USBINTR_INT_ON_FRAME_LIST_ROLLOVER(pHCDData);#else /* Give sufficient delay for the frame list to rollover. This is * the worst case condition where the frame list rolls over in * less than 1024 ms */ OS_DELAY_MS(USB_EHCD_MAX_FRAMELIST_SIZE);#endif /* Wait for event handler task to free the resources */ OS_WAIT_FOR_EVENT(pHCDPipe->DeleteSynchEventID, OS_WAIT_INFINITE); /* Delete the event created */ OS_DESTROY_EVENT(pHCDPipe->DeleteSynchEventID); /* Free the PIPE */ OS_FREE(pHCDPipe); }/* End of else */ OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdDeletePipe - Exit\n",0,0,0,0); /* Return the success status */ return USBHST_SUCCESS; }/* End of function usbEhcdDeletePipe() *//***************************************************************************** usbEhcdModifyDefaultPipe - modifies the default pipe characteristics.** This function is used to modify the properties (device speed and maximum * packet size) of the default pipe (address 0, endpoint 0). <uBusIndex> * specifies the host controller bus index. <uDefaultPipeHandle> holds the* pipe handle of the default pipe. <uDeviceSpeed> is the speed of the * device which needs to be modified. <uMaxPacketSize> is the maximum packet* size of the default pipe which needs to be modified. <uHighSpeedHubInfo>* specifies the nearest high speed hub and the port number information. This* information will be used to handle a split transfer to the full / low speed* device. The high byte will hold the high speed hub address. The low byte* will hold the port number to which the USB 1.1 device is connected.*** RETURNS: * USBHST_SUCCESS - Returned if the deafult pipe properties were modified* successfully.* USBHST_INVALID_PARAMETER - Returned if the parameters are not valid.** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbEhcdModifyDefaultPipe ( UINT8 uBusIndex, /* Host controller bus index */ UINT32 uDefaultPipeHandle, /* Handle to the default pipe */ UINT8 uDeviceSpeed, /* Speed of the device in default state */ UINT8 uMaxPacketSize, /* Maximum packet size of the default pipe */ UINT16 uHighSpeedHubInfo /* High speed hub info for USB 1.1 device */ ) { /* To hold the pointer to the EHCD maintained pipe data structure */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* Pointer to the HCD specific data structure */ pUSB_EHCD_DATA pHCDData = NULL; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_TRANSFER, "usbEhcdModifyDefaultPipe() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdModifyDefaultPipe - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if ((g_EHCDControllerCount <= uBusIndex) || (0 == uDefaultPipeHandle) || (USBHST_HIGH_SPEED != uDeviceSpeed && USBHST_FULL_SPEED != uDeviceSpeed && USBHST_LOW_SPEED != uDeviceSpeed)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdModifyDefaultPipe - parameters not valid\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Extract the global data structure */ pHCDData = g_pEHCDData[uBusIndex]; /* Assert if the global pointer is not valid */ OS_ASSERT(NULL != pHCDData); /* Check if this request is for the Root hub */ if (0 == pHCDData->RHData.uDeviceAddress) { return USBHST_SUCCESS; } /* WARNING : This function will change on split support */ /* Extract the default pipe handle */ pHCDPipe = (pUSB_EHCD_PIPE)uDefaultPipeHandle; /* Flush the contents of the QH to RAM */ CACHE_DMA_INVALIDATE (pHCDPipe->pQH, sizeof(USB_EHCD_QH)); /* Modify the default pipe contents */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pHCDPipe->pQH->uEndPointCharacteristics, uDeviceSpeed, ENDPOINT_CHARACTERISTICS_ENDPT_SPEED ); /*pHCDPipe->pQH->dword2.mult = 1;*/ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pHCDPipe->pQH->uEndPointCapabilities, 1, ENDPOINT_CAPABILITIES_MULT ); /* Update the hub address and port number for the USB 1.1 device */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -