📄 usbehcdtransfermanagement.c
字号:
pQH->uEndPointCapabilities, ((((pEndpointDesc->wMaxPacketSize) & USB_EHCD_ENDPOINT_NUMBER_OF_TRANSACTIONS_MASK) >> 11)+ 1), ENDPOINT_CAPABILITIES_MULT ); /* Update the mask value in the QH */ USB_EHCD_SET_BITFIELD(QH, pQH->uEndPointCapabilities, uUFrameMask, ENDPOINT_CAPABILITIES_UFRAME_S ); }/* End of else */ }/* End of else */ /* Populate the fields of the QH - End */ /* Exclusively access the list */ OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID, OS_WAIT_INFINITE); /* Link the Queue head in the list - start */ /* If it is the interrupt endpoint, link it to the periodic schedule */ if (USBHST_INTERRUPT_TRANSFER == pHCDPipe->uEndpointType) { USB_EHCD_ADD_TO_HC_INTERRUPT_SCHEDULE(pHCDData, uListIndex, pQH); } /* * If it is a control or bulk endpoint, * link it to the asynchronous schedule. */ else { USB_EHCD_ADD_TO_HC_ASYNCH_SCHEDULE(pHCDData, pQH); } /* Release the exclusive list access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* Link the Queue head in the list - End */ OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCreatePipe - Exit\n",0,0,0,0); return USBHST_SUCCESS; } /* End of function usbEhcdCreatePipe() *//***************************************************************************** usbEhcdDeletePipe - deletes a pipe created already.** This function is used to delete a pipe specific to an* endpoint.** RETURNS: * USBHST_SUCCESS - Returned if the pipe was deleted successfully* USBHST_INVALID_PARAMETER - Returned if the parameters are* not valid.* ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbEhcdDeletePipe ( UINT8 uBusIndex, /* Index of the host controller */ UINT32 uPipeHandle /* Handle of the pipe to be deleted */ ) { /* To hold the status of the request */ USBHST_STATUS Status = USBHST_FAILURE; /* 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, "usbEhcdDeletePipe() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdDeletePipe - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if ((g_EHCDControllerCount <= uBusIndex) || (0 == uPipeHandle)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDeletePipe - parameters are 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); /* Extract the USB_EHCD_PIPE data structure */ pHCDPipe = (pUSB_EHCD_PIPE)uPipeHandle; /* Check if the request is for the Root hub and route it */ if ((pHCDData->RHData.pInterruptPipe == pHCDPipe) || (pHCDData->RHData.pControlPipe == pHCDPipe)) { Status = usbEhcdRHDeletePipe(pHCDData, uPipeHandle); return Status; } /* Check if the endpoint type is valid */ if ((USBHST_CONTROL_TRANSFER != pHCDPipe->uEndpointType) && (USBHST_BULK_TRANSFER != pHCDPipe->uEndpointType) && (USBHST_INTERRUPT_TRANSFER != pHCDPipe->uEndpointType) && (USBHST_ISOCHRONOUS_TRANSFER != pHCDPipe->uEndpointType)) { OS_LOG_MESSAGE_HIGH(EHCD,"EHCD_CreatePipe - Invalid endpoint type\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Exclusively access the list */ OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID, OS_WAIT_INFINITE); /* Mark the endpoint for deletion */ pHCDPipe->PipeDeletedFlag = TRUE; /* Check if it is a non-periodic endpoint */ if ((USBHST_CONTROL_TRANSFER == pHCDPipe->uEndpointType) || (USBHST_BULK_TRANSFER == pHCDPipe->uEndpointType)) { /* To hold the pointer to the EHCD maintained pipe data structure */ pUSB_EHCD_PIPE pHCDTempPipe = NULL; /* Search the asychronous list and update the next pointers */ for (pHCDTempPipe = pHCDData->pDefaultPipe; (pHCDPipe != pHCDTempPipe->pNext) && (pHCDData->pDefaultPipe != pHCDTempPipe->pNext); pHCDTempPipe = pHCDTempPipe->pNext); /* Deletion of the default pipe is not through this function. So * the pHCDPipe can never be the same as pHCDData->pDefaultPipe */ /* Update the HCD maintained link pointers */ pHCDTempPipe->pNext = pHCDPipe->pNext; /* If this QH forms the tail, update the tail element */ if (pHCDData->pAsynchTailPipe == pHCDPipe) { pHCDData->pAsynchTailPipe = pHCDTempPipe; } /* Update the HC maintained next pointers */ USB_EHCD_SET_BITFIELD(QH, pHCDTempPipe->pQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_PCI(pHCDPipe->pNext->pQH) >> 5), HORIZONTAL_LINK_POINTER); /* Disable the asynchronous schedule */ USB_EHCD_CLR_BIT(pHCDData, USBCMD, ASYNCH_SCHEDULE_ENABLE); OS_DELAY_MS(1); USB_EHCD_SET_FIELD(pHCDData, ASYNCLISTADDR, LINK_PTR_LOW, ((UINT32)USB_EHCD_CONVERT_TO_PCI(pHCDPipe->pNext->pQH) >> USB_EHCD_ASYNCHLISTADDR_LINK_PTR_LOW)); /* Enable the asynchronous schedule */ USB_EHCD_SET_BIT(pHCDData, USBCMD, ASYNCH_SCHEDULE_ENABLE); /* Release the exclusive access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* 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_ASYNCH_RECLAMATION_LIST(pHCDData, pHCDPipe); /* * Enable an interrupt to be generated * when the Asynchronous list is advanced. */ USB_EHCD_SET_BIT_USBCMD_INT_ON_ASYNC_ADVANCE_DOORBELL(pHCDData); /* Enable the aynch advance interrupt */ USB_EHCD_SET_BIT_USBINTR_INT_ON_ASYNC_ADVANCE_DOORBELL(pHCDData); /* 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); } /* It is a periodic endpoint, */ else { /* 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 */ for (;(pTempQH != (pUSB_EHCD_QH)pHCDData-> TreeListData[pHCDPipe->uListIndex].pTailPointer) && (pTempQH->pNext != pHCDPipe->pQH) && (NULL != pTempQH); pTempQH = pTempQH->pNext); /* 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 == pHCDPipe->pQH) { pHCDData->TreeListData[pHCDPipe->uListIndex].pTailPointer = pTempQH; } /* Copy the t bits */ USB_EHCD_SET_BITFIELD( QH, pTempQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_GET_BITFIELD( 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) { /* The QH's next pointer should point to the tail's next element */ USB_EHCD_SET_BITFIELD(QH, pTempQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_PCI(pHCDPipe->pQH->pNext) >> 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(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; /* 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -