diff mbox

[U-Boot,03/10] dm: pci: Allow a PCI bus to be found without an alias

Message ID 1439431779-16857-4-git-send-email-sjg@chromium.org
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass Aug. 13, 2015, 2:09 a.m. UTC
At present, until a PCI bus is probed, it cannot be found by its sequence
number unless it has an alias. This is the same with any device.

However with PCI this is more annoying than usual, since bus 0 is always the
same device.

Add a function that tries a little harder to locate PCI bus 0. This means
that PCI enumeration will happen automatically on the first access.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 drivers/pci/pci-uclass.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

Comments

Bin Meng Aug. 13, 2015, 2:44 a.m. UTC | #1
Hi Simon,

On Thu, Aug 13, 2015 at 10:09 AM, Simon Glass <sjg@chromium.org> wrote:
> At present, until a PCI bus is probed, it cannot be found by its sequence
> number unless it has an alias. This is the same with any device.
>
> However with PCI this is more annoying than usual, since bus 0 is always the
> same device.
>
> Add a function that tries a little harder to locate PCI bus 0. This means
> that PCI enumeration will happen automatically on the first access.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  drivers/pci/pci-uclass.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> index 7d41d56..a72e297 100644
> --- a/drivers/pci/pci-uclass.c
> +++ b/drivers/pci/pci-uclass.c
> @@ -17,6 +17,22 @@
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> +static int pci_get_bus(int busnum, struct udevice **busp)
> +{
> +       int ret;
> +
> +       ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
> +
> +       /* Since buses may not be numbered yet, try a little harder with bus 0*/
> +       if (ret == -ENODEV && !busnum) {

We should remove !busnum as it is possible to read configuration
registers that are not on bus 0.

> +               ret = uclass_first_device(UCLASS_PCI, busp);
> +               if (!ret && (*busp)->seq != busnum)

The test of (*busp)->seq has the assumption that busnum should be 0,
however it is not always the case.

> +                       return -ENODEV;
> +       }
> +
> +       return ret;
> +}
> +
>  struct pci_controller *pci_bus_to_hose(int busnum)
>  {
>         struct udevice *bus;
> @@ -125,7 +141,7 @@ int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
>         struct udevice *bus;
>         int ret;
>
> -       ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
> +       ret = pci_get_bus(PCI_BUS(bdf), &bus);
>         if (ret)
>                 return ret;
>         return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
> @@ -203,7 +219,7 @@ int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
>         struct udevice *bus;
>         int ret;
>
> -       ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
> +       ret = pci_get_bus(PCI_BUS(bdf), &bus);
>         if (ret)
>                 return ret;
>
> @@ -268,7 +284,7 @@ int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
>         struct udevice *bus;
>         int ret;
>
> -       ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
> +       ret = pci_get_bus(PCI_BUS(bdf), &bus);
>         if (ret)
>                 return ret;
>
> --

Regards,
Bin
diff mbox

Patch

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 7d41d56..a72e297 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -17,6 +17,22 @@ 
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static int pci_get_bus(int busnum, struct udevice **busp)
+{
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp);
+
+	/* Since buses may not be numbered yet, try a little harder with bus 0*/
+	if (ret == -ENODEV && !busnum) {
+		ret = uclass_first_device(UCLASS_PCI, busp);
+		if (!ret && (*busp)->seq != busnum)
+			return -ENODEV;
+	}
+
+	return ret;
+}
+
 struct pci_controller *pci_bus_to_hose(int busnum)
 {
 	struct udevice *bus;
@@ -125,7 +141,7 @@  int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
 	struct udevice *bus;
 	int ret;
 
-	ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+	ret = pci_get_bus(PCI_BUS(bdf), &bus);
 	if (ret)
 		return ret;
 	return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
@@ -203,7 +219,7 @@  int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
 	struct udevice *bus;
 	int ret;
 
-	ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+	ret = pci_get_bus(PCI_BUS(bdf), &bus);
 	if (ret)
 		return ret;
 
@@ -268,7 +284,7 @@  int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
 	struct udevice *bus;
 	int ret;
 
-	ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+	ret = pci_get_bus(PCI_BUS(bdf), &bus);
 	if (ret)
 		return ret;