📄 usbohci.c
字号:
uRegisterValue); USB_OHCI_REG_WRITE (uHostControllerIndex, (pOhciControllerInfo->uBaseAddress + USB_OHCI_RH_DESCRIPTOR_B_REGISTER_OFFSET), 0xFFFF0000); /* Disable and power off the ports and again power on the ports */ usbOhciPowerOffPorts(uHostControllerIndex); /* * Clear any pending interrupts */ USB_OHCI_REG_WRITE (uHostControllerIndex, (pOhciControllerInfo->uBaseAddress + USB_OHCI_INTERRUPT_STATUS_REGISTER_OFFSET), USB_OHCI_INTERRUPT_MASK);#ifndef USB_OHCI_POLLING_MODE /* Create the ISR event */ pOhciControllerInfo->isrEvent = OS_CREATE_EVENT(OS_EVENT_NON_SIGNALED); /* Check whether the event was created successfully */ if (OS_INVALID_EVENT_ID == pOhciControllerInfo->isrEvent) { /* Failed to create ISR event */ OS_LOG_MESSAGE_HIGH( OHCD, "Failed to create ISR event.\n", 0, 0, 0, 0); return FALSE; } /* Register the interrupt handler for the OHCI Controller */ uTemp = (UINT32) uHostControllerIndex; /* Call the function to register an ISR */ if (pOhciBusInfo[uHostControllerIndex]->pFuncIntConnect != NULL) uStatus = pOhciBusInfo[uHostControllerIndex]->pFuncIntConnect (usbOhciIsr, uTemp, pOhciControllerInfo->uIrqNumber); else uStatus = BUS_OPERATION_FAILURE; /* Check whether the interrupt handler was registered successfully */ if (uStatus == BUS_OPERATION_FAILURE) { /* Failed to register the interrupt handler */ return FALSE; } /* Enable all the OHCI interrupts */ USB_OHCI_REG_WRITE (uHostControllerIndex, (pOhciControllerInfo->uBaseAddress + USB_OHCI_INTERRUPT_ENABLE_REGISTER_OFFSET), USB_OHCI_INTERRUPT_MASK);#endif /* End of #ifndef USB_OHCI_POLLING_MODE */ /* Spawn the interrupt handler in polling mode */ pOhciControllerInfo->isrThreadId = OS_CREATE_THREAD("usbOhciIsr", /* Task Name */ 100, /* Task Priority */ usbOhciPollingIsr, /* Task Entry Function */ uHostControllerIndex); /* Argument to the task */ /* Check whether the interrupt handler thread was created successfully */ if (pOhciControllerInfo->isrThreadId == OS_THREAD_FAILURE) { /* Debug message */ OS_LOG_MESSAGE_HIGH ( OHCD, "Failed to spawn the interrupt handler thread.....\n", 0, 0, 0, 0); /* Failed to spawn the interrupt handler */ return FALSE; } /* Initialize the OHCI Controller (END) */ /* Set the flag to indicate the host controller is initialized */ pOhciControllerInfo->bHostControllerInitialized = TRUE; OS_LOG_MESSAGE_LOW( OHCD, "Exiting the function: usbOhciInitializeHostController().\n", 0, 0, 0, 0); return TRUE; } /* End of function usbOhciInitializeHostController() */VOID usbOhciPowerOffPorts ( UINT32 uHostControllerIndex ) { /* 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 loop index */ UINT32 uIndex = 0; /* To hold the offset of the port status register */ UINT32 uPortStatusRegisterOffset = 0; /* To hold the number of downstream ports */ UINT32 uNumberOfDownstreamPorts = 0; /* To hold the pointer to the host controller information */ PUSB_OHCI_INFORMATION pOhciControllerInfo = NULL; OS_LOG_MESSAGE_LOW( OHCD, "Entering the function: usbOhciPowerOffPorts().\n", 0, 0, 0, 0); /* Obtain the pointer to the host controller information */ pOhciControllerInfo = &usbOhciControllerInfo[uHostControllerIndex]; /* Obtain the base address */ uBaseAddress = pOhciControllerInfo->uBaseAddress; /* * NOTE: If the root hub supports ganged power on the down stream ports, * power on all the downstream ports. Else power on 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); uNumberOfDownstreamPorts = USB_OHCI_REG_READ(uHostControllerIndex, uBaseAddress + USB_OHCI_RH_DESCRIPTOR_A_REGISTER_OFFSET); /* Mask the other fields of the root hub description register */ uNumberOfDownstreamPorts = uNumberOfDownstreamPorts & 0x000000FF; /* Obtain the number of ports supported by the host controller (END) */ /* Disable all the downstream ports then power up the ports*/ for (uIndex = 1; uIndex <= uNumberOfDownstreamPorts; uIndex++) { uPortStatusRegisterOffset = USB_OHCI_RH_PORT_STATUS_REGISTER_OFFSET(uIndex); /* Read the contents of the port status register */ uRegisterValue = USB_OHCI_REG_READ(uHostControllerIndex, uBaseAddress + uPortStatusRegisterOffset); /* Clear Port Enable */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + uPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_CCS); } /* * 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 Change (LPSC) bit * to set the port power state. */ USB_OHCI_REG_WRITE(uHostControllerIndex, (uBaseAddress + USB_OHCI_RH_STATUS_REGISTER_OFFSET), USB_OHCI_RH_STATUS__LPS); /* Return from the function */ return; } /* * 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); return; } /* Obtain the number of ports supported by the host controller (BEGIN) */ /* Read the contents of the root hub description register */ uNumberOfDownstreamPorts = USB_OHCI_REG_READ(uHostControllerIndex, uBaseAddress + USB_OHCI_RH_DESCRIPTOR_A_REGISTER_OFFSET); /* Mask the other fields of the root hub description register */ uNumberOfDownstreamPorts = uNumberOfDownstreamPorts & 0x000000FF; /* Obtain the number of ports supported by the host controller (END) */ /* Power on all the downstream ports */ for (uIndex = 1; uIndex <= uNumberOfDownstreamPorts; uIndex++) { /* Obtain the base address of the port status register */ uPortStatusRegisterOffset = USB_OHCI_RH_PORT_STATUS_REGISTER_OFFSET(uIndex); /* Read the contents of the port status register */ uRegisterValue = USB_OHCI_REG_READ(uHostControllerIndex, uBaseAddress + uPortStatusRegisterOffset); /* * 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 + uPortStatusRegisterOffset), USB_OHCI_RH_PORT_STATUS_LSDA); } OS_LOG_MESSAGE_LOW( OHCD, "Exiting the function: usbOhciPowerOffPorts().\n", 0, 0, 0, 0); return; } /* End of function usbOhciPowerOffPorts () *//********************************************************************************* usbOhciDisable - function to disable the OHCI controller** This function is called on a warm reboot. It power-offs all the port of the * controller followed by resetting hte host controller.** RETURNS: N/A* * ERRNO: none** \NOMANUAL*/LOCAL VOID usbOhciDisable ( int startType ) { /* To hold the pointer to the host controller information */ PUSB_OHCI_INFORMATION pOhciControllerInfo = NULL; UINT8 index = 0; /* if the global array is NULL, return */ if (usbOhciControllerInfo == NULL || maxOhciCount == 0) return; while (index < maxOhciCount) { pOhciControllerInfo = &usbOhciControllerInfo[index]; if (pOhciControllerInfo) { /* power off the ports */ usbOhciPowerOffPorts (index); /* Reset the OHCI Controller */ USB_OHCI_REG_WRITE (index, (pOhciControllerInfo->uBaseAddress + USB_OHCI_COMMAND_STATUS_REGISTER_OFFSET), USB_OHCI_COMMAND_STATUS_HCR);#ifndef USB_OHCI_POLLING_MODE /* Unregister the IRQ */ if ((pOhciBusInfo[index] != NULL) && (pOhciBusInfo[index]->pFuncIntDisconnect != NULL)) pOhciBusInfo[index]->pFuncIntDisconnect (usbOhciIsr, index, pOhciControllerInfo->uIrqNumber);#endif } index++; } return; }#ifdef NO_CACHE_COHERENCY/***************************************************************************** usbOhciRegWrite - write contents to a HC register** This function is used to write the contents to a host controller register.** RETURNS: None** ERRNO:* None.* * \NOMANUAL*/VOID usbOhciRegWrite ( UINT32 index, /* Index of host controller */ UINT32 address,/* Address to which contents have to be written */ UINT32 value /* Value to be written */ ) { (*((volatile UINT32 *) (address)) = (USB_OHCD_SWAP_DATA (index, (value)))) ; cacheFlush(DATA_CACHE,(pVOID)address, 4); }/***************************************************************************** usbOhciRegRead - read contents of a HC register** This function is used to read the contents of a host controller register.** RETURNS: UINT32 value which indicates contents of the register** ERRNO:* None.* * \NOMANUAL*/UINT32 usbOhciRegRead ( UINT32 index, /* Index of host controller */ UINT32 address /* Address from which contents have to be read */ ) { cacheInvalidate(DATA_CACHE, (pVOID)address, 4); return (USB_OHCD_SWAP_DATA (index, *((volatile UINT32 *)address))); } #endif /* End of NO_CACHE_COHERENCY *//* End of File usbOhci.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -