From patchwork Thu Jun 17 06:15:51 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [09/10] pci: set PCI multi-function bit appropriately. Date: Wed, 16 Jun 2010 20:15:51 -0000 From: Isaku Yamahata X-Patchwork-Id: 55973 Message-Id: <81d134b49ddbd54e82648618c0ce4e4d11fb77c3.1276755023.git.yamahata@valinux.co.jp> To: qemu-devel@nongnu.org Cc: jan.kiszka@siemens.com, mst@redhat.com, allen.m.kay@intel.com, blauwirbel@gmail.com, yamahata@valinux.co.jp, kraxel@redhat.com, stefano.stabellini@eu.citrix.com, jean.guyader@gmail.com set PCI multi-function bit appropriately. Signed-off-by: Isaku Yamahata --- changes v1 -> v2: don't set header type register in configuration space. --- hw/pci.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 5316aa5..ee391dc 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -607,6 +607,30 @@ static void pci_init_wmask_bridge(PCIDevice *d) pci_set_word(d->wmask + PCI_BRIDGE_CONTROL, 0xffff); } +static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev) +{ + uint8_t slot = PCI_SLOT(dev->devfn); + uint8_t func_max = 8; + uint8_t func; + + 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); @@ -660,6 +684,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, if (is_bridge) { pci_init_wmask_bridge(pci_dev); } + pci_init_multifunction(bus, pci_dev); if (!config_read) config_read = pci_default_read_config;