📄 usbehcdrhemulation.c
字号:
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_LOW(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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -