Message ID | 1440280741-16169-3-git-send-email-sjg@chromium.org |
---|---|
State | Superseded |
Delegated to: | Simon Glass |
Headers | show |
Hi Simon, On Sun, Aug 23, 2015 at 5:58 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> > --- > > Changes in v2: > - Adjust pci_get_bus() to probe bus 0 so that the required bus is found > > drivers/pci/pci-uclass.c | 23 ++++++++++++++++++++--- > 1 file changed, 20 insertions(+), 3 deletions(-) > > diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c > index c90e7ac..ca47dc3 100644 > --- a/drivers/pci/pci-uclass.c > +++ b/drivers/pci/pci-uclass.c > @@ -20,6 +20,23 @@ > > 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) { > + ret = uclass_first_device(UCLASS_PCI, busp); > + if (!ret) By looking at the API comments of uclass_first_device(), I think this logic should be: if (ret || ((!ret) && (!*busp))) > + return -ENODEV; > + ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp); > + } > + > + return ret; > +} > + > struct pci_controller *pci_bus_to_hose(int busnum) > { > struct udevice *bus; > @@ -128,7 +145,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); > @@ -206,7 +223,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; > > @@ -271,7 +288,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; > > -- I think we need also update pci_bus_to_hose() to use pci_get_bus() instead of calling uclass_get_device_by_seq(). Regards, Bin
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index c90e7ac..ca47dc3 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -20,6 +20,23 @@ 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) { + ret = uclass_first_device(UCLASS_PCI, busp); + if (!ret) + return -ENODEV; + ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, busp); + } + + return ret; +} + struct pci_controller *pci_bus_to_hose(int busnum) { struct udevice *bus; @@ -128,7 +145,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); @@ -206,7 +223,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; @@ -271,7 +288,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;
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> --- Changes in v2: - Adjust pci_get_bus() to probe bus 0 so that the required bus is found drivers/pci/pci-uclass.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)