Blame 0014-usb-ohci-Add-support-for-being-a-companion-controlle.patch

Hans de Goede 3f1f29
From 90ac519e89c71ac9f9731b21cef510b5cbaee38b Mon Sep 17 00:00:00 2001
Hans de Goede 3f1f29
From: Hans de Goede <hdegoede@redhat.com>
Hans de Goede 3f1f29
Date: Fri, 24 Jun 2011 20:29:05 +0200
Hans de Goede 3f1f29
Subject: [PATCH 14/35] usb-ohci: Add support for being a companion controller
Hans de Goede 3f1f29
Hans de Goede 3f1f29
To use as a companion controller, use pci-ohci as device and set the
Hans de Goede 3f1f29
masterbus and num-ports properties, ie:
Hans de Goede 3f1f29
Hans de Goede 3f1f29
-device usb-ehci,addr=0b.1,multifunction=on,id=ehci0
Hans de Goede 3f1f29
-device pci-ohci,addr=0b.0,multifunction=on,masterbus=ehci0.0,num-ports=4
Hans de Goede 3f1f29
Hans de Goede 3f1f29
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Hans de Goede 3f1f29
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede 3f1f29
---
Hans de Goede 3f1f29
 hw/usb-ohci.c |   52 ++++++++++++++++++++++++++++++++++++++++------------
Hans de Goede 3f1f29
 1 files changed, 40 insertions(+), 12 deletions(-)
Hans de Goede 3f1f29
Hans de Goede 3f1f29
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
Hans de Goede 3f1f29
index 46f0bcb..c77a20e 100644
Hans de Goede 3f1f29
--- a/hw/usb-ohci.c
Hans de Goede 3f1f29
+++ b/hw/usb-ohci.c
Hans de Goede 3f1f29
@@ -1716,8 +1716,9 @@ static USBPortOps ohci_port_ops = {
Hans de Goede 3f1f29
 static USBBusOps ohci_bus_ops = {
Hans de Goede 3f1f29
 };
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
-static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
Hans de Goede 3f1f29
-                          int num_ports, uint32_t localmem_base)
Hans de Goede 3f1f29
+static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
Hans de Goede 3f1f29
+                         int num_ports, uint32_t localmem_base,
Hans de Goede 3f1f29
+                         char *masterbus, uint32_t firstport)
Hans de Goede 3f1f29
 {
Hans de Goede 3f1f29
     int i;
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
@@ -1737,38 +1738,58 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
Hans de Goede 3f1f29
                 usb_frame_time, usb_bit_time);
Hans de Goede 3f1f29
     }
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
+    ohci->num_ports = num_ports;
Hans de Goede 3f1f29
+    if (masterbus) {
Hans de Goede 3f1f29
+        USBPort *ports[OHCI_MAX_PORTS];
Hans de Goede 3f1f29
+        for(i = 0; i < num_ports; i++) {
Hans de Goede 3f1f29
+            ports[i] = &ohci->rhport[i].port;
Hans de Goede 3f1f29
+        }
Hans de Goede 3f1f29
+        if (usb_register_companion(masterbus, ports, num_ports,
Hans de Goede 3f1f29
+                firstport, ohci, &ohci_port_ops,
Hans de Goede 3f1f29
+                USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL) != 0) {
Hans de Goede 3f1f29
+            return -1;
Hans de Goede 3f1f29
+        }
Hans de Goede 3f1f29
+    } else {
Hans de Goede 3f1f29
+        usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
Hans de Goede 3f1f29
+        for (i = 0; i < num_ports; i++) {
Hans de Goede 3f1f29
+            usb_register_port(&ohci->bus, &ohci->rhport[i].port,
Hans de Goede 3f1f29
+                              ohci, i, &ohci_port_ops,
Hans de Goede 3f1f29
+                              USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
Hans de Goede 3f1f29
+        }
Hans de Goede 3f1f29
+    }
Hans de Goede 3f1f29
+
Hans de Goede 3f1f29
     ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci,
Hans de Goede 3f1f29
                                        DEVICE_LITTLE_ENDIAN);
