[U-Boot] [PATCH v2 2/9] dm: pci: Add a way to iterate through all PCI devices

Simon Glass sjg at chromium.org
Mon Aug 10 14:58:31 CEST 2015


Hi Bin,

On 10 August 2015 at 00:18, Bin Meng <bmeng.cn at gmail.com> wrote:
> Hi Simon,
>
> On Sat, Aug 8, 2015 at 10:26 PM, Simon Glass <sjg at 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 <sjg at 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


More information about the U-Boot mailing list