[systemd-devel] [RFC][PATCH] udev: net_id - support multi-function, multi-port enpo* device names

Tom Gundersen teg at jklm.no
Wed Apr 1 13:58:41 PDT 2015


I pushed a version of this only handling the multi-port devices. We
can deal with multi-function if and when they appear in the wild.

-t

On Wed, Apr 1, 2015 at 4:52 PM, Tom Gundersen <teg at jklm.no> wrote:
> I'd argue that having firmware labels for such devices makes no sense, but they exist, so make sure
> we handle them as best as we can.
> ---
>  src/udev/udev-builtin-net_id.c | 64 ++++++++++++++++++++++++++++--------------
>  1 file changed, 43 insertions(+), 21 deletions(-)
>
> diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
> index 71f3a59..1a72190 100644
> --- a/src/udev/udev-builtin-net_id.c
> +++ b/src/udev/udev-builtin-net_id.c
> @@ -35,7 +35,7 @@
>   * Type of names:
>   *   b<number>                             -- BCMA bus core number
>   *   ccw<name>                             -- CCW bus group name
> - *   o<index>                              -- on-board device index number
> + *   o<index>[f<function>][d<dev_port>]    -- on-board device index number
>   *   s<slot>[f<function>][d<dev_port>]     -- hotplug slot index number
>   *   x<MAC>                                -- MAC address
>   *   [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
> @@ -126,11 +126,38 @@ struct netnames {
>          char ccw_group[IFNAMSIZ];
>  };
>
> +/* read the 256 bytes PCI configuration space to check the multi-function bit */
> +static bool is_pci_multifunction(struct udev_device *dev) {
> +        _cleanup_fclose_ FILE *f = NULL;
> +        const char *filename;
> +        uint8_t config[64];
> +
> +        filename = strjoina(udev_device_get_syspath(dev), "/config");
> +        f = fopen(filename, "re");
> +        if (!f)
> +                return false;
> +        if (fread(&config, sizeof(config), 1, f) != 1)
> +                return false;
> +
> +        /* bit 0-6 header type, bit 7 multi/single function device */
> +        if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
> +                return true;
> +
> +        return false;
> +}
> +
>  /* retrieve on-board index number and label from firmware */
>  static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
> +        unsigned func, dev_port = 0;
> +        size_t l;
> +        char *s;
> +        const char *attr;
>          const char *index;
>          int idx;
>
> +        if (sscanf(udev_device_get_sysname(names->pcidev), "%*x:%*x:%*x.%u", &func) != 1)
> +                return -ENOENT;
> +
>          /* ACPI _DSM  -- device specific method for naming a PCI or PCI Express device */
>          index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
>          /* SMBIOS type 41 -- Onboard Devices Extended Information */
> @@ -141,30 +168,25 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
>          idx = strtoul(index, NULL, 0);
>          if (idx <= 0)
>                  return -EINVAL;
> -        snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
>
> -        names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
> -        return 0;
> -}
> -
> -/* read the 256 bytes PCI configuration space to check the multi-function bit */
> -static bool is_pci_multifunction(struct udev_device *dev) {
> -        _cleanup_fclose_ FILE *f = NULL;
> -        const char *filename;
> -        uint8_t config[64];
> +        /* kernel provided multi-device index */
> +        attr = udev_device_get_sysattr_value(dev, "dev_port");
> +        if (attr)
> +                dev_port = strtol(attr, NULL, 10);
>
> -        filename = strjoina(udev_device_get_syspath(dev), "/config");
> -        f = fopen(filename, "re");
> -        if (!f)
> -                return false;
> -        if (fread(&config, sizeof(config), 1, f) != 1)
> -                return false;
> +        s = names->pci_onboard;
> +        l = sizeof(names->pci_onboard);
> +        l = strpcpyf(&s, l, "o%d", idx);
> +        if (func > 0 || is_pci_multifunction(names->pcidev))
> +                l = strpcpyf(&s, l, "f%d", func);
> +        if (dev_port > 0)
> +                l = strpcpyf(&s, l, "d%d", dev_port);
> +        if (l == 0)
> +                names->pci_onboard[0] = '\0';
>
> -        /* bit 0-6 header type, bit 7 multi/single function device */
> -        if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
> -                return true;
> +        names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
>
> -        return false;
> +        return 0;
>  }
>
>  static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
> --
> 2.3.4
>


More information about the systemd-devel mailing list