Hi Bin, On 10 August 2015 at 00:18, Bin Meng <bmeng...@gmail.com> wrote: > Hi Simon, > > On Sat, Aug 8, 2015 at 10:26 PM, Simon Glass <s...@chromium.org> wrote: >> These functions allow iteration through all PCI devices including bridges. >> The children of each PCI bus are returned in turn. This can be useful for >> configuring, checking or enumerating all the devices. >> >> Signed-off-by: Simon Glass <s...@chromium.org> >> --- >> >> Changes in v2: >> - Add a comment as to why we need to scan multiple PCI controllers >> >> drivers/pci/pci-uclass.c | 62 >> ++++++++++++++++++++++++++++++++++++++++++++++++ >> include/pci.h | 25 +++++++++++++++++++ >> 2 files changed, 87 insertions(+) >> >> diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c >> index b79927e..2d5a0c1 100644 >> --- a/drivers/pci/pci-uclass.c >> +++ b/drivers/pci/pci-uclass.c >> @@ -775,6 +775,68 @@ static int pci_bridge_write_config(struct udevice *bus, >> pci_dev_t bdf, >> return pci_bus_write_config(hose->ctlr, bdf, offset, value, size); >> } >> >> +static int skip_to_next_device(struct udevice *bus, struct udevice **devp) >> +{ >> + struct udevice *dev; >> + int ret = 0; >> + >> + /* >> + * Scan through all the PCI controllers. On x86 there will only be >> one >> + * but that is not necessarily true on other hardware. >> + */ >> + do { >> + do { >> + device_find_first_child(bus, &dev); >> + if (dev) { >> + *devp = dev; >> + return 0; >> + } >> + } while (dev); > > There is no need to do a 'do..while' here.
I think I misunderstood your comment last time. Yes I think this can be removed. > >> + ret = uclass_next_device(&bus); >> + if (ret) >> + return ret; >> + } while (bus); >> + >> + return 0; >> +} >> + >> +int pci_find_next_device(struct udevice **devp) >> +{ >> + struct udevice *child = *devp; >> + struct udevice *bus = child->parent; >> + int ret; >> + >> + /* First try all the siblings */ >> + *devp = NULL; >> + while (child) { >> + device_find_next_child(&child); >> + if (child) { >> + *devp = child; >> + return 0; >> + } >> + } >> + >> + /* We ran out of siblings. Try the next bus */ >> + ret = uclass_next_device(&bus); >> + if (ret) >> + return ret; >> + >> + return bus ? skip_to_next_device(bus, devp) : 0; >> +} >> + >> +int pci_find_first_device(struct udevice **devp) >> +{ >> + struct udevice *bus; >> + int ret; >> + >> + *devp = NULL; >> + ret = uclass_first_device(UCLASS_PCI, &bus); >> + if (ret) >> + return ret; >> + >> + return skip_to_next_device(bus, devp); >> +} >> + >> UCLASS_DRIVER(pci) = { >> .id = UCLASS_PCI, >> .name = "pci", >> diff --git a/include/pci.h b/include/pci.h >> index d1e2765..488ff44 100644 >> --- a/include/pci.h >> +++ b/include/pci.h >> @@ -910,6 +910,31 @@ int pci_bus_find_devfn(struct udevice *bus, pci_dev_t >> find_devfn, >> struct udevice **devp); >> >> /** >> + * pci_find_first_device() - return the first available PCI device >> + * >> + * This function and pci_find_first_device() allow iteration through all >> + * available PCI devices on all buses. Assuming there are any, this will >> + * return the first one. >> + * >> + * @devp: Set to the first available device, or NULL if no more are >> left >> + * or we got an error >> + * @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe) >> + */ >> +int pci_find_first_device(struct udevice **devp); >> + >> +/** >> + * pci_find_next_device() - return the next available PCI device >> + * >> + * Finds the next available PCI device after the one supplied, or sets @devp >> + * to NULL if there are no more. >> + * >> + * @devp: On entry, the last device returned. Set to the next available >> + * device, or NULL if no more are left or we got an error >> + * @return 0 if all is OK, -ve on error (e.g. a bus/bridge failed to probe) >> + */ >> +int pci_find_next_device(struct udevice **devp); >> + >> +/** >> * pci_get_ff() - Returns a mask for the given access size >> * >> * @size: Access size >> -- > > Regards, > Bin Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot