Revision 02e2da45
b/hw/acpi.c | ||
---|---|---|
548 | 548 |
|
549 | 549 |
register_savevm("piix4_pm", 0, 1, pm_save, pm_load, s); |
550 | 550 |
|
551 |
s->smbus = i2c_init_bus(); |
|
551 |
s->smbus = i2c_init_bus(NULL, "i2c");
|
|
552 | 552 |
s->irq = sci_irq; |
553 | 553 |
qemu_register_reset(piix4_reset, 0, s); |
554 | 554 |
|
b/hw/apb_pci.c | ||
---|---|---|
231 | 231 |
|
232 | 232 |
s = qemu_mallocz(sizeof(APBState)); |
233 | 233 |
/* Ultrasparc PBM main bus */ |
234 |
s->bus = pci_register_bus(pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32); |
|
234 |
s->bus = pci_register_bus(NULL, "pci", |
|
235 |
pci_apb_set_irq, pci_pbm_map_irq, pic, 0, 32); |
|
235 | 236 |
|
236 | 237 |
pci_mem_config = cpu_register_io_memory(0, pci_apb_config_read, |
237 | 238 |
pci_apb_config_write, s); |
b/hw/grackle_pci.c | ||
---|---|---|
133 | 133 |
int pci_mem_config, pci_mem_data; |
134 | 134 |
|
135 | 135 |
s = qemu_mallocz(sizeof(GrackleState)); |
136 |
s->bus = pci_register_bus(pci_grackle_set_irq, pci_grackle_map_irq, |
|
136 |
s->bus = pci_register_bus(NULL, "pci", |
|
137 |
pci_grackle_set_irq, pci_grackle_map_irq, |
|
137 | 138 |
pic, 0, 4); |
138 | 139 |
|
139 | 140 |
pci_mem_config = cpu_register_io_memory(0, pci_grackle_config_read, |
b/hw/gt64xxx.c | ||
---|---|---|
1128 | 1128 |
s = qemu_mallocz(sizeof(GT64120State)); |
1129 | 1129 |
s->pci = qemu_mallocz(sizeof(GT64120PCIState)); |
1130 | 1130 |
|
1131 |
s->pci->bus = pci_register_bus(pci_gt64120_set_irq, pci_gt64120_map_irq, |
|
1131 |
s->pci->bus = pci_register_bus(NULL, "pci", |
|
1132 |
pci_gt64120_set_irq, pci_gt64120_map_irq, |
|
1132 | 1133 |
pic, 144, 4); |
1133 | 1134 |
s->ISD_handle = cpu_register_io_memory(0, gt64120_read, gt64120_write, s); |
1134 | 1135 |
d = pci_register_device(s->pci->bus, "GT64120 PCI Bus", sizeof(PCIDevice), |
b/hw/i2c.c | ||
---|---|---|
11 | 11 |
|
12 | 12 |
struct i2c_bus |
13 | 13 |
{ |
14 |
BusState qbus; |
|
14 | 15 |
i2c_slave *current_dev; |
15 | 16 |
i2c_slave *dev; |
16 | 17 |
int saved_address; |
... | ... | |
39 | 40 |
} |
40 | 41 |
|
41 | 42 |
/* Create a new I2C bus. */ |
42 |
i2c_bus *i2c_init_bus(void)
|
|
43 |
i2c_bus *i2c_init_bus(DeviceState *parent, const char *name)
|
|
43 | 44 |
{ |
44 | 45 |
i2c_bus *bus; |
45 | 46 |
|
46 |
bus = (i2c_bus *)qemu_mallocz(sizeof(i2c_bus)); |
|
47 |
bus = FROM_QBUS(i2c_bus, qbus_create(BUS_TYPE_I2C, sizeof(i2c_bus), |
|
48 |
parent, name)); |
|
47 | 49 |
register_savevm("i2c_bus", -1, 1, i2c_bus_save, i2c_bus_load, bus); |
48 | 50 |
return bus; |
49 | 51 |
} |
... | ... | |
63 | 65 |
/* TODO: Make this handle multiple masters. */ |
64 | 66 |
int i2c_start_transfer(i2c_bus *bus, int address, int recv) |
65 | 67 |
{ |
66 |
i2c_slave *dev; |
|
68 |
DeviceState *qdev; |
|
69 |
i2c_slave *slave = NULL; |
|
67 | 70 |
|
68 |
for (dev = bus->dev; dev; dev = dev->next) { |
|
69 |
if (dev->address == address) |
|
71 |
LIST_FOREACH(qdev, &bus->qbus.children, sibling) { |
|
72 |
slave = I2C_SLAVE_FROM_QDEV(qdev); |
|
73 |
if (slave->address == address) |
|
70 | 74 |
break; |
71 | 75 |
} |
72 | 76 |
|
73 |
if (!dev)
|
|
77 |
if (!slave)
|
|
74 | 78 |
return 1; |
75 | 79 |
|
76 | 80 |
/* If the bus is already busy, assume this is a repeated |
77 | 81 |
start condition. */ |
78 |
bus->current_dev = dev;
|
|
79 |
dev->info->event(dev, recv ? I2C_START_RECV : I2C_START_SEND);
|
|
82 |
bus->current_dev = slave;
|
|
83 |
slave->info->event(slave, recv ? I2C_START_RECV : I2C_START_SEND);
|
|
80 | 84 |
return 0; |
81 | 85 |
} |
82 | 86 |
|
... | ... | |
130 | 134 |
void i2c_slave_load(QEMUFile *f, i2c_slave *dev) |
131 | 135 |
{ |
132 | 136 |
i2c_bus *bus; |
133 |
bus = qdev_get_bus(&dev->qdev);
|
|
137 |
bus = FROM_QBUS(i2c_bus, qdev_get_parent_bus(&dev->qdev));
|
|
134 | 138 |
dev->address = qemu_get_byte(f); |
135 | 139 |
if (bus->saved_address == dev->address) { |
136 | 140 |
bus->current_dev = dev; |
137 | 141 |
} |
138 | 142 |
} |
139 | 143 |
|
140 |
static void i2c_slave_qdev_init(DeviceState *dev, void *opaque)
|
|
144 |
static void i2c_slave_qdev_init(DeviceState *dev, DeviceInfo *base)
|
|
141 | 145 |
{ |
142 |
I2CSlaveInfo *info = opaque;
|
|
146 |
I2CSlaveInfo *info = container_of(base, I2CSlaveInfo, qdev);
|
|
143 | 147 |
i2c_slave *s = I2C_SLAVE_FROM_QDEV(dev); |
144 | 148 |
|
145 | 149 |
s->info = info; |
146 |
s->bus = qdev_get_bus(dev); |
|
147 | 150 |
s->address = qdev_get_prop_int(dev, "address", 0); |
148 |
s->next = s->bus->dev; |
|
149 |
s->bus->dev = s; |
|
150 | 151 |
|
151 | 152 |
info->init(s); |
152 | 153 |
} |
... | ... | |
154 | 155 |
void i2c_register_slave(const char *name, int size, I2CSlaveInfo *info) |
155 | 156 |
{ |
156 | 157 |
assert(size >= sizeof(i2c_slave)); |
157 |
qdev_register(name, size, i2c_slave_qdev_init, info); |
|
158 |
info->qdev.init = i2c_slave_qdev_init; |
|
159 |
info->qdev.bus_type = BUS_TYPE_I2C; |
|
160 |
qdev_register(name, size, &info->qdev); |
|
158 | 161 |
} |
159 | 162 |
|
160 | 163 |
DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, int addr) |
161 | 164 |
{ |
162 | 165 |
DeviceState *dev; |
163 | 166 |
|
164 |
dev = qdev_create(bus, name); |
|
167 |
dev = qdev_create(&bus->qbus, name);
|
|
165 | 168 |
qdev_set_prop_int(dev, "address", addr); |
166 | 169 |
qdev_init(dev); |
167 | 170 |
return dev; |
b/hw/i2c.h | ||
---|---|---|
25 | 25 |
typedef void (*i2c_slave_initfn)(i2c_slave *dev); |
26 | 26 |
|
27 | 27 |
typedef struct { |
28 |
DeviceInfo qdev; |
|
29 |
|
|
28 | 30 |
/* Callbacks provided by the device. */ |
29 | 31 |
i2c_slave_initfn init; |
30 | 32 |
i2c_event_cb event; |
... | ... | |
39 | 41 |
|
40 | 42 |
/* Remaining fields for internal use by the I2C code. */ |
41 | 43 |
int address; |
42 |
void *next; |
|
43 |
i2c_bus *bus; |
|
44 | 44 |
}; |
45 | 45 |
|
46 |
i2c_bus *i2c_init_bus(void);
|
|
46 |
i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
|
|
47 | 47 |
void i2c_set_slave_address(i2c_slave *dev, int address); |
48 | 48 |
int i2c_bus_busy(i2c_bus *bus); |
49 | 49 |
int i2c_start_transfer(i2c_bus *bus, int address, int recv); |
b/hw/mips_malta.c | ||
---|---|---|
907 | 907 |
for (i = 0; i < 8; i++) { |
908 | 908 |
/* TODO: Populate SPD eeprom data. */ |
909 | 909 |
DeviceState *eeprom; |
910 |
eeprom = qdev_create(smbus, "smbus-eeprom"); |
|
910 |
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
|
|
911 | 911 |
qdev_set_prop_int(eeprom, "address", 0x50 + i); |
912 | 912 |
qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256)); |
913 | 913 |
qdev_init(eeprom); |
b/hw/musicpal.c | ||
---|---|---|
431 | 431 |
s->irq = irq; |
432 | 432 |
|
433 | 433 |
i2c = qemu_mallocz(sizeof(i2c_interface)); |
434 |
i2c->bus = i2c_init_bus(); |
|
434 |
i2c->bus = i2c_init_bus(NULL, "i2c");
|
|
435 | 435 |
i2c->current_addr = -1; |
436 | 436 |
|
437 | 437 |
s->wm = i2c_create_slave(i2c->bus, "wm8750", MP_WM_ADDR); |
b/hw/omap_i2c.c | ||
---|---|---|
433 | 433 |
s->irq = irq; |
434 | 434 |
s->drq[0] = dma[0]; |
435 | 435 |
s->drq[1] = dma[1]; |
436 |
s->bus = i2c_init_bus(); |
|
436 |
s->bus = i2c_init_bus(NULL, "i2c");
|
|
437 | 437 |
omap_i2c_reset(s); |
438 | 438 |
|
439 | 439 |
iomemtype = cpu_register_io_memory(0, omap_i2c_readfn, |
... | ... | |
454 | 454 |
s->irq = irq; |
455 | 455 |
s->drq[0] = dma[0]; |
456 | 456 |
s->drq[1] = dma[1]; |
457 |
s->bus = i2c_init_bus(); |
|
457 |
s->bus = i2c_init_bus(NULL, "i2c");
|
|
458 | 458 |
omap_i2c_reset(s); |
459 | 459 |
|
460 | 460 |
iomemtype = l4_register_io_memory(0, omap_i2c_readfn, |
b/hw/pc.c | ||
---|---|---|
1105 | 1105 |
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]); |
1106 | 1106 |
for (i = 0; i < 8; i++) { |
1107 | 1107 |
DeviceState *eeprom; |
1108 |
eeprom = qdev_create(smbus, "smbus-eeprom"); |
|
1108 |
eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
|
|
1109 | 1109 |
qdev_set_prop_int(eeprom, "address", 0x50 + i); |
1110 | 1110 |
qdev_set_prop_ptr(eeprom, "data", eeprom_buf + (i * 256)); |
1111 | 1111 |
qdev_init(eeprom); |
b/hw/pci.c | ||
---|---|---|
30 | 30 |
//#define DEBUG_PCI |
31 | 31 |
|
32 | 32 |
struct PCIBus { |
33 |
BusState qbus; |
|
33 | 34 |
int bus_num; |
34 | 35 |
int devfn_min; |
35 | 36 |
pci_set_irq_fn set_irq; |
... | ... | |
87 | 88 |
return 0; |
88 | 89 |
} |
89 | 90 |
|
90 |
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
|
91 |
PCIBus *pci_register_bus(DeviceState *parent, const char *name, |
|
92 |
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
|
91 | 93 |
qemu_irq *pic, int devfn_min, int nirq) |
92 | 94 |
{ |
93 | 95 |
PCIBus *bus; |
94 | 96 |
static int nbus = 0; |
95 | 97 |
|
96 |
bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int))); |
|
98 |
bus = FROM_QBUS(PCIBus, qbus_create(BUS_TYPE_PCI, |
|
99 |
sizeof(PCIBus) + (nirq * sizeof(int)), |
|
100 |
parent, name)); |
|
97 | 101 |
bus->set_irq = set_irq; |
98 | 102 |
bus->map_irq = map_irq; |
99 | 103 |
bus->irq_opaque = pic; |
... | ... | |
320 | 324 |
qemu_free_irqs(pci_dev->irq); |
321 | 325 |
pci_irq_index--; |
322 | 326 |
pci_dev->bus->devices[pci_dev->devfn] = NULL; |
323 |
qemu_free(pci_dev);
|
|
327 |
qdev_free(&pci_dev->qdev);
|
|
324 | 328 |
return 0; |
325 | 329 |
} |
326 | 330 |
|
... | ... | |
821 | 825 |
|
822 | 826 |
for (i = 0; pci_nic_models[i]; i++) { |
823 | 827 |
if (strcmp(nd->model, pci_nic_models[i]) == 0) { |
824 |
dev = qdev_create(bus, pci_nic_names[i]); |
|
828 |
dev = qdev_create(&bus->qbus, pci_nic_names[i]);
|
|
825 | 829 |
qdev_set_prop_int(dev, "devfn", devfn); |
826 | 830 |
qdev_set_netdev(dev, nd); |
827 | 831 |
qdev_init(dev); |
... | ... | |
901 | 905 |
return s->bus; |
902 | 906 |
} |
903 | 907 |
|
904 |
static void pci_qdev_init(DeviceState *qdev, void *opaque) |
|
908 |
typedef struct { |
|
909 |
DeviceInfo qdev; |
|
910 |
pci_qdev_initfn init; |
|
911 |
} PCIDeviceInfo; |
|
912 |
|
|
913 |
static void pci_qdev_init(DeviceState *qdev, DeviceInfo *base) |
|
905 | 914 |
{ |
906 | 915 |
PCIDevice *pci_dev = (PCIDevice *)qdev; |
907 |
pci_qdev_initfn init;
|
|
916 |
PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
|
|
908 | 917 |
PCIBus *bus; |
909 | 918 |
int devfn; |
910 | 919 |
|
911 |
init = opaque; |
|
912 |
bus = qdev_get_bus(qdev); |
|
920 |
bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev)); |
|
913 | 921 |
devfn = qdev_get_prop_int(qdev, "devfn", -1); |
914 | 922 |
pci_dev = do_pci_register_device(pci_dev, bus, "FIXME", devfn, |
915 | 923 |
NULL, NULL);//FIXME:config_read, config_write); |
916 | 924 |
assert(pci_dev); |
917 |
init(pci_dev); |
|
925 |
info->init(pci_dev);
|
|
918 | 926 |
} |
919 | 927 |
|
920 | 928 |
void pci_qdev_register(const char *name, int size, pci_qdev_initfn init) |
921 | 929 |
{ |
922 |
qdev_register(name, size, pci_qdev_init, init); |
|
930 |
PCIDeviceInfo *info; |
|
931 |
|
|
932 |
info = qemu_mallocz(sizeof(*info)); |
|
933 |
info->init = init; |
|
934 |
info->qdev.init = pci_qdev_init; |
|
935 |
info->qdev.bus_type = BUS_TYPE_PCI; |
|
936 |
|
|
937 |
qdev_register(name, size, &info->qdev); |
|
923 | 938 |
} |
924 | 939 |
|
925 | 940 |
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name) |
926 | 941 |
{ |
927 | 942 |
DeviceState *dev; |
928 | 943 |
|
929 |
dev = qdev_create(bus, name); |
|
944 |
dev = qdev_create(&bus->qbus, name);
|
|
930 | 945 |
qdev_set_prop_int(dev, "devfn", devfn); |
931 | 946 |
qdev_init(dev); |
932 | 947 |
|
b/hw/pci.h | ||
---|---|---|
183 | 183 |
|
184 | 184 |
typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level); |
185 | 185 |
typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num); |
186 |
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
|
186 |
PCIBus *pci_register_bus(DeviceState *parent, const char *name, |
|
187 |
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, |
|
187 | 188 |
qemu_irq *pic, int devfn_min, int nirq); |
188 | 189 |
|
189 | 190 |
PCIDevice *pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn, |
b/hw/piix_pci.c | ||
---|---|---|
176 | 176 |
I440FXState *s; |
177 | 177 |
|
178 | 178 |
s = qemu_mallocz(sizeof(I440FXState)); |
179 |
b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, pic, 0, 4); |
|
179 |
b = pci_register_bus(NULL, "pci", |
|
180 |
piix3_set_irq, pci_slot_get_pirq, pic, 0, 4); |
|
180 | 181 |
s->bus = b; |
181 | 182 |
|
182 | 183 |
register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s); |
b/hw/pl022.c | ||
---|---|---|
297 | 297 |
pl022_writefn, s); |
298 | 298 |
sysbus_init_mmio(dev, 0x1000, iomemtype); |
299 | 299 |
sysbus_init_irq(dev, &s->irq); |
300 |
s->ssi = ssi_create_bus(); |
|
301 |
qdev_attach_child_bus(&dev->qdev, "ssi", s->ssi); |
|
300 |
s->ssi = ssi_create_bus(&dev->qdev, "ssi"); |
|
302 | 301 |
pl022_reset(s); |
303 | 302 |
register_savevm("pl022_ssp", -1, 1, pl022_save, pl022_load, s); |
304 | 303 |
} |
b/hw/ppc4xx_pci.c | ||
---|---|---|
370 | 370 |
|
371 | 371 |
controller = qemu_mallocz(sizeof(PPC4xxPCIState)); |
372 | 372 |
|
373 |
controller->pci_state.bus = pci_register_bus(ppc4xx_pci_set_irq, |
|
373 |
controller->pci_state.bus = pci_register_bus(NULL, "pci", |
|
374 |
ppc4xx_pci_set_irq, |
|
374 | 375 |
ppc4xx_pci_map_irq, |
375 | 376 |
pci_irqs, 0, 4); |
376 | 377 |
|
b/hw/ppce500_pci.c | ||
---|---|---|
317 | 317 |
|
318 | 318 |
controller = qemu_mallocz(sizeof(PPCE500PCIState)); |
319 | 319 |
|
320 |
controller->pci_state.bus = pci_register_bus(mpc85xx_pci_set_irq, |
|
320 |
controller->pci_state.bus = pci_register_bus(NULL, "pci", |
|
321 |
mpc85xx_pci_set_irq, |
|
321 | 322 |
mpc85xx_pci_map_irq, |
322 | 323 |
pci_irqs, 0x88, 4); |
323 | 324 |
d = pci_register_device(controller->pci_state.bus, |
b/hw/prep_pci.c | ||
---|---|---|
136 | 136 |
int PPC_io_memory; |
137 | 137 |
|
138 | 138 |
s = qemu_mallocz(sizeof(PREPPCIState)); |
139 |
s->bus = pci_register_bus(prep_set_irq, prep_map_irq, pic, 0, 4); |
|
139 |
s->bus = pci_register_bus(NULL, "pci", |
|
140 |
prep_set_irq, prep_map_irq, pic, 0, 4); |
|
140 | 141 |
|
141 | 142 |
register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s); |
142 | 143 |
register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s); |
b/hw/pxa2xx.c | ||
---|---|---|
863 | 863 |
register_savevm("pxa2xx_ssp", -1, 0, |
864 | 864 |
pxa2xx_ssp_save, pxa2xx_ssp_load, s); |
865 | 865 |
|
866 |
s->bus = ssi_create_bus(); |
|
867 |
qdev_attach_child_bus(&dev->qdev, "ssi", s->bus); |
|
866 |
s->bus = ssi_create_bus(&dev->qdev, "ssi"); |
|
868 | 867 |
} |
869 | 868 |
|
870 | 869 |
/* Real-Time Clock */ |
... | ... | |
1500 | 1499 |
PXA2xxI2CState *s = qemu_mallocz(sizeof(PXA2xxI2CState)); |
1501 | 1500 |
|
1502 | 1501 |
/* FIXME: Should the slave device really be on a separate bus? */ |
1503 |
dev = i2c_create_slave(i2c_init_bus(), "pxa2xx-i2c-slave", 0); |
|
1502 |
dev = i2c_create_slave(i2c_init_bus(NULL, "dummy"), "pxa2xx-i2c-slave", 0);
|
|
1504 | 1503 |
s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE_FROM_QDEV(dev)); |
1505 | 1504 |
s->slave->host = s; |
1506 | 1505 |
|
1507 | 1506 |
s->irq = irq; |
1508 |
s->bus = i2c_init_bus(); |
|
1507 |
s->bus = i2c_init_bus(NULL, "i2c");
|
|
1509 | 1508 |
s->offset = base - (base & (~region_size) & TARGET_PAGE_MASK); |
1510 | 1509 |
|
1511 | 1510 |
iomemtype = cpu_register_io_memory(0, pxa2xx_i2c_readfn, |
... | ... | |
2117 | 2116 |
DeviceState *dev; |
2118 | 2117 |
dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base, |
2119 | 2118 |
s->pic[pxa27x_ssp[i].irqn]); |
2120 |
s->ssp[i] = qdev_get_child_bus(dev, "ssi"); |
|
2119 |
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
|
|
2121 | 2120 |
} |
2122 | 2121 |
|
2123 | 2122 |
if (usb_enabled) { |
... | ... | |
2229 | 2228 |
DeviceState *dev; |
2230 | 2229 |
dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base, |
2231 | 2230 |
s->pic[pxa255_ssp[i].irqn]); |
2232 |
s->ssp[i] = qdev_get_child_bus(dev, "ssi"); |
|
2231 |
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
|
|
2233 | 2232 |
} |
2234 | 2233 |
|
2235 | 2234 |
if (usb_enabled) { |
b/hw/qdev.c | ||
---|---|---|
41 | 41 |
|
42 | 42 |
struct DeviceType { |
43 | 43 |
const char *name; |
44 |
qdev_initfn init; |
|
45 |
void *opaque; |
|
44 |
DeviceInfo *info; |
|
46 | 45 |
int size; |
47 | 46 |
DeviceType *next; |
48 | 47 |
}; |
49 | 48 |
|
50 |
struct ChildBusList { |
|
51 |
const char *name; |
|
52 |
void *ptr; |
|
53 |
ChildBusList *next; |
|
54 |
}; |
|
49 |
/* This is a nasty hack to allow passing a NULL bus to qdev_create. */ |
|
50 |
BusState *main_system_bus; |
|
55 | 51 |
|
56 | 52 |
static DeviceType *device_type_list; |
57 | 53 |
|
58 | 54 |
/* Register a new device type. */ |
59 |
DeviceType *qdev_register(const char *name, int size, qdev_initfn init, |
|
60 |
void *opaque) |
|
55 |
void qdev_register(const char *name, int size, DeviceInfo *info) |
|
61 | 56 |
{ |
62 | 57 |
DeviceType *t; |
63 | 58 |
|
... | ... | |
68 | 63 |
device_type_list = t; |
69 | 64 |
t->name = qemu_strdup(name); |
70 | 65 |
t->size = size; |
71 |
t->init = init; |
|
72 |
t->opaque = opaque; |
|
73 |
|
|
74 |
return t; |
|
66 |
t->info = info; |
|
75 | 67 |
} |
76 | 68 |
|
77 | 69 |
/* Create a new device. This only initializes the device state structure |
78 | 70 |
and allows properties to be set. qdev_init should be called to |
79 | 71 |
initialize the actual device emulation. */ |
80 |
DeviceState *qdev_create(void *bus, const char *name)
|
|
72 |
DeviceState *qdev_create(BusState *bus, const char *name)
|
|
81 | 73 |
{ |
82 | 74 |
DeviceType *t; |
83 | 75 |
DeviceState *dev; |
... | ... | |
88 | 80 |
} |
89 | 81 |
} |
90 | 82 |
if (!t) { |
91 |
fprintf(stderr, "Unknown device '%s'\n", name); |
|
92 |
exit(1); |
|
83 |
hw_error("Unknown device '%s'\n", name); |
|
93 | 84 |
} |
94 | 85 |
|
95 | 86 |
dev = qemu_mallocz(t->size); |
96 | 87 |
dev->name = name; |
97 | 88 |
dev->type = t; |
98 |
dev->bus = bus; |
|
89 |
|
|
90 |
if (!bus) { |
|
91 |
/* ???: This assumes system busses have no additional state. */ |
|
92 |
if (!main_system_bus) { |
|
93 |
main_system_bus = qbus_create(BUS_TYPE_SYSTEM, sizeof(BusState), |
|
94 |
NULL, "main-system-bus"); |
|
95 |
} |
|
96 |
bus = main_system_bus; |
|
97 |
} |
|
98 |
if (t->info->bus_type != bus->type) { |
|
99 |
/* TODO: Print bus type names. */ |
|
100 |
hw_error("Device '%s' on wrong bus type (%d/%d)", name, |
|
101 |
t->info->bus_type, bus->type); |
|
102 |
} |
|
103 |
dev->parent_bus = bus; |
|
104 |
LIST_INSERT_HEAD(&bus->children, dev, sibling); |
|
99 | 105 |
return dev; |
100 | 106 |
} |
101 | 107 |
|
... | ... | |
104 | 110 |
calling this function. */ |
105 | 111 |
void qdev_init(DeviceState *dev) |
106 | 112 |
{ |
107 |
dev->type->init(dev, dev->type->opaque); |
|
113 |
dev->type->info->init(dev, dev->type->info); |
|
114 |
} |
|
115 |
|
|
116 |
/* Unlink device from bus and free the structure. */ |
|
117 |
void qdev_free(DeviceState *dev) |
|
118 |
{ |
|
119 |
LIST_REMOVE(dev, sibling); |
|
120 |
free(dev); |
|
108 | 121 |
} |
109 | 122 |
|
110 | 123 |
static DeviceProperty *create_prop(DeviceState *dev, const char *name) |
... | ... | |
169 | 182 |
} |
170 | 183 |
} |
171 | 184 |
|
172 |
void *qdev_get_bus(DeviceState *dev)
|
|
185 |
BusState *qdev_get_parent_bus(DeviceState *dev)
|
|
173 | 186 |
{ |
174 |
return dev->bus; |
|
187 |
return dev->parent_bus;
|
|
175 | 188 |
} |
176 | 189 |
|
177 | 190 |
static DeviceProperty *find_prop(DeviceState *dev, const char *name) |
... | ... | |
267 | 280 |
return drives_table[index].bdrv; |
268 | 281 |
} |
269 | 282 |
|
270 |
void *qdev_get_child_bus(DeviceState *dev, const char *name)
|
|
283 |
BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
|
|
271 | 284 |
{ |
272 |
ChildBusList *bus;
|
|
285 |
BusState *bus;
|
|
273 | 286 |
|
274 |
for (bus = dev->child_bus; bus; bus = bus->next) {
|
|
287 |
LIST_FOREACH(bus, &dev->child_bus, sibling) {
|
|
275 | 288 |
if (strcmp(name, bus->name) == 0) { |
276 |
return bus->ptr;
|
|
289 |
return bus; |
|
277 | 290 |
} |
278 | 291 |
} |
279 | 292 |
return NULL; |
280 | 293 |
} |
281 | 294 |
|
282 |
void qdev_attach_child_bus(DeviceState *dev, const char *name, void *bus) |
|
283 |
{ |
|
284 |
ChildBusList *p; |
|
285 |
|
|
286 |
assert(!qdev_get_child_bus(dev, name)); |
|
287 |
p = qemu_mallocz(sizeof(*p)); |
|
288 |
p->name = qemu_strdup(name); |
|
289 |
p->ptr = bus; |
|
290 |
p->next = dev->child_bus; |
|
291 |
dev->child_bus = p; |
|
292 |
} |
|
293 |
|
|
294 | 295 |
static int next_scsi_bus; |
295 | 296 |
|
296 | 297 |
/* Create a scsi bus, and attach devices to it. */ |
... | ... | |
309 | 310 |
attach(host, drives_table[index].bdrv, unit); |
310 | 311 |
} |
311 | 312 |
} |
313 |
|
|
314 |
BusState *qbus_create(BusType type, size_t size, |
|
315 |
DeviceState *parent, const char *name) |
|
316 |
{ |
|
317 |
BusState *bus; |
|
318 |
|
|
319 |
bus = qemu_mallocz(size); |
|
320 |
bus->type = type; |
|
321 |
bus->parent = parent; |
|
322 |
bus->name = qemu_strdup(name); |
|
323 |
LIST_INIT(&bus->children); |
|
324 |
if (parent) { |
|
325 |
LIST_INSERT_HEAD(&parent->child_bus, bus, sibling); |
|
326 |
} |
|
327 |
return bus; |
|
328 |
} |
b/hw/qdev.h | ||
---|---|---|
2 | 2 |
#define QDEV_H |
3 | 3 |
|
4 | 4 |
#include "hw.h" |
5 |
#include "sys-queue.h" |
|
5 | 6 |
|
6 | 7 |
typedef struct DeviceType DeviceType; |
7 | 8 |
|
8 | 9 |
typedef struct DeviceProperty DeviceProperty; |
9 | 10 |
|
10 |
typedef struct ChildBusList ChildBusList;
|
|
11 |
typedef struct BusState BusState;
|
|
11 | 12 |
|
12 | 13 |
/* This structure should not be accessed directly. We declare it here |
13 | 14 |
so that it can be embedded in individual device state structures. */ |
14 |
struct DeviceState |
|
15 |
{ |
|
15 |
struct DeviceState { |
|
16 | 16 |
const char *name; |
17 | 17 |
DeviceType *type; |
18 |
void *bus;
|
|
18 |
BusState *parent_bus;
|
|
19 | 19 |
DeviceProperty *props; |
20 | 20 |
int num_irq_sink; |
21 | 21 |
qemu_irq *irq_sink; |
... | ... | |
23 | 23 |
qemu_irq *gpio_out; |
24 | 24 |
int num_gpio_in; |
25 | 25 |
qemu_irq *gpio_in; |
26 |
ChildBusList *child_bus;
|
|
26 |
LIST_HEAD(, BusState) child_bus;
|
|
27 | 27 |
NICInfo *nd; |
28 |
LIST_ENTRY(DeviceState) sibling; |
|
29 |
}; |
|
30 |
|
|
31 |
typedef enum { |
|
32 |
BUS_TYPE_SYSTEM, |
|
33 |
BUS_TYPE_PCI, |
|
34 |
BUS_TYPE_SCSI, |
|
35 |
BUS_TYPE_I2C, |
|
36 |
BUS_TYPE_SSI |
|
37 |
} BusType; |
|
38 |
|
|
39 |
struct BusState { |
|
40 |
DeviceState *parent; |
|
41 |
const char *name; |
|
42 |
BusType type; |
|
43 |
LIST_HEAD(, DeviceState) children; |
|
44 |
LIST_ENTRY(BusState) sibling; |
|
28 | 45 |
}; |
29 | 46 |
|
30 | 47 |
/*** Board API. This should go away once we have a machine config file. ***/ |
31 | 48 |
|
32 |
DeviceState *qdev_create(void *bus, const char *name);
|
|
49 |
DeviceState *qdev_create(BusState *bus, const char *name);
|
|
33 | 50 |
void qdev_init(DeviceState *dev); |
51 |
void qdev_free(DeviceState *dev); |
|
34 | 52 |
|
35 | 53 |
/* Set properties between creation and init. */ |
36 | 54 |
void qdev_set_prop_int(DeviceState *dev, const char *name, uint64_t value); |
... | ... | |
41 | 59 |
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n); |
42 | 60 |
void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin); |
43 | 61 |
|
44 |
void *qdev_get_child_bus(DeviceState *dev, const char *name);
|
|
62 |
BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
|
|
45 | 63 |
|
46 | 64 |
/*** Device API. ***/ |
47 | 65 |
|
48 |
typedef void (*qdev_initfn)(DeviceState *dev, void *opaque); |
|
66 |
typedef struct DeviceInfo DeviceInfo; |
|
67 |
|
|
68 |
typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info); |
|
49 | 69 |
typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv, |
50 | 70 |
int unit); |
51 | 71 |
|
52 |
DeviceType *qdev_register(const char *name, int size, qdev_initfn init, |
|
53 |
void *opaque); |
|
72 |
struct DeviceInfo { |
|
73 |
qdev_initfn init; |
|
74 |
BusType bus_type; |
|
75 |
}; |
|
76 |
|
|
77 |
void qdev_register(const char *name, int size, DeviceInfo *info); |
|
54 | 78 |
|
55 | 79 |
/* Register device properties. */ |
56 | 80 |
void qdev_init_irq_sink(DeviceState *dev, qemu_irq_handler handler, int nirq); |
57 | 81 |
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n); |
58 | 82 |
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n); |
59 |
void qdev_attach_child_bus(DeviceState *dev, const char *name, void *bus); |
|
60 | 83 |
|
61 | 84 |
void scsi_bus_new(DeviceState *host, SCSIAttachFn attach); |
62 | 85 |
|
63 | 86 |
CharDriverState *qdev_init_chardev(DeviceState *dev); |
64 | 87 |
|
65 |
void *qdev_get_bus(DeviceState *dev);
|
|
88 |
BusState *qdev_get_parent_bus(DeviceState *dev);
|
|
66 | 89 |
uint64_t qdev_get_prop_int(DeviceState *dev, const char *name, uint64_t def); |
67 | 90 |
void *qdev_get_prop_ptr(DeviceState *dev, const char *name); |
68 | 91 |
|
... | ... | |
76 | 99 |
#define DO_UPCAST(type, field, dev) container_of(dev, type, field) |
77 | 100 |
#endif |
78 | 101 |
|
102 |
/*** BUS API. ***/ |
|
103 |
|
|
104 |
BusState *qbus_create(BusType type, size_t size, |
|
105 |
DeviceState *parent, const char *name); |
|
106 |
|
|
107 |
#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev) |
|
108 |
|
|
79 | 109 |
#endif |
b/hw/realview.c | ||
---|---|---|
109 | 109 |
|
110 | 110 |
dev = sysbus_create_varargs("realview_pci", 0x60000000, |
111 | 111 |
pic[48], pic[49], pic[50], pic[51], NULL); |
112 |
pci_bus = qdev_get_child_bus(dev, "pci"); |
|
112 |
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
|
|
113 | 113 |
if (usb_enabled) { |
114 | 114 |
usb_ohci_init_pci(pci_bus, 3, -1); |
115 | 115 |
} |
b/hw/sh_pci.c | ||
---|---|---|
174 | 174 |
int mem, reg, iop; |
175 | 175 |
|
176 | 176 |
p = qemu_mallocz(sizeof(SHPCIC)); |
177 |
p->bus = pci_register_bus(set_irq, map_irq, pic, devfn_min, nirq); |
|
177 |
p->bus = pci_register_bus(NULL, "pci", |
|
178 |
set_irq, map_irq, pic, devfn_min, nirq); |
|
178 | 179 |
|
179 | 180 |
p->dev = pci_register_device(p->bus, "SH PCIC", sizeof(PCIDevice), |
180 | 181 |
-1, NULL, NULL); |
b/hw/spitz.c | ||
---|---|---|
706 | 706 |
CorgiSSPState *s = FROM_SSI_SLAVE(CorgiSSPState, dev); |
707 | 707 |
|
708 | 708 |
qdev_init_gpio_in(&dev->qdev, corgi_ssp_gpio_cs, 3); |
709 |
s->bus[0] = ssi_create_bus(); |
|
710 |
qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]); |
|
711 |
s->bus[1] = ssi_create_bus(); |
|
712 |
qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]); |
|
713 |
s->bus[2] = ssi_create_bus(); |
|
714 |
qdev_attach_child_bus(&dev->qdev, "ssi2", s->bus[2]); |
|
709 |
s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0"); |
|
710 |
s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1"); |
|
711 |
s->bus[2] = ssi_create_bus(&dev->qdev, "ssi2"); |
|
715 | 712 |
|
716 | 713 |
register_savevm("spitz_ssp", -1, 1, spitz_ssp_save, spitz_ssp_load, s); |
717 | 714 |
} |
b/hw/ssi.c | ||
---|---|---|
10 | 10 |
#include "ssi.h" |
11 | 11 |
|
12 | 12 |
struct SSIBus { |
13 |
SSISlave *slave;
|
|
13 |
BusState qbus;
|
|
14 | 14 |
}; |
15 | 15 |
|
16 |
static void ssi_slave_init(DeviceState *dev, void *opaque)
|
|
16 |
static void ssi_slave_init(DeviceState *dev, DeviceInfo *base_info)
|
|
17 | 17 |
{ |
18 |
SSISlaveInfo *info = opaque;
|
|
18 |
SSISlaveInfo *info = container_of(base_info, SSISlaveInfo, qdev);
|
|
19 | 19 |
SSISlave *s = SSI_SLAVE_FROM_QDEV(dev); |
20 |
SSIBus *bus = qdev_get_bus(dev); |
|
20 |
SSIBus *bus; |
|
21 |
|
|
22 |
bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); |
|
23 |
if (LIST_FIRST(&bus->qbus.children) != dev |
|
24 |
|| LIST_NEXT(dev, sibling) != NULL) { |
|
25 |
hw_error("Too many devices on SSI bus"); |
|
26 |
} |
|
21 | 27 |
|
22 |
bus->slave = s; |
|
23 | 28 |
s->info = info; |
24 | 29 |
info->init(s); |
25 | 30 |
} |
... | ... | |
27 | 32 |
void ssi_register_slave(const char *name, int size, SSISlaveInfo *info) |
28 | 33 |
{ |
29 | 34 |
assert(size >= sizeof(SSISlave)); |
30 |
qdev_register(name, size, ssi_slave_init, info); |
|
35 |
info->qdev.init = ssi_slave_init; |
|
36 |
info->qdev.bus_type = BUS_TYPE_SSI; |
|
37 |
qdev_register(name, size, &info->qdev); |
|
31 | 38 |
} |
32 | 39 |
|
33 | 40 |
DeviceState *ssi_create_slave(SSIBus *bus, const char *name) |
34 | 41 |
{ |
35 | 42 |
DeviceState *dev; |
36 |
dev = qdev_create(bus, name); |
|
43 |
dev = qdev_create(&bus->qbus, name);
|
|
37 | 44 |
qdev_init(dev); |
38 | 45 |
return dev; |
39 | 46 |
} |
40 | 47 |
|
41 |
SSIBus *ssi_create_bus(void)
|
|
48 |
SSIBus *ssi_create_bus(DeviceState *parent, const char *name)
|
|
42 | 49 |
{ |
43 |
return qemu_mallocz(sizeof(SSIBus)); |
|
50 |
BusState *bus; |
|
51 |
bus = qbus_create(BUS_TYPE_SSI, sizeof(SSIBus), parent, name); |
|
52 |
return FROM_QBUS(SSIBus, bus); |
|
44 | 53 |
} |
45 | 54 |
|
46 | 55 |
uint32_t ssi_transfer(SSIBus *bus, uint32_t val) |
47 | 56 |
{ |
48 |
if (!bus->slave) { |
|
57 |
DeviceState *dev; |
|
58 |
SSISlave *slave; |
|
59 |
dev = LIST_FIRST(&bus->qbus.children); |
|
60 |
if (!dev) { |
|
49 | 61 |
return 0; |
50 | 62 |
} |
51 |
return bus->slave->info->transfer(bus->slave, val); |
|
63 |
slave = SSI_SLAVE_FROM_QDEV(dev); |
|
64 |
return slave->info->transfer(slave, val); |
|
52 | 65 |
} |
b/hw/ssi.h | ||
---|---|---|
17 | 17 |
|
18 | 18 |
/* Slave devices. */ |
19 | 19 |
typedef struct { |
20 |
DeviceInfo qdev; |
|
20 | 21 |
void (*init)(SSISlave *dev); |
21 | 22 |
uint32_t (*transfer)(SSISlave *dev, uint32_t val); |
22 | 23 |
} SSISlaveInfo; |
... | ... | |
34 | 35 |
DeviceState *ssi_create_slave(SSIBus *bus, const char *name); |
35 | 36 |
|
36 | 37 |
/* Master interface. */ |
37 |
SSIBus *ssi_create_bus(void);
|
|
38 |
SSIBus *ssi_create_bus(DeviceState *parent, const char *name);
|
|
38 | 39 |
|
39 | 40 |
uint32_t ssi_transfer(SSIBus *bus, uint32_t val); |
40 | 41 |
|
b/hw/stellaris.c | ||
---|---|---|
874 | 874 |
static void stellaris_i2c_init(SysBusDevice * dev) |
875 | 875 |
{ |
876 | 876 |
stellaris_i2c_state *s = FROM_SYSBUS(stellaris_i2c_state, dev); |
877 |
i2c_bus *bus = i2c_init_bus();
|
|
877 |
i2c_bus *bus; |
|
878 | 878 |
int iomemtype; |
879 | 879 |
|
880 | 880 |
sysbus_init_irq(dev, &s->irq); |
881 |
qdev_attach_child_bus(&dev->qdev, "i2c", bus);
|
|
881 |
bus = i2c_init_bus(&dev->qdev, "i2c");
|
|
882 | 882 |
s->bus = bus; |
883 | 883 |
|
884 | 884 |
iomemtype = cpu_register_io_memory(0, stellaris_i2c_readfn, |
... | ... | |
1239 | 1239 |
{ |
1240 | 1240 |
stellaris_ssi_bus_state *s = FROM_SSI_SLAVE(stellaris_ssi_bus_state, dev); |
1241 | 1241 |
|
1242 |
s->bus[0] = ssi_create_bus(); |
|
1243 |
qdev_attach_child_bus(&dev->qdev, "ssi0", s->bus[0]); |
|
1244 |
s->bus[1] = ssi_create_bus(); |
|
1245 |
qdev_attach_child_bus(&dev->qdev, "ssi1", s->bus[1]); |
|
1242 |
s->bus[0] = ssi_create_bus(&dev->qdev, "ssi0"); |
|
1243 |
s->bus[1] = ssi_create_bus(&dev->qdev, "ssi1"); |
|
1246 | 1244 |
qdev_init_gpio_in(&dev->qdev, stellaris_ssi_bus_select, 1); |
1247 | 1245 |
|
1248 | 1246 |
register_savevm("stellaris_ssi_bus", -1, 1, |
... | ... | |
1320 | 1318 |
if (board->dc2 & (1 << 12)) { |
1321 | 1319 |
DeviceState *dev; |
1322 | 1320 |
dev = sysbus_create_simple("stellaris-i2c", 0x40020000, pic[8]); |
1323 |
i2c = qdev_get_child_bus(dev, "i2c"); |
|
1321 |
i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
|
|
1324 | 1322 |
if (board->peripherals & BP_OLED_I2C) { |
1325 | 1323 |
i2c_create_slave(i2c, "ssd0303", 0x3d); |
1326 | 1324 |
} |
b/hw/sysbus.c | ||
---|---|---|
21 | 21 |
#include "sysbus.h" |
22 | 22 |
#include "sysemu.h" |
23 | 23 |
|
24 |
typedef struct { |
|
25 |
DeviceInfo qdev; |
|
26 |
sysbus_initfn init; |
|
27 |
} SysBusDeviceInfo; |
|
28 |
|
|
24 | 29 |
void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq) |
25 | 30 |
{ |
26 | 31 |
assert(n >= 0 && n < dev->num_irq); |
... | ... | |
97 | 102 |
dev->mmio[n].cb = cb; |
98 | 103 |
} |
99 | 104 |
|
100 |
static void sysbus_device_init(DeviceState *dev, void *opaque)
|
|
105 |
static void sysbus_device_init(DeviceState *dev, DeviceInfo *base)
|
|
101 | 106 |
{ |
102 |
sysbus_initfn init = (sysbus_initfn)opaque;
|
|
107 |
SysBusDeviceInfo *info = container_of(base, SysBusDeviceInfo, qdev);
|
|
103 | 108 |
|
104 |
init(sysbus_from_qdev(dev)); |
|
109 |
info->init(sysbus_from_qdev(dev));
|
|
105 | 110 |
} |
106 | 111 |
|
107 | 112 |
void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init) |
108 | 113 |
{ |
114 |
SysBusDeviceInfo *info; |
|
115 |
|
|
116 |
info = qemu_mallocz(sizeof(*info)); |
|
117 |
info->init = init; |
|
118 |
info->qdev.init = sysbus_device_init; |
|
119 |
info->qdev.bus_type = BUS_TYPE_SYSTEM; |
|
120 |
|
|
109 | 121 |
assert(size >= sizeof(SysBusDevice)); |
110 |
qdev_register(name, size, sysbus_device_init, init);
|
|
122 |
qdev_register(name, size, &info->qdev);
|
|
111 | 123 |
} |
112 | 124 |
|
113 | 125 |
DeviceState *sysbus_create_varargs(const char *name, |
b/hw/unin_pci.c | ||
---|---|---|
175 | 175 |
/* Use values found on a real PowerMac */ |
176 | 176 |
/* Uninorth main bus */ |
177 | 177 |
s = qemu_mallocz(sizeof(UNINState)); |
178 |
s->bus = pci_register_bus(pci_unin_set_irq, pci_unin_map_irq, |
|
178 |
s->bus = pci_register_bus(NULL, "pci", |
|
179 |
pci_unin_set_irq, pci_unin_map_irq, |
|
179 | 180 |
pic, 11 << 3, 4); |
180 | 181 |
|
181 | 182 |
pci_mem_config = cpu_register_io_memory(0, pci_unin_main_config_read, |
b/hw/versatile_pci.c | ||
---|---|---|
118 | 118 |
for (i = 0; i < 4; i++) { |
119 | 119 |
sysbus_init_irq(dev, &s->irq[i]); |
120 | 120 |
} |
121 |
bus = pci_register_bus(pci_vpb_set_irq, pci_vpb_map_irq, s->irq, |
|
121 |
bus = pci_register_bus(&dev->qdev, "pci", |
|
122 |
pci_vpb_set_irq, pci_vpb_map_irq, s->irq, |
|
122 | 123 |
11 << 3, 4); |
123 |
qdev_attach_child_bus(&dev->qdev, "pci", bus); |
|
124 | 124 |
|
125 | 125 |
/* ??? Register memory space. */ |
126 | 126 |
|
b/hw/versatilepb.c | ||
---|---|---|
201 | 201 |
|
202 | 202 |
dev = sysbus_create_varargs("versatile_pci", 0x40000000, |
203 | 203 |
sic[27], sic[28], sic[29], sic[30], NULL); |
204 |
pci_bus = qdev_get_child_bus(dev, "pci"); |
|
204 |
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
|
|
205 | 205 |
|
206 | 206 |
/* The Versatile PCI bridge does not provide access to PCI IO space, |
207 | 207 |
so many of the qemu PCI devices are not useable. */ |
Also available in: Unified diff