]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names.c
2 * The PCI Library -- ID to Name Translation
4 * Copyright (c) 1997--2014 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
16 static char *id_lookup(struct pci_access
*a
, int flags
, int cat
, int id1
, int id2
, int id3
, int id4
)
21 while (!(name
= pci_id_lookup(a
, flags
, cat
, id1
, id2
, id3
, id4
)))
23 if ((flags
& PCI_LOOKUP_CACHE
) && !a
->id_cache_status
)
25 if (pci_id_cache_load(a
, flags
))
28 if (!tried_hwdb
&& !(flags
& (PCI_LOOKUP_SKIP_LOCAL
| PCI_LOOKUP_NO_HWDB
)))
31 if (name
= pci_id_hwdb_lookup(a
, cat
, id1
, id2
, id3
, id4
))
33 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, name
, SRC_HWDB
);
37 if (flags
& PCI_LOOKUP_NETWORK
)
39 if (name
= pci_id_net_lookup(a
, cat
, id1
, id2
, id3
, id4
))
41 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, name
, SRC_NET
);
43 pci_id_cache_dirty(a
);
46 pci_id_insert(a
, cat
, id1
, id2
, id3
, id4
, "", SRC_NET
);
47 /* We want to iterate the lookup to get the allocated ID entry from the hash */
52 return (name
[0] ? name
: NULL
);
56 id_lookup_subsys(struct pci_access
*a
, int flags
, int iv
, int id
, int isv
, int isd
)
59 if (iv
> 0 && id
> 0) /* Per-device lookup */
60 d
= id_lookup(a
, flags
, ID_SUBSYSTEM
, iv
, id
, isv
, isd
);
61 if (!d
) /* Generic lookup */
62 d
= id_lookup(a
, flags
, ID_GEN_SUBSYSTEM
, isv
, isd
, 0, 0);
63 if (!d
&& iv
== isv
&& id
== isd
) /* Check for subsystem == device */
64 d
= id_lookup(a
, flags
, ID_DEVICE
, iv
, id
, 0, 0);
69 format_name(char *buf
, int size
, int flags
, char *name
, char *num
, char *unknown
)
72 if ((flags
& PCI_LOOKUP_NO_NUMBERS
) && !name
)
74 else if (flags
& PCI_LOOKUP_NUMERIC
)
75 res
= snprintf(buf
, size
, "%s", num
);
77 res
= snprintf(buf
, size
, ((flags
& PCI_LOOKUP_MIXED
) ? "%s [%s]" : "%s %s"), unknown
, num
);
78 else if (!(flags
& PCI_LOOKUP_MIXED
))
79 res
= snprintf(buf
, size
, "%s", name
);
81 res
= snprintf(buf
, size
, "%s [%s]", name
, num
);
82 if (res
>= size
&& size
>= 4)
83 buf
[size
-2] = buf
[size
-3] = buf
[size
-4] = '.';
84 else if (res
< 0 || res
>= size
)
85 return "<pci_lookup_name: buffer too small>";
90 format_name_pair(char *buf
, int size
, int flags
, char *v
, char *d
, char *num
)
93 if ((flags
& PCI_LOOKUP_NO_NUMBERS
) && (!v
|| !d
))
95 if (flags
& PCI_LOOKUP_NUMERIC
)
96 res
= snprintf(buf
, size
, "%s", num
);
97 else if (flags
& PCI_LOOKUP_MIXED
)
100 res
= snprintf(buf
, size
, "%s %s [%s]", v
, d
, num
);
102 res
= snprintf(buf
, size
, "Device [%s]", num
);
104 res
= snprintf(buf
, size
, "%s Device [%s]", v
, num
);
109 res
= snprintf(buf
, size
, "%s %s", v
, d
);
111 res
= snprintf(buf
, size
, "Device %s", num
);
113 res
= snprintf(buf
, size
, "%s Device %s", v
, num
+5);
115 if (res
>= size
&& size
>= 4)
116 buf
[size
-2] = buf
[size
-3] = buf
[size
-4] = '.';
117 else if (res
< 0 || res
>= size
)
118 return "<pci_lookup_name: buffer too small>";
123 pci_lookup_name(struct pci_access
*a
, char *buf
, int size
, int flags
, ...)
126 char *v
, *d
, *cls
, *pif
;
127 int iv
, id
, isv
, isd
, icls
, ipif
;
128 char numbuf
[16], pifbuf
[32];
130 va_start(args
, flags
);
132 flags
|= a
->id_lookup_mode
;
133 if (!(flags
& PCI_LOOKUP_NO_NUMBERS
))
135 if (a
->numeric_ids
> 1)
136 flags
|= PCI_LOOKUP_MIXED
;
137 else if (a
->numeric_ids
)
138 flags
|= PCI_LOOKUP_NUMERIC
;
140 if (flags
& PCI_LOOKUP_MIXED
)
141 flags
&= ~PCI_LOOKUP_NUMERIC
;
143 if (!a
->id_hash
&& !(flags
& (PCI_LOOKUP_NUMERIC
| PCI_LOOKUP_SKIP_LOCAL
)) && !a
->id_load_failed
)
144 pci_load_name_list(a
);
146 switch (flags
& 0xffff)
148 case PCI_LOOKUP_VENDOR
:
149 iv
= va_arg(args
, int);
150 sprintf(numbuf
, "%04x", iv
);
151 return format_name(buf
, size
, flags
, id_lookup(a
, flags
, ID_VENDOR
, iv
, 0, 0, 0), numbuf
, "Vendor");
152 case PCI_LOOKUP_DEVICE
:
153 iv
= va_arg(args
, int);
154 id
= va_arg(args
, int);
155 sprintf(numbuf
, "%04x", id
);
156 return format_name(buf
, size
, flags
, id_lookup(a
, flags
, ID_DEVICE
, iv
, id
, 0, 0), numbuf
, "Device");
157 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_DEVICE
:
158 iv
= va_arg(args
, int);
159 id
= va_arg(args
, int);
160 sprintf(numbuf
, "%04x:%04x", iv
, id
);
161 v
= id_lookup(a
, flags
, ID_VENDOR
, iv
, 0, 0, 0);
162 d
= id_lookup(a
, flags
, ID_DEVICE
, iv
, id
, 0, 0);
163 return format_name_pair(buf
, size
, flags
, v
, d
, numbuf
);
164 case PCI_LOOKUP_SUBSYSTEM
| PCI_LOOKUP_VENDOR
:
165 isv
= va_arg(args
, int);
166 sprintf(numbuf
, "%04x", isv
);
167 v
= id_lookup(a
, flags
, ID_VENDOR
, isv
, 0, 0, 0);
168 return format_name(buf
, size
, flags
, v
, numbuf
, "Unknown vendor");
169 case PCI_LOOKUP_SUBSYSTEM
| PCI_LOOKUP_DEVICE
:
170 iv
= va_arg(args
, int);
171 id
= va_arg(args
, int);
172 isv
= va_arg(args
, int);
173 isd
= va_arg(args
, int);
174 sprintf(numbuf
, "%04x", isd
);
175 return format_name(buf
, size
, flags
, id_lookup_subsys(a
, flags
, iv
, id
, isv
, isd
), numbuf
, "Device");
176 case PCI_LOOKUP_VENDOR
| PCI_LOOKUP_DEVICE
| PCI_LOOKUP_SUBSYSTEM
:
177 iv
= va_arg(args
, int);
178 id
= va_arg(args
, int);
179 isv
= va_arg(args
, int);
180 isd
= va_arg(args
, int);
181 v
= id_lookup(a
, flags
, ID_VENDOR
, isv
, 0, 0, 0);
182 d
= id_lookup_subsys(a
, flags
, iv
, id
, isv
, isd
);
183 sprintf(numbuf
, "%04x:%04x", isv
, isd
);
184 return format_name_pair(buf
, size
, flags
, v
, d
, numbuf
);
185 case PCI_LOOKUP_CLASS
:
186 icls
= va_arg(args
, int);
187 sprintf(numbuf
, "%04x", icls
);
188 cls
= id_lookup(a
, flags
, ID_SUBCLASS
, icls
>> 8, icls
& 0xff, 0, 0);
189 if (!cls
&& (cls
= id_lookup(a
, flags
, ID_CLASS
, icls
>> 8, 0, 0, 0)))
191 if (!(flags
& PCI_LOOKUP_NUMERIC
)) /* Include full class number */
192 flags
|= PCI_LOOKUP_MIXED
;
194 return format_name(buf
, size
, flags
, cls
, numbuf
, "Class");
195 case PCI_LOOKUP_PROGIF
:
196 icls
= va_arg(args
, int);
197 ipif
= va_arg(args
, int);
198 sprintf(numbuf
, "%02x", ipif
);
199 pif
= id_lookup(a
, flags
, ID_PROGIF
, icls
>> 8, icls
& 0xff, ipif
, 0);
200 if (!pif
&& icls
== 0x0101 && !(ipif
& 0x70))
202 /* IDE controllers have complex prog-if semantics */
203 sprintf(pifbuf
, "%s%s%s%s%s",
204 (ipif
& 0x80) ? " Master" : "",
205 (ipif
& 0x08) ? " SecP" : "",
206 (ipif
& 0x04) ? " SecO" : "",
207 (ipif
& 0x02) ? " PriP" : "",
208 (ipif
& 0x01) ? " PriO" : "");
213 return format_name(buf
, size
, flags
, pif
, numbuf
, "ProgIf");
215 return "<pci_lookup_name: invalid request>";