📄 usbehcdrhemulation.c
字号:
/* 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 = USB_EHCD_SWAP_DATA(uBusIndex,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 */ { /* * If only the host controller supports port * power switching, power off the port. */ if (USB_EHCD_GET_FIELD(pHCDData, HCSPARAMS, PPC) == 1) { /* 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 = USB_EHCD_SWAP_DATA(uBusIndex, uPortStatus); /* Update the connect status change */ uPortStatus &= ~(USB_EHCD_RH_PORT_CONNECT_CHANGE); /* Swap the data to LE format data */ uPortStatus = USB_EHCD_SWAP_DATA(uBusIndex, 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 = USB_EHCD_SWAP_DATA(uBusIndex,uPortStatus); /* Update the reset change */ uPortStatus &= (~USB_EHCD_RH_PORT_RESET_CHANGE); /* Swap the data to CPU format data */ uPortStatus = USB_EHCD_SWAP_DATA(uBusIndex,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 */ if (pURB->uTransferLength >= 7 + (uPortBytes * 2)) { pURB->uTransferLength = 7 + (uPortBytes * 2); } /* Copy the data */ OS_MEMCPY(pURB->pTransferBuffer, pBuffer, pURB->uTransferLength);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -