xref: /aosp_15_r20/external/pciutils/lib/names-hwdb.c (revision c2e0c6b56a71da9abe8df5c8348fb3eb5c2c9251)
1 /*
2  *	The PCI Library -- Looking up Names via UDEV and HWDB
3  *
4  *	Copyright (c) 2013--2014 Tom Gundersen <[email protected]>
5  *	Copyright (c) 2014 Martin Mares <[email protected]>
6  *
7  *	Can be freely distributed and used under the terms of the GNU GPL v2+.
8  *
9  *	SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include <string.h>
13 
14 #include "internal.h"
15 #include "names.h"
16 
17 #ifdef PCI_HAVE_HWDB
18 
19 #include <libudev.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 
23 char *
pci_id_hwdb_lookup(struct pci_access * a,int cat,int id1,int id2,int id3,int id4 UNUSED)24 pci_id_hwdb_lookup(struct pci_access *a, int cat, int id1, int id2, int id3, int id4 UNUSED)
25 {
26   char modalias[64];
27   const char *key = NULL;
28 
29   const char *disabled = pci_get_param(a, "hwdb.disable");
30   if (disabled && atoi(disabled))
31     return NULL;
32 
33   switch (cat)
34     {
35     case ID_VENDOR:
36       sprintf(modalias, "pci:v%08X*", id1);
37       key = "ID_VENDOR_FROM_DATABASE";
38       break;
39     case ID_DEVICE:
40       sprintf(modalias, "pci:v%08Xd%08X*", id1, id2);
41       key = "ID_MODEL_FROM_DATABASE";
42       break;
43     case ID_SUBSYSTEM:
44       /*
45        * There is no udev hwdb key which returns subsystem. Also note that query
46        * modalias "pci:v%08Xd%08Xsv%08Xsd%08X*" matches also hwdb device with
47        * modalias "pci:v%08Xd%08Xsv*sd*" (which is the default modalias), so
48        * there is no way to get information specific for the subsystem.
49        */
50       return NULL;
51     case ID_GEN_SUBSYSTEM:
52       /* There is no udev hwdb key which returns generic subsystem. */
53       return NULL;
54     case ID_CLASS:
55       sprintf(modalias, "pci:v*d*sv*sd*bc%02X*", id1);
56       key = "ID_PCI_CLASS_FROM_DATABASE";
57       break;
58     case ID_SUBCLASS:
59       sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02X*", id1, id2);
60       key = "ID_PCI_SUBCLASS_FROM_DATABASE";
61       break;
62     case ID_PROGIF:
63       sprintf(modalias, "pci:v*d*sv*sd*bc%02Xsc%02Xi%02X*", id1, id2, id3);
64       key = "ID_PCI_INTERFACE_FROM_DATABASE";
65       break;
66     }
67 
68   if (key)
69     {
70       if (!a->id_udev_hwdb)
71 	{
72 	  a->debug("Initializing UDEV HWDB\n");
73 	  a->id_udev = udev_new();
74 	  a->id_udev_hwdb = udev_hwdb_new(a->id_udev);
75 	}
76 
77       struct udev_list_entry *entry;
78       udev_list_entry_foreach(entry, udev_hwdb_get_properties_list_entry(a->id_udev_hwdb, modalias, 0))
79 	{
80 	  const char *entry_name = udev_list_entry_get_name(entry);
81 	  if (entry_name && !strcmp(entry_name, key))
82 	    {
83 	      const char *entry_value = udev_list_entry_get_value(entry);
84 	      if (entry_value)
85 		return pci_strdup(a, entry_value);
86 	    }
87 	}
88     }
89 
90   return NULL;
91 }
92 
93 void
pci_id_hwdb_free(struct pci_access * a)94 pci_id_hwdb_free(struct pci_access *a)
95 {
96   if (a->id_udev_hwdb)
97     {
98       udev_hwdb_unref(a->id_udev_hwdb);
99       a->id_udev_hwdb = NULL;
100     }
101   if (a->id_udev)
102     {
103       udev_unref(a->id_udev);
104       a->id_udev = NULL;
105     }
106 }
107 
108 #else
109 
110 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)111 pci_id_hwdb_lookup(struct pci_access *a UNUSED, int cat UNUSED, int id1 UNUSED, int id2 UNUSED, int id3 UNUSED, int id4 UNUSED)
112 {
113   return NULL;
114 }
115 
116 void
pci_id_hwdb_free(struct pci_access * a UNUSED)117 pci_id_hwdb_free(struct pci_access *a UNUSED)
118 {
119 }
120 
121 #endif
122