]> mj.ucw.cz Git - pciutils.git/commitdiff
Simplified pci_fill_info() and friends fill-info
authorMartin Mares <mj@ucw.cz>
Fri, 21 Jan 2022 20:39:18 +0000 (21:39 +0100)
committerMartin Mares <mj@ucw.cz>
Fri, 21 Jan 2022 20:39:18 +0000 (21:39 +0100)
Previously, we kept track of which fields were already filled, which
was quite brittle.

Now we keep only the set of already known fields in struct pci_dev.
We check if the current field is needed against this information.

Not only this simplifies the whole thing, but it also enables future
back-ends to call pci_fill_info() recursively as needed.

lib/access.c
lib/caps.c
lib/fbsd-device.c
lib/generic.c
lib/hurd.c
lib/internal.h
lib/sysfs.c

index b257849a685e198418de511d2d0fed12607f850b..9bd69891dde5c082ce1d81fe250248d1a8c153d2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library -- User Access
  *
- *     Copyright (c) 1997--2018 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2022 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -198,7 +198,7 @@ pci_fill_info_v35(struct pci_dev *d, int flags)
       pci_reset_properties(d);
     }
   if (uflags & ~d->known_fields)
-    d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields);
+    d->methods->fill_info(d, uflags);
   return d->known_fields;
 }
 
index c3b918059fe12d0e3b287b183ddf0c8c59461220..3c025a98347debabe0867822f1735dbd86cca72f 100644 (file)
@@ -80,17 +80,16 @@ pci_scan_ext_caps(struct pci_dev *d)
   while (where);
 }
 
-unsigned int
+void
 pci_scan_caps(struct pci_dev *d, unsigned int want_fields)
 {
-  if ((want_fields & PCI_FILL_EXT_CAPS) && !(d->known_fields & PCI_FILL_CAPS))
+  if (want_fields & PCI_FILL_EXT_CAPS)
     want_fields |= PCI_FILL_CAPS;
 
-  if (want_fields & PCI_FILL_CAPS)
+  if (want_fill(d, want_fields, PCI_FILL_CAPS))
     pci_scan_trad_caps(d);
-  if (want_fields & PCI_FILL_EXT_CAPS)
+  if (want_fill(d, want_fields, PCI_FILL_EXT_CAPS))
     pci_scan_ext_caps(d);
-  return want_fields;
 }
 
 void
index cffab69ead982f41343162e3849d9e4d3617acaa..396ff1d66e77516275b1fc8da96efef7dd900688 100644 (file)
@@ -159,7 +159,7 @@ fbsd_scan(struct pci_access *a)
   free(matches);
 }
 
-static int
+static void
 fbsd_fill_info(struct pci_dev *d, int flags)
 {
   struct pci_conf_io conf;
@@ -200,16 +200,14 @@ fbsd_fill_info(struct pci_dev *d, int flags)
       d->access->error("fbsd_fill_info: ioctl(PCIOCGETCONF) failed: %s", strerror(errno));
     }
 
-  if (flags & PCI_FILL_IDENT)
+  if (want_fill(d, flags, PCI_FILL_IDENT))
     {
       d->vendor_id = match.pc_vendor;
       d->device_id = match.pc_device;
     }
-  if (flags & PCI_FILL_CLASS)
-    {
-      d->device_class = (match.pc_class << 8) | match.pc_subclass;
-    }
-  if (flags & (PCI_FILL_BASES | PCI_FILL_SIZES))
+  if (want_fill(d, flags, PCI_FILL_CLASS))
+    d->device_class = (match.pc_class << 8) | match.pc_subclass;
+  if (want_fill(d, flags PCI_FILL_BASES | PCI_FILL_SIZES))
     {
       d->rom_base_addr = 0;
       d->rom_size = 0;
@@ -242,9 +240,6 @@ fbsd_fill_info(struct pci_dev *d, int flags)
            }
        }
     }
-
-  return flags & (PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_BASES |
-                 PCI_FILL_SIZES);
 }
 
 static int
index ef9e2a34b4f4d35b41bb4362745f9c24458c10f5..e80158fb9b14c82768b60d9018a0d6a9d4f1a9ed 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library -- Generic Direct Access Functions
  *
- *     Copyright (c) 1997--2000 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2022 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -74,39 +74,36 @@ pci_generic_scan(struct pci_access *a)
   pci_generic_scan_bus(a, busmap, 0);
 }
 
-unsigned int
+static int
+get_hdr_type(struct pci_dev *d)
+{
+  if (d->hdrtype < 0)
+    d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
+  return d->hdrtype;
+}
+
+void
 pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
 {
   struct pci_access *a = d->access;
-  unsigned int done = 0;
 
-  if ((flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE)) && d->hdrtype < 0)
-    d->hdrtype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f;
-
-  if (flags & PCI_FILL_IDENT)
+  if (want_fill(d, flags, PCI_FILL_IDENT))
     {
       d->vendor_id = pci_read_word(d, PCI_VENDOR_ID);
       d->device_id = pci_read_word(d, PCI_DEVICE_ID);
-      done |= PCI_FILL_IDENT;
     }
 
-  if (flags & PCI_FILL_CLASS)
-    {
-      d->device_class = pci_read_word(d, PCI_CLASS_DEVICE);
-      done |= PCI_FILL_CLASS;
-    }
+  if (want_fill(d, flags, PCI_FILL_CLASS))
+    d->device_class = pci_read_word(d, PCI_CLASS_DEVICE);
 
-  if (flags & PCI_FILL_IRQ)
-    {
-      d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
-      done |= PCI_FILL_IRQ;
-    }
+  if (want_fill(d, flags, PCI_FILL_IRQ))
+    d->irq = pci_read_byte(d, PCI_INTERRUPT_LINE);
 
-  if (flags & PCI_FILL_BASES)
+  if (want_fill(d, flags, PCI_FILL_BASES))
     {
       int cnt = 0, i;
       memset(d->base_addr, 0, sizeof(d->base_addr));
-      switch (d->hdrtype)
+      switch (get_hdr_type(d))
        {
        case PCI_HEADER_TYPE_NORMAL:
          cnt = 6;
@@ -148,14 +145,13 @@ pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
                }
            }
        }
-      done |= PCI_FILL_BASES;
     }
 
-  if (flags & PCI_FILL_ROM_BASE)
+  if (want_fill(d, flags, PCI_FILL_ROM_BASE))
     {
       int reg = 0;
       d->rom_base_addr = 0;
-      switch (d->hdrtype)
+      switch (get_hdr_type(d))
        {
        case PCI_HEADER_TYPE_NORMAL:
          reg = PCI_ROM_ADDRESS;
@@ -170,13 +166,9 @@ pci_generic_fill_info(struct pci_dev *d, unsigned int flags)
          if (u != 0xffffffff)
            d->rom_base_addr = u;
        }
-      done |= PCI_FILL_ROM_BASE;
     }
 
-  if (flags & (PCI_FILL_CAPS | PCI_FILL_EXT_CAPS))
-    done |= pci_scan_caps(d, flags);
-
-  return done;
+  pci_scan_caps(d, flags);
 }
 
 static int
index 90cf89f7c0695aa8bc1cdf0f4d6cbf9e6c2a57e3..0939a20707cad5c7f58e0e1e63afc51bd2118434 100644 (file)
@@ -328,26 +328,16 @@ hurd_fill_rom(struct pci_dev *d)
   d->rom_size = rom.size;
 }
 
-static unsigned int
+static void
 hurd_fill_info(struct pci_dev *d, unsigned int flags)
 {
-  unsigned int done = 0;
-
   if (!d->access->buscentric)
     {
-      if (flags & (PCI_FILL_BASES | PCI_FILL_SIZES))
-       {
-         hurd_fill_regions(d);
-         done |= PCI_FILL_BASES | PCI_FILL_SIZES;
-       }
-      if (flags & PCI_FILL_ROM_BASE)
-       {
-         hurd_fill_rom(d);
-         done |= PCI_FILL_ROM_BASE;
-       }
+      if (want_fill(d, flags, PCI_FILL_BASES | PCI_FILL_SIZES))
+       hurd_fill_regions(d);
+      if (want_fill(d, flags, PCI_FILL_ROM_BASE))
+       hurd_fill_rom(d);
     }
-
-  return done | pci_generic_fill_info(d, flags & ~done);
 }
 
 struct pci_methods pm_hurd = {
index 17c27e194a29ce6af54b908639c2ff5f8755e0ec..942e3cb7feafa8f45f0b2ec3e31bcd413b9b5b38 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library -- Internal Stuff
  *
- *     Copyright (c) 1997--2018 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2022 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -41,7 +41,7 @@ struct pci_methods {
   void (*init)(struct pci_access *);
   void (*cleanup)(struct pci_access *);
   void (*scan)(struct pci_access *);
-  unsigned int (*fill_info)(struct pci_dev *, unsigned int flags);
+  void (*fill_info)(struct pci_dev *, unsigned int flags);
   int (*read)(struct pci_dev *, int pos, byte *buf, int len);
   int (*write)(struct pci_dev *, int pos, byte *buf, int len);
   int (*read_vpd)(struct pci_dev *, int pos, byte *buf, int len);
@@ -52,7 +52,7 @@ struct pci_methods {
 /* generic.c */
 void pci_generic_scan_bus(struct pci_access *, byte *busmap, int bus);
 void pci_generic_scan(struct pci_access *);
-unsigned int pci_generic_fill_info(struct pci_dev *, unsigned int flags);
+void pci_generic_fill_info(struct pci_dev *, unsigned int flags);
 int pci_generic_block_read(struct pci_dev *, int pos, byte *buf, int len);
 int pci_generic_block_write(struct pci_dev *, int pos, byte *buf, int len);
 
@@ -75,6 +75,18 @@ int pci_fill_info_v33(struct pci_dev *, int flags) VERSIONED_ABI;
 int pci_fill_info_v34(struct pci_dev *, int flags) VERSIONED_ABI;
 int pci_fill_info_v35(struct pci_dev *, int flags) VERSIONED_ABI;
 
+static inline int want_fill(struct pci_dev *d, unsigned want_fields, unsigned int try_fields)
+{
+  want_fields &= try_fields;
+  if ((d->known_fields & want_fields) == want_fields)
+    return 0;
+  else
+    {
+      d->known_fields |= try_fields;
+      return 1;
+    }
+}
+
 struct pci_property {
   struct pci_property *next;
   u32 key;
@@ -89,7 +101,7 @@ int pci_set_param_internal(struct pci_access *acc, char *param, char *val, int c
 void pci_free_params(struct pci_access *acc);
 
 /* caps.c */
-unsigned int pci_scan_caps(struct pci_dev *, unsigned int want_fields);
+void pci_scan_caps(struct pci_dev *, unsigned int want_fields);
 void pci_free_caps(struct pci_dev *);
 
 extern struct pci_methods pm_intel_conf1, pm_intel_conf2, pm_linux_proc,
index fb6424105e84d927c03270546ee410979ed1ed60..4b8b2cdfb0c608b9cf817300243ebdabce107f6e 100644 (file)
@@ -288,11 +288,9 @@ sysfs_fill_slots(struct pci_access *a)
   closedir(dir);
 }
 
-static unsigned int
+static void
 sysfs_fill_info(struct pci_dev *d, unsigned int flags)
 {
-  unsigned int done = 0;
-
   if (!d->access->buscentric)
     {
       /*
@@ -300,61 +298,45 @@ sysfs_fill_info(struct pci_dev *d, unsigned int flags)
        *  the kernel's view, which has regions and IRQs remapped and other fields
        *  (most importantly classes) possibly fixed if the device is known broken.
        */
-      if (flags & PCI_FILL_IDENT)
+      if (want_fill(d, flags, PCI_FILL_IDENT))
        {
          d->vendor_id = sysfs_get_value(d, "vendor", 1);
          d->device_id = sysfs_get_value(d, "device", 1);
-         done |= PCI_FILL_IDENT;
        }
-      if (flags & PCI_FILL_CLASS)
-       {
-         d->device_class = sysfs_get_value(d, "class", 1) >> 8;
-         done |= PCI_FILL_CLASS;
-       }
-      if (flags & PCI_FILL_IRQ)
-       {
+      if (want_fill(d, flags, PCI_FILL_CLASS))
+       d->device_class = sysfs_get_value(d, "class", 1) >> 8;
+      if (want_fill(d, flags, PCI_FILL_IRQ))
          d->irq = sysfs_get_value(d, "irq", 1);
-         done |= PCI_FILL_IRQ;
-       }
-      if (flags & (PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS))
-       {
+      if (want_fill(d, flags, PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS))
          sysfs_get_resources(d);
-         done |= PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES | PCI_FILL_IO_FLAGS;
-       }
     }
 
-  if (flags & PCI_FILL_PHYS_SLOT)
+  if (want_fill(d, flags, PCI_FILL_PHYS_SLOT))
     {
       struct pci_dev *pd;
       sysfs_fill_slots(d->access);
       for (pd = d->access->devices; pd; pd = pd->next)
        pd->known_fields |= PCI_FILL_PHYS_SLOT;
-      done |= PCI_FILL_PHYS_SLOT;
     }
 
-  if (flags & PCI_FILL_MODULE_ALIAS)
+  if (want_fill(d, flags, PCI_FILL_MODULE_ALIAS))
     {
       char buf[OBJBUFSIZE];
       if (sysfs_get_string(d, "modalias", buf, 0))
        d->module_alias = pci_set_property(d, PCI_FILL_MODULE_ALIAS, buf);
-      done |= PCI_FILL_MODULE_ALIAS;
     }
 
-  if (flags & PCI_FILL_LABEL)
+  if (want_fill(d, flags, PCI_FILL_LABEL))
     {
       char buf[OBJBUFSIZE];
       if (sysfs_get_string(d, "label", buf, 0))
        d->label = pci_set_property(d, PCI_FILL_LABEL, buf);
-      done |= PCI_FILL_LABEL;
     }
 
-  if (flags & PCI_FILL_NUMA_NODE)
-    {
-      d->numa_node = sysfs_get_value(d, "numa_node", 0);
-      done |= PCI_FILL_NUMA_NODE;
-    }
+  if (want_fill(d, flags, PCI_FILL_NUMA_NODE))
+    d->numa_node = sysfs_get_value(d, "numa_node", 0);
 
-  if (flags & PCI_FILL_IOMMU_GROUP)
+  if (want_fill(d, flags, PCI_FILL_IOMMU_GROUP))
     {
       char *group_link = sysfs_deref_link(d, "iommu_group");
       if (group_link)
@@ -362,10 +344,9 @@ sysfs_fill_info(struct pci_dev *d, unsigned int flags)
           pci_set_property(d, PCI_FILL_IOMMU_GROUP, basename(group_link));
           free(group_link);
         }
-      done |= PCI_FILL_IOMMU_GROUP;
     }
 
-  if (flags & PCI_FILL_DT_NODE)
+  if (want_fill(d, flags, PCI_FILL_DT_NODE))
     {
       char *node = sysfs_deref_link(d, "of_node");
       if (node)
@@ -373,10 +354,9 @@ sysfs_fill_info(struct pci_dev *d, unsigned int flags)
          pci_set_property(d, PCI_FILL_DT_NODE, node);
          free(node);
        }
-      done |= PCI_FILL_DT_NODE;
     }
 
-  return done | pci_generic_fill_info(d, flags & ~done);
+  pci_generic_fill_info(d, flags);
 }
 
 /* Intent of the sysfs_setup() caller */