Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-06 Thread Arnd Bergmann
On Tuesday, September 6, 2016 7:49:49 PM CEST Tomasz Nowicki wrote:
> On 05.09.2016 04:25, Bjorn Helgaas wrote:
> > On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:
> >> Some platforms may not be fully compliant with generic set of PCI config
> >> accessors. For these cases we implement the way to overwrite accessors
> >> set. Algorithm traverses available quirk list (static array),
> >> matches against  and
> >> returns pci_config_window structure with fancy PCI config ops.
> >> oem_id, oem_table_id and rev come from MCFG table standard header.
> >>
> >> It is possible to define custom init call which is responsible for
> >> setting up PCI configuration access accordingly to quirk requirements.
> >> If custom init call is not defined, use standard 
> >> pci_acpi_setup_ecam_mapping().
> >>
> >> pci_generic_ecam_ops will be used for platforms free from quirks.
> >>
> >> Signed-off-by: Tomasz Nowicki 
> >> Signed-off-by: Dongdong Liu 
> >> Signed-off-by: Christopher Covington 
> >> ---
> >>  drivers/pci/host/Makefile  |  1 +
> >>  drivers/pci/host/mcfg-quirks.c | 86 
> >> ++
> >>  drivers/pci/host/mcfg-quirks.h | 20 ++
> >>  include/linux/pci-acpi.h   |  2 +
> >>  4 files changed, 109 insertions(+)
> >>  create mode 100644 drivers/pci/host/mcfg-quirks.c
> >>  create mode 100644 drivers/pci/host/mcfg-quirks.h
> >
> > If the object is to work around defects in the ACPI MCFG table, I
> > think I'd put the quirks closer to drivers/acpi/pci_mcfg.c, where we
> > parse that table.  What if we actually put them directly *in*
> > drivers/acpi/pci_mcfg.c?
> 
> Then we need to export quirk init calls or ecam ops from 
> drivers/pci/host/* directory.
> 
> Currently we keep mcfg quirk handling code and related drivers in one 
> place drivers/pci/host/

I think that's the wrong place to have it, it just leads to people
trying to share code with the host drivers in that directory, which
hasn't really worked out so far, it just adds complexity.

Arnd


Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-06 Thread Arnd Bergmann
On Tuesday, September 6, 2016 7:49:49 PM CEST Tomasz Nowicki wrote:
> On 05.09.2016 04:25, Bjorn Helgaas wrote:
> > On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:
> >> Some platforms may not be fully compliant with generic set of PCI config
> >> accessors. For these cases we implement the way to overwrite accessors
> >> set. Algorithm traverses available quirk list (static array),
> >> matches against  and
> >> returns pci_config_window structure with fancy PCI config ops.
> >> oem_id, oem_table_id and rev come from MCFG table standard header.
> >>
> >> It is possible to define custom init call which is responsible for
> >> setting up PCI configuration access accordingly to quirk requirements.
> >> If custom init call is not defined, use standard 
> >> pci_acpi_setup_ecam_mapping().
> >>
> >> pci_generic_ecam_ops will be used for platforms free from quirks.
> >>
> >> Signed-off-by: Tomasz Nowicki 
> >> Signed-off-by: Dongdong Liu 
> >> Signed-off-by: Christopher Covington 
> >> ---
> >>  drivers/pci/host/Makefile  |  1 +
> >>  drivers/pci/host/mcfg-quirks.c | 86 
> >> ++
> >>  drivers/pci/host/mcfg-quirks.h | 20 ++
> >>  include/linux/pci-acpi.h   |  2 +
> >>  4 files changed, 109 insertions(+)
> >>  create mode 100644 drivers/pci/host/mcfg-quirks.c
> >>  create mode 100644 drivers/pci/host/mcfg-quirks.h
> >
> > If the object is to work around defects in the ACPI MCFG table, I
> > think I'd put the quirks closer to drivers/acpi/pci_mcfg.c, where we
> > parse that table.  What if we actually put them directly *in*
> > drivers/acpi/pci_mcfg.c?
> 
> Then we need to export quirk init calls or ecam ops from 
> drivers/pci/host/* directory.
> 
> Currently we keep mcfg quirk handling code and related drivers in one 
> place drivers/pci/host/

I think that's the wrong place to have it, it just leads to people
trying to share code with the host drivers in that directory, which
hasn't really worked out so far, it just adds complexity.

Arnd


Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-06 Thread Tomasz Nowicki

On 05.09.2016 04:25, Bjorn Helgaas wrote:

On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:

Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set. Algorithm traverses available quirk list (static array),
matches against  and
returns pci_config_window structure with fancy PCI config ops.
oem_id, oem_table_id and rev come from MCFG table standard header.

It is possible to define custom init call which is responsible for
setting up PCI configuration access accordingly to quirk requirements.
If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping().

pci_generic_ecam_ops will be used for platforms free from quirks.

Signed-off-by: Tomasz Nowicki 
Signed-off-by: Dongdong Liu 
Signed-off-by: Christopher Covington 
---
 drivers/pci/host/Makefile  |  1 +
 drivers/pci/host/mcfg-quirks.c | 86 ++
 drivers/pci/host/mcfg-quirks.h | 20 ++
 include/linux/pci-acpi.h   |  2 +
 4 files changed, 109 insertions(+)
 create mode 100644 drivers/pci/host/mcfg-quirks.c
 create mode 100644 drivers/pci/host/mcfg-quirks.h


If the object is to work around defects in the ACPI MCFG table, I
think I'd put the quirks closer to drivers/acpi/pci_mcfg.c, where we
parse that table.  What if we actually put them directly *in*
drivers/acpi/pci_mcfg.c?


Then we need to export quirk init calls or ecam ops from 
drivers/pci/host/* directory.


Currently we keep mcfg quirk handling code and related drivers in one 
place drivers/pci/host/


Tomasz


Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-06 Thread Tomasz Nowicki

On 05.09.2016 04:25, Bjorn Helgaas wrote:

On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:

Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set. Algorithm traverses available quirk list (static array),
matches against  and
returns pci_config_window structure with fancy PCI config ops.
oem_id, oem_table_id and rev come from MCFG table standard header.

It is possible to define custom init call which is responsible for
setting up PCI configuration access accordingly to quirk requirements.
If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping().

pci_generic_ecam_ops will be used for platforms free from quirks.

Signed-off-by: Tomasz Nowicki 
Signed-off-by: Dongdong Liu 
Signed-off-by: Christopher Covington 
---
 drivers/pci/host/Makefile  |  1 +
 drivers/pci/host/mcfg-quirks.c | 86 ++
 drivers/pci/host/mcfg-quirks.h | 20 ++
 include/linux/pci-acpi.h   |  2 +
 4 files changed, 109 insertions(+)
 create mode 100644 drivers/pci/host/mcfg-quirks.c
 create mode 100644 drivers/pci/host/mcfg-quirks.h


If the object is to work around defects in the ACPI MCFG table, I
think I'd put the quirks closer to drivers/acpi/pci_mcfg.c, where we
parse that table.  What if we actually put them directly *in*
drivers/acpi/pci_mcfg.c?


Then we need to export quirk init calls or ecam ops from 
drivers/pci/host/* directory.


Currently we keep mcfg quirk handling code and related drivers in one 
place drivers/pci/host/


Tomasz


Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-04 Thread Bjorn Helgaas
On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set. Algorithm traverses available quirk list (static array),
> matches against  and
> returns pci_config_window structure with fancy PCI config ops.
> oem_id, oem_table_id and rev come from MCFG table standard header.
> 
> It is possible to define custom init call which is responsible for
> setting up PCI configuration access accordingly to quirk requirements.
> If custom init call is not defined, use standard 
> pci_acpi_setup_ecam_mapping().
> 
> pci_generic_ecam_ops will be used for platforms free from quirks.
> 
> Signed-off-by: Tomasz Nowicki 
> Signed-off-by: Dongdong Liu 
> Signed-off-by: Christopher Covington 
> ---
>  drivers/pci/host/Makefile  |  1 +
>  drivers/pci/host/mcfg-quirks.c | 86 
> ++
>  drivers/pci/host/mcfg-quirks.h | 20 ++
>  include/linux/pci-acpi.h   |  2 +
>  4 files changed, 109 insertions(+)
>  create mode 100644 drivers/pci/host/mcfg-quirks.c
>  create mode 100644 drivers/pci/host/mcfg-quirks.h
> 
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 8843410..500cf78 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
>  obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
> diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
> new file mode 100644
> index 000..aa9907b
> --- /dev/null
> +++ b/drivers/pci/host/mcfg-quirks.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2016 Semihalf
> + *   Author: Tomasz Nowicki 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation (the "GPL").
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 (GPLv2) for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 (GPLv2) along with this source code.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mcfg-quirks.h"
> +
> +struct pci_cfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + struct resource domain_range;
> + struct resource bus_range;
> + struct pci_ops *ops;
> + struct pci_config_window *(*init)(struct acpi_pci_root *root,
> +   struct pci_ops *ops);
> +};
> +
> +#define MCFG_DOM_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1), NULL, 0)
> +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0x)
> +#define MCFG_BUS_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1),  \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +
> +static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
> +/*   { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
> +};
> +
> +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
> +  struct acpi_table_header *mcfg_header)
> +{
> + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_header->oem_revision);
> +}
> +
> +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
> +{
> + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
> + struct resource *bus_res = >secondary;
> + struct pci_cfg_fixup *f = mcfg_quirks;
> + struct acpi_table_header *mcfg_header;
> + acpi_status status;
> + int i;
> +
> + status = acpi_get_table(ACPI_SIG_MCFG, 0, _header);
> + if (ACPI_FAILURE(status))
> + return NULL;

I remember working out why pci_mcfg_parse() has to cache the data from
MCFG, but I don't remember the actual reason...  a comment there would
have been helpful.  Anyway, now I wonder why it's OK to call
acpi_get_table(ACPI_SIG_MCFG) again here.  I 

Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-04 Thread Bjorn Helgaas
On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set. Algorithm traverses available quirk list (static array),
> matches against  and
> returns pci_config_window structure with fancy PCI config ops.
> oem_id, oem_table_id and rev come from MCFG table standard header.
> 
> It is possible to define custom init call which is responsible for
> setting up PCI configuration access accordingly to quirk requirements.
> If custom init call is not defined, use standard 
> pci_acpi_setup_ecam_mapping().
> 
> pci_generic_ecam_ops will be used for platforms free from quirks.
> 
> Signed-off-by: Tomasz Nowicki 
> Signed-off-by: Dongdong Liu 
> Signed-off-by: Christopher Covington 
> ---
>  drivers/pci/host/Makefile  |  1 +
>  drivers/pci/host/mcfg-quirks.c | 86 
> ++
>  drivers/pci/host/mcfg-quirks.h | 20 ++
>  include/linux/pci-acpi.h   |  2 +
>  4 files changed, 109 insertions(+)
>  create mode 100644 drivers/pci/host/mcfg-quirks.c
>  create mode 100644 drivers/pci/host/mcfg-quirks.h
> 
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 8843410..500cf78 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
>  obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
> diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
> new file mode 100644
> index 000..aa9907b
> --- /dev/null
> +++ b/drivers/pci/host/mcfg-quirks.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2016 Semihalf
> + *   Author: Tomasz Nowicki 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation (the "GPL").
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 (GPLv2) for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 (GPLv2) along with this source code.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mcfg-quirks.h"
> +
> +struct pci_cfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + struct resource domain_range;
> + struct resource bus_range;
> + struct pci_ops *ops;
> + struct pci_config_window *(*init)(struct acpi_pci_root *root,
> +   struct pci_ops *ops);
> +};
> +
> +#define MCFG_DOM_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1), NULL, 0)
> +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0x)
> +#define MCFG_BUS_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1),  \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +
> +static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
> +/*   { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
> +};
> +
> +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
> +  struct acpi_table_header *mcfg_header)
> +{
> + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_header->oem_revision);
> +}
> +
> +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
> +{
> + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
> + struct resource *bus_res = >secondary;
> + struct pci_cfg_fixup *f = mcfg_quirks;
> + struct acpi_table_header *mcfg_header;
> + acpi_status status;
> + int i;
> +
> + status = acpi_get_table(ACPI_SIG_MCFG, 0, _header);
> + if (ACPI_FAILURE(status))
> + return NULL;

I remember working out why pci_mcfg_parse() has to cache the data from
MCFG, but I don't remember the actual reason...  a comment there would
have been helpful.  Anyway, now I wonder why it's OK to call
acpi_get_table(ACPI_SIG_MCFG) again here.  I guess I'd be inclined to
just cache the OEM info along with the rest of the data so you don't
have to get the table again here.

> + 

Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-04 Thread Bjorn Helgaas
On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set. Algorithm traverses available quirk list (static array),
> matches against  and
> returns pci_config_window structure with fancy PCI config ops.
> oem_id, oem_table_id and rev come from MCFG table standard header.
> 
> It is possible to define custom init call which is responsible for
> setting up PCI configuration access accordingly to quirk requirements.
> If custom init call is not defined, use standard 
> pci_acpi_setup_ecam_mapping().
> 
> pci_generic_ecam_ops will be used for platforms free from quirks.
> 
> Signed-off-by: Tomasz Nowicki 
> Signed-off-by: Dongdong Liu 
> Signed-off-by: Christopher Covington 
> ---
>  drivers/pci/host/Makefile  |  1 +
>  drivers/pci/host/mcfg-quirks.c | 86 
> ++
>  drivers/pci/host/mcfg-quirks.h | 20 ++
>  include/linux/pci-acpi.h   |  2 +
>  4 files changed, 109 insertions(+)
>  create mode 100644 drivers/pci/host/mcfg-quirks.c
>  create mode 100644 drivers/pci/host/mcfg-quirks.h

If the object is to work around defects in the ACPI MCFG table, I
think I'd put the quirks closer to drivers/acpi/pci_mcfg.c, where we
parse that table.  What if we actually put them directly *in*
drivers/acpi/pci_mcfg.c?

> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 8843410..500cf78 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
>  obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
> diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
> new file mode 100644
> index 000..aa9907b
> --- /dev/null
> +++ b/drivers/pci/host/mcfg-quirks.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2016 Semihalf
> + *   Author: Tomasz Nowicki 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation (the "GPL").
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 (GPLv2) for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 (GPLv2) along with this source code.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mcfg-quirks.h"
> +
> +struct pci_cfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + struct resource domain_range;
> + struct resource bus_range;
> + struct pci_ops *ops;
> + struct pci_config_window *(*init)(struct acpi_pci_root *root,
> +   struct pci_ops *ops);
> +};
> +
> +#define MCFG_DOM_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1), NULL, 0)
> +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0x)
> +#define MCFG_BUS_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1),  \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +
> +static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
> +/*   { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
> +};
> +
> +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
> +  struct acpi_table_header *mcfg_header)
> +{
> + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_header->oem_revision);
> +}
> +
> +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
> +{
> + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
> + struct resource *bus_res = >secondary;
> + struct pci_cfg_fixup *f = mcfg_quirks;
> + struct acpi_table_header *mcfg_header;
> + acpi_status status;
> + int i;
> +
> + status = acpi_get_table(ACPI_SIG_MCFG, 0, _header);
> + if (ACPI_FAILURE(status))
> + return NULL;
> +
> + /*
> +  * 

Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-09-04 Thread Bjorn Helgaas
On Mon, Aug 08, 2016 at 03:05:39PM +0200, Tomasz Nowicki wrote:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set. Algorithm traverses available quirk list (static array),
> matches against  and
> returns pci_config_window structure with fancy PCI config ops.
> oem_id, oem_table_id and rev come from MCFG table standard header.
> 
> It is possible to define custom init call which is responsible for
> setting up PCI configuration access accordingly to quirk requirements.
> If custom init call is not defined, use standard 
> pci_acpi_setup_ecam_mapping().
> 
> pci_generic_ecam_ops will be used for platforms free from quirks.
> 
> Signed-off-by: Tomasz Nowicki 
> Signed-off-by: Dongdong Liu 
> Signed-off-by: Christopher Covington 
> ---
>  drivers/pci/host/Makefile  |  1 +
>  drivers/pci/host/mcfg-quirks.c | 86 
> ++
>  drivers/pci/host/mcfg-quirks.h | 20 ++
>  include/linux/pci-acpi.h   |  2 +
>  4 files changed, 109 insertions(+)
>  create mode 100644 drivers/pci/host/mcfg-quirks.c
>  create mode 100644 drivers/pci/host/mcfg-quirks.h

If the object is to work around defects in the ACPI MCFG table, I
think I'd put the quirks closer to drivers/acpi/pci_mcfg.c, where we
parse that table.  What if we actually put them directly *in*
drivers/acpi/pci_mcfg.c?

> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 8843410..500cf78 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
>  obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
> diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
> new file mode 100644
> index 000..aa9907b
> --- /dev/null
> +++ b/drivers/pci/host/mcfg-quirks.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2016 Semihalf
> + *   Author: Tomasz Nowicki 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation (the "GPL").
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 (GPLv2) for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 (GPLv2) along with this source code.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mcfg-quirks.h"
> +
> +struct pci_cfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + struct resource domain_range;
> + struct resource bus_range;
> + struct pci_ops *ops;
> + struct pci_config_window *(*init)(struct acpi_pci_root *root,
> +   struct pci_ops *ops);
> +};
> +
> +#define MCFG_DOM_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1), NULL, 0)
> +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0x)
> +#define MCFG_BUS_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1),  \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +
> +static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
> +/*   { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
> +};
> +
> +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
> +  struct acpi_table_header *mcfg_header)
> +{
> + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_header->oem_revision);
> +}
> +
> +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
> +{
> + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
> + struct resource *bus_res = >secondary;
> + struct pci_cfg_fixup *f = mcfg_quirks;
> + struct acpi_table_header *mcfg_header;
> + acpi_status status;
> + int i;
> +
> + status = acpi_get_table(ACPI_SIG_MCFG, 0, _header);
> + if (ACPI_FAILURE(status))
> + return NULL;
> +
> + /*
> +  * First match against PCI topology  then use OEM ID, OEM
> +  * table ID, and OEM revision from MCFG table standard header.
> +  */

Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-08-09 Thread Tomasz Nowicki

