summary refs log tree commit diff stats
path: root/hw/usb-hub.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-02-15 17:25:25 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-02-15 17:25:25 -0600
commit7718564ba1295f35188a5fb3ac8633c29d43b166 (patch)
tree5aa858b930de7f4c25867f05f867c049d4f713f5 /hw/usb-hub.c
parent65b31cc207b8ab949033870acf55bb124d12848e (diff)
parent7c605a23b2c7606f5f06b7d83d8927b1dc111478 (diff)
downloadfocaccia-qemu-7718564ba1295f35188a5fb3ac8633c29d43b166.tar.gz
focaccia-qemu-7718564ba1295f35188a5fb3ac8633c29d43b166.zip
Merge remote-tracking branch 'kraxel/usb.38' into staging
* kraxel/usb.38: (28 commits)
  xhci: handle USB_RET_NAK
  xhci: remote wakeup support
  xhci: kill port arg from xhci_setup_packet
  xhci: stop on errors
  xhci: add trb type name lookup support.
  xhci: signal low- and fullspeed support
  usb: add USBBusOps->wakeup_endpoint
  usb: pass USBEndpoint to usb_wakeup
  usb: maintain async packet list per endpoint
  usb: Set USBEndpoint in usb_packet_setup().
  usb: add USBEndpoint->{nr,pid}
  usb: USBPacket: add status, rename owner -> ep
  usb: fold usb_generic_handle_packet into usb_handle_packet
  usb: kill handle_packet callback
  usb-xhci: switch to usb_find_device()
  usb-musb: switch to usb_find_device()
  usb-ohci: switch to usb_find_device()
  usb-ehci: switch to usb_find_device()
  usb-uhci: switch to usb_find_device()
  usb: handle dev == NULL in usb_handle_packet()
  ...
Diffstat (limited to 'hw/usb-hub.c')
-rw-r--r--hw/usb-hub.c72
1 files changed, 28 insertions, 44 deletions
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 7604730b7a..a12856e2e9 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -37,6 +37,7 @@ typedef struct USBHubPort {
 
 typedef struct USBHubState {
     USBDevice dev;
+    USBEndpoint *intr;
     USBHubPort ports[NUM_PORTS];
 } USBHubState;
 
@@ -163,7 +164,7 @@ static void usb_hub_attach(USBPort *port1)
     } else {
         port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
     }
-    usb_wakeup(&s->dev);
+    usb_wakeup(s->intr);
 }
 
 static void usb_hub_detach(USBPort *port1)
@@ -171,7 +172,7 @@ static void usb_hub_detach(USBPort *port1)
     USBHubState *s = port1->opaque;
     USBHubPort *port = &s->ports[port1->index];
 
-    usb_wakeup(&s->dev);
+    usb_wakeup(s->intr);
 
     /* Let upstream know the device on this port is gone */
     s->dev.port->ops->child_detach(s->dev.port, port1->dev);
@@ -199,7 +200,7 @@ static void usb_hub_wakeup(USBPort *port1)
 
     if (port->wPortStatus & PORT_STAT_SUSPEND) {
         port->wPortChange |= PORT_STAT_C_SUSPEND;
-        usb_wakeup(&s->dev);
+        usb_wakeup(s->intr);
     }
 }
 
@@ -220,6 +221,26 @@ static void usb_hub_complete(USBPort *port, USBPacket *packet)
     s->dev.port->ops->complete(s->dev.port, packet);
 }
 
+static USBDevice *usb_hub_find_device(USBDevice *dev, uint8_t addr)
+{
+    USBHubState *s = DO_UPCAST(USBHubState, dev, dev);
+    USBHubPort *port;
+    USBDevice *downstream;
+    int i;
+
+    for (i = 0; i < NUM_PORTS; i++) {
+        port = &s->ports[i];
+        if (!(port->wPortStatus & PORT_STAT_ENABLE)) {
+            continue;
+        }
+        downstream = usb_find_device(&port->port, addr);
+        if (downstream != NULL) {
+            return downstream;
+        }
+    }
+    return NULL;
+}
+
 static void usb_hub_handle_reset(USBDevice *dev)
 {
     USBHubState *s = DO_UPCAST(USBHubState, dev, dev);
@@ -305,7 +326,7 @@ static int usb_hub_handle_control(USBDevice *dev, USBPacket *p,
                 break;
             case PORT_RESET:
                 if (dev && dev->attached) {
-                    usb_send_msg(dev, USB_MSG_RESET);
+                    usb_device_reset(dev);
                     port->wPortChange |= PORT_STAT_C_RESET;
                     /* set enable bit */
                     port->wPortStatus |= PORT_STAT_ENABLE;
@@ -396,7 +417,7 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
 
     switch(p->pid) {
     case USB_TOKEN_IN:
-        if (p->devep == 1) {
+        if (p->ep->nr == 1) {
             USBHubPort *port;
             unsigned int status;
             uint8_t buf[4];
@@ -435,44 +456,6 @@ static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
     return ret;
 }
 
-static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p)
-{
-    USBHubPort *port;
-    USBDevice *dev;
-    int i, ret;
-
-    for(i = 0; i < NUM_PORTS; i++) {
-        port = &s->ports[i];
-        dev = port->port.dev;
-        if (dev && dev->attached && (port->wPortStatus & PORT_STAT_ENABLE)) {
-            ret = usb_handle_packet(dev, p);
-            if (ret != USB_RET_NODEV) {
-                return ret;
-            }
-        }
-    }
-    return USB_RET_NODEV;
-}
-
-static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p)
-{
-    USBHubState *s = (USBHubState *)dev;
-
-#if defined(DEBUG) && 0
-    printf("usb_hub: pid=0x%x\n", pid);
-#endif
-    if (dev->state == USB_STATE_DEFAULT &&
-        dev->addr != 0 &&
-        p->devaddr != dev->addr &&
-        (p->pid == USB_TOKEN_SETUP ||
-         p->pid == USB_TOKEN_OUT ||
-         p->pid == USB_TOKEN_IN)) {
-        /* broadcast the packet to the devices */
-        return usb_hub_broadcast_packet(s, p);
-    }
-    return usb_generic_handle_packet(dev, p);
-}
-
 static void usb_hub_handle_destroy(USBDevice *dev)
 {
     USBHubState *s = (USBHubState *)dev;
@@ -499,6 +482,7 @@ static int usb_hub_initfn(USBDevice *dev)
     int i;
 
     usb_desc_init(dev);
+    s->intr = usb_ep_get(dev, USB_TOKEN_IN, 1);
     for (i = 0; i < NUM_PORTS; i++) {
         port = &s->ports[i];
         usb_register_port(usb_bus_from_device(dev),
@@ -541,7 +525,7 @@ static void usb_hub_class_initfn(ObjectClass *klass, void *data)
     uc->init           = usb_hub_initfn;
     uc->product_desc   = "QEMU USB Hub";
     uc->usb_desc       = &desc_hub;
-    uc->handle_packet  = usb_hub_handle_packet;
+    uc->find_device    = usb_hub_find_device;
     uc->handle_reset   = usb_hub_handle_reset;
     uc->handle_control = usb_hub_handle_control;
     uc->handle_data    = usb_hub_handle_data;