aboutsummaryrefslogtreecommitdiffstats
path: root/src/hw
diff options
context:
space:
mode:
Diffstat (limited to 'src/hw')
-rw-r--r--src/hw/usb-xhci.c4
-rw-r--r--src/hw/usb.c13
-rw-r--r--src/hw/usb.h5
3 files changed, 20 insertions, 2 deletions
diff --git a/src/hw/usb-xhci.c b/src/hw/usb-xhci.c
index ca1fe251..e3052a51 100644
--- a/src/hw/usb-xhci.c
+++ b/src/hw/usb-xhci.c
@@ -1042,7 +1042,7 @@ xhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
xhci_xfer_data(pipe, dir, data, datalen);
xhci_xfer_status(pipe, dir, datalen);
- int cc = xhci_event_wait(xhci, &pipe->reqs, 1000);
+ int cc = xhci_event_wait(xhci, &pipe->reqs, usb_xfer_time(p, datalen));
if (cc != CC_SUCCESS) {
dprintf(1, "%s: control xfer failed (cc %d)\n", __func__, cc);
return -1;
@@ -1062,7 +1062,7 @@ xhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datalen)
GET_LOWFLAT(pipe->pipe.cntl), struct usb_xhci_s, usb);
xhci_xfer_normal(pipe, data, datalen);
- int cc = xhci_event_wait(xhci, &pipe->reqs, 1000);
+ int cc = xhci_event_wait(xhci, &pipe->reqs, usb_xfer_time(p, datalen));
if (cc != CC_SUCCESS) {
dprintf(1, "%s: bulk xfer failed (cc %d)\n", __func__, cc);
return -1;
diff --git a/src/hw/usb.c b/src/hw/usb.c
index 7b8a9f5f..46b46be8 100644
--- a/src/hw/usb.c
+++ b/src/hw/usb.c
@@ -187,6 +187,19 @@ usb_getFrameExp(struct usbdevice_s *usbdev
return (period <= 4) ? 0 : period - 4;
}
+// Maximum time (in ms) a data transfer should take
+int
+usb_xfer_time(struct usb_pipe *pipe, int datalen)
+{
+ // Use the maximum command time (5 seconds), except for
+ // set_address commands where we don't want to stall the boot if
+ // the device doesn't actually exist. Add 100ms to account for
+ // any controller delays.
+ if (!pipe->devaddr)
+ return USB_TIME_STATUS + 100;
+ return USB_TIME_COMMAND + 100;
+}
+
// Find the first endpoing of a given type in an interface description.
struct usb_endpoint_descriptor *
findEndPointDesc(struct usbdevice_s *usbdev, int type, int dir)
diff --git a/src/hw/usb.h b/src/hw/usb.h
index 61962964..3a663ce1 100644
--- a/src/hw/usb.h
+++ b/src/hw/usb.h
@@ -84,6 +84,10 @@ struct usbhub_op_s {
#define USB_TIME_DRSTR 50
#define USB_TIME_RSTRCY 10
+#define USB_TIME_STATUS 50
+#define USB_TIME_DATAIN 500
+#define USB_TIME_COMMAND 5000
+
#define USB_TIME_SETADDR_RECOVERY 2
#define USB_PID_OUT 0xe1
@@ -237,6 +241,7 @@ void usb_desc2pipe(struct usb_pipe *pipe, struct usbdevice_s *usbdev
, struct usb_endpoint_descriptor *epdesc);
int usb_getFrameExp(struct usbdevice_s *usbdev
, struct usb_endpoint_descriptor *epdesc);
+int usb_xfer_time(struct usb_pipe *pipe, int datalen);
struct usb_endpoint_descriptor *findEndPointDesc(struct usbdevice_s *usbdev
, int type, int dir);
void usb_enumerate(struct usbhub_s *hub);