> Date: Mon, 2 Mar 2020 13:56:11 +0100
> From: Patrick Wildt <patr...@blueri.se>
> 
> 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?

ok kettenis@

> 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