📄 usbehcdrhemulation.c
字号:
/* Release the exclusive access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* Remove the requests queued for the endpoint */ for (pRequestInfo = pHCDPipe->pRequestQueueHead; NULL != pRequestInfo; pRequestInfo = pTempRequestInfo) { /* Assert if URB is not valid */ OS_ASSERT(NULL != pRequestInfo->pUrb); /* Hold the next pointer temporarily */ pTempRequestInfo = pRequestInfo->pNext; /* Update the request status to cancelled */ pRequestInfo->pUrb->nStatus = USBHST_TRANSFER_CANCELLED; /* Call the callback functions if registered */ if (NULL != pRequestInfo->pUrb->pfCallback) { pRequestInfo->pUrb->pfCallback(pRequestInfo->pUrb); } /* Free memory allocated for the request information */ OS_FREE(pRequestInfo); } OS_FREE(pHCDData->RHData.pInterruptPipe); pHCDData->RHData.pInterruptPipe = NULL; } else { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRHDeletePipe - Invalid pipe handle\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRHDeletePipe - Exit\n",0,0,0,0); return USBHST_SUCCESS; } /* End of usbEhcdRHDeletePipe() *//***************************************************************************** usbEhcdRHSubmitURB - submits a request to an endpoint.** This routine submits a request to an endpoint.** RETURNS: USBHST_SUCCESS if the URB is submitted successfully.* USBHST_INVALID_PARAMETER if the parameters are not valid.* USBHST_INSUFFICIENT_BANDWIDTH if memory is insufficient for the request.** ERRNO:* None.*/USBHST_STATUS usbEhcdRHSubmitURB ( pUSB_EHCD_DATA pHCDData, /* Ptr to HCD block */ UINT32 uPipeHandle, /* Pipe Handle Identifier */ pUSBHST_URB pURB /* Ptr to User Request Block */ ) { /* Status of the request */ USBHST_STATUS Status = USBHST_FAILURE; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRHSubmitURB - Entry\n",0,0,0,0); /* Check if the parameters are valid */ if (NULL == pHCDData || 0 == uPipeHandle || NULL == pURB) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRHSubmitURB - Invalid parameters\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Check if it is a control request */ if (uPipeHandle == (UINT32)(pHCDData->RHData.pControlPipe) || ((uPipeHandle == (UINT32)pHCDData->pDefaultPipe) && (0 == pHCDData->RHData.uDeviceAddress))) { Status = usbEhcdRhProcessControlRequest(pHCDData, pURB); } /* Check if it is an interrupt request */ else if (uPipeHandle == (UINT32)(pHCDData->RHData.pInterruptPipe)) { Status = usbEhcdRhProcessInterruptRequest(pHCDData, pURB); } else { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRHSubmitURB - Invalid pipe handle\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRHSubmitURB - Exit\n",0,0,0,0); return Status; } /* End of usbEhcdRHSubmitURB() *//***************************************************************************** usbEhcdRhProcessControlRequest - processes a control transfer request** This routine processes a control transfer request.** RETURNS: USBHST_SUCCESS if the URB is submitted successfully.* USBHST_INVALID_PARAMETER if the parameters are not valid.* USBHST_INSUFFICIENT_BANDWIDTH if memory is insufficient for the request.** ERRNO:* None.*/USBHST_STATUS usbEhcdRhProcessControlRequest ( pUSB_EHCD_DATA pHCDData, /* Ptr to HCD block */ pUSBHST_URB pURB /* Ptr to User Request Block */ ) { /* Status of the request */ USBHST_STATUS Status = USBHST_FAILURE; /* Pointer to the setup packet */ pUSBHST_SETUP_PACKET pSetup = NULL; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhProcessControlRequest - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if (NULL == pHCDData || NULL == pURB || NULL == pURB->pTransferSpecificData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhProcessControlRequest - \ Invalid parameters\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Extract the setup packet from the URB */ pSetup = (pUSBHST_SETUP_PACKET)pURB->pTransferSpecificData; /* Check if it is a standard request */ if (USB_EHCD_RH_STANDARD_REQUEST == (USB_EHCD_RH_REQUEST_TYPE & pSetup->bmRequestType)) { Status = usbEhcdRhProcessStandardRequest(pHCDData, pURB); } /* Check if it is a class specific request */ else if (USB_EHCD_RH_CLASS_SPECIFIC_REQUEST == (USB_EHCD_RH_REQUEST_TYPE & pSetup->bmRequestType)) { Status = usbEhcdRhProcessClassSpecificRequest(pHCDData, pURB); } else { OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhProcessControlRequest - Invalid request\n",0,0,0,0); Status = USBHST_INVALID_PARAMETER; } OS_LOG_MESSAGE_MEDIUM (EHCD,"usbEhcdRhProcessControlRequest - Exit\n",0,0,0,0); return Status; } /* End of function usbEhcdRhProcessControlRequest() *//***************************************************************************** usbEhcdRhProcessInterruptRequest - processes a interrupt transfer request** This routine processes a interrupt transfer request.** RETURNS: USBHST_SUCCESS if the URB is submitted successfully.* USBHST_INVALID_PARAMETER if the parameters are not valid.* USBHST_INSUFFICIENT_BANDWIDTH if memory is insufficient for the request.** ERRNO:* None.*/USBHST_STATUS usbEhcdRhProcessInterruptRequest ( pUSB_EHCD_DATA pHCDData, /* Ptr to HCD block */ pUSBHST_URB pURB /* Ptr to User Request Block */ ) { /* To hold the return status of the function */ USBHST_STATUS Status = USBHST_SUCCESS; /* To hold the interrupt data */ UINT32 uInterruptData = 0; /* Check the validity of the parameters */ if (NULL == pHCDData || NULL == pURB || NULL == pURB->pTransferBuffer) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhProcessInterruptRequest - \ Invalid parameters\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* * Check if the Root hub is configured * to accept any interrupt transfer request. */ if ((0 == pHCDData->RHData.uConfigValue) || (NULL == pHCDData->RHData.pInterruptPipe) || (TRUE == pHCDData->RHData.pInterruptPipe->PipeDeletedFlag)) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhProcessInterruptRequest - \ Invalid request - device not configured\n",0,0,0,0); return USBHST_INVALID_REQUEST; } /* Assert if the structure members are invalid */ OS_ASSERT(NULL != pHCDData->RHData.pHubInterruptData); /* Exclusively access the request resource */ OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID, OS_WAIT_INFINITE); /* Copy the existing interrupt data */ OS_MEMCPY(&uInterruptData, pHCDData->RHData.pHubInterruptData, pHCDData->RHData.uSizeInterruptData); /* If interrupt data is available, copy the data directly to URB buffer */ if (0 != uInterruptData) { OS_MEMCPY(pURB->pTransferBuffer, &uInterruptData, pHCDData->RHData.uSizeInterruptData); /* Initialize the interrupt data */ OS_MEMSET(pHCDData->RHData.pHubInterruptData, 0, pHCDData->RHData.uSizeInterruptData); /* Release the exclusive access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); /* Update the length */ pURB->uTransferLength = pHCDData->RHData.uSizeInterruptData; /* Update the status of URB */ pURB->nStatus = Status; /* * If a callback function is registered, call the callback * function. */ if (pURB->pfCallback) { pURB->pfCallback(pURB); } } else { /* Pointer to the request information */ pUSB_EHCD_REQUEST_INFO pRequest = NULL; /* Allocate memory for the request data structure */ pRequest = (pUSB_EHCD_REQUEST_INFO)OS_MALLOC(sizeof(USB_EHCD_REQUEST_INFO)); /* Check if memory allocation is successful */ if (NULL == pRequest) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhProcessInterruptRequest - \ memory not allocated\n",0,0,0,0); return USBHST_INSUFFICIENT_MEMORY; } /* Initialize the request structure */ OS_MEMSET(pRequest, 0, sizeof(USB_EHCD_REQUEST_INFO)); /* Copy the USB_EHCD_PIPE pointer */ pRequest->pHCDPipe = pHCDData->RHData.pInterruptPipe; /* Store the URB pointer in the request data structure */ pRequest->pUrb = pURB; /* Add to the request list */ if (NULL == pRequest->pHCDPipe->pRequestQueueHead) { pRequest->pHCDPipe->pRequestQueueHead = pRequest; pRequest->pHCDPipe->pRequestQueueTail = pRequest; } else { /* Update the next pointer of the tail element */ pRequest->pHCDPipe->pRequestQueueTail->pNext = pRequest; /* Update the tail element to point to the request */ pRequest->pHCDPipe->pRequestQueueTail = pRequest; } /* Release the exclusive access */ OS_RELEASE_EVENT(pHCDData->RequestSynchEventID); } return Status; } /* End of function usbEhcdRhProcessInterruptRequest() *//***************************************************************************** usbEhcdRhProcessStandardRequest - processes a standard transfer request** This routine processes a standard transfer request.** RETURNS: USBHST_SUCCESS if the URB is submitted successfully.* USBHST_INVALID_PARAMETER if the parameters are not valid.* USBHST_INSUFFICIENT_BANDWIDTH if memory is insufficient for the request.** ERRNO:* None.*/USBHST_STATUS usbEhcdRhProcessStandardRequest ( pUSB_EHCD_DATA pHCDData, /* Ptr to HCD block */ pUSBHST_URB pURB /* Ptr to User Request Block */ ) { /* To hold the return status of the function */ USBHST_STATUS Status = USBHST_SUCCESS; /* Pointer to the setup packet */ pUSBHST_SETUP_PACKET pSetup = NULL; OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhProcessStandardRequest - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if (NULL == pHCDData || NULL == pURB || NULL == pURB->pTransferSpecificData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhProcessStandardRequest - \ Invalid parameters\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Extract the setup packet from the URB */ pSetup = (pUSBHST_SETUP_PACKET)pURB->pTransferSpecificData; /* Swap the 16 bit values */ pSetup->wValue = OS_UINT16_CPU_TO_LE(pSetup->wValue); pSetup->wIndex = OS_UINT16_CPU_TO_LE(pSetup->wIndex); pSetup->wLength = OS_UINT16_CPU_TO_LE(pSetup->wLength); /* Handle the standard request */ switch(pSetup->bRequest) { case USBHST_REQ_CLEAR_FEATURE:/* Clear feature request */ { /* Based on the recipient, handle the request */ switch (pSetup->bmRequestType &USB_EHCD_RH_RECIPIENT_MASK) { case USBHST_RECIPIENT_DEVICE: /* Device recipient */ { /* Check the feature selector */ if (USBHST_FEATURE_DEVICE_REMOTE_WAKEUP == pSetup->wValue) { /* Disable the device remote wakeup feature */ pHCDData->RHData.bRemoteWakeupEnabled = FALSE; } /* Update the URB status */ pURB->nStatus = USBHST_SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -