📄 usbhalendpoint.c
字号:
USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointOUT exiting: No Interrupts to service...", USB_HAL_WV_FILTER); return OK; } /* Get the first list element */ pErp = usbListFirst(&pPipeInfo->listHead); /* * If the pErp pointer is NULL, then the list is empty. * If the list is empty, return OK */ if (pErp == NULL) { USBHAL_DEBUG ("usbHalProcessEndpointOUT : List is empty\n",0,0,0,0,0,0); /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); /* * Check if the list is empty when a setup interrupt * has occured. */ if ((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_SETUP_PID_MASK) != 0) { /* Get the first element of the control IN endpoint */ pErp = usbListFirst(&pHalInfo->pPipeInfo[0]->listHead); /* * If the control IN endpoint list is not empty, * call the callback function of the request submitted to * the control IN endpoint. */ if (pErp != NULL) { /* Unlink this element */ usbListUnlink(&pErp->tcdLink); /* * We should not clear the interrupt status here. * If instead of an OUT interrupt, a setup interrupt has * occurred, the code should be in a position to handle this. * If we clear the interrupt status here, * the setup interrupt would be lost. */ /* Update the result of the ERP */ pErp->result = S_usbTcdLib_PID_MISMATCH; /* Call the callback function for the ERP */ if (pErp->targCallback != NULL) (*pErp->targCallback)(pErp); } } return OK; } /* Check if the PID is valid */ switch (pErp->bfrList[0].pid) { case USB_PID_OUT: if ((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_OUT_PID_MASK) == 0) status = ERROR; break; case USB_PID_SETUP: if ((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_SETUP_PID_MASK) == 0) status = ERROR; break; default: status = ERROR; } /* If the status is an ERROR, call the callback and return an ERROR */ if (status == ERROR) { /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointOUT exiting: PID mismatch...", USB_HAL_WV_FILTER); USBHAL_ERR("usbHalProcessEndpointOUT : PID mismatch\n",0,0,0,0,0,0); /* Unlink this element */ usbListUnlink(&pErp->tcdLink); /* * We should not clear the interrupt status here. * If instead of an OUT interrupt, a setup interrupt has * occurred, the code should be in a position to handle this. * If we clear the interrupt status here, * the setup interrupt would be lost. */ /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); /* Update the result of the ERP */ pErp->result = S_usbTcdLib_PID_MISMATCH; /* Call the callback function for the ERP */ if (pErp->targCallback != NULL) (*pErp->targCallback)(pErp); return ERROR; } /* If the data transfer has resulted in an error, complete the request */ if (((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_TRANSFER_STATUS_MASK) != USBTCD_ENDPOINT_DATA_UNDERRUN) && ((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_TRANSFER_STATUS_MASK) != USBTCD_ENDPOINT_TRANSFER_SUCCESS)) { USBHAL_ERR ("usbHalProcessEndpointOUT : data transfer error\n", 0,0,0,0,0,0); /* Unlink this element */ usbListUnlink (&pErp->tcdLink); /* * Update the result of the ERP based on the error codes reported in * the endpoint interrupt status */ switch (pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_TRANSFER_STATUS_MASK) { case USBTCD_ENDPOINT_DATA_TOGGLE_ERROR: pErp->result = S_usbTcdLib_DATA_TOGGLE_FAULT; break; case USBTCD_ENDPOINT_PID_MISMATCH: pErp->result = S_usbTcdLib_PID_MISMATCH; break; case USBTCD_ENDPOINT_COMMN_FAULT: pErp->result = S_usbTcdLib_COMM_FAULT; break; case USBTCD_ENDPOINT_STALL_ERROR: pErp->result = S_usbTcdLib_STALL_ERROR; break; case USBTCD_ENDPOINT_DATA_OVERRUN: pErp->result = S_usbTcdLib_DATA_OVERRUN; break; default: pErp->result = S_usbTcdLib_GENERAL_FAULT; } /* Reset the endpoint interrupt status */ pPipeInfo->uEndpointInterruptStatus = 0; /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); /* Call the callback function for the ERP */ if (pErp->targCallback != NULL) (*pErp->targCallback)(pErp); /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointOUT exiting: Data Transfer Error...", USB_HAL_WV_FILTER); return ERROR; } /* Calculate the index into the buffer list */ while((pErp->bfrList[uIndex].bfrLen != 0) && ((pErp->bfrList[uIndex].actLen) == (pErp->bfrList[uIndex].bfrLen)) && (uIndex < pErp->bfrCount)) uIndex++; /* Check if the index is invalid */ if (uIndex == pErp->bfrCount) { USBHAL_ERR("usbHalProcessEndpointOUT : invalid buffer index\n", 0,0,0,0,0,0); /* Unlink this element */ usbListUnlink(&pErp->tcdLink); /* Reset the endpoint interrupt status */ pPipeInfo->uEndpointInterruptStatus = 0; /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); /* Update the result of the ERP */ pErp->result = S_usbTcdLib_GENERAL_FAULT; /* Call the callback function for the ERP */ if (pErp->targCallback != NULL) (*pErp->targCallback)(pErp); return ERROR; } /* Initialize the TRB for copying data from the Endpoint buffer */ trbHeaderInit((pTRB_HEADER)&trbCopyDataFromEpBuf, pHalInfo->pTCDHandle, TCD_FNC_COPY_DATA_FROM_EPBUF, sizeof(TRB_COPY_DATA_FROM_EPBUF)); trbCopyDataFromEpBuf.pipeHandle = pPipeInfo->pipeHandle; trbCopyDataFromEpBuf.pBuffer = pErp->bfrList[uIndex].pBfr + pErp->bfrList[uIndex].actLen; trbCopyDataFromEpBuf.uActLength = pErp->bfrList[uIndex].bfrLen - pErp->bfrList[uIndex].actLen; /* Call the single entry point of the TCD */ status = (*pHalInfo->tcdExecFunc)(&trbCopyDataFromEpBuf); /* * If the status is not OK, call the callback with error * and return ERROR */ if (status != OK) { /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointOUT exiting: TCD Error in copying the data...", USB_HAL_WV_FILTER); USBHAL_ERR("usbHalProcessEndpointOUT : Error in copying data" "from EP buffer\n",0,0,0,0,0,0); /* Unlink this element */ usbListUnlink (&pErp->tcdLink); /* Reset the endpoint interrupt status */ pPipeInfo->uEndpointInterruptStatus = 0; /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); /* Update the result of the ERP */ pErp->result = S_usbTcdLib_GENERAL_FAULT; /* Call the callback function for the ERP */ if (pErp->targCallback != NULL) (*pErp->targCallback)(pErp); return ERROR; } /* Update the buffer list actual length */ pErp->bfrList[uIndex].actLen += trbCopyDataFromEpBuf.uActLength; /* * If the entire data for the request is retrieved , call * the callback function for the ERP */ if (((pErp->bfrList[uIndex].actLen == pErp->bfrList[uIndex].bfrLen) && ((uIndex + 1 ) == pErp->bfrCount)) || ((trbCopyDataFromEpBuf.uActLength < pPipeInfo->maxPacketSize) && (pErp->bfrList[uIndex].actLen != 0)) || ((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_TRANSFER_STATUS_MASK) == USBTCD_ENDPOINT_DATA_UNDERRUN)) { /* Unlink this element */ usbListUnlink (&pErp->tcdLink); /* Reset the endpoint interrupt status */ pPipeInfo->uEndpointInterruptStatus = 0; /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); /* Update the ERP result */ pErp->result = 0; /* Call the callback function for the ERP */ if (pErp->targCallback != NULL) (*pErp->targCallback)(pErp); } else { /* Reset the endpoint interrupt status */ pPipeInfo->uEndpointInterruptStatus = 0; /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); } /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointOUT exiting...", USB_HAL_WV_FILTER); USBHAL_DEBUG("usbHalProcessEndpointOUT - Exiting\n",0,0,0,0,0,0); return OK; }/********************************************************************************* usbHalProcessEndpointIN - process an IN endpoint request** This function is called by the interrupt handler module when there is an* interrupt on an IN endpoint. This function is also called when the* usbTcdErpSubmit() is called for sending data to the USB host.** RETURNS: OK if IN endpoint request is processed successfully, ERROR otherwise.** ERRNO:* None.** \NOMANUAL*/STATUS usbHalProcessEndpointIN ( pUSBHAL_TCD pHalInfo, /* USBHAL_TCD */ pUSBHAL_PIPE_INFO pPipeInfo /* USBHAL_PIPE_INFO */ ) { pUSB_ERP pErp = NULL; /* USB_ERP */ STATUS status = OK; UINT32 uIndex = 0; TRB_IS_BUFFER_EMPTY trbIsBufferEmpty; /* TRB_IS_BUFFER_EMPTY */ /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointIN entered...", USB_HAL_WV_FILTER); USBHAL_DEBUG("usbHalProcessEndpointIN - Entering\n",0,0,0,0,0,0); /* Check the validity of the parameters */ if ((pHalInfo == NULL) || (pPipeInfo == NULL)) { /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointIN exiting: Bad Parameters Received...", USB_HAL_WV_FILTER); USBHAL_ERR("usbHalProcessEndpointIN : Invalid parameters\n",0,0,0,0,0,0); return ERROR; } /* Acquire the mutex created for this list */ OSS_MUTEX_TAKE(pPipeInfo->mutexHandle, OSS_BLOCK); /* Get the first list element */ pErp = usbListFirst(&pPipeInfo->listHead); /* * If the pErp pointer is NULL, then the list is empty. * If the list is empty, return OK */ if (pErp == NULL) { /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointIN exiting: List is empty...", USB_HAL_WV_FILTER); USBHAL_DEBUG("usbHalProcessEndpointIN - List is empty\n",0,0,0,0,0,0); /* Reset the endpoint interrupt status */ pPipeInfo->uEndpointInterruptStatus = 0; /* Release the mutex */ OSS_MUTEX_RELEASE (pPipeInfo->mutexHandle); return OK; } /* Initialize the TRB */ memset (&trbIsBufferEmpty, 0, sizeof(TRB_IS_BUFFER_EMPTY)); /* Check if an interrupt is pending for this endpoint */ if (pPipeInfo->uEndpointInterruptStatus != 0) { /* Check if the PID is valid */ switch (pErp->bfrList[0].pid) { case USB_PID_IN: if ((pPipeInfo->uEndpointInterruptStatus & USBTCD_ENDPOINT_IN_PID_MASK) == 0) status = ERROR; break; default: status = ERROR; } /* If the status is not OK, return an ERROR */ if (status != OK) { /* WindView Instrumentation */ USB_HAL_LOG_EVENT(USB_HAL_ENDPOINT, "usbHalProcessEndpointIN exiting: PID Mismatch...", USB_HAL_WV_FILTER); USBHAL_ERR("usbHalProcessEndpointIN : PID mismatch\n",0,0,0,0,0,0); /* Unlink this element */ usbListUnlink (&pErp->tcdLink); /* Reset the endpoint interrupt status */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -