[RFC/RFT PATCH 03/18] PCI: Introduce pci_scan_root_bus_bridge()

Arnd Bergmann arnd at arndb.de
Fri Apr 28 08:28:38 EDT 2017


On Wed, Apr 26, 2017 at 1:17 PM, Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
> Current pci_scan_root_bus() interface is made up of two main
> code paths:
>
> - pci_create_root_bus()
> - pci_scan_child_bus()
>
> pci_create_root_bus() is a wrapper function that allows to create
> a struct pci_host_bridge structure, initialize it with the passed
> parameters and register it with the kernel.
>
> As the struct pci_host_bridge require additional struct members,
> pci_create_root_bus() parameters list has grown in time, making
> it unwieldy to add further parameters to it in case the struct
> pci_host_bridge gains more members fields to augment its functionality.
>
> Since PCI core code provides functions to allocate struct
> pci_host_bridge, instead of forcing the pci_create_root_bus() interface
> to add new parameters to cater for new struct pci_host_bridge
> functionality, it is more suitable to add an interface in PCI
> core code to scan a PCI bus straight from a struct pci_host_bridge
> created and customized by each specific PCI host controller driver.
>
> Add a pci_scan_root_bus_bridge() function to allow PCI host controller
> drivers to create and initialize struct pci_host_bridge and scan
> the resulting bus.
>
> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Bjorn Helgaas <bhelgaas at google.com>

Good idea, yes. To avoid growing the number of interfaces too
much, should we change the existing users of pci_register_host_bridge
in host drivers over to this entry point, and make the other one
local to probe.c then?

> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 7e4ffc4..c7a7f72 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -2412,6 +2412,44 @@ void pci_bus_release_busn_res(struct pci_bus *b)
>                         res, ret ? "can not be" : "is");
>  }
>
> +int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge)
> +{
> +       struct resource_entry *window;
> +       bool found = false;
> +       struct pci_bus *b;
> +       int max, bus, ret;
> +
> +       if (!bridge)
> +               return -EINVAL;
> +
> +       resource_list_for_each_entry(window, &bridge->windows)
> +               if (window->res->flags & IORESOURCE_BUS) {
> +                       found = true;
> +                       break;
> +               }
> +
> +       ret = pci_register_host_bridge(bridge);
> +       if (ret < 0)
> +               return ret;
> +
> +       b = bridge->bus;
> +       bus = bridge->busnr;
> +
> +       if (!found) {
> +               dev_info(&b->dev,
> +                "No busn resource found for root bus, will use [bus %02x-ff]\n",
> +                       bus);
> +               pci_bus_insert_busn_res(b, bus, 255);
> +       }
> +
> +       max = pci_scan_child_bus(b);
> +
> +       if (!found)
> +               pci_bus_update_busn_res_end(b, max);
> +
> +       return 0;
> +}
> +

We probably want an EXPORT_SYMBOL() here as well.

     Arnd



More information about the linux-arm-kernel mailing list