📄 usbehcdeventhandler.c
字号:
return; }/* End of usbEhcdProcessTransferCompletion() *//***************************************************************************** usbEhcdCleanupAsynchPipes - cleans up the asynchronous pipes.** This is used to perform the cleanup functionality of the asynchronous pipes.** RETURNS: N/A.** ERRNO:* None.** \NOMANUAL*/LOCAL VOID usbEhcdCleanupAsynchPipes ( pUSB_EHCD_DATA pEHCDData ) { /* To hold the pointer to the pipe information */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* To hold the request information */ pUSB_EHCD_REQUEST_INFO pRequestInfo = NULL; /* To hold the temporary request information */ pUSB_EHCD_REQUEST_INFO pTempRequestInfo = NULL; /* Pointer to the tail of Queue TD */ pUSB_EHCD_QTD pQTDTail = NULL; /* Pointer to the head of Queue TD */ pUSB_EHCD_QTD pQTDHead = NULL; /* Pointer to the temporary QTD */ pUSB_EHCD_QTD pTempQTD = NULL; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_EVENT_HANDLER, "usbEhcdCleanupAsynchPipes() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCleanupAsynchPipes - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if (NULL == pEHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCleanupAsynchPipes - parameter not valid\n",0,0,0,0); return; } /* Exclusively access the reclamation list */ OS_WAIT_FOR_EVENT(pEHCDData->ReclamationListSynchEventID, OS_WAIT_INFINITE); /* Search the list and remove the element */ for (pHCDPipe = pEHCDData->pAsynchReclamationListHead; NULL != pHCDPipe; pHCDPipe = pEHCDData->pAsynchReclamationListHead) { /* Update the head of the reclamation list */ pEHCDData->pAsynchReclamationListHead = pHCDPipe->pNext; /* Release the reclamationsychronisation event */ OS_RELEASE_EVENT(pEHCDData->ReclamationListSynchEventID); /* This loop retrieves the requests which are queued to the * endpoint and releases the TDs. This is done by exclusively * accessing the request list. */ /* Exclusively access the request synchronisation list * This is done as the request list which is maintained for the HC * is also accessed. */ OS_WAIT_FOR_EVENT(pEHCDData->RequestSynchEventID, OS_WAIT_INFINITE); /* Remove the requests from the endpoint queue */ for (pRequestInfo = pHCDPipe->pRequestQueueHead; NULL != pRequestInfo; pRequestInfo = pHCDPipe->pRequestQueueHead) { /* Check if the request is not the head element of the HCD queue */ if (pRequestInfo != pEHCDData->pRequestQueueHead) { /* Search for the request element in the HCD maintained list * and free the request */ for (pTempRequestInfo = pEHCDData->pRequestQueueHead; (NULL != pTempRequestInfo) && (pRequestInfo != pTempRequestInfo->pListRequest); pTempRequestInfo = pTempRequestInfo->pListRequest); /* Assert if the request is not found */ OS_ASSERT(NULL != pTempRequestInfo); /* Unlink the request from the HCD list */ pTempRequestInfo->pListRequest = pRequestInfo->pListRequest; if (NULL == pTempRequestInfo->pListRequest) { pEHCDData->pRequestQueueTail = pTempRequestInfo; } } /* This is the head of the HCD request queue */ else { /* Update the head element */ pEHCDData->pRequestQueueHead = pRequestInfo->pListRequest; if (NULL == pEHCDData->pRequestQueueHead) { pEHCDData->pRequestQueueTail = NULL; } } /* Update the head of the pipe request queue */ pHCDPipe->pRequestQueueHead = pRequestInfo->pNext; /* Release the request synchronisation event */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); /* Add all the TDs to the free QTD pool */ /* Get the tail of the TD list */ pQTDTail = (pUSB_EHCD_QTD)pRequestInfo->pTail; /* Get the head of the TD list */ pQTDHead = (pUSB_EHCD_QTD)pRequestInfo->pHead; /* Assert if the head or tail is invalid */ OS_ASSERT(NULL != pQTDHead); OS_ASSERT(NULL != pQTDTail); /* Release all the TDs associated with this Request */ for (; pQTDHead != pQTDTail; pQTDHead = pTempQTD) { /* Store the next pointer temporarily */ pTempQTD = pQTDHead->pNext; /* Add the TD to the free list */ usbEhcdAddToFreeQTDList(pQTDHead); } /* Add the tail element to the list */ usbEhcdAddToFreeQTDList(pQTDTail); /* Update the URB's status to cancelled */ pRequestInfo->pUrb->nStatus = USBHST_TRANSFER_CANCELLED; /* Call the callback function if it is registered */ if (NULL != pRequestInfo->pUrb->pfCallback) { (pRequestInfo->pUrb->pfCallback)(pRequestInfo->pUrb); } /* Free the memory allocated for the request information */ OS_FREE(pRequestInfo); /* Exclusively access the request synchronisation list */ OS_WAIT_FOR_EVENT(pEHCDData->RequestSynchEventID, OS_WAIT_INFINITE); }/* End of for () */ /* Release the request synchronisation event */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); /* Release the QHs */ /* Assert if the QH is invalid */ OS_ASSERT(NULL != pHCDPipe->pQH); /* Add the QH to the free list */ usbEhcdAddToFreeQHList(pHCDPipe->pQH); /* Release the semaphore to the waiting task */ OS_RELEASE_EVENT(pHCDPipe->DeleteSynchEventID); /* Exclusively access the reclamation list */ OS_WAIT_FOR_EVENT(pEHCDData->ReclamationListSynchEventID, OS_WAIT_INFINITE); } /* Search the list which contains the requests which need to be removed * and release the memory allocated for all of them. */ for (pRequestInfo = pEHCDData->pHeadAsynchCancelList; NULL != pRequestInfo; pRequestInfo = pEHCDData->pHeadAsynchCancelList) { /* Update the head of the asynch request reclamation list */ pEHCDData->pHeadAsynchCancelList = pRequestInfo->pListRequest; /* Release the exclusive access */ OS_RELEASE_EVENT(pEHCDData->ReclamationListSynchEventID); /* Get the tail of the TD list */ pQTDTail = (pUSB_EHCD_QTD)pRequestInfo->pTail; /* Get the head of the TD list */ pQTDHead = (pUSB_EHCD_QTD)pRequestInfo->pHead; /* Assert if the head or tail is invalid */ OS_ASSERT(NULL != pQTDHead); OS_ASSERT(NULL != pQTDTail); /* Release all the TDs associated with this Request */ for (; pQTDHead != pQTDTail; pQTDHead = pTempQTD) { /* Store the next pointer temporarily */ pTempQTD = pQTDHead->pNext; /* Add the TD to the free list */ usbEhcdAddToFreeQTDList(pQTDHead); } /* Add the tail element to the list */ usbEhcdAddToFreeQTDList(pQTDTail); /* Release the semaphore to the waiting task */ OS_RELEASE_EVENT(pRequestInfo->pHCDPipe->DeleteSynchEventID); /* Free the memory allocated for the request information */ OS_FREE(pRequestInfo); /* Exclusively access the reclamation list */ OS_WAIT_FOR_EVENT(pEHCDData->ReclamationListSynchEventID, OS_WAIT_INFINITE); } /* Check if some request pending in Reclamation list or cancel list, if not disable the intr */ if ((NULL == pEHCDData->pAsynchReclamationListHead) && (NULL == pEHCDData->pHeadAsynchCancelList)) { /* Disable Async advance intr */ USB_EHCD_CLR_BIT_USBINTR_INT_ON_ASYNC_ADVANCE_DOORBELL(pEHCDData); USB_EHCD_CLR_BIT_USBCMD_INT_ON_ASYNC_ADVANCE_DOORBELL(pEHCDData); } /* Release the exclusive access */ OS_RELEASE_EVENT(pEHCDData->ReclamationListSynchEventID); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCleanupAsynchPipes - Exit\n",0,0,0,0); return; }/* End of usbEhcdCleanupAsynchPipes() *//***************************************************************************** usbEhcdCleanupPeriodicPipes - cleans up the periodic pipes.** This is used to perform the cleanup functionality of the periodic pipes.** RETURNS: N/A.** ERRNO:* None.** \NOMANUAL*/LOCAL VOID usbEhcdCleanupPeriodicPipes ( pUSB_EHCD_DATA pEHCDData ) { /* To hold the pointer to the pipe information */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* To hold the request information */ pUSB_EHCD_REQUEST_INFO pRequestInfo = NULL; /* To hold the temporary request information */ pUSB_EHCD_REQUEST_INFO pTempRequestInfo = NULL; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_EVENT_HANDLER, "usbEhcdCleanupPeriodicPipes() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCleanupPeriodicPipes - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if (NULL == pEHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCleanupPeriodicPipes - parameter not \ valid\n",0,0,0,0); return; } /* Exclusively access the reclamation list */ OS_WAIT_FOR_EVENT(pEHCDData->ReclamationListSynchEventID, OS_WAIT_INFINITE); /* Search the list and remove the element */ for (pHCDPipe = pEHCDData->pPeriodicReclamationListHead; NULL != pHCDPipe; pHCDPipe = pEHCDData->pPeriodicReclamationListHead) { /* Update the head of the reclamation list */ pEHCDData->pPeriodicReclamationListHead = pHCDPipe->pNext; /* Release the reclamationsychronisation event */ OS_RELEASE_EVENT(pEHCDData->ReclamationListSynchEventID); /* This loop retrieves the requests which are queued to the * endpoint and releases the TDs. This is done by exclusively * accessing the request list. */ /* Exclusively access the request synchronisation list * This is done as the request list which is maintained for the HC * is also accessed. */ OS_WAIT_FOR_EVENT(pEHCDData->RequestSynchEventID, OS_WAIT_INFINITE); /* Remove the requests from the endpoint queue */ for (pRequestInfo = pHCDPipe->pRequestQueueHead; NULL != pRequestInfo; pRequestInfo = pHCDPipe->pRequestQueueHead) { /* Check if the request is not the head element of the HCD queue */ if (pRequestInfo != pEHCDData->pRequestQueueHead) { /* Search for the request element in the HCD maintained list * and free the request
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -