aboutsummaryrefslogtreecommitdiffstats
path: root/hw/usb.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2011-09-15 12:10:21 +0200
committerGerd Hoffmann <kraxel@redhat.com>2011-10-13 12:58:51 +0200
commite0b8e72dd95f5fe133c8bb952a464814ca06fe8b (patch)
tree11c2928dee2be883a0021f776238cbe40e4c376b /hw/usb.c
parent3393bc105d58e1f4a27d9a8e7062da9cef260cc3 (diff)
usb: fix port reset
commit 891fb2cd4592b6fe76106a69e0ca40efbf82726a removed the implicit detach before (re-)attaching in usb_attach(). Some usb host controllers used that behavior though to do a port reset by a detach+attach sequence. This patch establishes old behavior by adding a new usb_reset() function for port resets and putting it into use, thereby also unifying port reset behavior of all host controllers. The patch also adds asserts to usb_attach() and usb_detach() to make sure the calls are symmetrical. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'hw/usb.c')
-rw-r--r--hw/usb.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/hw/usb.c b/hw/usb.c
index fa90204c5..2216efe07 100644
--- a/hw/usb.c
+++ b/hw/usb.c
@@ -33,6 +33,7 @@ void usb_attach(USBPort *port)
assert(dev != NULL);
assert(dev->attached);
+ assert(dev->state == USB_STATE_NOTATTACHED);
port->ops->attach(port);
usb_send_msg(dev, USB_MSG_ATTACH);
}
@@ -42,10 +43,21 @@ void usb_detach(USBPort *port)
USBDevice *dev = port->dev;
assert(dev != NULL);
+ assert(dev->state != USB_STATE_NOTATTACHED);
port->ops->detach(port);
usb_send_msg(dev, USB_MSG_DETACH);
}
+void usb_reset(USBPort *port)
+{
+ USBDevice *dev = port->dev;
+
+ assert(dev != NULL);
+ usb_detach(port);
+ usb_attach(port);
+ usb_send_msg(dev, USB_MSG_RESET);
+}
+
void usb_wakeup(USBDevice *dev)
{
if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) {