aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2009-12-01 11:54:39 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2009-12-01 11:54:39 -0600
commit365369847f2827b14b96c52d0fbaf9cce404e68a (patch)
tree1ee8e1be27e3223b310bbb3d91bf2e54435280b0
parent0cbfcd2b03bd602b7c65f73267bf84d4f7e9fe8d (diff)
parent98304c846d8866dae6322ef400ce6595b23cfc41 (diff)
Merge commit 'mst/for_anthony' into mst
-rw-r--r--hw/apb_pci.c5
-rw-r--r--hw/apb_pci.h9
-rw-r--r--hw/grackle_pci.c8
-rw-r--r--hw/lsi53c895a.c2
-rw-r--r--hw/mips_malta.c2
-rw-r--r--hw/msix.c48
-rw-r--r--hw/msix.h1
-rw-r--r--hw/pc.c5
-rw-r--r--hw/pci-hotplug.c4
-rw-r--r--hw/pci.c192
-rw-r--r--hw/pci.h50
-rw-r--r--hw/pci_host.c50
-rw-r--r--hw/pci_host.h15
-rw-r--r--hw/pcie_host.c31
-rw-r--r--hw/pcie_host.h4
-rw-r--r--hw/piix_pci.c2
-rw-r--r--hw/ppc4xx_pci.c2
-rw-r--r--hw/ppc_newworld.c1
-rw-r--r--hw/ppc_oldworld.c1
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/ppce500_pci.c4
-rw-r--r--hw/prep_pci.c3
-rw-r--r--hw/prep_pci.h8
-rw-r--r--hw/r2d.c1
-rw-r--r--hw/realview.c1
-rw-r--r--hw/sh_pci.c2
-rw-r--r--hw/sh_pci.h9
-rw-r--r--hw/sun4u.c1
-rw-r--r--hw/unin_pci.c16
-rw-r--r--hw/usb-ohci.c1
-rw-r--r--hw/usb-ohci.h9
-rw-r--r--hw/usb-uhci.c1
-rw-r--r--hw/usb-uhci.h9
-rw-r--r--hw/versatile_pci.c1
-rw-r--r--hw/versatilepb.c1
-rw-r--r--hw/virtio-pci.c12
-rw-r--r--hw/vmware_vga.c1
-rw-r--r--hw/vmware_vga.h9
-rw-r--r--qemu-common.h2
39 files changed, 290 insertions, 235 deletions
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 39998791f..f2ed136fd 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -29,6 +29,7 @@
#include "sysbus.h"
#include "pci.h"
#include "pci_host.h"
+#include "apb_pci.h"
/* debug APB */
//#define DEBUG_APB
@@ -235,10 +236,10 @@ static int pci_pbm_init_device(SysBusDevice *dev)
pci_apb_iowrite, s);
sysbus_init_mmio(dev, 0x10000ULL, pci_ioport);
/* mem_config */
- pci_mem_config = pci_host_config_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x10ULL, pci_mem_config);
/* mem_data */
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x10000000ULL, pci_mem_data);
return 0;
}
diff --git a/hw/apb_pci.h b/hw/apb_pci.h
new file mode 100644
index 000000000..8869f9d32
--- /dev/null
+++ b/hw/apb_pci.h
@@ -0,0 +1,9 @@
+#ifndef APB_PCI_H
+#define APB_PCI_H
+
+#include "qemu-common.h"
+
+PCIBus *pci_apb_init(target_phys_addr_t special_base,
+ target_phys_addr_t mem_base,
+ qemu_irq *pic, PCIBus **bus2, PCIBus **bus3);
+#endif
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index f3a8a7da1..089d1fba0 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -108,8 +108,8 @@ static int pci_grackle_init_device(SysBusDevice *dev)
s = FROM_SYSBUS(GrackleState, dev);
- pci_mem_config = pci_host_config_register_io_memory(&s->host_state);
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
@@ -126,8 +126,8 @@ static int pci_dec_21154_init_device(SysBusDevice *dev)
s = FROM_SYSBUS(GrackleState, dev);
- pci_mem_config = pci_host_config_register_io_memory(&s->host_state);
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
return 0;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 7e47fc9ab..8b8a80b89 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -31,6 +31,8 @@ do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__); exit(1);} while
do { fprintf(stderr, "lsi_scsi: error: " fmt , ## __VA_ARGS__);} while (0)
#endif
+#define LSI_MAX_DEVS 7
+
#define LSI_SCNTL0_TRG 0x01
#define LSI_SCNTL0_AAP 0x02
#define LSI_SCNTL0_EPC 0x08
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 76884570f..571d8ced1 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -32,6 +32,8 @@
#include "flash.h"
#include "mips.h"
#include "pci.h"
+#include "usb-uhci.h"
+#include "vmware_vga.h"
#include "qemu-char.h"
#include "sysemu.h"
#include "audio/audio.h"
diff --git a/hw/msix.c b/hw/msix.c
index 548ffd5c8..4bc614723 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -105,14 +105,6 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
return 0;
}
-static void msix_free_irq_entries(PCIDevice *dev)
-{
- int vector;
-
- for (vector = 0; vector < dev->msix_entries_nr; ++vector)
- dev->msix_entry_used[vector] = 0;
-}
-
/* Handle MSI-X capability config write. */
void msix_write_config(PCIDevice *dev, uint32_t addr,
uint32_t val, int len)
@@ -217,6 +209,15 @@ void msix_mmio_map(PCIDevice *d, int region_num,
d->msix_mmio_index);
}
+static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
+{
+ int vector;
+ for (vector = 0; vector < nentries; ++vector) {
+ unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
+ dev->msix_table_page[offset] |= MSIX_VECTOR_MASK;
+ }
+}
+
/* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is
* modified, it should be retrieved with msix_bar_size. */
int msix_init(struct PCIDevice *dev, unsigned short nentries,
@@ -234,6 +235,7 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
sizeof *dev->msix_entry_used);
dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
+ msix_mask_all(dev, nentries);
dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read,
msix_mmio_write, dev);
@@ -261,6 +263,16 @@ err_index:
return ret;
}
+static void msix_free_irq_entries(PCIDevice *dev)
+{
+ int vector;
+
+ for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
+ dev->msix_entry_used[vector] = 0;
+ msix_clr_pending(dev, vector);
+ }
+}
+
/* Clean up resources for the device. */
int msix_uninit(PCIDevice *dev)
{
@@ -351,8 +363,10 @@ void msix_reset(PCIDevice *dev)
if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
return;
msix_free_irq_entries(dev);
- dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] &= MSIX_ENABLE_MASK;
+ dev->config[dev->msix_cap + MSIX_ENABLE_OFFSET] &=
+ ~dev->wmask[dev->msix_cap + MSIX_ENABLE_OFFSET];
memset(dev->msix_table_page, 0, MSIX_PAGE_SIZE);
+ msix_mask_all(dev, dev->msix_entries_nr);
}
/* PCI spec suggests that devices make it possible for software to configure
@@ -375,6 +389,18 @@ int msix_vector_use(PCIDevice *dev, unsigned vector)
/* Mark vector as unused. */
void msix_vector_unuse(PCIDevice *dev, unsigned vector)
{
- if (vector < dev->msix_entries_nr && dev->msix_entry_used[vector])
- --dev->msix_entry_used[vector];
+ if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) {
+ return;
+ }
+ if (--dev->msix_entry_used[vector]) {
+ return;
+ }
+ msix_clr_pending(dev, vector);
+}
+
+void msix_unuse_all_vectors(PCIDevice *dev)
+{
+ if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
+ return;
+ msix_free_irq_entries(dev);
}
diff --git a/hw/msix.h b/hw/msix.h
index 39fa568f9..a9f7993c3 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -25,6 +25,7 @@ uint32_t msix_bar_size(PCIDevice *dev);
int msix_vector_use(PCIDevice *dev, unsigned vector);
void msix_vector_unuse(PCIDevice *dev, unsigned vector);
+void msix_unuse_all_vectors(PCIDevice *dev);
void msix_notify(PCIDevice *dev, unsigned vector);
diff --git a/hw/pc.c b/hw/pc.c
index 7c791c413..97964b27e 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -25,6 +25,11 @@
#include "pc.h"
#include "fdc.h"
#include "pci.h"
+#include "vmware_vga.h"
+#include "usb-uhci.h"
+#include "usb-ohci.h"
+#include "prep_pci.h"
+#include "apb_pci.h"
#include "block.h"
#include "sysemu.h"
#include "audio/audio.h"
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index a25449814..081d6d1ac 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -113,7 +113,7 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
goto err;
}
- dev = pci_find_device(pci_find_host_bus(0), pci_bus, slot, 0);
+ dev = pci_find_device(pci_find_root_bus(0), pci_bus, slot, 0);
if (!dev) {
monitor_printf(mon, "no pci device with address %s\n", pci_addr);
goto err;
@@ -257,7 +257,7 @@ void pci_device_hot_remove(Monitor *mon, const char *pci_addr)
return;
}
- d = pci_find_device(pci_find_host_bus(0), bus, slot, 0);
+ d = pci_find_device(pci_find_root_bus(0), bus, slot, 0);
if (!d) {
monitor_printf(mon, "slot %d empty\n", slot);
return;
diff --git a/hw/pci.c b/hw/pci.c
index 5b3461cd6..8cf008d31 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -23,7 +23,6 @@
*/
#include "hw.h"
#include "pci.h"
-#include "pci_host.h"
#include "monitor.h"
#include "net.h"
#include "sysemu.h"
@@ -146,7 +145,7 @@ static void pci_host_bus_register(int domain, PCIBus *bus)
QLIST_INSERT_HEAD(&host_buses, host, next);
}
-PCIBus *pci_find_host_bus(int domain)
+PCIBus *pci_find_root_bus(int domain)
{
struct PCIHostBus *host;
@@ -239,13 +238,6 @@ int pci_bus_num(PCIBus *s)
return s->parent_dev->config[PCI_SECONDARY_BUS];
}
-static uint8_t pci_sub_bus(PCIBus *s)
-{
- if (!s->parent_dev)
- return 255; /* pci host bridge */
- return s->parent_dev->config[PCI_SUBORDINATE_BUS];
-}
-
static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
{
PCIDevice *s = container_of(pv, PCIDevice, config);
@@ -379,7 +371,7 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *s
return -1;
/* Note: QEMU doesn't implement domains other than 0 */
- if (!pci_find_bus(pci_find_host_bus(dom), bus))
+ if (!pci_find_bus(pci_find_root_bus(dom), bus))
return -1;
*domp = dom;
@@ -409,7 +401,7 @@ PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
if (!devaddr) {
*devfnp = -1;
- return pci_find_bus(pci_find_host_bus(0), 0);
+ return pci_find_bus(pci_find_root_bus(0), 0);
}
if (pci_parse_devaddr(devaddr, &dom, &bus, &slot) < 0) {
@@ -417,7 +409,7 @@ PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
}
*devfnp = slot << 3;
- return pci_find_bus(pci_find_host_bus(0), bus);
+ return pci_find_bus(pci_find_root_bus(0), bus);
}
static void pci_init_cmask(PCIDevice *dev)
@@ -434,15 +426,15 @@ static void pci_init_cmask(PCIDevice *dev)
static void pci_init_wmask(PCIDevice *dev)
{
- int i;
int config_size = pci_config_size(dev);
dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
pci_set_word(dev->wmask + PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
- for (i = PCI_CONFIG_HEADER_SIZE; i < config_size; ++i)
- dev->wmask[i] = 0xff;
+
+ memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
+ config_size - PCI_CONFIG_HEADER_SIZE);
}
static void pci_init_wmask_bridge(PCIDevice *d)
@@ -495,7 +487,8 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
uint8_t header_type)
{
if (devfn < 0) {
- for(devfn = bus->devfn_min ; devfn < 256; devfn += 8) {
+ for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
+ devfn += 8) {
if (!bus->devices[devfn])
goto found;
}
@@ -637,24 +630,28 @@ static uint32_t pci_config_get_io_base(PCIDevice *d,
val = ((uint32_t)d->config[base] & PCI_IO_RANGE_MASK) << 8;
if (d->config[base] & PCI_IO_RANGE_TYPE_32) {
- val |= (uint32_t)pci_get_word(d->config + PCI_IO_BASE_UPPER16) << 16;
+ val |= (uint32_t)pci_get_word(d->config + base_upper16) << 16;
}
return val;
}
-static uint64_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
+static pcibus_t pci_config_get_memory_base(PCIDevice *d, uint32_t base)
{
- return ((uint64_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
+ return ((pcibus_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK)
<< 16;
}
-static uint64_t pci_config_get_pref_base(PCIDevice *d,
+static pcibus_t pci_config_get_pref_base(PCIDevice *d,
uint32_t base, uint32_t upper)
{
- uint64_t val;
- val = ((uint64_t)pci_get_word(d->config + base) &
- PCI_PREF_RANGE_MASK) << 16;
- val |= (uint64_t)pci_get_long(d->config + upper) << 32;
+ pcibus_t tmp;
+ pcibus_t val;
+
+ tmp = (pcibus_t)pci_get_word(d->config + base);
+ val = (tmp & PCI_PREF_RANGE_MASK) << 16;
+ if (tmp & PCI_PREF_RANGE_TYPE_64) {
+ val |= (pcibus_t)pci_get_long(d->config + upper) << 32;
+ }
return val;
}
@@ -720,83 +717,95 @@ static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
}
if (base > limit) {
- no_map:
- *addr = PCI_BAR_UNMAPPED;
- *size = 0;
+ goto no_map;
+ }
+ *addr = base;
+ *size = limit - base + 1;
+ return;
+no_map:
+ *addr = PCI_BAR_UNMAPPED;
+ *size = 0;
+}
+
+static pcibus_t pci_bar_address(PCIDevice *d,
+ int reg, uint8_t type, pcibus_t size)
+{
+ pcibus_t new_addr, last_addr;
+ int bar = pci_bar(d, reg);
+ uint16_t cmd = pci_get_word(d->config + PCI_COMMAND);
+
+ if (type & PCI_BASE_ADDRESS_SPACE_IO) {
+ if (!(cmd & PCI_COMMAND_IO)) {
+ return PCI_BAR_UNMAPPED;
+ }
+ new_addr = pci_get_long(d->config + bar) & ~(size - 1);
+ last_addr = new_addr + size - 1;
+ /* NOTE: we have only 64K ioports on PC */
+ if (last_addr <= new_addr || new_addr == 0 || last_addr > UINT16_MAX) {
+ return PCI_BAR_UNMAPPED;
+ }
+ return new_addr;
+ }
+
+ if (!(cmd & PCI_COMMAND_MEMORY)) {
+ return PCI_BAR_UNMAPPED;
+ }
+ if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ new_addr = pci_get_quad(d->config + bar);
} else {
- *addr = base;
- *size = limit - base + 1;
+ new_addr = pci_get_long(d->config + bar);
+ }
+ /* the ROM slot has a specific enable bit */
+ if (reg == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE)) {
+ return PCI_BAR_UNMAPPED;
}
+ new_addr &= ~(size - 1);
+ last_addr = new_addr + size - 1;
+ /* NOTE: we do not support wrapping */
+ /* XXX: as we cannot support really dynamic
+ mappings, we handle specific values as invalid
+ mappings. */
+ if (last_addr <= new_addr || new_addr == 0 ||
+ last_addr == PCI_BAR_UNMAPPED) {
+ return PCI_BAR_UNMAPPED;
+ }
+
+ /* Now pcibus_t is 64bit.
+ * Check if 32 bit BAR wraps around explicitly.
+ * Without this, PC ide doesn't work well.
+ * TODO: remove this work around.
+ */
+ if (!(type & PCI_BASE_ADDRESS_MEM_TYPE_64) && last_addr >= UINT32_MAX) {
+ return PCI_BAR_UNMAPPED;
+ }
+
+ /*
+ * OS is allowed to set BAR beyond its addressable
+ * bits. For example, 32 bit OS can set 64bit bar
+ * to >4G. Check it. TODO: we might need to support
+ * it in the future for e.g. PAE.
+ */
+ if (last_addr >= TARGET_PHYS_ADDR_MAX) {
+ return PCI_BAR_UNMAPPED;
+ }
+
+ return new_addr;
}
static void pci_update_mappings(PCIDevice *d)
{
PCIIORegion *r;
- int cmd, i;
- pcibus_t last_addr, new_addr;
- pcibus_t filtered_size;
+ int i;
+ pcibus_t new_addr, filtered_size;
- cmd = pci_get_word(d->config + PCI_COMMAND);
for(i = 0; i < PCI_NUM_REGIONS; i++) {
r = &d->io_regions[i];
/* this region isn't registered */
- if (r->size == 0)
+ if (!r->size)
continue;
- if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
- if (cmd & PCI_COMMAND_IO) {
- new_addr = pci_get_long(d->config + pci_bar(d, i));
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we have only 64K ioports on PC */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr >= 0x10000) {
- new_addr = PCI_BAR_UNMAPPED;
- }
- } else {
- new_addr = PCI_BAR_UNMAPPED;
- }
- } else {
- if (cmd & PCI_COMMAND_MEMORY) {
- if (r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {
- new_addr = pci_get_quad(d->config + pci_bar(d, i));
- } else {
- new_addr = pci_get_long(d->config + pci_bar(d, i));
- }
- /* the ROM slot has a specific enable bit */
- if (i == PCI_ROM_SLOT && !(new_addr & PCI_ROM_ADDRESS_ENABLE))
- goto no_mem_map;
- new_addr = new_addr & ~(r->size - 1);
- last_addr = new_addr + r->size - 1;
- /* NOTE: we do not support wrapping */
- /* XXX: as we cannot support really dynamic
- mappings, we handle specific values as invalid
- mappings. */
- if (last_addr <= new_addr || new_addr == 0 ||
- last_addr == PCI_BAR_UNMAPPED ||
-
- /* Now pcibus_t is 64bit.
- * Check if 32 bit BAR wrap around explicitly.
- * Without this, PC ide doesn't work well.
- * TODO: remove this work around.
- */
- (!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) &&
- last_addr >= UINT32_MAX) ||
-
- /*
- * OS is allowed to set BAR beyond its addressable
- * bits. For example, 32 bit OS can set 64bit bar
- * to >4G. Check it.
- */
- last_addr >= TARGET_PHYS_ADDR_MAX) {
- new_addr = PCI_BAR_UNMAPPED;
- }
- } else {
- no_mem_map:
- new_addr = PCI_BAR_UNMAPPED;
- }
- }
+ new_addr = pci_bar_address(d, i, r->type, r->size);
/* bridge filtering */
filtered_size = r->size;
@@ -986,7 +995,7 @@ static void pci_info_device(PCIBus *bus, PCIDevice *d)
base, limit);
base = pci_bridge_get_base(d, PCI_BASE_ADDRESS_SPACE_MEMORY);
- limit= pci_config_get_memory_base(d, PCI_BASE_ADDRESS_SPACE_MEMORY);
+ limit= pci_bridge_get_limit(d, PCI_BASE_ADDRESS_SPACE_MEMORY);
monitor_printf(mon,
" memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
base, limit);
@@ -1032,7 +1041,7 @@ static void pci_for_each_device_under_bus(PCIBus *bus,
PCIDevice *d;
int devfn;
- for(devfn = 0; devfn < 256; devfn++) {
+ for(devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
d = bus->devices[devfn];
if (d)
fn(bus, d);
@@ -1180,7 +1189,10 @@ PCIBus *pci_find_bus(PCIBus *bus, int bus_num)
/* try child bus */
QLIST_FOREACH(sec, &bus->child, sibling) {
- if (pci_bus_num(sec) <= bus_num && bus_num <= pci_sub_bus(sec)) {
+
+ if (!bus->parent_dev /* pci host bridge */
+ || (pci_bus_num(sec) <= bus_num &&
+ bus->parent_dev->config[PCI_SUBORDINATE_BUS])) {
return pci_find_bus(sec, bus_num);
}
}
diff --git a/hw/pci.h b/hw/pci.h
index 9a56d0df6..0baf69bd5 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -101,14 +101,6 @@ typedef struct PCIIORegion {
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus master */
-#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
-#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
-#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
-#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
-#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
-#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
-#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
-#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_REVISION_ID 0x08 /* 8 bits */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
@@ -128,7 +120,6 @@ typedef struct PCIIORegion {
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
-#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
#define PCI_IO_LIMIT 0x1d
#define PCI_IO_RANGE_TYPE_32 0x01
@@ -140,6 +131,7 @@ typedef struct PCIIORegion {
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
#define PCI_PREF_MEMORY_LIMIT 0x26
#define PCI_PREF_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_RANGE_TYPE_64 0x01
#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
#define PCI_PREF_LIMIT_UPPER32 0x2c
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c /* 16 bits */
@@ -293,11 +285,9 @@ PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
const char *default_devaddr);
PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
const char *default_devaddr);
-void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
-uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
int pci_bus_num(PCIBus *s);
void pci_for_each_device(PCIBus *bus, int bus_num, void (*fn)(PCIBus *bus, PCIDevice *d));
-PCIBus *pci_find_host_bus(int domain);
+PCIBus *pci_find_root_bus(int domain);
PCIBus *pci_find_bus(PCIBus *bus, int bus_num);
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, int slot, int function);
PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr);
@@ -384,17 +374,10 @@ typedef struct {
PCIConfigWriteFunc *config_write;
/* pci config header type */
- uint8_t header_type; /* this is necessary for initialization
- * code to know its header type before
- * device specific code can initialize
- * configuration space.
- */
+ uint8_t header_type;
/* pcie stuff */
- int is_express; /* is this device pci express?
- * initialization code needs to know this before
- * each specific device initialization.
- */
+ int is_express; /* is this device pci express? */
} PCIDeviceInfo;
void pci_qdev_register(PCIDeviceInfo *info);
@@ -413,31 +396,6 @@ static inline uint32_t pci_config_size(PCIDevice *d)
return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
}
-/* lsi53c895a.c */
-#define LSI_MAX_DEVS 7
-
-/* vmware_vga.c */
-void pci_vmsvga_init(PCIBus *bus);
-
-/* usb-uhci.c */
-void usb_uhci_piix3_init(PCIBus *bus, int devfn);
-void usb_uhci_piix4_init(PCIBus *bus, int devfn);
-
-/* usb-ohci.c */
-void usb_ohci_init_pci(struct PCIBus *bus, int devfn);
-
-/* prep_pci.c */
-PCIBus *pci_prep_init(qemu_irq *pic);
-
-/* apb_pci.c */
-PCIBus *pci_apb_init(target_phys_addr_t special_base,
- target_phys_addr_t mem_base,
- qemu_irq *pic, PCIBus **bus2, PCIBus **bus3);
-
-/* sh_pci.c */
-PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *pic, int devfn_min, int nirq);
-
/* These are not pci specific. Should move into a separate header.
* Only pci.c uses them, so keep them here for now.
*/
diff --git a/hw/pci_host.c b/hw/pci_host.c
index f4518dce7..eeb8deeaf 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -40,22 +40,18 @@ do { printf("pci_host_data: " fmt , ## __VA_ARGS__); } while (0)
*/
/* the helper functio to get a PCIDeice* for a given pci address */
-static inline PCIDevice *pci_addr_to_dev(PCIBus *bus, uint32_t addr)
+static inline PCIDevice *pci_dev_find_by_addr(PCIBus *bus, uint32_t addr)
{
- uint8_t bus_num = (addr >> 16) & 0xff;
- uint8_t devfn = (addr >> 8) & 0xff;
- return pci_find_device(bus, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-}
+ uint8_t bus_num = addr >> 16;
+ uint8_t devfn = addr >> 8;
-static inline uint32_t pci_addr_to_config(uint32_t addr)
-{
- return addr & (PCI_CONFIG_SPACE_SIZE - 1);
+ return pci_find_device(bus, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
}
void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
{
- PCIDevice *pci_dev = pci_addr_to_dev(s, addr);
- uint32_t config_addr = pci_addr_to_config(addr);
+ PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
+ uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
if (!pci_dev)
return;
@@ -67,29 +63,19 @@ void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
{
- PCIDevice *pci_dev = pci_addr_to_dev(s, addr);
- uint32_t config_addr = pci_addr_to_config(addr);
+ PCIDevice *pci_dev = pci_dev_find_by_addr(s, addr);
+ uint32_t config_addr = addr & (PCI_CONFIG_SPACE_SIZE - 1);
uint32_t val;
+ assert(len == 1 || len == 2 || len == 4);
if (!pci_dev) {
- switch(len) {
- case 1:
- val = 0xff;
- break;
- case 2:
- val = 0xffff;
- break;
- default:
- case 4:
- val = 0xffffffff;
- break;
- }
- } else {
- val = pci_dev->config_read(pci_dev, config_addr, len);
- PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
- __func__, pci_dev->name, config_addr, val, len);
+ return ~0x0;
}
+ val = pci_dev->config_read(pci_dev, config_addr, len);
+ PCI_DPRINTF("%s: %s: addr=%02"PRIx32" val=%08"PRIx32" len=%d\n",
+ __func__, pci_dev->name, config_addr, val, len);
+
return val;
}
@@ -131,7 +117,7 @@ static CPUReadMemoryFunc * const pci_host_config_read[] = {
&pci_host_config_readl,
};
-int pci_host_config_register_io_memory(PCIHostState *s)
+int pci_host_conf_register_mmio(PCIHostState *s)
{
return cpu_register_io_memory(pci_host_config_read,
pci_host_config_write, s);
@@ -171,7 +157,7 @@ static CPUReadMemoryFunc * const pci_host_config_read_noswap[] = {
&pci_host_config_readl_noswap,
};
-int pci_host_config_register_io_memory_noswap(PCIHostState *s)
+int pci_host_conf_register_mmio_noswap(PCIHostState *s)
{
return cpu_register_io_memory(pci_host_config_read_noswap,
pci_host_config_write_noswap, s);
@@ -195,7 +181,7 @@ static uint32_t pci_host_config_readl_ioport(void *opaque, uint32_t addr)
return val;
}
-void pci_host_config_register_ioport(pio_addr_t ioport, PCIHostState *s)
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
{
register_ioport_write(ioport, 4, 4, pci_host_config_writel_ioport, s);
register_ioport_read(ioport, 4, 4, pci_host_config_readl_ioport, s);
@@ -218,7 +204,7 @@ static CPUReadMemoryFunc * const pci_host_data_read_mmio[] = {
pci_host_data_readl_mmio,
};
-int pci_host_data_register_io_memory(PCIHostState *s)
+int pci_host_data_register_mmio(PCIHostState *s)
{
return cpu_register_io_memory(pci_host_data_read_mmio,
pci_host_data_write_mmio,
diff --git a/hw/pci_host.h b/hw/pci_host.h
index e5e877f4c..a006687f8 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -30,19 +30,22 @@
#include "sysbus.h"
-typedef struct {
+struct PCIHostState {
SysBusDevice busdev;
uint32_t config_reg;
PCIBus *bus;
-} PCIHostState;
+};
+
+void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
+uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
/* for mmio */
-int pci_host_config_register_io_memory(PCIHostState *s);
-int pci_host_config_register_io_memory_noswap(PCIHostState *s);
-int pci_host_data_register_io_memory(PCIHostState *s);
+int pci_host_conf_register_mmio(PCIHostState *s);
+int pci_host_conf_register_mmio_noswap(PCIHostState *s);
+int pci_host_data_register_mmio(PCIHostState *s);
/* for ioio */
-void pci_host_config_register_ioport(pio_addr_t ioport, PCIHostState *s);
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s);
void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s);
#endif /* PCI_HOST_H */
diff --git a/hw/pcie_host.c b/hw/pcie_host.c
index b52fec681..fbd6c3759 100644
--- a/hw/pcie_host.c
+++ b/hw/pcie_host.c
@@ -46,7 +46,8 @@
/* a helper function to get a PCIDevice for a given mmconfig address */
-static inline PCIDevice *pcie_mmcfg_addr_to_dev(PCIBus *s, uint32_t mmcfg_addr)
+static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s,
+ uint32_t mmcfg_addr)
{
return pci_find_device(s, PCIE_MMCFG_BUS(mmcfg_addr),
PCI_SLOT(PCIE_MMCFG_DEVFN(mmcfg_addr)),
@@ -56,7 +57,7 @@ static inline PCIDevice *pcie_mmcfg_addr_to_dev(PCIBus *s, uint32_t mmcfg_addr)
static void pcie_mmcfg_data_write(PCIBus *s,
uint32_t mmcfg_addr, uint32_t val, int len)
{
- PCIDevice *pci_dev = pcie_mmcfg_addr_to_dev(s, mmcfg_addr);
+ PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
if (!pci_dev)
return;
@@ -65,31 +66,15 @@ static void pcie_mmcfg_data_write(PCIBus *s,
PCIE_MMCFG_CONFOFFSET(mmcfg_addr), val, len);
}
-static uint32_t pcie_mmcfg_data_read(PCIBus *s,
- uint32_t mmcfg_addr, int len)
+static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t addr, int len)
{
- PCIDevice *pci_dev = pcie_mmcfg_addr_to_dev(s, mmcfg_addr);
- uint32_t val;
+ PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, addr);
+ assert(len == 1 || len == 2 || len == 4);
if (!pci_dev) {
- switch(len) {
- case 1:
- val = 0xff;
- break;
- case 2:
- val = 0xffff;
- break;
- default:
- case 4:
- val = 0xffffffff;
- break;
- }
- } else {
- val = pci_dev->config_read(pci_dev,
- PCIE_MMCFG_CONFOFFSET(mmcfg_addr), len);
+ return ~0x0;
}
-
- return val;
+ return pci_dev->config_read(pci_dev, PCIE_MMCFG_CONFOFFSET(addr), len);
}
static void pcie_mmcfg_data_writeb(void *opaque,
diff --git a/hw/pcie_host.h b/hw/pcie_host.h
index a7771c912..7754ac94e 100644
--- a/hw/pcie_host.h
+++ b/hw/pcie_host.h
@@ -24,7 +24,7 @@
#include "pci_host.h"
-typedef struct {
+struct PCIExpressHost {
PCIHostState pci;
/* express part */
@@ -37,7 +37,7 @@ typedef struct {
/* result of cpu_register_io_memory() to map MMCONFIG area */
int mmio_index;
-} PCIExpressHost;
+};
int pcie_host_init(PCIExpressHost *e);
void pcie_host_mmcfg_unmap(PCIExpressHost *e);
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 5fb7d7be9..a44f941dc 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -180,7 +180,7 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev)
{
I440FXState *s = FROM_SYSBUS(I440FXState, dev);
- pci_host_config_register_ioport(0xcf8, s);
+ pci_host_conf_register_ioport(0xcf8, s);
pci_host_data_register_ioport(0xcfc, s);
return 0;
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 3aa7489e2..2d00b6122 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -378,7 +378,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index);
/* CFGDATA */
- index = pci_host_data_register_io_memory(&controller->pci_state);
+ index = pci_host_data_register_mmio(&controller->pci_state);
if (index < 0)
goto free;
cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index da868d302..7579ddd34 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -29,6 +29,7 @@
#include "nvram.h"
#include "pc.h"
#include "pci.h"
+#include "usb-ohci.h"
#include "net.h"
#include "sysemu.h"
#include "boards.h"
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 9b49a3dbd..32fd03a90 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -32,6 +32,7 @@
#include "net.h"
#include "isa.h"
#include "pci.h"
+#include "usb-ohci.h"
#include "boards.h"
#include "fw_cfg.h"
#include "escc.h"
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index cd561e10c..eb758f2da 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -29,6 +29,8 @@
#include "sysemu.h"
#include "isa.h"
#include "pci.h"
+#include "prep_pci.h"
+#include "usb-ohci.h"
#include "ppc.h"
#include "boards.h"
#include "qemu-log.h"
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 223de3ae3..a72fb86d2 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -293,13 +293,13 @@ PCIBus *ppce500_pci_init(qemu_irq pci_irqs[4], target_phys_addr_t registers)
controller->pci_dev = d;
/* CFGADDR */
- index = pci_host_config_register_io_memory_noswap(&controller->pci_state);
+ index = pci_host_conf_register_mmio_noswap(&controller->pci_state);
if (index < 0)
goto free;
cpu_register_physical_memory(registers + PCIE500_CFGADDR, 4, index);
/* CFGDATA */
- index = pci_host_data_register_io_memory(&controller->pci_state);
+ index = pci_host_data_register_mmio(&controller->pci_state);
if (index < 0)
goto free;
cpu_register_physical_memory(registers + PCIE500_CFGDATA, 4, index);
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index a338f81e1..19f028c7b 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -25,6 +25,7 @@
#include "hw.h"
#include "pci.h"
#include "pci_host.h"
+#include "prep_pci.h"
typedef PCIHostState PREPPCIState;
@@ -127,7 +128,7 @@ PCIBus *pci_prep_init(qemu_irq *pic)
s->bus = pci_register_bus(NULL, "pci",
prep_set_irq, prep_map_irq, pic, 0, 4);
- pci_host_config_register_ioport(0xcf8, s);
+ pci_host_conf_register_ioport(0xcf8, s);
pci_host_data_register_ioport(0xcfc, s);
diff --git a/hw/prep_pci.h b/hw/prep_pci.h
new file mode 100644
index 000000000..cd6851288
--- /dev/null
+++ b/hw/prep_pci.h
@@ -0,0 +1,8 @@
+#ifndef QEMU_PREP_PCI_H
+#define QEMU_PREP_PCI_H
+
+#include "qemu-common.h"
+
+PCIBus *pci_prep_init(qemu_irq *pic);
+
+#endif
diff --git a/hw/r2d.c b/hw/r2d.c
index c074a6e9c..e4c02f05e 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -29,6 +29,7 @@
#include "sysemu.h"
#include "boards.h"
#include "pci.h"
+#include "sh_pci.h"
#include "net.h"
#include "sh7750_regs.h"
#include "ide.h"
diff --git a/hw/realview.c b/hw/realview.c
index f0b834734..3322c4fd5 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -12,6 +12,7 @@
#include "primecell.h"
#include "devices.h"
#include "pci.h"
+#include "usb-ohci.h"
#include "net.h"
#include "sysemu.h"
#include "boards.h"
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 4277b01c9..abe4c7568 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -24,6 +24,8 @@
#include "hw.h"
#include "sh.h"
#include "pci.h"
+#include "pci_host.h"
+#include "sh_pci.h"
#include "bswap.h"
typedef struct {
diff --git a/hw/sh_pci.h b/hw/sh_pci.h
new file mode 100644
index 000000000..b1a5ec37c
--- /dev/null
+++ b/hw/sh_pci.h
@@ -0,0 +1,9 @@
+#ifndef QEMU_SH_PCI_H
+#define QEMU_SH_PCI_H
+
+#include "qemu-common.h"
+
+PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
+ void *pic, int devfn_min, int nirq);
+
+#endif
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 2189fa06a..a7a227bbe 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -23,6 +23,7 @@
*/
#include "hw.h"
#include "pci.h"
+#include "apb_pci.h"
#include "pc.h"
#include "nvram.h"
#include "fdc.h"
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index fe13e7b3e..5b3f118fc 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -84,8 +84,8 @@ static int pci_unin_main_init_device(SysBusDevice *dev)
/* Uninorth main bus */
s = FROM_SYSBUS(UNINState, dev);
- pci_mem_config = pci_host_config_register_io_memory(&s->host_state);
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
@@ -103,8 +103,8 @@ static int pci_dec_21154_init_device(SysBusDevice *dev)
s = FROM_SYSBUS(UNINState, dev);
// XXX: s = &pci_bridge[2];
- pci_mem_config = pci_host_config_register_io_memory_noswap(&s->host_state);
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio_noswap(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
return 0;
@@ -118,8 +118,8 @@ static int pci_unin_agp_init_device(SysBusDevice *dev)
/* Uninorth AGP bus */
s = FROM_SYSBUS(UNINState, dev);
- pci_mem_config = pci_host_config_register_io_memory_noswap(&s->host_state);
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio_noswap(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
return 0;
@@ -133,8 +133,8 @@ static int pci_unin_internal_init_device(SysBusDevice *dev)
/* Uninorth internal bus */
s = FROM_SYSBUS(UNINState, dev);
- pci_mem_config = pci_host_config_register_io_memory_noswap(&s->host_state);
- pci_mem_data = pci_host_data_register_io_memory(&s->host_state);
+ pci_mem_config = pci_host_conf_register_mmio_noswap(&s->host_state);
+ pci_mem_data = pci_host_data_register_mmio(&s->host_state);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
return 0;
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 0f7f4de15..7ab3a9861 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -32,6 +32,7 @@
#include "pci.h"
#include "pxa.h"
#include "devices.h"
+#include "usb-ohci.h"
//#define DEBUG_OHCI
/* Dump packet contents. */
diff --git a/hw/usb-ohci.h b/hw/usb-ohci.h
new file mode 100644
index 000000000..eefcef360
--- /dev/null
+++ b/hw/usb-ohci.h
@@ -0,0 +1,9 @@
+#ifndef QEMU_USB_OHCI_H
+#define QEMU_USB_OHCI_H
+
+#include "qemu-common.h"
+
+void usb_ohci_init_pci(struct PCIBus *bus, int devfn);
+
+#endif
+
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 8babb0265..671916e05 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -29,6 +29,7 @@
#include "usb.h"
#include "pci.h"
#include "qemu-timer.h"
+#include "usb-uhci.h"
//#define DEBUG
//#define DEBUG_DUMP_DATA
diff --git a/hw/usb-uhci.h b/hw/usb-uhci.h
new file mode 100644
index 000000000..911948edb
--- /dev/null
+++ b/hw/usb-uhci.h
@@ -0,0 +1,9 @@
+#ifndef QEMU_USB_UHCI_H
+#define QEMU_USB_UHCI_H
+
+#include "qemu-common.h"
+
+void usb_uhci_piix3_init(PCIBus *bus, int devfn);
+void usb_uhci_piix4_init(PCIBus *bus, int devfn);
+
+#endif
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index a0d7d07ad..153c6514f 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -9,6 +9,7 @@
#include "sysbus.h"
#include "pci.h"
+#include "pci_host.h"
typedef struct {
SysBusDevice busdev;
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 226c616ee..391f5b88c 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -14,6 +14,7 @@
#include "net.h"
#include "sysemu.h"
#include "pci.h"
+#include "usb-ohci.h"
#include "boards.h"
/* Primary interrupt controller. */
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index aebcf9d0d..d222ce03f 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -185,8 +185,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break;
case VIRTIO_PCI_QUEUE_PFN:
pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
- if (pa == 0)
- virtio_pci_reset(&proxy->pci_dev.qdev);
+ if (pa == 0) {
+ virtio_reset(proxy->vdev);
+ msix_unuse_all_vectors(&proxy->pci_dev);
+ }
else
virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
break;
@@ -199,8 +201,10 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
break;
case VIRTIO_PCI_STATUS:
vdev->status = val & 0xFF;
- if (vdev->status == 0)
- virtio_pci_reset(&proxy->pci_dev.qdev);
+ if (vdev->status == 0) {
+ virtio_reset(proxy->vdev);
+ msix_unuse_all_vectors(&proxy->pci_dev);
+ }
break;
case VIRTIO_MSI_CONFIG_VECTOR:
msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 33e876e95..bb3410105 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -24,6 +24,7 @@
#include "hw.h"
#include "console.h"
#include "pci.h"
+#include "vmware_vga.h"
#define VERBOSE
#undef DIRECT_VRAM
diff --git a/hw/vmware_vga.h b/hw/vmware_vga.h
new file mode 100644
index 000000000..2e0813c81
--- /dev/null
+++ b/hw/vmware_vga.h
@@ -0,0 +1,9 @@
+#ifndef QEMU_VMWARE_VGA_H
+#define QEMU_VMWARE_VGA_H
+
+#include "qemu-common.h"
+
+/* vmware_vga.c */
+void pci_vmsvga_init(PCIBus *bus);
+
+#endif
diff --git a/qemu-common.h b/qemu-common.h
index b1e038bd0..57af677f0 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -198,6 +198,8 @@ typedef struct i2c_bus i2c_bus;
typedef struct i2c_slave i2c_slave;
typedef struct SMBusDevice SMBusDevice;
typedef struct QEMUTimer QEMUTimer;
+typedef struct PCIHostState PCIHostState;
+typedef struct PCIExpressHost PCIExpressHost;
typedef struct PCIBus PCIBus;
typedef struct PCIDevice PCIDevice;
typedef struct SerialState SerialState;