📄 usbehcdeventhandler.c
字号:
} /* Store the address of the head in the local */ pQTDHead = (pUSB_EHCD_QTD)(pTempRequestInfo->pHead); /* Release all the TDs associated with this Request */ for (; pQTDHead != (pUSB_EHCD_QTD)pTempRequestInfo->pTail; 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((pUSB_EHCD_QTD)(pTempRequestInfo->pTail)); if ((NULL != pTempRequestInfo->pUrb->pTransferBuffer) && (USBHST_SUCCESS == pTempRequestInfo->pUrb->nStatus)) { /* Invalidate the cache */ CACHE_USER_INVALIDATE(pTempRequestInfo->pUrb->pTransferBuffer, pTempRequestInfo->pUrb->uTransferLength); } /* Call the callback function if it is registered */ if (NULL != pTempRequestInfo->pUrb->pfCallback) { /* if the status is Time Out change to STALL for USBD to understand the error */ (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 { /* Update the previous request information */ pPreRequestInfo = pRequestInfo; /* Update the request information pointer */ pRequestInfo = pRequestInfo->pListRequest; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdProcessTransferCompletion - \ No request to be serviced\n",0,0,0,0); } } else { /* To be done for isochronous transfers */ if (USBHST_HIGH_SPEED == pRequestInfo->pHCDPipe->uSpeed) { /* Pointer to the tail of Queue TD */ pUSB_EHCD_ITD pITDTail = NULL; /* Pointer to the head of Queue TD */ pUSB_EHCD_ITD pITDHead = NULL; /* Pointer to the temporary QH */ pUSB_EHCD_ITD pTempITD = NULL; /* Micro frame mask value */ UINT8 uMicroFrameMask = 0; /* Microframe Index */ UINT8 uMicroFrameIndex=0; /* Status bit */ UINT8 uTailStatusBit = 0; /* Get the tail of the TD list */ pITDTail = (pUSB_EHCD_ITD)pRequestInfo->pTail; /* Get the head of the TD list */ pITDHead = (pUSB_EHCD_ITD)pRequestInfo->pHead; /* Assert if the head or tail is invalid */ OS_ASSERT(NULL != pITDHead); OS_ASSERT(NULL != pITDTail); /* Assert if the URB is invalid */ OS_ASSERT(NULL != pRequestInfo->pUrb); /* Get the micro frame mask valeu */ uMicroFrameMask = pRequestInfo->pHCDPipe->uUFrameMaskValue; /* Invalidate the cache */ CACHE_DMA_INVALIDATE(pITDTail, sizeof(USB_EHCD_ITD)); /* Check the status bit for the last uFrames * to verify the transfer complletion */ for (uMicroFrameIndex=0; USB_EHCD_MAX_MICROFRAME_NUMBER > uMicroFrameIndex; uMicroFrameIndex++) { if ((uMicroFrameMask << uMicroFrameIndex) & 0x80) { /* Get the status bit of Tail ITD */ uTailStatusBit = USB_EHCD_GET_BITFIELD(ITD, pITDTail-> uTransactionStatusControlList[uMicroFrameIndex], TRANSACTION_STATUS) & USB_EHCD_ITD_STATUS_ACTIVE; break; } }/* End of for () */ if (0 == uTailStatusBit) { /* Update the number of bytes transferred and status*/ usbEhcdUpdateITDData(pITDHead, pITDTail, (pUSBHST_ISO_PACKET_DESC) (pRequestInfo->pUrb->pTransferSpecificData), uMicroFrameMask); /* 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 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 = 0; } /* Unlink the last ITD from the frame list */ usbEhcdUnLinkITD(pEHCDData, pITDHead); /* Remove the last ITD from list */ usbEhcdAddToFreeITDList(pITDTail); /* Release the event */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); /* Update the temp pointer which is used for freeing */ pTempRequestInfo = pRequestInfo; /* Update the request pointer */ pRequestInfo = pRequestInfo->pListRequest; /* 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(SITD, pSITDTail->uTransferState, TRANSFER_STATE_STATUS) & USB_EHCD_SITD_STATUS_ACTIVE)) { /* Update the number of bytes transferred and status*/ usbEhcdUpdateSITDData(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 = 0; } /* Unlink the last SITD from frame list */ usbEhcdUnLinkSITD(pEHCDData, pSITDTail); /* Remove the last ITD from list */ usbEhcdAddToFreeSITDList(pSITDTail); /* Release the event */ OS_RELEASE_EVENT(pEHCDData->RequestSynchEventID); /* Update the temp pointer which is used for freeing */ pTempRequestInfo = pRequestInfo; /* Update the request pointer */ pRequestInfo = pRequestInfo->pListRequest; /* 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -