Hi,

as it turns out, puc(4) has trouble with 64-bit BARs.  The issue is that
puc(4) tries to map every BAR before doing anything else.  While iter-
ating over the BARs it assumes the next BAR is always 4 bytes after the
other.  For 64-bit BARs that's wrong.  On a device with a 64-bit BAR, it
will map the BAR correctly, and then using the 0x4 offset try to map an-
other BAR, thus breaking the previously correctly mapped bar.

Now I'm not sure this is the best fix, but I think the easiest way is to
just skip that particular entry.  Thus, with two 64-bit BARs, sc->sc_bar
mappings[1] and [3] will be empty.  That's fine since the pucdata.c
entries reference the absolute BAR address, like 0x10 and 0x18, and the
mapping to the index of the array is done using that absolute value:

    #define PUC_PORT_BAR_INDEX(bar) (((bar) - PCI_MAPREG_START) / 4)

    bar = PUC_PORT_BAR_INDEX(desc->ports[i].bar);
    if (!sc->sc_bar_mappings[bar].mapped) {
        ...

Feedback?

Patrick

diff --git a/sys/dev/pci/puc.c b/sys/dev/pci/puc.c
index 2c5f3065177..7ec25ecaad2 100644
--- a/sys/dev/pci/puc.c
+++ b/sys/dev/pci/puc.c
@@ -163,8 +163,11 @@ puc_pci_attach(struct device *parent, struct device *self, 
void *aux)
                    0, &sc->sc_bar_mappings[i].t, &sc->sc_bar_mappings[i].h,
                    &sc->sc_bar_mappings[i].a, &sc->sc_bar_mappings[i].s, 0)
                      == 0);
-               if (sc->sc_bar_mappings[i].mapped)
+               if (sc->sc_bar_mappings[i].mapped) {
+                       if (type == PCI_MAPREG_MEM_TYPE_64BIT)
+                               i++;
                        continue;
+               }
 
 #if NCOM > 0
                /*
@@ -184,6 +187,8 @@ puc_pci_attach(struct device *parent, struct device *self, 
void *aux)
                        sc->sc_bar_mappings[i].h = comconsioh;
                        sc->sc_bar_mappings[i].s = COM_NPORTS;
                        sc->sc_bar_mappings[i].mapped = 1;
+                       if (type == PCI_MAPREG_MEM_TYPE_64BIT)
+                               i++;
                        continue;
                }
 #endif

Reply via email to