diff options
Diffstat (limited to 'payloads/libpayload/drivers/usb')
-rw-r--r-- | payloads/libpayload/drivers/usb/ehci.c | 2 | ||||
-rw-r--r-- | payloads/libpayload/drivers/usb/ehci_private.h | 3 | ||||
-rw-r--r-- | payloads/libpayload/drivers/usb/ehci_rh.c | 27 |
3 files changed, 24 insertions, 8 deletions
diff --git a/payloads/libpayload/drivers/usb/ehci.c b/payloads/libpayload/drivers/usb/ehci.c index aa7ea3b980..578db37a90 100644 --- a/payloads/libpayload/drivers/usb/ehci.c +++ b/payloads/libpayload/drivers/usb/ehci.c @@ -203,7 +203,7 @@ static int closest_usb2_hub(const usbdev_t *dev, int *const addr, int *const por const usbdev_t *usb1dev; do { usb1dev = dev; - if ((dev->hub > 0) && (dev->hub < 128)) + if ((dev->hub >= 0) && (dev->hub < 128)) dev = dev->controller->devices[dev->hub]; else dev = NULL; diff --git a/payloads/libpayload/drivers/usb/ehci_private.h b/payloads/libpayload/drivers/usb/ehci_private.h index c9fa6e07da..8519c0f2af 100644 --- a/payloads/libpayload/drivers/usb/ehci_private.h +++ b/payloads/libpayload/drivers/usb/ehci_private.h @@ -80,6 +80,9 @@ typedef volatile struct { u8 res1[0x40-0x1c]; u32 configflag; portsc_t portsc[0]; + u8 res2[0x40]; + u32 hostpc; + /* hostpc register is used for CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT */ } __attribute__ ((packed)) hc_op_t; typedef volatile struct { diff --git a/payloads/libpayload/drivers/usb/ehci_rh.c b/payloads/libpayload/drivers/usb/ehci_rh.c index 6109505c7f..da8d8aff8b 100644 --- a/payloads/libpayload/drivers/usb/ehci_rh.c +++ b/payloads/libpayload/drivers/usb/ehci_rh.c @@ -30,6 +30,7 @@ //#define USB_DEBUG #include <libpayload.h> +#include <kconfig.h> #include "ehci.h" #include "ehci_private.h" @@ -91,6 +92,8 @@ ehci_rh_hand_over_port (usbdev_t *dev, int port) static void ehci_rh_scanport (usbdev_t *dev, int port) { + usb_speed port_speed; + if (RH_INST(dev)->devices[port]!=-1) { usb_debug("Unregister device at port %x\n", port+1); usb_detach_device(dev->controller, RH_INST(dev)->devices[port]); @@ -99,7 +102,9 @@ ehci_rh_scanport (usbdev_t *dev, int port) /* device connected, handle */ if (RH_INST(dev)->ports[port] & P_CURR_CONN_STATUS) { mdelay(100); // usb20 spec 9.1.2 - if ((RH_INST(dev)->ports[port] & P_LINE_STATUS) == P_LINE_STATUS_LOWSPEED) { + if (!IS_ENABLED(CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT) && + (RH_INST(dev)->ports[port] & P_LINE_STATUS) == + P_LINE_STATUS_LOWSPEED) { ehci_rh_hand_over_port(dev, port); return; } @@ -133,8 +138,16 @@ ehci_rh_scanport (usbdev_t *dev, int port) ehci_rh_hand_over_port(dev, port); return; } - usb_debug("port %x hosts a USB2 device\n", port+1); - RH_INST(dev)->devices[port] = usb_attach_device(dev->controller, dev->address, port, 2); + if (IS_ENABLED(CONFIG_LP_USB_EHCI_HOSTPC_ROOT_HUB_TT)) { + port_speed = (usb_speed) + ((EHCI_INST(dev->controller)->operation->hostpc + >> 25) & 0x03); + } else { + usb_debug("port %x hosts a USB2 device\n", port+1); + port_speed = HIGH_SPEED; + } + RH_INST(dev)->devices[port] = usb_attach_device(dev->controller + , dev->address, port, port_speed); } /* RW/C register, so clear it by writing 1 */ RH_INST(dev)->ports[port] |= P_CONN_STATUS_CHANGE; @@ -186,12 +199,12 @@ ehci_rh_init (usbdev_t *dev) } mdelay(20); // ehci spec 2.3.9 + dev->speed = HIGH_SPEED; + dev->address = 0; + dev->hub = -1; + dev->port = -1; for (i=0; i < RH_INST(dev)->n_ports; i++) { RH_INST(dev)->devices[i] = -1; ehci_rh_scanport(dev, i); } - - dev->address = 0; - dev->hub = -1; - dev->port = -1; } |