On 08.08.2016 17:34, Mark Salter wrote:

On Mon, 2016-08-08 at 15:05 +0200, Tomasz Nowicki wrote:

Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set. Algorithm traverses available quirk list (static array),
matches against  and
returns pci_config_window structure with fancy PCI config ops.
oem_id, oem_table_id and rev come from MCFG table standard header.

It is possible to define custom init call which is responsible for
setting up PCI configuration access accordingly to quirk requirements.
If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping().

pci_generic_ecam_ops will be used for platforms free from quirks.

Signed-off-by: Tomasz Nowicki 
Signed-off-by: Dongdong Liu 
Signed-off-by: Christopher Covington 
---
 drivers/pci/host/Makefile  |  1 +
 drivers/pci/host/mcfg-quirks.c | 86 ++
 drivers/pci/host/mcfg-quirks.h | 20 ++
 include/linux/pci-acpi.h   |  2 +
 4 files changed, 109 insertions(+)
 create mode 100644 drivers/pci/host/mcfg-quirks.c
 create mode 100644 drivers/pci/host/mcfg-quirks.h

diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 8843410..500cf78 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
new file mode 100644
index 000..aa9907b
--- /dev/null
+++ b/drivers/pci/host/mcfg-quirks.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 Semihalf
+ * Author: Tomasz Nowicki 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mcfg-quirks.h"
+
+struct pci_cfg_fixup {
+   char oem_id[ACPI_OEM_ID_SIZE + 1];
+   char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+   u32 oem_revision;
+   struct resource domain_range;
+   struct resource bus_range;
+   struct pci_ops *ops;
+   struct pci_config_window *(*init)(struct acpi_pci_root *root,
+ struct pci_ops *ops);
+};
+
+#define MCFG_DOM_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1), NULL, 0)
+#define MCFG_DOM_ANY   MCFG_DOM_RANGE(0x0, 0x)
+#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1),  \
+   NULL, IORESOURCE_BUS)
+#define MCFG_BUS_ANY   MCFG_BUS_RANGE(0x0, 0xff)
+
+static struct pci_cfg_fixup mcfg_quirks[] __initconst = {

 ^^

I get section warnings because pci_cfg_fixup_match() is not
an init function.

WARNING: vmlinux.o(.text+0x3f6c74): Section mismatch in reference from the 
function pci_mcfg_match_quirks() to the variable .init.rodata:$d
The function pci_mcfg_match_quirks() references
the variable __initconst $d.
This is often because pci_mcfg_match_quirks lacks a __initconst
annotation or the annotation of $d is wrong.


Thanks Mark. I will fix it.

Tomasz


Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-08-09 Thread Tomasz Nowicki

On 08.08.2016 17:34, Mark Salter wrote:

On Mon, 2016-08-08 at 15:05 +0200, Tomasz Nowicki wrote:

Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set. Algorithm traverses available quirk list (static array),
matches against  and
returns pci_config_window structure with fancy PCI config ops.
oem_id, oem_table_id and rev come from MCFG table standard header.

It is possible to define custom init call which is responsible for
setting up PCI configuration access accordingly to quirk requirements.
If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping().

pci_generic_ecam_ops will be used for platforms free from quirks.

Signed-off-by: Tomasz Nowicki 
Signed-off-by: Dongdong Liu 
Signed-off-by: Christopher Covington 
---
 drivers/pci/host/Makefile  |  1 +
 drivers/pci/host/mcfg-quirks.c | 86 ++
 drivers/pci/host/mcfg-quirks.h | 20 ++
 include/linux/pci-acpi.h   |  2 +
 4 files changed, 109 insertions(+)
 create mode 100644 drivers/pci/host/mcfg-quirks.c
 create mode 100644 drivers/pci/host/mcfg-quirks.h

diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 8843410..500cf78 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
new file mode 100644
index 000..aa9907b
--- /dev/null
+++ b/drivers/pci/host/mcfg-quirks.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 Semihalf
+ * Author: Tomasz Nowicki 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mcfg-quirks.h"
+
+struct pci_cfg_fixup {
+   char oem_id[ACPI_OEM_ID_SIZE + 1];
+   char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+   u32 oem_revision;
+   struct resource domain_range;
+   struct resource bus_range;
+   struct pci_ops *ops;
+   struct pci_config_window *(*init)(struct acpi_pci_root *root,
+ struct pci_ops *ops);
+};
+
+#define MCFG_DOM_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1), NULL, 0)
+#define MCFG_DOM_ANY   MCFG_DOM_RANGE(0x0, 0x)
+#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1),  \
+   NULL, IORESOURCE_BUS)
+#define MCFG_BUS_ANY   MCFG_BUS_RANGE(0x0, 0xff)
+
+static struct pci_cfg_fixup mcfg_quirks[] __initconst = {

 ^^

I get section warnings because pci_cfg_fixup_match() is not
an init function.

WARNING: vmlinux.o(.text+0x3f6c74): Section mismatch in reference from the 
function pci_mcfg_match_quirks() to the variable .init.rodata:$d
The function pci_mcfg_match_quirks() references
the variable __initconst $d.
This is often because pci_mcfg_match_quirks lacks a __initconst
annotation or the annotation of $d is wrong.


Thanks Mark. I will fix it.

Tomasz


Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-08-08 Thread Mark Salter
On Mon, 2016-08-08 at 15:05 +0200, Tomasz Nowicki wrote:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set. Algorithm traverses available quirk list (static array),
> matches against  and
> returns pci_config_window structure with fancy PCI config ops.
> oem_id, oem_table_id and rev come from MCFG table standard header.
> 
> It is possible to define custom init call which is responsible for
> setting up PCI configuration access accordingly to quirk requirements.
> If custom init call is not defined, use standard 
> pci_acpi_setup_ecam_mapping().
> 
> pci_generic_ecam_ops will be used for platforms free from quirks.
> 
> Signed-off-by: Tomasz Nowicki 
> Signed-off-by: Dongdong Liu 
> Signed-off-by: Christopher Covington 
> ---
>  drivers/pci/host/Makefile  |  1 +
>  drivers/pci/host/mcfg-quirks.c | 86 
> ++
>  drivers/pci/host/mcfg-quirks.h | 20 ++
>  include/linux/pci-acpi.h   |  2 +
>  4 files changed, 109 insertions(+)
>  create mode 100644 drivers/pci/host/mcfg-quirks.c
>  create mode 100644 drivers/pci/host/mcfg-quirks.h
> 
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 8843410..500cf78 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
>  obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
> diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
> new file mode 100644
> index 000..aa9907b
> --- /dev/null
> +++ b/drivers/pci/host/mcfg-quirks.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2016 Semihalf
> + *   Author: Tomasz Nowicki 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation (the "GPL").
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 (GPLv2) for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 (GPLv2) along with this source code.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mcfg-quirks.h"
> +
> +struct pci_cfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + struct resource domain_range;
> + struct resource bus_range;
> + struct pci_ops *ops;
> + struct pci_config_window *(*init)(struct acpi_pci_root *root,
> +   struct pci_ops *ops);
> +};
> +
> +#define MCFG_DOM_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1), NULL, 0)
> +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0x)
> +#define MCFG_BUS_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1),  \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +
> +static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
                                             ^^

