That's quite a hack you wrote, but I think any nicer way of doing it is going to require a big rewrite..
Patrick Wildt <patr...@blueri.se> wrote: > 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 >