From patchwork Wed Sep 30 10:18:16 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 34594 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B772AB7B74 for ; Wed, 30 Sep 2009 23:38:53 +1000 (EST) Received: from localhost ([127.0.0.1]:55233 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MszOM-0006hm-JH for incoming@patchwork.ozlabs.org; Wed, 30 Sep 2009 09:38:50 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MswIu-0004v3-3o for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:21:00 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MswIU-0004bD-D0 for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:52 -0400 Received: from [199.232.76.173] (port=43904 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MswIN-0004ZW-UR for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:28 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:55868) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MswIM-0005ph-W8 for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:27 -0400 Received: from nm.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with ESMTP id B279649C2F; Wed, 30 Sep 2009 19:20:17 +0900 (JST) Received: from yamahata by nm.local.valinux.co.jp with local (Exim 4.69) (envelope-from ) id 1MswGd-0003sg-3y; Wed, 30 Sep 2009 19:18:39 +0900 From: Isaku Yamahata To: qemu-devel@nongnu.org, anthony@codemonkey.ws Date: Wed, 30 Sep 2009 19:18:16 +0900 Message-Id: <1254305917-14784-41-git-send-email-yamahata@valinux.co.jp> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> References: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: yamahata@valinux.co.jp Subject: [Qemu-devel] [PATCH 40/61] pci: use qdev to get parent bus with PCIBus. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Now qdev tracks the relationship between bus and device, so a member, bus, in PCIDevice/PCIBridge and parent_dev in PCIBus are redundant. This patch removes them and introduces some helper functions which will be used later. For non-qdevfied device, keep the bus member in PCIDevice. It will be removed once all of PCIDevices are converted. Signed-off-by: Isaku Yamahata --- hw/pci-hotplug.c | 7 ++--- hw/pci.c | 69 +++++++++++++++++++++++++++++++++++++++++++----------- hw/pci.h | 8 +++++- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index f3dc421..1aa1241 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -181,11 +181,10 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict) monitor_printf(mon, "invalid type: %s\n", type); if (dev) { - qemu_system_device_hot_add(pci_bus_num(dev->bus), - PCI_SLOT(dev->devfn), 1); + int bus_num = pci_bus_num(pci_get_parent_bus(dev)); + qemu_system_device_hot_add(bus_num, PCI_SLOT(dev->devfn), 1); monitor_printf(mon, "OK domain %d, bus %d, slot %d, function %d\n", - 0, pci_bus_num(dev->bus), PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); + 0, bus_num, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); } else monitor_printf(mon, "failed to add %s\n", opts); } diff --git a/hw/pci.c b/hw/pci.c index a8694f8..ec6c7d4 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -44,7 +44,6 @@ struct PCIBus { uint32_t config_reg; /* XXX: suppress */ void *irq_opaque; PCIDevice *devices[256]; - PCIDevice *parent_dev; QLIST_ENTRY(PCIBus) next; /* The bus IRQ state is the logical OR of the connected devices. Keep a count of the number of devices with raised IRQs. */ @@ -84,6 +83,37 @@ static const VMStateDescription vmstate_pcibus = { } }; +static PCIBus *qbus_to_pcibus(struct BusState *qbus) +{ + return DO_UPCAST(PCIBus, qbus, qbus); +} + +PCIDevice *qdev_to_pcidev(struct DeviceState *qdev) +{ + return DO_UPCAST(PCIDevice, qdev, qdev); +} + +PCIBus *pci_get_parent_bus(PCIDevice *dev) +{ + if (dev->qdev.info == NULL) { + /* for non-qdevfied device */ + assert(dev->bus != NULL); + return dev->bus; + } + + return qbus_to_pcibus(dev->qdev.parent_bus); +} + +BusState *pci_bus_to_qbus(PCIBus *bus) +{ + return &bus->qbus; +} + +PCIDevice *pci_bus_to_dev(PCIBus *bus) +{ + return qdev_to_pcidev(bus->qbus.parent); +} + static void pci_bus_reset(void *opaque) { PCIBus *bus = opaque; @@ -127,7 +157,6 @@ static PCIBus *pci_register_secondary_bus(PCIDevice *dev, bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name)); bus->map_irq = map_irq; - bus->parent_dev = dev; QLIST_INSERT_AFTER(dev->bus, bus, next); return bus; } @@ -379,7 +408,6 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, } else if (bus->devices[devfn]) { return NULL; } - pci_dev->bus = bus; pci_dev->devfn = devfn; pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); memset(pci_dev->irq_state, 0, sizeof(pci_dev->irq_state)); @@ -410,6 +438,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name, pci_dev = qemu_mallocz(instance_size); pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, config_read, config_write); + /* XXX for non-qdevfied device */ + pci_dev->bus = bus; return pci_dev; } static target_phys_addr_t pci_to_cpu_addr(target_phys_addr_t addr) @@ -448,7 +478,7 @@ int pci_unregister_device(PCIDevice *pci_dev) pci_unregister_io_regions(pci_dev); qemu_free_irqs(pci_dev->irq); - pci_dev->bus->devices[pci_dev->devfn] = NULL; + pci_get_parent_bus(pci_dev)->devices[pci_dev->devfn] = NULL; qdev_free(&pci_dev->qdev); return 0; } @@ -891,11 +921,11 @@ static void pci_set_irq(void *opaque, int irq_num, int level) pci_dev->irq_state[irq_num] = level; for (;;) { - bus = pci_dev->bus; + bus = pci_get_parent_bus(pci_dev); irq_num = bus->map_irq(pci_dev, irq_num); if (bus->set_irq) break; - pci_dev = bus->parent_dev; + pci_dev = pci_bus_to_dev(bus); } bus->irq_count[irq_num] += change; bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0); @@ -963,7 +993,8 @@ static void pci_info_device(PCIDevice *d) const pci_class_desc *desc; monitor_printf(mon, " Bus %2d, device %3d, function %d:\n", - d->bus->bus_num, PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); + pci_get_parent_bus(d)->bus_num, + PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); class = le16_to_cpu(*((uint16_t *)(d->config + PCI_CLASS_DEVICE))); monitor_printf(mon, " "); desc = pci_class_descriptions; @@ -1118,16 +1149,27 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, typedef struct { PCIDevice dev; - PCIBus *bus; } PCIBridge; +static PCIBridge *pci_dev_to_br(PCIDevice *d) +{ + return DO_UPCAST(PCIBridge, dev, d); +} + +static PCIBus *pci_bridge_get_secbus(PCIBridge *bridge) +{ + /* assuming only one bus is registered */ + return qbus_to_pcibus(QLIST_FIRST(&bridge->dev.qdev.child_bus)); +} + static void pci_bridge_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { - PCIBridge *s = (PCIBridge *)d; + PCIBridge *bridge = pci_dev_to_br(d); + PCIBus *bus = pci_bridge_get_secbus(bridge); pci_default_write_config(d, address, val, len); - s->bus->bus_num = d->config[PCI_SECONDARY_BUS]; + bus->bus_num = d->config[PCI_SECONDARY_BUS]; } PCIBus *pci_find_bus(int bus_num) @@ -1167,8 +1209,7 @@ PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid, uint16_t did, PCI_HEADER_TYPE_MULTI_FUNCTION | PCI_HEADER_TYPE_BRIDGE; // header_type s->dev.config[0x1E] = 0xa0; // secondary status - s->bus = pci_register_secondary_bus(&s->dev, map_irq, name); - return s->bus; + return pci_register_secondary_bus(&s->dev, map_irq, name); } static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base) @@ -1315,8 +1356,8 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent) monitor_printf(mon, "%*sclass %s, addr %02x:%02x.%x, " "pci id %04x:%04x (sub %04x:%04x)\n", - indent, "", ctxt, - d->bus->bus_num, PCI_SLOT(d->devfn), PCI_FUNC(d->devfn), + indent, "", ctxt, pci_get_parent_bus(d)->bus_num, + PCI_SLOT(d->devfn), PCI_FUNC(d->devfn), le16_to_cpu(*((uint16_t *)(d->config + PCI_VENDOR_ID))), le16_to_cpu(*((uint16_t *)(d->config + PCI_DEVICE_ID))), le16_to_cpu(*((uint16_t *)(d->config + PCI_SUBSYSTEM_VENDOR_ID))), diff --git a/hw/pci.h b/hw/pci.h index 3327905..0aedbf5 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -204,7 +204,9 @@ struct PCIDevice { uint8_t *used; /* the following fields are read only */ - PCIBus *bus; + PCIBus *bus; /* non qdevfied device only + * Once all the device is qdevified, this will be removed. + */ uint32_t devfn; char name[64]; PCIIORegion io_regions[PCI_NUM_REGIONS]; @@ -291,6 +293,10 @@ int pci_bus_num(PCIBus *s); void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d)); PCIBus *pci_find_bus(int bus_num); PCIDevice *pci_find_device(int bus_num, int slot, int function); +PCIBus *pci_get_parent_bus(PCIDevice *dev); +PCIDevice *qdev_to_pcidev(struct DeviceState *qdev); +BusState *pci_bus_to_qbus(PCIBus *bus); +PCIDevice *pci_bus_to_dev(PCIBus *bus); int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp, unsigned *slotp);