📄 usbuhcdrhemulate.c
字号:
OS_LOG_MESSAGE_MEDIUM(UHCD,"Switch on features to be selected\n",0,0,0,0); /* Switch on the feature to be selected */ switch (wValue) { case USB_UHCD_PORT_RESET: /* If port reset */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : port reset\n",0,0,0,0); /* * Clear the enable condition on the port. * This is done as by giving a reset signal the port * would be enabled */ usbUhcdPortClearBit(pHCDData, offset, 2); /* * Give a minimum debounce time (100ms is minimum) * Additional 10ms is given here for software delays. */ /* Assert a reset on the port */ usbUhcdPortSetBit(pHCDData, offset, 9); /* * The reset signal should be driven atleast for 50ms * from the Root hub. * Additional 10ms is given here for software delays. */ usbUhciDelay(pHCDData,20); /* update the reset change field in the HCD structure */ pHCDData->usbUhcdResetChange[port-1] = 1; /* Stop reset signalling on the port */ usbUhcdPortClearBit(pHCDData, offset, 9); usbUhciDelay(pHCDData,1); /* Enable the port */ usbUhcdPortSetBit(pHCDData, offset, 2); /* Give a settling time */ usbUhciDelay(pHCDData,10); /* Clear the port staus change */ usbUhcdPortClearBit(pHCDData, offset, 1); /* Clear the Port Enable change bit */ usbUhcdPortClearBit(pHCDData, offset, 3); break; }/* End of case USB_UHCD_PORT_RESET */ case USB_UHCD_PORT_SUSPEND:/* If port suspend */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : port suspend\n",0,0,0,0); OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking port\n",0,0,0,0); /* * Suspend the port only if port is enabled * and global suspend is inactive */ if (usbUhcdIsBitSet (pHCDData, offset, 2) && usbUhcdIsBitReset (pHCDData, USB_UHCD_USBCMD, 3)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Port enabled so suspend\n",0,0,0,0); /* Set the bit to suspend the port */ usbUhcdPortSetBit (pHCDData, offset, 12); } else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Port not enabled\n",0,0,0,0); return USB_UHCD_FAIL; } break; }/* End of case USB_UHCD_PORT_SUSPEND */ /* The following features are functional no-operations */ case USB_UHCD_PORT_POWER: /* Port Power */ case USB_UHCD_C_PORT_CONNECTION: /* c_port_connection */ case USB_UHCD_C_PORT_ENABLE: /* c_port_enable */ case USB_UHCD_C_PORT_SUSPEND : /* c_port_suspend */ case USB_UHCD_C_PORT_OVERCURRENT: /* c_port_over_current */ case USB_UHCD_C_PORT_RESET: /* c_port_reset */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : c port reset\n",0,0,0,0); break; } default: { OS_LOG_MESSAGE_MEDIUM(UHCD,"case : default__fail\n",0,0,0,0); return USB_UHCD_FAIL; }/* End of default */ }/* End of switch () */ }/* End of else */ OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting set port feature\n",0,0,0,0); /* Return success from the function */ return USB_UHCD_PASS; }/* End of usbUhcdSetPortFeature() *//***************************************************************************** usbUhcdClearPortFeature - handles the hub specific request for Root hub** This function handles the CLEAR_PORT_FEATURE hub specific.** RETURNS: USB_UHCD_FAIL if there is an error in clearing the port status** ERRNO:* None.** \NOMANUAL*/INT32 usbUhcdClearPortFeature ( PUHCD_DATA pHCDData, USBHST_URB *pUrb ) { /* To hold the offset of the port register */ UINT32 offset = 0; /* To hold the port number */ UINT8 port = 0 ; UINT16 wValue = 0; UINT16 wIndex = 0; UINT16 wLength = 0; pUSBHST_SETUP_PACKET pSetupPacket = (pUSBHST_SETUP_PACKET )pUrb->pTransferSpecificData; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering clear port feature\n",0,0,0,0); /* Check if the URB and the DevReqest pointers are valid */ if (NULL == pUrb || NULL == pUrb->pTransferSpecificData) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pointers are not valid \n",0,0,0,0); return USB_UHCD_FAIL; } wValue = OS_UINT16_CPU_TO_LE(pSetupPacket->wValue); wIndex = OS_UINT16_CPU_TO_LE(pSetupPacket->wIndex); wLength = OS_UINT16_CPU_TO_LE(pSetupPacket->wLength); /* Extract the port number from URB */ port = wIndex; OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking validity of parameters\n",0,0,0,0); /* * Check whether there are any invalid conditions. * i.e invalid port, invalid DevRequest parameters */ if (port < USB_UHCD_PORT_1 || port > USB_UHCD_PORT_2 || wLength!=0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Invalid conditions\n",0,0,0,0); return USB_UHCD_FAIL; } /* The parameters are ok */ else { OS_LOG_MESSAGE_MEDIUM(UHCD,"Valid parameters\n",0,0,0,0); /* Get the correct offset based on port number */ offset = (port==1)? (USB_UHCD_PORT1) : (USB_UHCD_PORT2); OS_LOG_MESSAGE_MEDIUM(UHCD,"Switch on features to be selected\n",0,0,0,0); /* Switch on the feature selected */ switch (wValue) { case USB_UHCD_PORT_ENABLE:/* Port enable */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"case : port enable\n",0,0,0,0); usbUhcdPortClearBit (pHCDData, offset, 1); break; }/* End of case USB_UHCD_PORT_ENABLE */ case USB_UHCD_PORT_SUSPEND:/* Port Suspend */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : port suspend\n",0,0,0,0); OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking port is enabled or not\n",0,0,0,0); /* * Suspend can be cleared only if the port is enabled * & suspended */ if (usbUhcdIsBitSet (pHCDData, offset, 2) && usbUhcdIsBitSet (pHCDData, offset, 12)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Port is enabled\n",0,0,0,0); /* If the HC is suspended, then clear that first */ if (usbUhcdIsBitSet (pHCDData, USB_UHCD_USBCMD, 3) ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"HC is suspended\n",0,0,0,0); /* Force global resume */ usbUhcdRegxSetBit (pHCDData, USB_UHCD_USBCMD, 4); /* * A mininum of 20ms is required between setting and * clearing the global resume * Additional 10ms is given for the software delays. */ OS_DELAY_MS(50); /* Clear global resume */ usbUhcdRegxClearBit (pHCDData, USB_UHCD_USBCMD, 4); } /* Drive port resume */ usbUhcdPortSetBit (pHCDData, offset, 6); /* * A minimum of 20ms is required between setting and * clearing the global resume * Addition 10ms is given for software delays. */ OS_DELAY_MS(30); /* Stop port resume */ usbUhcdPortClearBit (pHCDData, offset, 6); } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting case : port suspend\n",0,0,0,0); break; }/* End of case USB_UHCD_PORT_SUSPEND */ case USB_UHCD_C_PORT_CONNECTION:/* if C_PORT_CONNECTOION */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : c port connection\n",0,0,0,0); OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking connect status change\n",0,0,0,0); /* If there is a connect status change, clear it */ if (usbUhcdIsBitSet (pHCDData, offset, 1) ) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Connect status change cleared\n",0,0,0,0); usbUhcdPortClearBit (pHCDData, offset, 1); } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting Case : connect status change\n",0,0,0,0); break; }/* End of case USB_UHCD_C_PORT_CONNECTION */ case USB_UHCD_C_PORT_ENABLE:/* C_PORT_ENABLED */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : c port enabled\n",0,0,0,0); OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking enable & disable change\n",0,0,0,0); /* If there is a Enable/Disable change, clear it */ if (usbUhcdIsBitSet (pHCDData, offset, 3)) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Cleared enable & disable change\n",0,0,0,0); usbUhcdPortClearBit (pHCDData, offset, 3); } OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting Case c port enabled\n",0,0,0,0); break; }/* End of case USB_UHCD_C_PORT_ENABLED */ case USB_UHCD_C_PORT_RESET:/* C_PORT_RESET */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : c port reset\n",0,0,0,0); /* Clear the HCD maintained reset change flag */ pHCDData->usbUhcdResetChange [port-1] = 0; break; }/* End of case USB_UHCD_C_PORT_RESET */ /* The feature listed below are a functional no operation */ case USB_UHCD_PORT_POWER: /* Port Power */ case USB_UHCD_C_PORT_OVERCURRENT: /* c_port_over_current */ case USB_UHCD_C_PORT_SUSPEND : /* c_port_suspend */ case USB_UHCD_PORT_INDICATOR: /* Port Indicator */ { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : port indicator\n",0,0,0,0); break; } default: { OS_LOG_MESSAGE_MEDIUM(UHCD,"Case : default__fail\n",0,0,0,0); return USB_UHCD_FAIL; }/* End of default */ }/* End of switch */ }/* End of else */ OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting clear port feature\n",0,0,0,0); return USB_UHCD_PASS; }/* End of usbUhcdClearPortFeature() *//***************************************************************************** usbUhcdGetHubDescriptor - handles the hub specific request for Root hub** This function handles the GET_HUB_DESCRIPTOR hub specific request for* the Root hub.** RETURNS: USB_UHCD_FAIL if there is an error in retrieving the hub* descriptor** ERRNO:* None.** \NOMANUAL*/INT32 usbUhcdGetHubDescriptor ( USBHST_URB *pUrb ) { /* To hold the descriptor string */ UCHAR desc[13]; /* To hold the number of ports supported by the Root hub */ UINT8 nport = USB_UHCD_ROOT_HUB_PORTS; /* * To hold the number of bytes of the hub descriptor * This is done as the number of bytes is dependent on the number * of downstream ports supported by the Root hub. */ UINT8 nPortBytes = 0; /* To hold the index into the ports */ UINT8 i = 0; UINT16 wValue = 0; UINT16 wIndex = 0; UINT16 wLength = 0; pUSBHST_SETUP_PACKET pSetupPacket = (pUSBHST_SETUP_PACKET )pUrb->pTransferSpecificData; OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering GetHubDescriptor\n",0,0,0,0); /* Check if the URB and DevRequest pointers are valid */ if (NULL == pUrb || NULL == pUrb->pTransferSpecificData) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Pointers are not valid \n",0,0,0,0); return USB_UHCD_FAIL; } wValue = OS_UINT16_CPU_TO_LE(pSetupPacket->wValue); wIndex = OS_UINT16_CPU_TO_LE(pSetupPacket->wIndex); wLength = OS_UINT16_CPU_TO_LE(pSetupPacket->wLength); OS_LOG_MESSAGE_MEDIUM(UHCD,"Checking parameters\n",0,0,0,0); /* * Check whether there are any invalid conditions. * i.e invalid DevRequest parameters */ if (wValue != 0x2900 || wIndex != 0) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Invalid conditions\n",0,0,0,0); return USB_UHCD_FAIL; } /* Check whether the Buffer passed is valid */ if (pUrb->pTransferBuffer==NULL) { OS_LOG_MESSAGE_MEDIUM(UHCD,"Invalid buffer passed\n",0,0,0,0); return USB_UHCD_FAIL; } /* * Determine the number of bytes that the descriptor would occupy * ie. the num of bytes req to accomodate info about the ports */ nPortBytes = nport / 8; if (nport % 8) nPortBytes++; /* Population of the values of hub descriptor - Start */ /* Length of the descriptor */ desc[0] = 7 + (nPortBytes * 2); /* Hub Descriptor type */ desc[1] = USB_UHCD_HUB_DESCRIPTOR; /* Number of downstream ports */ desc[2] = nport; /* * The following 2 bytes give the hub characteristics * The Root hub doesn't provide any overcurrent protection */ desc[3] = USB_UHCD_INDIVIDUAL_PORT_POWER || \ USB_UHCD_HUB_NOT_COMPOUND_DEV || \ USB_UHCD_GLOBAL_OVER_CURRENT_PROT; desc[4] = 0; /* The power On to Power Good Time for the Root hub is 1 * 2ms */ desc[5] = 1; /* There are no specific maximim current requirements */ desc[6] = 0; /* The last few bytes of the descriptor is based on the number of ports */ for (i = 0; i < nPortBytes; i++) { /* Indicates whether the hub is removable */ desc [7+i] = USB_UHCD_HUB_REMOVABLE; /* Port power control mask should be 1 for all the ports */ desc [7+nPortBytes+i] = USB_UHCD_PORT_PWR_CTRL_MASK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -