Showing with 38 additions and 25 deletions.
  1. +6 −1 CHANGELOG.md
  2. +22 −17 src/hw/usb-xhci.c
  3. +9 −6 src/hw/usb.c
  4. +1 −1 src/hw/usb.h
7 changes: 6 additions & 1 deletion CHANGELOG.md
Expand Up @@ -5,6 +5,10 @@ Fourth digit in release number means PC Engines patch.

## [Unreleased]

## [rel-1.11.0.5] - 2018-06-08
### Fixed
- USB timings

## [rel-1.11.0.4] - 2018-04-06
### Fixed
- links to comparison between tags
Expand Down Expand Up @@ -62,7 +66,8 @@ Fourth digit in release number means PC Engines patch.
### Fixed
- prevented from printing character multiple times

[Unreleased]: https://github.com/pcengines/seabios/compare/rel-1.11.0.4...apu_support
[Unreleased]: https://github.com/pcengines/seabios/compare/rel-1.11.0.5...apu_support
[rel-1.11.0.5]: https://github.com/pcengines/seabios/compare/rel-1.11.0.4...rel-1.11.0.5
[rel-1.11.0.4]: https://github.com/pcengines/seabios/compare/rel-1.11.0.3...rel-1.11.0.4
[rel-1.11.0.3]: https://github.com/pcengines/seabios/compare/rel-1.11.0.2...rel-1.11.0.3
[rel-1.11.0.2]: https://github.com/pcengines/seabios/compare/rel-1.11.0.1...rel-1.11.0.2
Expand Down
39 changes: 22 additions & 17 deletions src/hw/usb-xhci.c
Expand Up @@ -312,7 +312,7 @@ static int wait_bit(u32 *reg, u32 mask, int value, u32 timeout)
* Root hub
****************************************************************/

#define XHCI_TIME_POSTPOWER 100
#define XHCI_TIME_POSTPOWER 500

// Check if device attached to port
static void
Expand All @@ -333,6 +333,7 @@ xhci_hub_detect(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);
xhci_print_port_state(3, __func__, port, portsc);
return (portsc & XHCI_PORTSC_CCS) ? 1 : 0;
}

Expand All @@ -342,35 +343,37 @@ 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);
if (!(portsc & XHCI_PORTSC_CCS))
// Device no longer connected?!
if (!(portsc & XHCI_PORTSC_CCS)) {
dprintf(3, "XHCI: Device no longer connected!\n");
return -1;
}

switch (xhci_get_field(portsc, XHCI_PORTSC_PLS)) {
case PLS_U0:
// A USB3 port - controller automatically performs reset
dprintf(3, "XHCI: USB3 port - controller automatically performs reset\n");
break;
case PLS_POLLING:
// A USB2 port - perform device reset
dprintf(3, "XHCI: USB2 port - performing device reset\n");
xhci_print_port_state(3, __func__, port, portsc);
writel(&xhci->pr[port].portsc, portsc | XHCI_PORTSC_PR);
if (wait_bit(&xhci->pr[port].portsc, XHCI_PORTSC_PED, XHCI_PORTSC_PED, 1500) != 0)
return -1;
break;
default:
return -1;
}

