📄 usbehcdeventhandler.c
字号:
} else /* The endpoint's halt bit is not set */ { /* * Fetch the host controller accessible region by * adding offset USB_EHCD_QTD_HEADER_SIZE to the * QTD. */ PUCHAR pQTDtemp = (PUCHAR) pHCDPipe->pQH->pQTD; pQTDtemp += USB_EHCD_QTD_HEADER_SIZE; /* * If this request completes with a short packet, * where the last TD of this request is not accessed * by the host controller, then this will succeed. * We should manually go and update the next link * pointers in this case. */ if ((pHCDPipe->pQH->uCurrentQtdPointer != USB_EHCD_SWAP_DATA(uBusIndex, USB_EHCD_CONVERT_TO_BUS_MEM(uBusIndex, pQTDtemp))) && (USB_EHCD_QTD_STATUS_ACTIVE == (USB_EHCD_GET_BITFIELD(uBusIndex, QTD, pHCDPipe->pQH->pQTD->uTransferInfo, TOKEN_STATUS) & USB_EHCD_QTD_STATUS_ACTIVE))) { /* Update the HC's next pointer */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pHCDPipe->pQH->uNextQtdPointer, (((unsigned) USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex, pQTDtemp)) >> 5), NEXTQTD_POINTER); /* Indicate that this is an invalid element * in the list */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pHCDPipe->pQH->uNextQtdPointer, USB_EHCD_VALID_LINK, NEXTQTD_POINTER_T); } } } /* If HCD is halted, clear the halt * condition on the pipe */ if (pRequestInfo->pUrb->nStatus == USBHST_STALL_ERROR) { /* * Clear the halt condition and * reset data toggle for the pipe */ pHCDPipe->pQH->uTransferInfo = 0; } /* Flush the contents of the cache to the RAM */ CACHE_DMA_FLUSH(pHCDPipe->pQH, sizeof(USB_EHCD_QH)); /* Flush the contents of the cache to the RAM */ CACHE_DMA_INVALIDATE(pHCDPipe->pQH, sizeof(USB_EHCD_QH)); } else { /* This check might be redundant as the controller always * processes the first request queued. Need to check * whether this needs to be retained */ /* Search for the request in the list */ for (pTempRequestInfo = pHCDPipe->pRequestQueueHead; (NULL != pTempRequestInfo) && (pTempRequestInfo->pNext != pRequestInfo); pTempRequestInfo = pTempRequestInfo->pNext); /* If the temporary request pointer is NULL, * it is an error */ OS_ASSERT(NULL != pTempRequestInfo); /* Update the next pointers */ pTempRequestInfo->pNext = pRequestInfo->pNext; /* * If we are removing the request pointed to by the tail, * the tail pointer needs to be reset */ if (pRequestInfo == pHCDPipe->pRequestQueueTail) { pHCDPipe->pRequestQueueTail = pTempRequestInfo; } /* Retrieve the TD previous to the TD being removed */ for (pTempQTD = pHCDPipe->pQH->pQTD; (NULL != pTempQTD) && (pTempQTD->pNext != pRequestInfo->pHead); pTempQTD = pTempQTD->pNext); /* Update the next pointers */ if (pRequestInfo->pNext == NULL) pTempQTD->pNext = NULL; else pTempQTD->pNext = pRequestInfo->pNext->pHead; /* * If this element is the last element, indicate that * the next element is invalid */ if (pTempQTD->pNext == NULL) { USB_EHCD_SET_BITFIELD(uBusIndex, QTD, pTempQTD->uNextQTDPointer, USB_EHCD_INVALID_LINK, NEXTQTD_POINTER_T); } else { /* Update the HC's next pointer */ PUCHAR tempQTD = (PUCHAR) pTempQTD->pNext; tempQTD += USB_EHCD_QTD_HEADER_SIZE; USB_EHCD_SET_BITFIELD(uBusIndex, QTD, pTempQTD->uNextQTDPointer, (((unsigned) USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex,tempQTD)) >> 5), NEXTQTD_POINTER) ; /* Indicate that this link is a valid link */ USB_EHCD_SET_BITFIELD(uBusIndex, QTD, pTempQTD->uNextQTDPointer, USB_EHCD_VALID_LINK, NEXTQTD_POINTER_T); } /* Flush the contents of the cache to the RAM */ CACHE_DMA_FLUSH(pTempQTD, sizeof(USB_EHCD_QTD)); /* * If the pipe's halted bit is set, * set the bit which disables host controller * access on this endpoint. */ if (pHCDPipe->bIsHalted) { USB_EHCD_SET_BITFIELD(uBusIndex, QH, pHCDPipe->pQH->uNextQtdPointer, USB_EHCD_INVALID_LINK, NEXTQTD_POINTER_T); } /* * If HCD is halted, clear the halt * condition on the pipe */ if (pRequestInfo->pUrb->nStatus == USBHST_STALL_ERROR) { /* * Clear the halt condition and * reset data toggle for the pipe */ pHCDPipe->pQH->uTransferInfo = 0; } } /* Remove the request from the Endpoint list - End */ /* 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); /* 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)); /* * 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); } /* If it is a control transfer, swap the contents of setup */ if (USBHST_CONTROL_TRANSFER == pTempRequestInfo->pHCDPipe->uEndpointType) { /* Swap back the contents of the buffer */ USB_EHCD_SWAP_BUFDATA(uBusIndex, pTempRequestInfo->pUrb->pTransferSpecificData, sizeof(USBHST_SETUP_PACKET)); } /* 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 { /* Isochronous transfer completion */ /* Check if it is a high speed data transfer request */ 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(uBusIndex, ITD, pITDTail-> uTransactionStatusControlList[ (USB_EHCD_MAX_MICROFRAME_NUMBER -1-uMicroFrameIndex)], TRANSACTION_STATUS) & USB_EHCD_ITD_STATUS_ACTIVE; break; } }/* End of for () */ if (0 == uTailStatusBit) { /* Update the number of bytes transferred and status*/ usbEhcdUpdateITDData(uBusIndex, 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -