]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
Rewritten support for UDEV's HWDB
authorMartin Mares <mj@ucw.cz>
Sat, 1 Nov 2014 17:38:08 +0000 (18:38 +0100)
committerMartin Mares <mj@ucw.cz>
Sat, 1 Nov 2014 17:38:08 +0000 (18:38 +0100)
HWDB is now handled in a way very similar to the DNS resolver.

The interface lives in a separate source file (lib/names-hwdb.c),
results of lookups are cached. Use of HWDB can be disabled either
by passing PCI_LOOKUP_NO_HWDB or by setting the hwdb.disabled
configuration parameter.

Also, there should be no more leaks of libudev's structures.

lib/Makefile
lib/init.c
lib/internal.h
lib/names-hash.c
lib/names-hwdb.c [new file with mode: 0644]
lib/names-parse.c
lib/names.c
lib/names.h
lib/params.c
lib/pci.h
pcilib.man

index 6f6efecddc4a7a0578d30b1a3f38c485dfc1846d..f119b728e3897214f23f48d5a5824c1b0ef8d981 100644 (file)
@@ -1,9 +1,9 @@
 # Makefile for The PCI Library
-# (c) 1999--2008 Martin Mares <mj@ucw.cz>
+# (c) 1999--2014 Martin Mares <mj@ucw.cz>
 
 # Expects to be invoked from the top-level Makefile and uses lots of its variables.
 
-OBJS=init access generic dump names filter names-hash names-parse names-net names-cache params caps
+OBJS=init access generic dump names filter names-hash names-parse names-net names-cache names-hwdb params caps
 INCL=internal.h pci.h config.h header.h sysdep.h types.h
 
 ifdef PCI_HAVE_PM_LINUX_SYSFS
@@ -88,5 +88,6 @@ names-cache.o: names-cache.c $(INCL) names.h
 names-hash.o: names-hash.c $(INCL) names.h
 names-net.o: names-net.c $(INCL) names.h
 names-parse.o: names-parse.c $(INCL) names.h
+names-hwdb.o: names-hwdb.c $(INCL) names.h
 filter.o: filter.c $(INCL)
 nbsd-libpci.o: nbsd-libpci.c $(INCL)
index d28271e8e3003780f9eb849c059ff0c2ec64c71a..064c9324a4e3f49cdfbc7cb3ba202f61912a6d68 100644 (file)
@@ -82,7 +82,7 @@ pci_mfree(void *x)
 }
 
 char *
-pci_strdup(struct pci_access *a, char *s)
+pci_strdup(struct pci_access *a, const char *s)
 {
   int len = strlen(s) + 1;
   char *t = pci_malloc(a, len);
@@ -162,6 +162,9 @@ pci_alloc(void)
   pci_define_param(a, "net.domain", PCI_ID_DOMAIN, "DNS domain used for resolving of ID's");
   pci_define_param(a, "net.cache_name", "~/.pciids-cache", "Name of the ID cache file");
   a->id_lookup_mode = PCI_LOOKUP_CACHE;
+#endif
+#ifdef PCI_HAVE_HWDB
+  pci_define_param(a, "hwdb.disable", "0", "Do not look up names in UDEV's HWDB if non-zero");
 #endif
   for (i=0; i<PCI_ACCESS_MAX; i++)
     if (pci_methods[i] && pci_methods[i]->config)
index 18a59e2e02db7f02090d93bc3851ae934ff841ee..ea63738afc8d6d7585474040d572a257e92204e7 100644 (file)
@@ -59,7 +59,7 @@ int pci_generic_block_write(struct pci_dev *, int pos, byte *buf, int len);
 /* init.c */
 void *pci_malloc(struct pci_access *, int);
 void pci_mfree(void *);
-char *pci_strdup(struct pci_access *a, char *s);
+char *pci_strdup(struct pci_access *a, const char *s);
 
 /* access.c */
 struct pci_dev *pci_alloc_dev(struct pci_access *);
index 9661d03b308d13be31f22899f0f6eb2f8f21c8b3..2f5bc3cf21e9bd807753f93d8b206c10877ec065 100644 (file)
 #include "internal.h"
 #include "names.h"
 
-#ifdef PCI_HAVE_HWDB
-#include <libudev.h>
-#include <stdio.h>
-#endif
-
 struct id_bucket {
   struct id_bucket *next;
   unsigned int full;
@@ -91,58 +86,8 @@ char
 *pci_id_lookup(struct pci_access *a, int flags, int cat, int id1, int id2, int id3, int id4)
 {
   struct id_entry *n, *best;
-  u32 id12, id34;
-
-#ifdef PCI_HAVE_HWDB
-  if (!(flags & PCI_LOOKUP_SKIP_LOCAL))
-    {
-      char modalias[64];
-      const char *key = NULL;
-      struct udev *udev = udev_new();
-      struct udev_hwdb *hwdb = udev_hwdb_new(udev);
-      struct udev_list_entry *entry;
-
-      switch(cat)
-        {
-        case ID_VENDOR:
-          sprintf(modalias, "pci:v%08X*", id1);
-          key = "ID_VENDOR_FROM_DATABASE";
-          break;
-        case ID_DEVICE:
-          sprintf(modalias, "pci:v%08Xd%08X*", id1, id2);
-          key = "ID_MODEL_FROM_DATABASE";
-          break;
-        case ID_SUBSYSTEM:
-          sprintf(modalias, "pci:v%08Xd%08Xsv%08Xsd%08X*", id1, id2, id3, id4);
-          key = "ID_MODEL_FROM_DATABASE";
-          break;
-        case ID_GEN_SUBSYSTEM:
-          sprintf(modalias, "pci:v*d*sv%08Xsd%08X*", id1, id2);
-          key = "ID_MODEL_FROM_DATABASE";
-          break;
-        case ID_CLASS:
-          sprintf(modalias, "pci:v*d*sv*sd*bc%02X*", id1);
-          key = "ID_PCI_CLASS_FROM_DATABASE";
-          break;
-        case ID_SUBCLASS:
-          sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02X*", id1, id2);
-          key = "ID_PCI_SUBCLASS_FROM_DATABASE";
-          break;
-        case ID_PROGIF:
-          sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02Xi%02X*", id1, id2, id3);
-          key = "ID_PCI_INTERFACE_FROM_DATABASE";
-          break;
-        }
-
-      if (key)
-          udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(hwdb, modalias, 0))
-              if (strcmp(udev_list_entry_get_name(entry), key) == 0)
-                return udev_list_entry_get_value(entry);
-    }
-#endif
-
-  id12 = id_pair(id1, id2);
-  id34 = id_pair(id3, id4);
+  u32 id12 = id_pair(id1, id2);
+  u32 id34 = id_pair(id3, id4);
 
   if (a->id_hash)
     {
@@ -158,6 +103,8 @@ char
            continue;
          if (n->src == SRC_CACHE && !(flags & PCI_LOOKUP_CACHE))
            continue;
+         if (n->src == SRC_HWDB && (flags & (PCI_LOOKUP_SKIP_LOCAL | PCI_LOOKUP_NO_HWDB)))
+           continue;
          if (!best || best->src < n->src)
            best = n;
        }
diff --git a/lib/names-hwdb.c b/lib/names-hwdb.c
new file mode 100644 (file)
index 0000000..07b3499
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ *     The PCI Library -- Looking up Names via UDEV and HWDB
+ *
+ *     Copyright (c) 2013--2014 Tom Gundersen <teg@jklm.no>
+ *     Copyright (c) 2014 Martin Mares <mj@ucw.cz>
+ *
+ *     Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include <string.h>
+
+#include "internal.h"
+#include "names.h"
+
+#ifdef PCI_HAVE_HWDB
+
+#include <libudev.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+char *
+pci_id_hwdb_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4)
+{
+  char modalias[64];
+  const char *key = NULL;
+
+  const char *disabled = pci_get_param(a, "hwdb.disable");
+  if (disabled && atoi(disabled))
+    return NULL;
+
+  switch (cat)
+    {
+    case ID_VENDOR:
+      sprintf(modalias, "pci:v%08X*", id1);
+      key = "ID_VENDOR_FROM_DATABASE";
+      break;
+    case ID_DEVICE:
+      sprintf(modalias, "pci:v%08Xd%08X*", id1, id2);
+      key = "ID_MODEL_FROM_DATABASE";
+      break;
+    case ID_SUBSYSTEM:
+      sprintf(modalias, "pci:v%08Xd%08Xsv%08Xsd%08X*", id1, id2, id3, id4);
+      key = "ID_MODEL_FROM_DATABASE";
+      break;
+    case ID_GEN_SUBSYSTEM:
+      sprintf(modalias, "pci:v*d*sv%08Xsd%08X*", id1, id2);
+      key = "ID_MODEL_FROM_DATABASE";
+      break;
+    case ID_CLASS:
+      sprintf(modalias, "pci:v*d*sv*sd*bc%02X*", id1);
+      key = "ID_PCI_CLASS_FROM_DATABASE";
+      break;
+    case ID_SUBCLASS:
+      sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02X*", id1, id2);
+      key = "ID_PCI_SUBCLASS_FROM_DATABASE";
+      break;
+    case ID_PROGIF:
+      sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02Xi%02X*", id1, id2, id3);
+      key = "ID_PCI_INTERFACE_FROM_DATABASE";
+      break;
+    }
+
+  if (key)
+    {
+      if (!a->id_udev_hwdb)
+       {
+         a->debug("Initializing UDEV HWDB\n");
+         a->id_udev = udev_new();
+         a->id_udev_hwdb = udev_hwdb_new(a->id_udev);
+       }
+
+      struct udev_list_entry *entry;
+      udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(a->id_udev_hwdb, modalias, 0))
+        if (strcmp(udev_list_entry_get_name(entry), key) == 0)
+         return pci_strdup(a, udev_list_entry_get_value(entry));
+    }
+
+  return NULL;
+}
+
+void
+pci_id_hwdb_free(struct pci_access *a)
+{
+  if (a->id_udev_hwdb)
+    {
+      udev_hwdb_unref(a->id_udev_hwdb);
+      a->id_udev_hwdb = NULL;
+    }
+  if (a->id_udev)
+    {
+      udev_unref(a->id_udev);
+      a->id_udev = NULL;
+    }
+}
+
+#else
+
+char *
+pci_id_hwdb_lookup(struct pci_access *a UNUSED, int cat UNUSED, int id1 UNUSED, int id2 UNUSED, int id3 UNUSED, int id4 UNUSED)
+{
+  return NULL;
+}
+
+void
+pci_id_hwdb_free(struct pci_access *a UNUSED)
+{
+}
+
+#endif
index 4997b58bf6c44ab28e24ba61bb6c962cc9632d52..f3b7da9ee1897c4bfc950c50d2de9b0777038c8b 100644 (file)
@@ -238,6 +238,7 @@ pci_free_name_list(struct pci_access *a)
 {
   pci_id_cache_flush(a);
   pci_id_hash_free(a);
+  pci_id_hwdb_free(a);
   a->id_load_failed = 0;
 }
 
index bda8c908fd6cee2fe89ef74a15da1d0c67deba41..d5353a8084407b902c9d57695d4df0f9ff1739e5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library -- ID to Name Translation
  *
- *     Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2014 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -16,6 +16,7 @@
 static char *id_lookup(struct pci_access *a, int flags, int cat, int id1, int id2, int id3, int id4)
 {
   char *name;
+  int tried_hwdb = 0;
 
   while (!(name = pci_id_lookup(a, flags, cat, id1, id2, id3, id4)))
     {
@@ -24,6 +25,15 @@ static char *id_lookup(struct pci_access *a, int flags, int cat, int id1, int id
          if (pci_id_cache_load(a, flags))
            continue;
        }
+      if (!tried_hwdb && !(flags & (PCI_LOOKUP_SKIP_LOCAL | PCI_LOOKUP_NO_HWDB)))
+       {
+         tried_hwdb = 1;
+         if (name = pci_id_hwdb_lookup(a, cat, id1, id2, id3, id4))
+           {
+             pci_id_insert(a, cat, id1, id2, id3, id4, name, SRC_HWDB);
+             continue;
+           }
+       }
       if (flags & PCI_LOOKUP_NETWORK)
         {
          if (name = pci_id_net_lookup(a, cat, id1, id2, id3, id4))
index 81c373fe023cbc628f079066aaf1dbd144ddeff1..d7e71ff7183a8edd67123b4edb4e24d6ec10db17 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library -- ID to Name Translation
  *
- *     Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2014 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -33,6 +33,7 @@ enum id_entry_src {
   SRC_UNKNOWN,
   SRC_CACHE,
   SRC_NET,
+  SRC_HWDB,
   SRC_LOCAL,
 };
 
@@ -67,3 +68,8 @@ void pci_id_hash_free(struct pci_access *a);
 /* names-dns.c */
 
 char *pci_id_net_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4);
+
+/* names-hwdb.c */
+
+char *pci_id_hwdb_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4);
+void pci_id_hwdb_free(struct pci_access *a);
index 0e6edbb03f85c4e3034c57a1bf0a0a40d776554e..4d48cab00b37f9e5946103fa33b7602d874174c5 100644 (file)
@@ -85,4 +85,3 @@ pci_walk_params(struct pci_access *acc, struct pci_param *prev)
   else
     return prev->next;
 }
