[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 40/61] pci: use qdev to get parent bus with PCIBus.
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH 40/61] pci: use qdev to get parent bus with PCIBus. |
Date: |
Wed, 30 Sep 2009 19:18:16 +0900 |
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 <address@hidden>
---
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);
--
1.6.0.2
- [Qemu-devel] [PATCH 58/61] ioapic: make the number of pins configurable., (continued)
- [Qemu-devel] [PATCH 58/61] ioapic: make the number of pins configurable., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 47/61] pci.h: add more status constats., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 57/61] ioapic: add callback when entry is set or ioapic is reset, Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 24/61] pci: define a constant to represent a unmapped bar and use it., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 18/61] pc: split out piix specific part from pc.c into pc_piix.c, Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 42/61] pci/brdige: qdevfy and initialize secondary bus and subordinate bus., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 35/61] piix_pci: use pci_swizzle_map_irq_fn()., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 34/61] pci: introduce pci_swizzle_map_irq_fn() for interrupt pin swizzle., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 60/61] pci: add opaque arg to pci_map_irq_fn., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 46/61] pci/bridge: implement intel 82801ba bridge., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 40/61] pci: use qdev to get parent bus with PCIBus.,
Isaku Yamahata <=
- [Qemu-devel] [PATCH 45/61] pci/monitor: print out bridge's filtering values and so on., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 29/61] pci: factor out the logic to get pci device from address., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 08/61] pc: make an unnecessary global variable, pit, local., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 52/61] pci: add a hook to replace default pci bus instead of 0 bus., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 33/61] pci: use the symbolic constant, PCI_ROM_ADDRESS_ENABLE instead of 1., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 48/61] pci id: add subclass codes for serial device., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 13/61] pc: split out cpu initialization from pc_init1() into pc_cpus_init()., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 10/61] pc: remove a global variable, RTCState *rtc_state., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 25/61] pci: use uint64_t for bar addr and size instead of uint32_t., Isaku Yamahata, 2009/09/30