?? usbehcdrhemulation.c
字號:
OS_MEMCPY(&uPortStatus,
(pHCDData->RHData.pPortStatus +
(pSetup->wIndex -1)),
USB_EHCD_RH_PORT_STATUS_SIZE);
/* Swap the data to the LE format */
uPortStatus = OS_UINT32_LE_TO_CPU(uPortStatus);
/* Clear the suspend bit */
uPortStatus &= ~(USB_EHCD_RH_PORT_SUSPEND_MASK);
/* Update the suspend change */
uPortStatus |= USB_EHCD_RH_PORT_SUSPEND_CHANGE;
/* Swap the data to CPU format data */
uPortStatus = OS_UINT32_CPU_TO_LE(uPortStatus);
/* Copy the status back to the port status */
OS_MEMCPY((pHCDData->RHData.pPortStatus +
(pSetup->wIndex -1)),
&uPortStatus,
USB_EHCD_RH_PORT_STATUS_SIZE);
/*
* Call the function to populate the interrupt
* status data
*/
usbEhcdCopyRHInterruptData(
pHCDData,
(USB_EHCD_RH_MASK_VALUE << (pSetup->wIndex -1)));
break;
}
case USB_EHCD_RH_PORT_POWER: /* Port Power */
{
/* Switch off power in the port */
USB_EHCD_CLR_BIT_PORT(pHCDData,
(pSetup->wIndex) -1,
PORT_POWER);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
break;
}
case USB_EHCD_RH_C_PORT_CONNECTION:/* c_port_connection */
{
if (USB_EHCD_GET_FIELD_PORT(pHCDData,
((pSetup->wIndex) -1),
CONNECT_STATUS_CHANGE) != 0)
{
/* Clear the connection status change */
USB_EHCD_CLR_BIT_PORT(pHCDData,
((pSetup->wIndex) -1),
CONNECT_STATUS_CHANGE);
}
/* This condition can happen if the EHCI does not support
* port power switching. In this case, if a device is connected
* while the target boots up, there is no connect status change
* and no root hub status change interrupt which is generated
*/
else
{
/* To hold the status of the port */
UINT32 uPortStatus = 0;
/* Copy the value in the port status register */
OS_MEMCPY(&uPortStatus,
(pHCDData->RHData.pPortStatus +
((pSetup->wIndex) -1)),
USB_EHCD_RH_PORT_STATUS_SIZE);
/* Swap the data from the LE format */
uPortStatus = OS_UINT32_LE_TO_CPU(uPortStatus);
/* Update the connect status change */
uPortStatus &= ~(USB_EHCD_RH_PORT_CONNECT_CHANGE);
/* Swap the data to LE format data */
uPortStatus = OS_UINT32_CPU_TO_LE(uPortStatus);
/* Copy the status back to the port status */
OS_MEMCPY((pHCDData->RHData.pPortStatus +
((pSetup->wIndex) -1)),
&uPortStatus,
USB_EHCD_RH_PORT_STATUS_SIZE);
}
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
break;
}
case USB_EHCD_RH_C_PORT_ENABLE:/* c_port_enabled */
{
/* Clear the port enable disable change */
USB_EHCD_CLR_BIT_PORT(pHCDData,
((pSetup->wIndex) -1),
PORT_ENABLE_DISABLE_CHANGE);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
break;
}
case USB_EHCD_RH_C_PORT_OVER_CURRENT:/* c_port_over_current */
{
/* Clear the overcurrent change */
USB_EHCD_CLR_BIT_PORT(pHCDData,
((pSetup->wIndex) -1),
OVER_CURRENT_CHANGE);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
break;
}
case USB_EHCD_RH_PORT_INDICATOR:/* Port Indicator */
{
/* Clear the Port indicator */
USB_EHCD_CLR_BIT_PORT(pHCDData,
((pSetup->wIndex & USB_EHCD_RH_PORT_NUMBER_MASK) -1),
PORT_INDICATOR_CONTROL);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
break;
}
case USB_EHCD_RH_PORT_TEST: /* Port test */
{
/* Clear the Port test */
USB_EHCD_CLR_BIT_PORT(pHCDData,
((pSetup->wValue & USB_EHCD_RH_PORT_NUMBER_MASK) -1),
PORT_TEST_CONTROL);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
break;
}
case USB_EHCD_RH_C_PORT_RESET:/* c_port_reset */
{
/* To hold the status of the port */
UINT32 uPortStatus = 0;
/* Clear the internal data for reset change */
/* Copy the value in the port status register */
OS_MEMCPY(&uPortStatus,
(pHCDData->RHData.pPortStatus +
(pSetup->wIndex -1)),
USB_EHCD_RH_PORT_STATUS_SIZE);
/* Swap the data to the LE format */
uPortStatus = OS_UINT32_LE_TO_CPU(uPortStatus);
/* Update the reset change */
uPortStatus &= (~USB_EHCD_RH_PORT_RESET_CHANGE);
/* Swap the data to CPU format data */
uPortStatus = OS_UINT32_CPU_TO_LE(uPortStatus);
/* Copy the status back to the port status */
OS_MEMCPY((pHCDData->RHData.pPortStatus +
(pSetup->wIndex -1)),
&uPortStatus,
USB_EHCD_RH_PORT_STATUS_SIZE);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
/*
* Call the function to populate the interrupt
* status data
*/
#if 0
usbEhcdCopyRHInterruptData(
pHCDData,
(USB_EHCD_RH_MASK_VALUE << (pSetup->wIndex -1)));
#endif
break;
}
case USB_EHCD_RH_C_PORT_SUSPEND:/* c_port_suspend */
{
/* To hold the status of the port */
UINT32 uPortStatus = 0;
/* Clear the internal data for suspend change */
/* Copy the value in the port status register */
OS_MEMCPY(&uPortStatus,
(pHCDData->RHData.pPortStatus +
(pSetup->wIndex -1)),
USB_EHCD_RH_PORT_STATUS_SIZE);
/* Update the suspend change */
uPortStatus &= (~USB_EHCD_RH_PORT_SUSPEND_CHANGE);
/* Copy the status back to the port status */
OS_MEMCPY((pHCDData->RHData.pPortStatus +
(pSetup->wIndex -1)),
&uPortStatus,
USB_EHCD_RH_PORT_STATUS_SIZE);
/* Update the URB status */
pURB->nStatus = USBHST_SUCCESS;
/*
* Call the function to populate the interrupt
* status data
*/
usbEhcdCopyRHInterruptData(
pHCDData,
(USB_EHCD_RH_MASK_VALUE << (pSetup->wIndex -1)));
break;
}
default: /* Unknown feature */
{
pURB->nStatus = USBHST_INVALID_REQUEST;
break;
}/* End of default */
}/* End of switch () */
OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhClearPortFeature - Exit\n",0,0,0,0);
return Status;
}
/* End of usbEhcdRhClearPortFeature() */
/***************************************************************************
*
* usbEhcdRhGetHubDescriptor - get the hub descriptor
*
* This routine gets the hub descriptor.
*
* RETURNS: USBHST_SUCCESS if the URB is submitted successfully.
* USBHST_INVALID_PARAMETER if the parameters are not valid.
*
* ERRNO:
* None.
*/
USBHST_STATUS usbEhcdRhGetHubDescriptor
(
pUSB_EHCD_DATA pHCDData, /* Ptr to HCD block */
pUSBHST_URB pURB /* Ptr to User Request Block */
)
{
/* To hold the request status */
USBHST_STATUS Status = USBHST_SUCCESS;
/* Pointer to the setup packet */
pUSBHST_SETUP_PACKET pSetup = NULL;
/* To hold the number of bytes alloted for the port information */
UINT32 uPortBytes = 0;
/* To hold the index into the ports */
UINT32 uIndex = 0;
/* Pointer to the buffer */
UCHAR *pBuffer = NULL;
OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhGetHubDescriptor - Entry\n",0,0,0,0);
/* Check the validity of the parameters */
if (NULL == pHCDData ||
NULL == pURB ||
NULL == pURB->pTransferSpecificData ||
NULL == pURB->pTransferBuffer)
{
OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhGetHubDescriptor - \
Invalid parameters\n",0,0,0,0);
pURB->nStatus = USBHST_INVALID_PARAMETER;
return USBHST_INVALID_PARAMETER;
}
/* Extract the setup packet */
pSetup = (pUSBHST_SETUP_PACKET)pURB->pTransferSpecificData;
/*
* Check whether there are any invalid conditions.
* i.e invalid DevRequest parameters
*/
if(0x2900 != pSetup->wValue ||
0 != pSetup->wIndex)
{
OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhGetHubDescriptor - \
Invalid parameters\n",0,0,0,0);
pURB->nStatus = USBHST_INVALID_PARAMETER;
return USBHST_INVALID_PARAMETER;
}
/*
* Determine the number of bytes that the descriptor would occupy
* ie. the num of bytes req to accomodate info about the ports
*/
uPortBytes = (pHCDData->RHData.uNumDownstreamPorts) / 8;
if(0 != pHCDData->RHData.uNumDownstreamPorts % 8)
{
uPortBytes++;
}
/* Allocate memory for the buffer */
pBuffer = (UCHAR *)OS_MALLOC(7 + (uPortBytes * 2));
/* Check if memory allocation is successful */
if(NULL == pBuffer)
{
OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhGetHubDescriptor - \
Memory not allocated\n",0,0,0,0);
pURB->nStatus = USBHST_MEMORY_NOT_ALLOCATED;
return USBHST_MEMORY_NOT_ALLOCATED;
}
/* Population of the values of hub descriptor - Start */
/* Length of the descriptor */
pBuffer[0] = 7 + (uPortBytes * 2);
/* Hub Descriptor type */
pBuffer[1] = 0x29;
/* Number of downstream ports */
pBuffer[2] = pHCDData->RHData.uNumDownstreamPorts;
/*
* The following 2 bytes give the hub characteristics
* The root hub has individual port overcurrent indication
* Read the Port power control field and update whether the root hub
* supports per port power switching or ganged power switching.
*/
pBuffer[3] = 0x08 | USB_EHCD_GET_FIELD(pHCDData,
HCSPARAMS,
PPC);
pBuffer[4] = 0;
/* The power On to Power Good Time for the Root hub is 1 * 2ms */
pBuffer[5] = 1;
/* There are no specific maximim current requirements */
pBuffer[6] = 0;
/* The last few bytes of the descriptor is based on the number of ports */
for(uIndex = 0;uIndex < uPortBytes ; uIndex++)
{
/* Indicates whether the hub is removable */
pBuffer[7+uIndex] = 0;
/* Port power control mask should be 1 for all the ports */
pBuffer[7+uPortBytes+uIndex] = 0xff;
}
/* Population of the values of hub descriptor - End */
/* Update the length */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -