[SeaBIOS] USB3 problems
Kevin O'Connor
kevin at koconnor.net
Tue Nov 10 14:57:57 CET 2015
On Mon, Nov 09, 2015 at 08:49:12AM -0500, Kevin O'Connor wrote:
> On Wed, Nov 04, 2015 at 03:30:52PM +0000, Wim Vervoorn wrote:
> > Hello,
> >
> > I am running into issues when using USB3 sticks in a system (on an XHCI controller).
> >
> > When I am using a single USB3 stick it gets detected properly. When I am using 2 USB3 sticks only one is detected. When using one USB3 and a USB2 stick it depends on the slots. In one case both are detected in the other case only the USB2 stick.
> >
> > I was first blaming this on the XHCI controller initialization but I have now reproduced this same issue on two completely different systems. One base on AMD Steppe Eagle and the other on an Intel Braswell.
> >
> > Does this sound familiar? Has anyone run into this before. (I am using two ADAT CI03 sticks)
>
> To summarize some off-list exchange of debug logs, it looks like this
> issue can be worked around by both applying the "msleep(20)" patch and
> by increasing USB_TIME_SIGATT to 500.
>
> I think making a new config file (eg, "etc/usb-time-sigatt") to allow
> USB_TIME_SIGATT to be configured without patching the code would make
> sense. I'll send a patch.
>
> I don't have a good solution for the msleep() issue right now.
Can you try reverting the msleep and sigatt changes and only apply the
patch below?
-Kevin
commit d331c611e5572270419406e1e0057cd17e502edd
Author: Kevin O'Connor <kevin at koconnor.net>
Date: Tue Nov 10 08:50:52 2015 -0500
xhci: Check for device disconnects during USB2 reset polling
Some XHCI controllers register super-speed devices on high-speed ports
and then disconnect them when the super-speed detection completes.
Make sure to recognize these disconnect events during the reset
process.
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
diff --git a/src/hw/usb-xhci.c b/src/hw/usb-xhci.c
index 173dff1..945b462 100644
--- a/src/hw/usb-xhci.c
+++ b/src/hw/usb-xhci.c
@@ -351,6 +351,9 @@ xhci_hub_reset(struct usbhub_s *hub, u32 port)
struct usb_xhci_s *xhci = container_of(hub->cntl, struct usb_xhci_s, usb);
u32 portsc = readl(&xhci->pr[port].portsc);
int rc;
+ if (!(portsc & XHCI_PORTSC_CCS))
+ // Device no longer connected?!
+ return -1;
switch (xhci_get_field(portsc, XHCI_PORTSC_PLS)) {
case PLS_U0:
@@ -360,11 +363,22 @@ xhci_hub_reset(struct usbhub_s *hub, u32 port)
case PLS_POLLING:
// A USB2 port - perform device reset and wait for completion
xhci_print_port_state(3, __func__, port, portsc);
- portsc |= XHCI_PORTSC_PR;
- writel(&xhci->pr[port].portsc, portsc);
- if (wait_bit(&xhci->pr[port].portsc, XHCI_PORTSC_PED, XHCI_PORTSC_PED, 100) != 0)
- return -1;
- portsc = readl(&xhci->pr[port].portsc);
+ writel(&xhci->pr[port].portsc, portsc | XHCI_PORTSC_PR);
+ u32 end = timer_calc(100);
+ for (;;) {
+ portsc = readl(&xhci->pr[port].portsc);
+ if (!(portsc & XHCI_PORTSC_CCS))
+ // Device disconnected during reset
+ return -1;
+ if (portsc & XHCI_PORTSC_PED)
+ // Reset complete
+ break;
+ if (timer_check(end)) {
+ warn_timeout();
+ return -1;
+ }
+ yield();
+ }
rc = speed_from_xhci[xhci_get_field(portsc, XHCI_PORTSC_SPEED)];
break;
default:
More information about the SeaBIOS
mailing list