summary refs log tree commit diff stats
path: root/hw/usb/core.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-06-02 17:07:21 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-06-02 17:07:21 +0100
commit82ea61c6da4daa81d8614297391b8087e806ded9 (patch)
tree5e5bcd8610952ca6b11e0af70d8d011563321167 /hw/usb/core.c
parent1673e89e93e08cbfee7c9b552008e5b39469ad0e (diff)
parent7bafd8889ea3599285a8fcb1262d50e52d941c0e (diff)
downloadfocaccia-qemu-82ea61c6da4daa81d8614297391b8087e806ded9.tar.gz
focaccia-qemu-82ea61c6da4daa81d8614297391b8087e806ded9.zip
Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-8' into staging
qtest: improve ehci/uhci test
usb: misc fixes, mostly for usb3/xhci

# gpg: Signature made Mon 02 Jun 2014 15:40:34 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-usb-8:
  xhci: order superspeed ports first
  xhci: make port reset trace point more verbose
  usb: add usb_pick_speed
  usb-host: add HAVE_STREAMS define
  usb-host: allow attaching usb3 devices to ehci
  usb: improve ehci/uhci test
  usb: move ehci register defines to header file
  usb: add uhci port status reserved bit
  usb: move uhci register defines to header file
  qtest: fix qpci_config_writel

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/usb/core.c')
-rw-r--r--hw/usb/core.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/hw/usb/core.c b/hw/usb/core.c
index 67ba7d6018..cf34755bba 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -28,6 +28,26 @@
 #include "qemu/iov.h"
 #include "trace.h"
 
+void usb_pick_speed(USBPort *port)
+{
+    static const int speeds[] = {
+        USB_SPEED_SUPER,
+        USB_SPEED_HIGH,
+        USB_SPEED_FULL,
+        USB_SPEED_LOW,
+    };
+    USBDevice *udev = port->dev;
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(speeds); i++) {
+        if ((udev->speedmask & (1 << speeds[i])) &&
+            (port->speedmask & (1 << speeds[i]))) {
+            udev->speed = speeds[i];
+            return;
+        }
+    }
+}
+
 void usb_attach(USBPort *port)
 {
     USBDevice *dev = port->dev;
@@ -35,6 +55,7 @@ void usb_attach(USBPort *port)
     assert(dev != NULL);
     assert(dev->attached);
     assert(dev->state == USB_STATE_NOTATTACHED);
+    usb_pick_speed(port);
     port->ops->attach(port);
     dev->state = USB_STATE_ATTACHED;
     usb_device_handle_attach(dev);