dprintf(3, "XHCI: Wait for device to complete reset and be enabled\n");
// Wait for device to complete reset and be enabled
u32 end = timer_calc(1500);
u32 end = timer_calc(2000);
for (;;) {
portsc = readl(&xhci->pr[port].portsc);
if (!(portsc & XHCI_PORTSC_CCS))
// Device disconnected during reset
if (!(portsc & XHCI_PORTSC_CCS)) {
dprintf(3, "XHCI: Device disconnected during reset\n");
return -1;
if (portsc & XHCI_PORTSC_PED)
// Reset complete
}
if (portsc & XHCI_PORTSC_PED) {
dprintf(3, "XHCI: Reset complete\n");
break;
}
if (timer_check(end)) {
warn_timeout();
return -1;
Expand Down Expand Up @@ -469,9 +472,9 @@ configure_xhci(void *data)

dprintf(3, "%s: resetting\n", __func__);
writel(&xhci->op->usbcmd, XHCI_CMD_HCRST);
if (wait_bit(&xhci->op->usbcmd, XHCI_CMD_HCRST, 0, 500) != 0)
if (wait_bit(&xhci->op->usbcmd, XHCI_CMD_HCRST, 0, 1000) != 0)
goto fail;
if (wait_bit(&xhci->op->usbsts, XHCI_STS_CNR, 0, 500) != 0)
if (wait_bit(&xhci->op->usbsts, XHCI_STS_CNR, 0, 1000) != 0)
goto fail;

writel(&xhci->op->config, xhci->slots);
Expand Down Expand Up @@ -796,7 +799,7 @@ static int xhci_cmd_submit(struct usb_xhci_s *xhci, struct xhci_inctx *inctx
mutex_lock(&xhci->cmds->lock);
xhci_trb_queue(xhci->cmds, inctx, 0, flags);
xhci_doorbell(xhci, 0, 0);
int rc = xhci_event_wait(xhci, xhci->cmds, 2000);
int rc = xhci_event_wait(xhci, xhci->cmds, 4000);
mutex_unlock(&xhci->cmds->lock);
return rc;
}
Expand Down Expand Up @@ -894,9 +897,10 @@ static int xhci_config_hub(struct usbhub_s *hub)
struct xhci_pipe *pipe = container_of(
hub->usbdev->defpipe, struct xhci_pipe, pipe);
struct xhci_slotctx *hdslot = (void*)xhci->devs[pipe->slotid].ptr_low;
if ((hdslot->ctx[3] >> 27) == 3)
// Already configured
if ((hdslot->ctx[3] >> 27) == 3) {
dprintf(3, "XHCI hub already configured\n");// Already configured
return 0;
}
struct xhci_inctx *in = xhci_alloc_inctx(hub->usbdev, 1);
if (!in)
return -1;
Expand Down Expand Up @@ -1015,6 +1019,7 @@ xhci_alloc_pipe(struct usbdevice_s *usbdev
struct xhci_pipe *defpipe = container_of(
usbdev->defpipe, struct xhci_pipe, pipe);
pipe->slotid = defpipe->slotid;

// Send configure command.
int cc = xhci_cmd_configure_endpoint(xhci, pipe->slotid, in);
if (cc != CC_SUCCESS) {
Expand Down
15 changes: 9 additions & 6 deletions src/hw/usb.c
Expand Up @@ -413,12 +413,14 @@ usb_hub_port_setup(void *data)
for (;;) {
// Detect if device present (and possibly start reset)
int ret = hub->op->detect(hub, port);
if (ret > 0)
// Device connected.
if (ret > 0) {
dprintf(3, "USB: Port %d device connected\n", port + 1);
break;
if (ret < 0 || timer_check(hub->detectend))
// No device found.
}
if (ret < 0 || timer_check(hub->detectend)) {
dprintf(3, "USB: Port %d no device found\n", port + 1);
goto done;
}
msleep(20);
}

Expand All @@ -427,9 +429,10 @@ usb_hub_port_setup(void *data)
// Reset port and determine device speed
mutex_lock(&hub->cntl->resetlock);
int ret = hub->op->reset(hub, port);
if (ret < 0)
// Reset failed
if (ret < 0) {
dprintf(3,"USB reset port failed\n");
goto resetfail;
}
usbdev->speed = ret;

msleep(20);
Expand Down
2 changes: 1 addition & 1 deletion src/hw/usb.h
Expand Up @@ -78,7 +78,7 @@ struct usbhub_op_s {
****************************************************************/

// USB mandated timings (in ms)
#define USB_TIME_SIGATT 500 // 100 // WIV changed to 500 to make ADATA CIO3 stick working ( 200 is sufficient for SanDisk Ultra USB 3.0)
#define USB_TIME_SIGATT 2500 // 100 // WIV changed to 2500 to give USB devices enough time to be detected and enumerated
#define USB_TIME_ATTDB 100
#define USB_TIME_DRST 10
#define USB_TIME_DRSTR 50
Expand Down