On Sun, Oct 01, 2017 at 04:25:05AM +0200, diffusae wrote:
Hello!
On 01.10.2017 02:07, Kevin O'Connor wrote:
That's an unusual failure. Can you recompile seabios with the debug level set to 5, reproduce, and forward the log? Then also provide a log with a boot when the USB 3 drive is not plugged in. Finally, please provide the output from "lsusb -t" and "lsusb".
To reproduce I've disconnected all other USB devices. With the drive plugged in, there is no USB 3 hub after boot. If there is no drive plugged in, than the timeout warning goes away:
|bfeab000| WARNING - Timeout at xhci_event_wait:735!
It looks like you're having the same USB2/USB3 device detection issue that has popped up in the past. For example, see:
https://mail.coreboot.org/pipermail/seabios/2015-December/010121.html
Interestingly, though, in your case the USB2 instance of the device persists past reset, but not past set_address. Worse, it appears the controller hangs when set_address is sent to the USB2 instance.
Can you recompile SeaBIOS with the patch below applied? I don't have a good way to test this, but I'm hopeful it will help detect the USB2 disconnect and avoid the controller hang.
-Kevin
diff --git a/src/hw/usb-xhci.c b/src/hw/usb-xhci.c index 50b3b86..a4cdd4e 100644 --- a/src/hw/usb-xhci.c +++ b/src/hw/usb-xhci.c @@ -779,29 +779,39 @@ static void xhci_trb_queue(struct xhci_ring *ring, trb->status & 0xffff); }
-static int xhci_cmd_submit(struct usb_xhci_s *xhci, - struct xhci_trb *cmd) +static int xhci_cmd_submit(struct usb_xhci_s *xhci, u32 command, u32 slotid + , struct xhci_inctx *inctx) { - int rc; + if (inctx) { + struct xhci_slotctx *slot = (void*)&inctx[1 << xhci->context64]; + u32 port = ((slot->ctx[1] >> 16) & 0xff) - 1; + u32 portsc = readl(&xhci->pr[port].portsc); + if (!(portsc & XHCI_PORTSC_CCS)) { + // Device no longer connected?! + xhci_print_port_state(1, __func__, port, portsc); + return -1; + } + } + + struct xhci_trb cmd = { + .ptr_low = (u32)inctx, + .ptr_high = 0, + .status = 0, + .control = (slotid << 24) | (command << 10), + };
mutex_lock(&xhci->cmds->lock); - xhci_trb_queue(xhci->cmds, cmd); + xhci_trb_queue(xhci->cmds, &cmd); xhci_doorbell(xhci, 0, 0); - rc = xhci_event_wait(xhci, xhci->cmds, 1000); + int rc = xhci_event_wait(xhci, xhci->cmds, 1000); mutex_unlock(&xhci->cmds->lock); return rc; }
static int xhci_cmd_enable_slot(struct usb_xhci_s *xhci) { - struct xhci_trb cmd = { - .ptr_low = 0, - .ptr_high = 0, - .status = 0, - .control = (CR_ENABLE_SLOT << 10) - }; dprintf(3, "%s:\n", __func__); - int cc = xhci_cmd_submit(xhci, &cmd); + int cc = xhci_cmd_submit(xhci, CR_ENABLE_SLOT, 0, NULL); if (cc != CC_SUCCESS) return -1; return (xhci->cmds->evt.control >> 24) & 0xff; @@ -809,55 +819,31 @@ static int xhci_cmd_enable_slot(struct usb_xhci_s *xhci)
static int xhci_cmd_disable_slot(struct usb_xhci_s *xhci, u32 slotid) { - struct xhci_trb cmd = { - .ptr_low = 0, - .ptr_high = 0, - .status = 0, - .control = (slotid << 24) | (CR_DISABLE_SLOT << 10) - }; dprintf(3, "%s: slotid %d\n", __func__, slotid); - return xhci_cmd_submit(xhci, &cmd); + return xhci_cmd_submit(xhci, CR_DISABLE_SLOT, slotid, NULL); }
static int xhci_cmd_address_device(struct usb_xhci_s *xhci, u32 slotid , struct xhci_inctx *inctx) { - struct xhci_trb cmd = { - .ptr_low = (u32)inctx, - .ptr_high = 0, - .status = 0, - .control = (slotid << 24) | (CR_ADDRESS_DEVICE << 10) - }; dprintf(3, "%s: slotid %d\n", __func__, slotid); - return xhci_cmd_submit(xhci, &cmd); + return xhci_cmd_submit(xhci, CR_ADDRESS_DEVICE, slotid, inctx); }
static int xhci_cmd_configure_endpoint(struct usb_xhci_s *xhci, u32 slotid , struct xhci_inctx *inctx) { - struct xhci_trb cmd = { - .ptr_low = (u32)inctx, - .ptr_high = 0, - .status = 0, - .control = (slotid << 24) | (CR_CONFIGURE_ENDPOINT << 10) - }; dprintf(3, "%s: slotid %d, add 0x%x, del 0x%x\n", __func__, slotid, inctx->add, inctx->del); - return xhci_cmd_submit(xhci, &cmd); + return xhci_cmd_submit(xhci, CR_CONFIGURE_ENDPOINT, slotid, inctx); }
static int xhci_cmd_evaluate_context(struct usb_xhci_s *xhci, u32 slotid , struct xhci_inctx *inctx) { - struct xhci_trb cmd = { - .ptr_low = (u32)inctx, - .ptr_high = 0, - .status = 0, - .control = (slotid << 24) | (CR_EVALUATE_CONTEXT << 10) - }; dprintf(3, "%s: slotid %d, add 0x%x, del 0x%x\n", __func__, slotid, inctx->add, inctx->del); - return xhci_cmd_submit(xhci, &cmd); + return xhci_cmd_submit(xhci, CR_EVALUATE_CONTEXT, slotid, inctx); }
static struct xhci_inctx *