//#define DEBUG_PCI
struct PCIBus {
+ BusState qbus;
int bus_num;
int devfn_min;
pci_set_irq_fn set_irq;
target_phys_addr_t pci_mem_base;
static uint16_t pci_default_sub_vendor_id = PCI_SUBVENDOR_ID_REDHAT_QUMRANET;
static uint16_t pci_default_sub_device_id = PCI_SUBDEVICE_ID_QEMU;
-static int pci_irq_index;
static PCIBus *first_bus;
static void pcibus_save(QEMUFile *f, void *opaque)
return 0;
}
-PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+PCIBus *pci_register_bus(DeviceState *parent, const char *name,
+ pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
qemu_irq *pic, int devfn_min, int nirq)
{
PCIBus *bus;
static int nbus = 0;
- bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
+ bus = FROM_QBUS(PCIBus, qbus_create(BUS_TYPE_PCI,
+ sizeof(PCIBus) + (nirq * sizeof(int)),
+ parent, name));
bus->set_irq = set_irq;
bus->map_irq = map_irq;
bus->irq_opaque = pic;
PCIConfigReadFunc *config_read,
PCIConfigWriteFunc *config_write)
{
- if (pci_irq_index >= PCI_DEVICES_MAX)
- return NULL;
-
if (devfn < 0) {
for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
if (!bus->devices[devfn])
config_write = pci_default_write_config;
pci_dev->config_read = config_read;
pci_dev->config_write = config_write;
- pci_dev->irq_index = pci_irq_index++;
bus->devices[devfn] = pci_dev;
pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
return pci_dev;
pci_unregister_io_regions(pci_dev);
qemu_free_irqs(pci_dev->irq);
- pci_irq_index--;
pci_dev->bus->devices[pci_dev->devfn] = NULL;
- qemu_free(pci_dev);
+ qdev_free(&pci_dev->qdev);
return 0;
}
"rtl8139",
"e1000",
"pcnet",
- "virtio_net",
+ "virtio-net-pci",
NULL
};
for (i = 0; pci_nic_models[i]; i++) {
if (strcmp(nd->model, pci_nic_models[i]) == 0) {
- dev = qdev_create(bus, pci_nic_names[i]);
+ dev = qdev_create(&bus->qbus, pci_nic_names[i]);
qdev_set_prop_int(dev, "devfn", devfn);
qdev_set_netdev(dev, nd);
qdev_init(dev);
return s->bus;
}
-static void pci_qdev_init(DeviceState *qdev, void *opaque)
+typedef struct {
+ DeviceInfo qdev;
+ pci_qdev_initfn init;
+} PCIDeviceInfo;
+
+static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
{
PCIDevice *pci_dev = (PCIDevice *)qdev;
- pci_qdev_initfn init;
+ PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
PCIBus *bus;
int devfn;
- init = opaque;
- bus = qdev_get_bus(qdev);
+ bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
devfn = qdev_get_prop_int(qdev, "devfn", -1);
pci_dev = do_pci_register_device(pci_dev, bus, "FIXME", devfn,
NULL, NULL);//FIXME:config_read, config_write);
assert(pci_dev);
- init(pci_dev);
+ info->init(pci_dev);
}
void pci_qdev_register(const char *name, int size, pci_qdev_initfn init)
{
- qdev_register(name, size, pci_qdev_init, init);
+ PCIDeviceInfo *info;
+
+ info = qemu_mallocz(sizeof(*info));
+ info->qdev.name = qemu_strdup(name);
+ info->qdev.size = size;
+ info->init = init;
+ info->qdev.init = pci_qdev_init;
+ info->qdev.bus_type = BUS_TYPE_PCI;
+
+ qdev_register(&info->qdev);
}
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name)
{
DeviceState *dev;
- dev = qdev_create(bus, name);
+ dev = qdev_create(&bus->qbus, name);
qdev_set_prop_int(dev, "devfn", devfn);
qdev_init(dev);