Just committed the patch below which should fix this.

Index: i386/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/pci/pci_machdep.c,v
retrieving revision 1.56
diff -u -p -r1.56 pci_machdep.c
--- i386/pci/pci_machdep.c      4 Jan 2011 21:17:49 -0000       1.56
+++ i386/pci/pci_machdep.c      9 Jan 2011 11:10:28 -0000
@@ -126,6 +126,7 @@ bus_addr_t pci_mcfg_addr;
 int pci_mcfg_min_bus, pci_mcfg_max_bus;
 bus_space_tag_t pci_mcfgt = I386_BUS_SPACE_MEM;
 bus_space_handle_t pci_mcfgh[256];
+void pci_mcfg_map_bus(int);
 
 struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
 
@@ -224,15 +225,6 @@ pci_make_tag(pci_chipset_tag_t pc, int b
 {
        pcitag_t tag;
 
-       if (pci_mcfg_addr) {
-               if (bus < pci_mcfg_min_bus  || bus > pci_mcfg_max_bus ||
-                   device >= 32 || function >= 8)
-                       panic("pci_make_tag: bad request");
-
-               tag.mode1 = (bus << 20) | (device << 15) | (function << 12);
-               return tag;
-       }
-
        switch (pci_mode) {
        case 1:
                if (bus >= 256 || device >= 32 || function >= 8)
@@ -259,16 +251,6 @@ pci_make_tag(pci_chipset_tag_t pc, int b
 void
 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int 
*fp)
 {
-       if (pci_mcfg_addr) {
-               if (bp != NULL)
-                       *bp = (tag.mode1 >> 20) & 0xff;
-               if (dp != NULL)
-                       *dp = (tag.mode1 >> 15) & 0x1f;
-               if (fp != NULL)
-                       *fp = (tag.mode1 >> 12) & 0x7;
-               return;
-       }
-
        switch (pci_mode) {
        case 1:
                if (bp != NULL)
@@ -294,12 +276,28 @@ pci_decompose_tag(pci_chipset_tag_t pc, 
 int
 pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag)
 {
-       if (pci_mcfg_addr)
-               return PCIE_CONFIG_SPACE_SIZE;
+       int bus;
+
+       if (pci_mcfg_addr) {
+               pci_decompose_tag(pc, tag, &bus, NULL, NULL);
+               if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus)
+                       return PCIE_CONFIG_SPACE_SIZE;
+       }
 
        return PCI_CONFIG_SPACE_SIZE;
 }
 
+void
+pci_mcfg_map_bus(int bus)
+{
+       if (pci_mcfgh[bus])
+               return;
+
+       if (bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20), 1 << 20,
+           0, &pci_mcfgh[bus]))
+               panic("pci_conf_read: cannot map mcfg space");
+}
+
 pcireg_t
 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
 {
@@ -308,13 +306,12 @@ pci_conf_read(pci_chipset_tag_t pc, pcit
 
        if (pci_mcfg_addr) {
                pci_decompose_tag(pc, tag, &bus, NULL, NULL);
-               if (pci_mcfgh[bus] == 0 &&
-                   bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20),
-                   1 << 20, 0, &pci_mcfgh[bus]))
-                       panic("pci_conf_read: cannot map mcfg space");
-               data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
-                   (tag.mode1 & 0x000ff000) | reg);
-               return data;
+               if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
+                       pci_mcfg_map_bus(bus);
+                       data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
+                           (tag.mode1 & 0x000ff00) << 4 | reg);
+                       return data;
+               }
        }
 
        PCI_CONF_LOCK();
@@ -345,13 +342,12 @@ pci_conf_write(pci_chipset_tag_t pc, pci
 
        if (pci_mcfg_addr) {
                pci_decompose_tag(pc, tag, &bus, NULL, NULL);
-               if (pci_mcfgh[bus] == 0 &&
-                   bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20),
-                   1 << 20, 0, &pci_mcfgh[bus]))
-                       panic("pci_conf_write: cannot map mcfg space");
-               bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
-                   (tag.mode1 & 0x000ff000) | reg, data);
-               return;
+               if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
+                       pci_mcfg_map_bus(bus);
+                       bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
+                           (tag.mode1 & 0x000ff00) << 4 | reg, data);
+                       return;
+               }
        }
 
        PCI_CONF_LOCK();
