[SeaBIOS] How to boot USB 3.0 devices with SeaBIOS
Kevin O'Connor
kevin at koconnor.net
Tue Oct 3 18:15:10 CEST 2017
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 *
More information about the SeaBIOS
mailing list