📄 usbehcdeventhandler.c
字号:
pEHCDData->pRequestQueueHead = pRequestInfo->pListRequest; /* Update the tail to NULL if the head is NULL */ if (NULL == pEHCDData->pRequestQueueHead) { pEHCDData->pRequestQueueTail = NULL; } } else { /* Update the next element in the request list */ pPreRequestInfo->pListRequest = pRequestInfo->pListRequest; /* If List Request for PreRequest is NULL, the update Tail to prev request */ if (NULL == pPreRequestInfo->pListRequest) { pEHCDData->pRequestQueueTail = pPreRequestInfo; } } /* Remove the request from the Endpoint list*/ USB_EHCD_DELETE_FROM_ENDPOINT_LIST(pRequestInfo); /* Remove all the ITDs from request list. */ while (pITDHead != pITDTail) { pTempITD = pITDHead; usbEhcdUnLinkITD(pEHCDData, pITDHead); pITDHead = pITDHead->pVerticalNext; usbEhcdAddToFreeITDList(pTempITD); } /* Check if this is the last ITD in the pipe * * reset the last frame index */ if (pRequestInfo->pHCDPipe->uLastIndex == pITDTail->uFrameListIndex +1) { pRequestInfo->pHCDPipe->uLastIndex = USB_EHCD_NO_LIST; } /* Unlink the last ITD from the frame list */ usbEhcdUnLinkITD(pEHCDData, pITDHead); /* Remove the last ITD from list */ usbEhcdAddToFreeITDList(pITDTail); /* Update the temp pointer which is used for freeing */ pTempRequestInfo = pRequestInfo; /* Update the request pointer */ pRequestInfo = pRequestInfo->pListRequest; /* Release the event */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); /* * Check if the buffer pointer is valid and the return * status is success */ if ((NULL != pTempRequestInfo->pUrb->pTransferBuffer) && (USBHST_SUCCESS == pTempRequestInfo->pUrb->nStatus)) { /* Invalidate the cache */ CACHE_USER_INVALIDATE( pTempRequestInfo->pUrb->pTransferBuffer, pTempRequestInfo->pUrb->uTransferLength); /* Swap back the contents of the buffer */ USB_EHCD_SWAP_BUFDATA(uBusIndex, pTempRequestInfo->pUrb->pTransferBuffer, pTempRequestInfo->pUrb->uTransferLength); } /* Call the callback function if it is registered */ if (NULL != pTempRequestInfo->pUrb->pfCallback) { (pTempRequestInfo->pUrb->pfCallback)(pTempRequestInfo->pUrb); } /* Free the memory allocated for the request information */ OS_FREE(pTempRequestInfo); /* Acquire the event */ OS_WAIT_FOR_EVENT(pEHCDData->RequestSynchEventID, OS_WAIT_INFINITE); } else /* If the request is not completed, goto the next element * in the HCD request list. */ { pPreRequestInfo = pRequestInfo; pRequestInfo = pRequestInfo->pListRequest; continue; } /* Whole of the request is not completed */ } else { /* Pointer to the tail of SITD */ pUSB_EHCD_SITD pSITDTail = NULL; /* Pointer to the head of Queue TD */ pUSB_EHCD_SITD pSITDHead = NULL; /* Pointer to the temporary QH */ pUSB_EHCD_SITD pTempSITD = NULL; /* Get the tail of the TD list */ pSITDTail = (pUSB_EHCD_SITD)pRequestInfo->pTail; /* Get the head of the TD list */ pSITDHead = (pUSB_EHCD_SITD)pRequestInfo->pHead; /* Assert if the head or tail is invalid */ OS_ASSERT(NULL != pSITDHead); OS_ASSERT(NULL != pSITDTail); /* Assert if the URB is invalid */ OS_ASSERT(NULL != pRequestInfo->pUrb); /* Invalidate the cache */ CACHE_DMA_INVALIDATE(pSITDTail, sizeof(USB_EHCD_SITD)); /* Check the status bit for the last Frame * to verify the transfer complletion */ if (0 == (USB_EHCD_GET_BITFIELD(uBusIndex, SITD, pSITDTail->uTransferState, TRANSFER_STATE_STATUS) & USB_EHCD_SITD_STATUS_ACTIVE)) { /* Update the number of bytes transferred and status*/ usbEhcdUpdateSITDData(uBusIndex, pSITDHead, pSITDTail, (pUSBHST_ISO_PACKET_DESC) (pRequestInfo->pUrb->pTransferSpecificData)); /* Update URB Status as Successs */ pRequestInfo->pUrb->nStatus = USBHST_SUCCESS; /* Remove the request from the HCD list - Start */ /* If this is the head element */ if (pRequestInfo == pEHCDData->pRequestQueueHead) { /* Update the head of the request list */ pEHCDData->pRequestQueueHead = pRequestInfo->pListRequest; /* Update the tail to NULL if the head is NULL */ if (NULL == pEHCDData->pRequestQueueHead) { pEHCDData->pRequestQueueTail = NULL; } } else { /* Update the next element in the request list */ pPreRequestInfo->pListRequest = pRequestInfo->pListRequest; /* If List Request for PreRequest is NULL, the update Tail to prev request */ if (NULL == pPreRequestInfo->pListRequest) { pEHCDData->pRequestQueueTail = pPreRequestInfo; } } /* Remove the request from the Endpoint list*/ USB_EHCD_DELETE_FROM_ENDPOINT_LIST(pRequestInfo); /* Remove all the SITDs from request list. */ while (pSITDHead != pSITDTail) { pTempSITD = pSITDHead; usbEhcdUnLinkSITD(pEHCDData, pSITDHead); pSITDHead = pSITDHead->pVerticalNext; usbEhcdAddToFreeSITDList(pTempSITD); } /* Check if this is the last SITD in the pipe * * reset the last frame index */ if (pRequestInfo->pHCDPipe->uLastIndex == pSITDTail->uFrameListIndex +1) { pRequestInfo->pHCDPipe->uLastIndex = USB_EHCD_NO_LIST; } /* Unlink the last SITD from frame list */ usbEhcdUnLinkSITD(pEHCDData, pSITDTail); /* Remove the last ITD from list */ usbEhcdAddToFreeSITDList(pSITDTail); /* Update the temp pointer which is used for freeing */ pTempRequestInfo = pRequestInfo; /* Update the request pointer */ pRequestInfo = pRequestInfo->pListRequest; /* Release the event */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); /* * Check if the buffer pointer is valid and the return * status is success */ if ((NULL != pTempRequestInfo->pUrb->pTransferBuffer) && (USBHST_SUCCESS == pTempRequestInfo->pUrb->nStatus)) { /* Invalidate the cache */ CACHE_USER_INVALIDATE( pTempRequestInfo->pUrb->pTransferBuffer, pTempRequestInfo->pUrb->uTransferLength); /* Swap back the contents of the buffer */ USB_EHCD_SWAP_BUFDATA(uBusIndex, pTempRequestInfo->pUrb->pTransferBuffer, pTempRequestInfo->pUrb->uTransferLength); } /* Call the callback function if it is registered */ if (NULL != pTempRequestInfo->pUrb->pfCallback) { (pTempRequestInfo->pUrb->pfCallback)(pTempRequestInfo->pUrb); } /* Free the memory allocated for the request information */ OS_FREE(pTempRequestInfo); /* Acquire the event */ OS_WAIT_FOR_EVENT(pEHCDData->RequestSynchEventID, OS_WAIT_INFINITE); } else /* If the request is not completed, goto the next element * in the HCD request list. */ { pPreRequestInfo = pRequestInfo; pRequestInfo = pRequestInfo->pListRequest; continue; } } /* End of else for full speed */ } /* End of else for isochronous */ }/* End of for (pRequestInfo = pEHCDData->pRequestQueueHead...*/ /* Release the exclusive access of the request list */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdProcessTransferCompletion - Exit\n",0,0,0,0); 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -