@@ -578,6 +578,33 @@ static void pci_init_wmask_bridge(PCIDevice *d)
pci_set_word(d->wmask + PCI_BRIDGE_CONTROL, 0xffff);
}
+static void pci_init_header_type(PCIBus *bus, PCIDevice *dev,
+ uint8_t devfn, uint8_t header_type)
+{
+ uint8_t slot = PCI_SLOT(devfn);
+ uint8_t func_max = 8;
+ uint8_t func;
+
+ dev->config[PCI_HEADER_TYPE] = header_type;
+
+ for (func = 0; func < func_max; ++func) {
+ if (bus->devices[PCI_DEVFN(slot, func)]) {
+ break;
+ }
+ }
+ if (func == func_max) {
+ return;
+ }
+
+ for (func = 0; func < func_max; ++func) {
+ if (bus->devices[PCI_DEVFN(slot, func)]) {
+ bus->devices[PCI_DEVFN(slot, func)]->config[PCI_HEADER_TYPE] |=
+ PCI_HEADER_TYPE_MULTI_FUNCTION;
+ }
+ }
+ dev->config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;
+}
+
static void pci_config_alloc(PCIDevice *pci_dev)
{
int config_size = pci_config_size(pci_dev);
@@ -632,6 +659,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
if (header_type == PCI_HEADER_TYPE_BRIDGE) {
pci_init_wmask_bridge(pci_dev);
}
+ pci_init_header_type(bus, pci_dev, devfn, header_type);
if (!config_read)
config_read = pci_default_read_config;
set PCI multi-function bit appropriately. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- hw/pci.c | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-)