📄 usbohciroothubemulation.c
字号:
/* * Alternate setting for the root hub interface is not supported. * Update the URB status. */ pUrb->nStatus = USBHST_INVALID_REQUEST; break; case USBHST_REQ_SYNCH_FRAME: /* USB SYNCH_FRAME request */ /* * SYNCH_FRAME request is not supported on the root hub. * Update the URB status. */ pUrb->nStatus = USBHST_INVALID_REQUEST; break; }; /* Swap back the contents of the setup data structure which has 16 bits */ pSetupPacket->wValue = OS_UINT16_CPU_TO_LE(pSetupPacket->wValue); pSetupPacket->wIndex = OS_UINT16_CPU_TO_LE(pSetupPacket->wIndex); pSetupPacket->wLength = OS_UINT16_CPU_TO_LE(pSetupPacket->wLength); /* Debug print */ OS_LOG_MESSAGE_LOW( OHCD, "Exiting the function: usbOhciProcessRootHubStandardRequest().\n", 0, 0, 0, 0); return USBHST_SUCCESS; } /* End of function usbOhciProcessRootHubStandardRequest () *//***************************************************************************** usbOhciProcessRootHubClassSpecificRequest - processes the hub class requests** This function processes the hub class specific requests addressed to the * root hub** PARAMETERS: <nHostControllerIndex (IN)> - Host controller index corresponding * to the host controller for which an interrupt has occurred.** <pURB (IN)> - Pointer to the URB.** RETURNS: USBHST_SUCCESS on success, * USBHST_INVALID_PARAMETER if the parameters are invalid** ERRNO:* None.** \NOMANUAL*/LOCAL USBHST_STATUS usbOhciProcessRootHubClassSpecificRequest ( UINT8 uHostControllerIndex, pUSBHST_URB pUrb ) { /* To hold the pointer to the host controller information */ PUSB_OHCI_INFORMATION pOhciControllerInfo = NULL; /* To hold the contents of the SETUP packet */ pUSBHST_SETUP_PACKET pSetupPacket = NULL; /* To hold the offset of the root hub port status register */ UINT8 uRootHubPortStatusRegisterOffset = 0; /* To hold the base address of the OHCI Controller */ UINT32 uBaseAddress = 0; /* To hold the value read from the registers */ UINT32 uRegisterValue = 0; /* To hold the length of the hub descriptor */ UINT16 uHubDescriptorLength = 0; /* To hold the hub descriptor */ PUSB_OHCI_HUB_CLASS_DESCRIPTOR pHubDescriptor = NULL; /* * To hold the number of bytes required to hold the 'DeviceRemovable' * and 'PortPwrCtrlMask' information of the device descriptor. * * NOTE: HUB_CLASS_DESCRIPTOR structure can hold the above two * information for maximum of 8 ports. If the number of ports * on the root hub is greater than 8, additional memory * should be allocated for the HUB_CLASS_DESCRIPTOR. */ UINT8 uNumberOfBytes = 0; /* Debug print */ OS_LOG_MESSAGE_LOW( OHCD, "Entering the function: usbOhciProcessRootHubClassSpecificRequest().\n", 0, 0, 0, 0); /* Obtain the pointer to the host controller information */ pOhciControllerInfo = &usbOhciControllerInfo[uHostControllerIndex]; /* Obtain the base address for the OHCI Controller */ uBaseAddress = usbOhciControllerInfo[uHostControllerIndex].uBaseAddress; /* Obtain the pointer to the SETUP packet */ pSetupPacket = (pUSBHST_SETUP_PACKET) pUrb->pTransferSpecificData; /* Swap the contents of the setup data structure which has 16 bits */ pSetupPacket->wValue = OS_UINT16_LE_TO_CPU(pSetupPacket->wValue); pSetupPacket->wIndex = OS_UINT16_LE_TO_CPU(pSetupPacket->wIndex); pSetupPacket->wLength = OS_UINT16_LE_TO_CPU(pSetupPacket->wLength); /* Check the request to be processed */ switch (pSetupPacket->bRequest) { case USBHST_REQ_CLEAR_FEATURE: /* Check the recipient of the request */ switch (pSetupPacket->bmRequestType & USB_OHCI_CONTROL_TRANSFER_REQUEST_RECIPIENT_MASK) { case USBHST_RECIPIENT_DEVICE: /* ClearHubFeature() request */ /* Check the feature selector for the request */ switch (pSetupPacket->wValue) { case USB_OHCI_C_HUB_LOCAL_POWER: /* Clear change in hub local power */ /* NOTE: This feature is not supported on the * root hub */ /* Update the URB status */ pUrb->nStatus = USBHST_INVALID_REQUEST; break; case USB_OHCI_C_HUB_OVER_CURRENT: /* Clear change in over current indicator */ /* * Update the contents of the HcRhStatus * register */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + USB_OHCI_RH_STATUS_REGISTER_OFFSET), USB_OHCI_RH_STATUS_OCIC); /* Update the URB status */ pUrb->nStatus = USBHST_SUCCESS; break; default: /* Invalid feature selector. Update URB status */ pUrb->nStatus = USBHST_INVALID_REQUEST; break; }; /* End of switch (pSetupPacket->wValue) */ break; case USBHST_RECIPIENT_OTHER: /* ClearPortFeature() request */ /* Check the port number */ if (pSetupPacket->wIndex > pOhciControllerInfo->uNumberOfDownStreamPorts) { /* Invalid port index. Update the URB status. */ pUrb->nStatus = USBHST_INVALID_REQUEST; break; } /* Obtain the offset of the root hub port status register */ uRootHubPortStatusRegisterOffset = USB_OHCI_RH_PORT_STATUS_REGISTER_OFFSET( pSetupPacket->wIndex); /* * NOTE: Do not Read -> OR the value -> Update the register. * This is because the register is write 1 to clear or * set. * * Further, writing a 1 to some fields will cause side * effects. Refer to the OHCI specification for more * information. */ /* Check whether the feature selector for the request */ switch (pSetupPacket->wValue) { case USB_OHCI_PORT_ENABLE: /* Clear the port enable state */ /* * NOTE: Write 1 to the Current Connect Status (CCS) * bit to clear the port enable state. */ /* Clear the port enable state */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + uRootHubPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_CCS); /* Update the URB status */ pUrb->nStatus = USBHST_SUCCESS; break; case USB_OHCI_PORT_SUSPEND: /* Clear the port suspend state */ /* * NOTE: Write 1 to the Port Over Current Indicator * (POCI) bit to clear the port suspend state. */ /* Clear the port suspend state */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + uRootHubPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_POCI); /* Update the URB status */ pUrb->nStatus = USBHST_SUCCESS; break; case USB_OHCI_PORT_POWER: /* * NOTE: If the root hub supports ganged power on * the down stream ports, power off all the * downstream ports. Else power off the * specified port. */ /* * Read the contents of the root hub descriptor A * register */ uRegisterValue = USB_OHCI_REG_READ(uHostControllerIndex, uBaseAddress + USB_OHCI_RH_DESCRIPTOR_A_REGISTER_OFFSET); /* * Check whether the root hub supports ganged power * on the down stream ports. */ if ((uRegisterValue & USB_OHCI_RH_DESCRIPTOR_A_REGISTER__PSM_MASK) == 0) { /* * NOTE: Write 1 to the Local Power Status * (LPS) bit to clear the port power * state. */ /* * Root hub supports ganged power. Power off * all the down stream ports */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + USB_OHCI_RH_STATUS_REGISTER_OFFSET), USB_OHCI_RH_STATUS__LPS); } else { /* * Read the contents of the root hub descriptor B * register */ uRegisterValue = USB_OHCI_REG_READ(uHostControllerIndex, uBaseAddress + USB_OHCI_RH_DESCRIPTOR_B_REGISTER_OFFSET); /* * Check whether the Port Power Control Mask bit * is set for the specified port. * * a) If this bit is set, the port's power state * is only affected by per-port power control * (Set/ClearPortPower). * b) If this bit is cleared, th port is * controlled by the global power switch * (Set/ClearGlobalPower). */ if (0 == (uRegisterValue & USB_OHCI_HC_RH_DESCRIPTOR_B_REGISTER__PPCM_MASK)) { /* * Port power state is controlled by the * global power switch */ /* * NOTE: Write 1 to the Local Power Status (LPS) * bit to clear the port power state. */ /* * Root hub supports ganged power. Power off * all the down stream ports */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + USB_OHCI_RH_STATUS_REGISTER_OFFSET), USB_OHCI_RH_STATUS__LPS); } else { /* * NOTE: Write 1 to the Low Speed Device Attach * (LSDA) bit to clear the port power state. */ /* Clear the port power state */ USB_OHCI_REG_WRITE( uHostControllerIndex, (uBaseAddress + uRootHubPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_LSDA); } } /* Update the URB status */ pUrb->nStatus = USBHST_SUCCESS; break; case USB_OHCI_C_PORT_CONNECTION: /* * NOTE: Write 1 to the connect status change (CSC) * bit to clear the connect status change. */ /* Clear the connect status change */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + uRootHubPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_CSC); /* Update the URB status */ pUrb->nStatus = USBHST_SUCCESS; break; case USB_OHCI_C_PORT_RESET: /* * NOTE: Write 1 to the port reset status change * (PRSC) bit to clear the port reset status change. */ /* Clear the port reset status change */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + uRootHubPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_PRSC); /* Update the URB status */ pUrb->nStatus = USBHST_SUCCESS; break; case USB_OHCI_C_PORT_ENABLE: /* * NOTE: Write 1 to the port enable status change * (PESC) bit to clear port enable status change.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -