From patchwork Fri Jun 24 19:32:58 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 101891 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 92B22B6F7E for ; Sat, 25 Jun 2011 06:21:40 +1000 (EST) Received: from localhost ([::1]:60934 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QaCsi-0005ci-D9 for incoming@patchwork.ozlabs.org; Fri, 24 Jun 2011 16:21:36 -0400 Received: from eggs.gnu.org ([140.186.70.92]:43008) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QaC78-0001F4-Q3 for qemu-devel@nongnu.org; Fri, 24 Jun 2011 15:32:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QaC75-0002RL-Qp for qemu-devel@nongnu.org; Fri, 24 Jun 2011 15:32:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:6726) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QaC75-0002Qu-2E for qemu-devel@nongnu.org; Fri, 24 Jun 2011 15:32:23 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5OJWMiW016864 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 24 Jun 2011 15:32:22 -0400 Received: from shalem.localdomain.com (vpn1-4-129.ams2.redhat.com [10.36.4.129]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p5OJW4ue031987; Fri, 24 Jun 2011 15:32:21 -0400 From: Hans de Goede To: Gerd Hoffmann Date: Fri, 24 Jun 2011 21:32:58 +0200 Message-Id: <1308943978-6152-12-git-send-email-hdegoede@redhat.com> In-Reply-To: <1308943978-6152-1-git-send-email-hdegoede@redhat.com> References: <1308943978-6152-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Hans de Goede , qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 11/11] usb-ohci: Add support for being a companion controller X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org To use as a companion controller, use pci-ohci as device and set the masterbus and num-ports properties, ie: -device usb-ehci,addr=0b.1,multifunction=on,id=ehci0 -device pci-ohci,addr=0b.0,multifunction=on,masterbus=ehci0.0,num-ports=4 Signed-off-by: Hans de Goede --- hw/usb-ohci.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 46 insertions(+), 13 deletions(-) diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index a113c0f..4d6ef10 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -1716,8 +1716,9 @@ static USBPortOps ohci_port_ops = { static USBBusOps ohci_bus_ops = { }; -static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, - int num_ports, uint32_t localmem_base) +static int usb_ohci_init(OHCIState *ohci, DeviceState *dev, + int num_ports, uint32_t localmem_base, + char *masterbus, uint32_t firstport) { int i; @@ -1737,39 +1738,64 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, usb_frame_time, usb_bit_time); } + ohci->num_ports = num_ports; + if (masterbus) { + USBPort *ports[OHCI_MAX_PORTS]; + for(i = 0; i < num_ports; i++) { + ohci->rhport[i].port.ops = &ohci_port_ops; + ohci->rhport[i].port.opaque = ohci; + ohci->rhport[i].port.index = i; + ohci->rhport[i].port.speedmask = + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL; + usb_port_location(&ohci->rhport[i].port, NULL, i+1); + ports[i] = &ohci->rhport[i].port; + } + if (usb_bus_register_companion(masterbus, ports, num_ports, + firstport) != 0) { + return -1; + } + } else { + usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); + for (i = 0; i < num_ports; i++) { + usb_register_port(&ohci->bus, &ohci->rhport[i].port, + ohci, i, &ohci_port_ops, + USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); + usb_port_location(&ohci->rhport[i].port, NULL, i+1); + } + } + ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci, DEVICE_LITTLE_ENDIAN); ohci->localmem_base = localmem_base; ohci->name = dev->info->name; - usb_bus_new(&ohci->bus, &ohci_bus_ops, dev); - ohci->num_ports = num_ports; - for (i = 0; i < num_ports; i++) { - usb_register_port(&ohci->bus, &ohci->rhport[i].port, ohci, i, &ohci_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - usb_port_location(&ohci->rhport[i].port, NULL, i+1); - } - ohci->async_td = 0; qemu_register_reset(ohci_reset, ohci); + + return 0; } typedef struct { PCIDevice pci_dev; OHCIState state; + char *masterbus; + uint32_t num_ports; + uint32_t firstport; } OHCIPCIState; static int usb_ohci_initfn_pci(struct PCIDevice *dev) { OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev); - int num_ports = 3; ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */ /* TODO: RST# value should be 0. */ ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */ - usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0); + if (usb_ohci_init(&ohci->state, &dev->qdev, ohci->num_ports, 0, + ohci->masterbus, ohci->firstport) != 0) { + return -1; + } ohci->state.irq = ohci->pci_dev.irq[0]; /* TODO: avoid cast below by using dev */ @@ -1793,7 +1819,8 @@ static int ohci_init_pxa(SysBusDevice *dev) { OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev); - usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset); + /* Cannot fail as we pass NULL for masterbus */ + usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset, NULL, 0); sysbus_init_irq(dev, &s->ohci.irq); sysbus_init_mmio(dev, 0x1000, s->ohci.mem); @@ -1808,6 +1835,12 @@ static PCIDeviceInfo ohci_pci_info = { .vendor_id = PCI_VENDOR_ID_APPLE, .device_id = PCI_DEVICE_ID_APPLE_IPID_USB, .class_id = PCI_CLASS_SERIAL_USB, + .qdev.props = (Property[]) { + DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus), + DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3), + DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0), + DEFINE_PROP_END_OF_LIST(), + }, }; static SysBusDeviceInfo ohci_sysbus_info = {