Patchwork [1/2] pci: set PCI multi-function bit appropriately.

login
register
mail settings
Submitter Isaku Yamahata
Date June 15, 2010, 5:06 a.m.
Message ID <8bca8f93effb9f689294f090d09625478a2c0dd9.1276573899.git.yamahata@valinux.co.jp>
Download mbox | patch
Permalink /patch/55605/
State New
Headers show

Comments

Isaku Yamahata - June 15, 2010, 5:06 a.m.
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(-)

Patch

diff --git a/hw/pci.c b/hw/pci.c
index 3777c1c..a01e9ac 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -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;