I get section warnings because pci_cfg_fixup_match() is not
an init function.

WARNING: vmlinux.o(.text+0x3f6c74): Section mismatch in reference from the 
function pci_mcfg_match_quirks() to the variable .init.rodata:$d
The function pci_mcfg_match_quirks() references
the variable __initconst $d.
This is often because pci_mcfg_match_quirks lacks a __initconst 
annotation or the annotation of $d is wrong.

> +/*   { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
> +};
> +
> +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
> +  struct acpi_table_header *mcfg_header)
> +{
> + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_header->oem_revision);
> +}
> +
> +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
> +{
> + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
> + struct resource *bus_res = >secondary;
> + struct pci_cfg_fixup *f = mcfg_quirks;
> + 

Re: [RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-08-08 Thread Mark Salter
On Mon, 2016-08-08 at 15:05 +0200, Tomasz Nowicki wrote:
> Some platforms may not be fully compliant with generic set of PCI config
> accessors. For these cases we implement the way to overwrite accessors
> set. Algorithm traverses available quirk list (static array),
> matches against  and
> returns pci_config_window structure with fancy PCI config ops.
> oem_id, oem_table_id and rev come from MCFG table standard header.
> 
> It is possible to define custom init call which is responsible for
> setting up PCI configuration access accordingly to quirk requirements.
> If custom init call is not defined, use standard 
> pci_acpi_setup_ecam_mapping().
> 
> pci_generic_ecam_ops will be used for platforms free from quirks.
> 
> Signed-off-by: Tomasz Nowicki 
> Signed-off-by: Dongdong Liu 
> Signed-off-by: Christopher Covington 
> ---
>  drivers/pci/host/Makefile  |  1 +
>  drivers/pci/host/mcfg-quirks.c | 86 
> ++
>  drivers/pci/host/mcfg-quirks.h | 20 ++
>  include/linux/pci-acpi.h   |  2 +
>  4 files changed, 109 insertions(+)
>  create mode 100644 drivers/pci/host/mcfg-quirks.c
>  create mode 100644 drivers/pci/host/mcfg-quirks.h
> 
> diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
> index 8843410..500cf78 100644
> --- a/drivers/pci/host/Makefile
> +++ b/drivers/pci/host/Makefile
> @@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
>  obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
>  obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
>  obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
> +obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
> diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
> new file mode 100644
> index 000..aa9907b
> --- /dev/null
> +++ b/drivers/pci/host/mcfg-quirks.c
> @@ -0,0 +1,86 @@
> +/*
> + * Copyright (C) 2016 Semihalf
> + *   Author: Tomasz Nowicki 
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License, version 2, as
> + * published by the Free Software Foundation (the "GPL").
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License version 2 (GPLv2) for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * version 2 (GPLv2) along with this source code.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "mcfg-quirks.h"
> +
> +struct pci_cfg_fixup {
> + char oem_id[ACPI_OEM_ID_SIZE + 1];
> + char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
> + u32 oem_revision;
> + struct resource domain_range;
> + struct resource bus_range;
> + struct pci_ops *ops;
> + struct pci_config_window *(*init)(struct acpi_pci_root *root,
> +   struct pci_ops *ops);
> +};
> +
> +#define MCFG_DOM_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1), NULL, 0)
> +#define MCFG_DOM_ANY MCFG_DOM_RANGE(0x0, 0x)
> +#define MCFG_BUS_RANGE(start, end)   DEFINE_RES_NAMED((start),   \
> + ((end) - (start) + 1),  \
> + NULL, IORESOURCE_BUS)
> +#define MCFG_BUS_ANY MCFG_BUS_RANGE(0x0, 0xff)
> +
> +static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
                                             ^^

I get section warnings because pci_cfg_fixup_match() is not
an init function.

WARNING: vmlinux.o(.text+0x3f6c74): Section mismatch in reference from the 
function pci_mcfg_match_quirks() to the variable .init.rodata:$d
The function pci_mcfg_match_quirks() references
the variable __initconst $d.
This is often because pci_mcfg_match_quirks lacks a __initconst 
annotation or the annotation of $d is wrong.

> +/*   { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
> +};
> +
> +static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
> +  struct acpi_table_header *mcfg_header)
> +{
> + return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
> + !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
> + ACPI_OEM_TABLE_ID_SIZE) &&
> + f->oem_revision == mcfg_header->oem_revision);
> +}
> +
> +struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
> +{
> + struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
> + struct resource *bus_res = >secondary;
> + struct pci_cfg_fixup *f = mcfg_quirks;
> + struct acpi_table_header *mcfg_header;
> + acpi_status status;
> + int i;
> +
> + status = acpi_get_table(ACPI_SIG_MCFG, 

[RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-08-08 Thread Tomasz Nowicki
Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set. Algorithm traverses available quirk list (static array),
matches against  and
returns pci_config_window structure with fancy PCI config ops.
oem_id, oem_table_id and rev come from MCFG table standard header.

It is possible to define custom init call which is responsible for
setting up PCI configuration access accordingly to quirk requirements.
If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping().

pci_generic_ecam_ops will be used for platforms free from quirks.

Signed-off-by: Tomasz Nowicki 
Signed-off-by: Dongdong Liu 
Signed-off-by: Christopher Covington 
---
 drivers/pci/host/Makefile  |  1 +
 drivers/pci/host/mcfg-quirks.c | 86 ++
 drivers/pci/host/mcfg-quirks.h | 20 ++
 include/linux/pci-acpi.h   |  2 +
 4 files changed, 109 insertions(+)
 create mode 100644 drivers/pci/host/mcfg-quirks.c
 create mode 100644 drivers/pci/host/mcfg-quirks.h

diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 8843410..500cf78 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
new file mode 100644
index 000..aa9907b
--- /dev/null
+++ b/drivers/pci/host/mcfg-quirks.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 Semihalf
+ * Author: Tomasz Nowicki 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mcfg-quirks.h"
+
+struct pci_cfg_fixup {
+   char oem_id[ACPI_OEM_ID_SIZE + 1];
+   char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+   u32 oem_revision;
+   struct resource domain_range;
+   struct resource bus_range;
+   struct pci_ops *ops;
+   struct pci_config_window *(*init)(struct acpi_pci_root *root,
+ struct pci_ops *ops);
+};
+
+#define MCFG_DOM_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1), NULL, 0)
+#define MCFG_DOM_ANY   MCFG_DOM_RANGE(0x0, 0x)
+#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1),  \
+   NULL, IORESOURCE_BUS)
+#define MCFG_BUS_ANY   MCFG_BUS_RANGE(0x0, 0xff)
+
+static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
+/* { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
+};
+
+static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
+struct acpi_table_header *mcfg_header)
+{
+   return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
+   !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
+   ACPI_OEM_TABLE_ID_SIZE) &&
+   f->oem_revision == mcfg_header->oem_revision);
+}
+
+struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
+{
+   struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
+   struct resource *bus_res = >secondary;
+   struct pci_cfg_fixup *f = mcfg_quirks;
+   struct acpi_table_header *mcfg_header;
+   acpi_status status;
+   int i;
+
+   status = acpi_get_table(ACPI_SIG_MCFG, 0, _header);
+   if (ACPI_FAILURE(status))
+   return NULL;
+
+   /*
+* First match against PCI topology  then use OEM ID, OEM
+* table ID, and OEM revision from MCFG table standard header.
+*/
+   for (i = 0; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
+   if (resource_contains(>domain_range, _res) &&
+   resource_contains(>bus_range, bus_res) &&
+   pci_mcfg_fixup_match(f, mcfg_header)) {
+   dev_info(>device->dev, "Applying PCI MCFG 

[RFC PATCH V5 3/5] PCI: Check platform specific ECAM quirks

2016-08-08 Thread Tomasz Nowicki
Some platforms may not be fully compliant with generic set of PCI config
accessors. For these cases we implement the way to overwrite accessors
set. Algorithm traverses available quirk list (static array),
matches against  and
returns pci_config_window structure with fancy PCI config ops.
oem_id, oem_table_id and rev come from MCFG table standard header.

It is possible to define custom init call which is responsible for
setting up PCI configuration access accordingly to quirk requirements.
If custom init call is not defined, use standard pci_acpi_setup_ecam_mapping().

pci_generic_ecam_ops will be used for platforms free from quirks.

Signed-off-by: Tomasz Nowicki 
Signed-off-by: Dongdong Liu 
Signed-off-by: Christopher Covington 
---
 drivers/pci/host/Makefile  |  1 +
 drivers/pci/host/mcfg-quirks.c | 86 ++
 drivers/pci/host/mcfg-quirks.h | 20 ++
 include/linux/pci-acpi.h   |  2 +
 4 files changed, 109 insertions(+)
 create mode 100644 drivers/pci/host/mcfg-quirks.c
 create mode 100644 drivers/pci/host/mcfg-quirks.h

diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 8843410..500cf78 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_PCI_HOST_THUNDER_ECAM) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_HOST_THUNDER_PEM) += pci-thunder-pem.o
 obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o
 obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o
+obj-$(CONFIG_ACPI_MCFG) += mcfg-quirks.o
diff --git a/drivers/pci/host/mcfg-quirks.c b/drivers/pci/host/mcfg-quirks.c
new file mode 100644
index 000..aa9907b
--- /dev/null
+++ b/drivers/pci/host/mcfg-quirks.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2016 Semihalf
+ * Author: Tomasz Nowicki 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "mcfg-quirks.h"
+
+struct pci_cfg_fixup {
+   char oem_id[ACPI_OEM_ID_SIZE + 1];
+   char oem_table_id[ACPI_OEM_TABLE_ID_SIZE + 1];
+   u32 oem_revision;
+   struct resource domain_range;
+   struct resource bus_range;
+   struct pci_ops *ops;
+   struct pci_config_window *(*init)(struct acpi_pci_root *root,
+ struct pci_ops *ops);
+};
+
+#define MCFG_DOM_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1), NULL, 0)
+#define MCFG_DOM_ANY   MCFG_DOM_RANGE(0x0, 0x)
+#define MCFG_BUS_RANGE(start, end) DEFINE_RES_NAMED((start),   \
+   ((end) - (start) + 1),  \
+   NULL, IORESOURCE_BUS)
+#define MCFG_BUS_ANY   MCFG_BUS_RANGE(0x0, 0xff)
+
+static struct pci_cfg_fixup mcfg_quirks[] __initconst = {
+/* { OEM_ID, OEM_TABLE_ID, REV, DOMAIN, BUS_RANGE, pci_ops, init_hook }, */
+};
+
+static bool pci_mcfg_fixup_match(struct pci_cfg_fixup *f,
+struct acpi_table_header *mcfg_header)
+{
+   return (!memcmp(f->oem_id, mcfg_header->oem_id, ACPI_OEM_ID_SIZE) &&
+   !memcmp(f->oem_table_id, mcfg_header->oem_table_id,
+   ACPI_OEM_TABLE_ID_SIZE) &&
+   f->oem_revision == mcfg_header->oem_revision);
+}
+
+struct pci_config_window *pci_mcfg_match_quirks(struct acpi_pci_root *root)
+{
+   struct resource dom_res = MCFG_DOM_RANGE(root->segment, root->segment);
+   struct resource *bus_res = >secondary;
+   struct pci_cfg_fixup *f = mcfg_quirks;
+   struct acpi_table_header *mcfg_header;
+   acpi_status status;
+   int i;
+
+   status = acpi_get_table(ACPI_SIG_MCFG, 0, _header);
+   if (ACPI_FAILURE(status))
+   return NULL;
+
+   /*
+* First match against PCI topology  then use OEM ID, OEM
+* table ID, and OEM revision from MCFG table standard header.
+*/
+   for (i = 0; i < ARRAY_SIZE(mcfg_quirks); i++, f++) {
+   if (resource_contains(>domain_range, _res) &&
+   resource_contains(>bus_range, bus_res) &&
+   pci_mcfg_fixup_match(f, mcfg_header)) {
+   dev_info(>device->dev, "Applying PCI MCFG quirks 
for %s %s rev: %d\n",
+f->oem_id, f->oem_table_id, f->oem_revision);
+