Hans de Goede 3f1f29
     ohci->localmem_base = localmem_base;
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
     ohci->name = dev->info->name;
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
-    usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
Hans de Goede 3f1f29
-    ohci->num_ports = num_ports;
Hans de Goede 3f1f29
-    for (i = 0; i < num_ports; i++) {
Hans de Goede 3f1f29
-        usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops,
Hans de Goede 3f1f29
-                          USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
Hans de Goede 3f1f29
-    }
Hans de Goede 3f1f29
-
Hans de Goede 3f1f29
     ohci->async_td = 0;
Hans de Goede 3f1f29
     qemu_register_reset(ohci_reset, ohci);
Hans de Goede 3f1f29
+
Hans de Goede 3f1f29
+    return 0;
Hans de Goede 3f1f29
 }
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
 typedef struct {
Hans de Goede 3f1f29
     PCIDevice pci_dev;
Hans de Goede 3f1f29
     OHCIState state;
Hans de Goede 3f1f29
+    char *masterbus;
Hans de Goede 3f1f29
+    uint32_t num_ports;
Hans de Goede 3f1f29
+    uint32_t firstport;
Hans de Goede 3f1f29
 } OHCIPCIState;
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
 static int usb_ohci_initfn_pci(struct PCIDevice *dev)
Hans de Goede 3f1f29
 {
Hans de Goede 3f1f29
     OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
Hans de Goede 3f1f29
-    int num_ports = 3;
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
     ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
Hans de Goede 3f1f29
     /* TODO: RST# value should be 0. */
Hans de Goede 3f1f29
     ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
-    usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0);
Hans de Goede 3f1f29
+    if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0,
Hans de Goede 3f1f29
+                      ohci->masterbus, ohci->firstport) != 0) {
Hans de Goede 3f1f29
+        return -1;
Hans de Goede 3f1f29
+    }
Hans de Goede 3f1f29
     ohci->state.irq = ohci->pci_dev.irq[0];
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
     /* TODO: avoid cast below by using dev */
Hans de Goede 3f1f29
@@ -1792,7 +1813,8 @@ static int ohci_init_pxa(SysBusDevice *dev)
Hans de Goede 3f1f29
 {
Hans de Goede 3f1f29
     OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev);
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
-    usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset);
Hans de Goede 3f1f29
+    /* Cannot fail as we pass NULL for masterbus */
Hans de Goede 3f1f29
+    usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0);
Hans de Goede 3f1f29
     sysbus_init_irq(dev, &s->ohci.irq);
Hans de Goede 3f1f29
     sysbus_init_mmio(dev, 0x1000, s->ohci.mem);
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
@@ -1807,6 +1829,12 @@ static PCIDeviceInfo ohci_pci_info = {
Hans de Goede 3f1f29
     .vendor_id    = PCI_VENDOR_ID_APPLE,
Hans de Goede 3f1f29
     .device_id    = PCI_DEVICE_ID_APPLE_IPID_USB,
Hans de Goede 3f1f29
     .class_id     = PCI_CLASS_SERIAL_USB,
Hans de Goede 3f1f29
+    .qdev.props   = (Property[]) {
Hans de Goede 3f1f29
+        DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus),
Hans de Goede 3f1f29
+        DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3),
Hans de Goede 3f1f29
+        DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0),
Hans de Goede 3f1f29
+        DEFINE_PROP_END_OF_LIST(),
Hans de Goede 3f1f29
+    },
Hans de Goede 3f1f29
 };
Hans de Goede 3f1f29
 
Hans de Goede 3f1f29
 static SysBusDeviceInfo ohci_sysbus_info = {
Hans de Goede 3f1f29
-- 
Hans de Goede 3f1f29
1.7.5.1
Hans de Goede 3f1f29