@@ -155,6 +155,7 @@ PCIBus *pci_register_bus(DeviceState *parent, const char *name,
}
PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq,
+ void *irq_opaque,
const char* name, int devfn_min)
{
PCIBus *bus;
@@ -162,6 +163,7 @@ PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq,
bus = FROM_QBUS(PCIBus, qbus_create(&pci_bus_info, &dev->qdev, name));
bus->map_irq = map_irq;
+ bus->irq_opaque = irq_opaque;
bus->bus_num = dev->config[PCI_SECONDARY_BUS];
bus->devfn_min = devfn_min;
@@ -1068,7 +1070,7 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
pci_dev->irq_state[irq_num] = level;
for (;;) {
bus = pci_get_parent_bus(pci_dev);
- irq_num = bus->map_irq(pci_dev, irq_num);
+ irq_num = bus->map_irq(bus->irq_opaque, pci_dev, irq_num);
if (bus->set_irq)
break;
pci_dev = pci_bus_to_dev(bus);
@@ -1078,7 +1080,7 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
}
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
-int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin)
+int pci_swizzle_map_irq_fn(void *opauqe, PCIDevice *pci_dev, int pin)
{
return (pin + PCI_SLOT(pci_dev->devfn) - 1) % PCI_NUM_PINS;
}
@@ -1524,7 +1526,7 @@ PCIBus *pci_bridge_create_simple(PCIBus *bus, int devfn, uint16_t vid,
pci_config_set_byte(d, PCI_SECONDARY_BUS, sec_bus);
pci_config_set_byte(d, PCI_SUBORDINATE_BUS, sub_bus);
- return pci_register_secondary_bus(d, map_irq, bus_name, 0);
+ return pci_register_secondary_bus(d, map_irq, d, name, 0);
}
PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint16_t vid,
@@ -355,13 +355,14 @@ int pci_device_load(PCIDevice *s, QEMUFile *f);
void pci_set_default_bus(PCIBus *bus);
typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
-typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
+typedef int (*pci_map_irq_fn)(void *opaque, PCIDevice *pci_dev, int irq_num);
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
-int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin);
+int pci_swizzle_map_irq_fn(void *opaque, PCIDevice *pci_dev, int pin);
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque, int devfn_min, int nirq);
PCIBus *pci_register_secondary_bus(PCIDevice *dev, pci_map_irq_fn map_irq,
+ void *irq_opaque,
const char* name, int devfn_min);
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
@@ -67,9 +67,9 @@ static void piix3_set_irq(void *opaque, int irq_num, int level);
/* return the global irq number corresponding to a given device irq
pin. We could also use the bus number to have a more precise
mapping. */
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+static int pci_slot_get_pirq(void *opaque, PCIDevice *pci_dev, int irq_num)
{
- return pci_swizzle_map_irq_fn(pci_dev, irq_num);
+ return pci_swizzle_map_irq_fn(NULL, pci_dev, irq_num);
}
static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
@@ -157,9 +157,9 @@ static void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
/* return the global irq number corresponding to a given device irq
pin. We could also use the bus number to have a more precise
mapping. */
-static int pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
+static int pci_slot_get_pirq(void *opaque, PCIDevice *pci_dev, int irq_num)
{
- return pci_swizzle_map_irq_fn(pci_dev, irq_num);
+ return pci_swizzle_map_irq_fn(NULL, pci_dev, irq_num);
}
/* PAM */
To convert pci int pin to global irq or GSI, not only the pci device which generates interrupt, but also the bus, like pci_set_irq_fn. So pass the opaque argument to pci_map_irq_fn like pci_set_irq_fn. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- hw/pci.c | 8 +++++--- hw/pci.h | 5 +++-- hw/piix_pci.c | 4 ++-- hw/q35.c | 4 ++-- 4 files changed, 12 insertions(+), 9 deletions(-)