-
index 37f08e62d40058f1d6752978edcf9c323a941ab1..8b1d02454657339b318e17099274bdc469c71d9e 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -1,7 +1,7 @@
 /*
  *     The PCI Library
  *
- *     Copyright (c) 1997--2013 Martin Mares <mj@ucw.cz>
+ *     Copyright (c) 1997--2014 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
@@ -73,6 +73,8 @@ struct pci_access {
   struct id_bucket *current_id_bucket;
   int id_load_failed;
   int id_cache_status;                 /* 0=not read, 1=read, 2=dirty */
+  struct udev *id_udev;                        /* names-hwdb.c */
+  struct udev_hwdb *id_udev_hwdb;
   int fd;                              /* proc/sys: fd for config space */
   int fd_rw;                           /* proc/sys: fd opened read-write */
   int fd_pos;                          /* proc/sys: current position */
@@ -240,6 +242,7 @@ enum pci_lookup_mode {
   PCI_LOOKUP_SKIP_LOCAL = 0x100000,    /* Do not consult local database */
   PCI_LOOKUP_CACHE = 0x200000,         /* Consult the local cache before using DNS */
   PCI_LOOKUP_REFRESH_CACHE = 0x400000, /* Forget all previously cached entries, but still allow updating the cache */
+  PCI_LOOKUP_NO_HWDB = 0x800000,       /* Do not ask udev's hwdb */
 };
 
 #endif
index 60c0bb1465fd823e38cf95962f22efecc9ab073b..dde7e2f01b2dfcb2fab6fd1303ed400c4da65835 100644 (file)
@@ -104,6 +104,11 @@ DNS domain containing the ID database.
 .B net.cache_name
 Name of the file used for caching of resolved ID's.
 
+.SS Parameters for resolving of ID's via UDEV's HWDB
+.TP
+.B hwdb.disable
+Disable use of HWDB if set to a non-zero value.
+
 .SH SEE ALSO
 
 .BR lspci (8),