Index: amd64/pci/pci_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/pci/pci_machdep.c,v
retrieving revision 1.38
diff -u -p -r1.38 pci_machdep.c
--- amd64/pci/pci_machdep.c     4 Jan 2011 21:17:49 -0000       1.38
+++ amd64/pci/pci_machdep.c     9 Jan 2011 11:10:28 -0000
@@ -108,6 +108,7 @@ bus_addr_t pci_mcfg_addr;
 int pci_mcfg_min_bus, pci_mcfg_max_bus;
 bus_space_tag_t pci_mcfgt = X86_BUS_SPACE_MEM;
 bus_space_handle_t pci_mcfgh[256];
+void pci_mcfg_map_bus(int);
 
 struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
 
@@ -170,14 +171,6 @@ pci_make_tag(pci_chipset_tag_t pc, int b
        if (bus >= 256 || device >= 32 || function >= 8)
                panic("pci_make_tag: bad request");
 
-       if (pci_mcfg_addr) {
-               if (bus < pci_mcfg_min_bus  || bus > pci_mcfg_max_bus ||
-                   device >= 32 || function >= 8)
-                       panic("pci_make_tag: bad request");
-
-               return (bus << 20) | (device << 15) | (function << 12);
-       }
-
        return (PCI_MODE1_ENABLE |
            (bus << 16) | (device << 11) | (function << 8));
 }
@@ -185,16 +178,6 @@ pci_make_tag(pci_chipset_tag_t pc, int b
 void
 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int 
*fp)
 {
-       if (pci_mcfg_addr) {
-               if (bp != NULL)
-                       *bp = (tag >> 20) & 0xff;
-               if (dp != NULL)
-                       *dp = (tag >> 15) & 0x1f;
-               if (fp != NULL)
-                       *fp = (tag >> 12) & 0x7;
-               return;
-       }
-
        if (bp != NULL)
                *bp = (tag >> 16) & 0xff;
        if (dp != NULL)
@@ -206,12 +189,28 @@ pci_decompose_tag(pci_chipset_tag_t pc, 
 int
 pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag)
 {
-       if (pci_mcfg_addr)
-               return PCIE_CONFIG_SPACE_SIZE;
+       int bus;
+
+       if (pci_mcfg_addr) {
+               pci_decompose_tag(pc, tag, &bus, NULL, NULL);
+               if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus)
+                       return PCIE_CONFIG_SPACE_SIZE;
+       }
 
        return PCI_CONFIG_SPACE_SIZE;
 }
 
+void
+pci_mcfg_map_bus(int bus)
+{
+       if (pci_mcfgh[bus])
+               return;
+
+       if (bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20), 1 << 20,
+           0, &pci_mcfgh[bus]))
+               panic("pci_conf_read: cannot map mcfg space");
+}
+
 pcireg_t
 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
 {
@@ -220,12 +219,12 @@ pci_conf_read(pci_chipset_tag_t pc, pcit
 
        if (pci_mcfg_addr) {
                pci_decompose_tag(pc, tag, &bus, NULL, NULL);
-               if (pci_mcfgh[bus] == 0 &&
-                   bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20),
-                   1 << 20, 0, &pci_mcfgh[bus]))
-                       panic("pci_conf_read: cannot map mcfg space");
-               return  bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
-                   (tag & 0x000ff000) | reg);
+               if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
+                       pci_mcfg_map_bus(bus);
+                       data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
+                           (tag & 0x000ff00) << 4 | reg);
+                       return data;
+               }
        }
 
        PCI_CONF_LOCK();
@@ -244,13 +243,12 @@ pci_conf_write(pci_chipset_tag_t pc, pci
 
        if (pci_mcfg_addr) {
                pci_decompose_tag(pc, tag, &bus, NULL, NULL);
-               if (pci_mcfgh[bus] == 0 &&
-                   bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20),
-                   1 << 20, 0, &pci_mcfgh[bus]))
-                       panic("pci_conf_write: cannot map mcfg space");
-               bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
-                   (tag & 0x000ff000) | reg, data);
-               return;
+               if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
+                       pci_mcfg_map_bus(bus);
+                       bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
+                           (tag & 0x000ff00) << 4 | reg, data);
+                       return;
+               }
        }
 
        PCI_CONF_LOCK();

Reply via email to