Rev 1302 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1302 | Rev 1324 | ||
|---|---|---|---|
| Line 1... | Line 1... | ||
| 1 | /* |
1 | /* |
| 2 | * The PCI Library -- ID to Name Translation |
2 | * The PCI Library -- ID to Name Translation |
| 3 | * |
3 | * |
| 4 | * Copyright (c) 1997--2005 Martin Mares <mj@ucw.cz> |
4 | * Copyright (c) 1997--2005 Martin Mares <mj@ucw.cz> |
| 5 | * |
5 | * |
| 6 | * Modified and ported to HelenOS by Jakub Jermar. |
6 | * May 8, 2006 - Modified and ported to HelenOS by Jakub Jermar. |
| 7 | * |
7 | * |
| 8 | * Can be freely distributed and used under the terms of the GNU GPL. |
8 | * Can be freely distributed and used under the terms of the GNU GPL. |
| 9 | */ |
9 | */ |
| 10 | 10 | ||
| 11 | #include <stdio.h> |
11 | #include <stdio.h> |
| Line 173... | Line 173... | ||
| 173 | p++; |
173 | p++; |
| 174 | nest = p - line; |
174 | nest = p - line; |
| 175 | 175 | ||
| 176 | if (!nest) { /* Top-level entries */ |
176 | if (!nest) { /* Top-level entries */ |
| 177 | if (p[0] == 'C' && p[1] == ' ') { /* Class block */ |
177 | if (p[0] == 'C' && p[1] == ' ') { /* Class block */ |
| 178 | if ((id1 = id_hex(p + 2, 2)) < 0 |
178 | if ((id1 = id_hex(p + 2, 2)) < 0 || !id_white_p(p[4])) |
| 179 | || !id_white_p(p[4])) |
- | |
| 180 | return parse_error; |
179 | return parse_error; |
| 181 | cat = ID_CLASS; |
180 | cat = ID_CLASS; |
| 182 | p += 5; |
181 | p += 5; |
| 183 | } else if (p[0] == 'S' && p[1] == ' ') { /* Generic subsystem block */ |
182 | } else if (p[0] == 'S' && p[1] == ' ') { /* Generic subsystem block */ |
| 184 | if ((id1 = id_hex(p + 2, 4)) < 0 || p[6]) |
183 | if ((id1 = id_hex(p + 2, 4)) < 0 || p[6]) |
| Line 190... | Line 189... | ||
| 190 | } else if (p[0] >= 'A' && p[0] <= 'Z' && p[1] == ' ') { /* Unrecognized block (RFU) */ |
189 | } else if (p[0] >= 'A' && p[0] <= 'Z' && p[1] == ' ') { /* Unrecognized block (RFU) */ |
| 191 | cat = ID_UNKNOWN; |
190 | cat = ID_UNKNOWN; |
| 192 | continue; |
191 | continue; |
| 193 | } else { /* Vendor ID */ |
192 | } else { /* Vendor ID */ |
| 194 | 193 | ||
| 195 | if ((id1 = id_hex(p, 4)) < 0 |
194 | if ((id1 = id_hex(p, 4)) < 0 || !id_white_p(p[4])) |
| 196 | || !id_white_p(p[4])) |
- | |
| 197 | return parse_error; |
195 | return parse_error; |
| 198 | cat = ID_VENDOR; |
196 | cat = ID_VENDOR; |
| 199 | p += 5; |
197 | p += 5; |
| 200 | } |
198 | } |
| 201 | id2 = id3 = id4 = 0; |
199 | id2 = id3 = id4 = 0; |
| Line 204... | Line 202... | ||
| 204 | else if (nest == 1) /* Nesting level 1 */ |
202 | else if (nest == 1) /* Nesting level 1 */ |
| 205 | switch (cat) { |
203 | switch (cat) { |
| 206 | case ID_VENDOR: |
204 | case ID_VENDOR: |
| 207 | case ID_DEVICE: |
205 | case ID_DEVICE: |
| 208 | case ID_SUBSYSTEM: |
206 | case ID_SUBSYSTEM: |
| 209 | if ((id2 = id_hex(p, 4)) < 0 |
207 | if ((id2 = id_hex(p, 4)) < 0 || !id_white_p(p[4])) |
| 210 | || !id_white_p(p[4])) |
- | |
| 211 | return parse_error; |
208 | return parse_error; |
| 212 | p += 5; |
209 | p += 5; |
| 213 | cat = ID_DEVICE; |
210 | cat = ID_DEVICE; |
| 214 | id3 = id4 = 0; |
211 | id3 = id4 = 0; |
| 215 | break; |
212 | break; |
| 216 | case ID_GEN_SUBSYSTEM: |
213 | case ID_GEN_SUBSYSTEM: |
| 217 | if ((id2 = id_hex(p, 4)) < 0 |
214 | if ((id2 = id_hex(p, 4)) < 0 || !id_white_p(p[4])) |
| 218 | || !id_white_p(p[4])) |
- | |
| 219 | return parse_error; |
215 | return parse_error; |
| 220 | p += 5; |
216 | p += 5; |
| 221 | id3 = id4 = 0; |
217 | id3 = id4 = 0; |
| 222 | break; |
218 | break; |
| 223 | case ID_CLASS: |
219 | case ID_CLASS: |
| 224 | case ID_SUBCLASS: |
220 | case ID_SUBCLASS: |
| 225 | case ID_PROGIF: |
221 | case ID_PROGIF: |
| 226 | if ((id2 = id_hex(p, 2)) < 0 |
222 | if ((id2 = id_hex(p, 2)) < 0 || !id_white_p(p[2])) |
| 227 | || !id_white_p(p[2])) |
- | |
| 228 | return parse_error; |
223 | return parse_error; |
| 229 | p += 3; |
224 | p += 3; |
| 230 | cat = ID_SUBCLASS; |
225 | cat = ID_SUBCLASS; |
| 231 | id3 = id4 = 0; |
226 | id3 = id4 = 0; |
| 232 | break; |
227 | break; |
| Line 234... | Line 229... | ||
| 234 | return parse_error; |
229 | return parse_error; |
| 235 | } else if (nest == 2) /* Nesting level 2 */ |
230 | } else if (nest == 2) /* Nesting level 2 */ |
| 236 | switch (cat) { |
231 | switch (cat) { |
| 237 | case ID_DEVICE: |
232 | case ID_DEVICE: |
| 238 | case ID_SUBSYSTEM: |
233 | case ID_SUBSYSTEM: |
| 239 | if ((id3 = id_hex(p, 4)) < 0 |
234 | if ((id3 = id_hex(p, 4)) < 0 || !id_white_p(p[4]) |
| 240 | || !id_white_p(p[4]) |
- | |
| 241 | || (id4 = id_hex(p + 5, 4)) < 0 |
235 | || (id4 = id_hex(p + 5, 4)) < 0 || !id_white_p(p[9])) |
| 242 | || !id_white_p(p[9])) |
- | |
| 243 | return parse_error; |
236 | return parse_error; |
| 244 | p += 10; |
237 | p += 10; |
| 245 | cat = ID_SUBSYSTEM; |
238 | cat = ID_SUBSYSTEM; |
| 246 | break; |
239 | break; |
| 247 | case ID_CLASS: |
240 | case ID_CLASS: |
| 248 | case ID_SUBCLASS: |
241 | case ID_SUBCLASS: |
| 249 | case ID_PROGIF: |
242 | case ID_PROGIF: |
| 250 | if ((id3 = id_hex(p, 2)) < 0 |
243 | if ((id3 = id_hex(p, 2)) < 0 || !id_white_p(p[2])) |
| 251 | || !id_white_p(p[2])) |
- | |
| 252 | return parse_error; |
244 | return parse_error; |
| 253 | p += 3; |
245 | p += 3; |
| 254 | cat = ID_PROGIF; |
246 | cat = ID_PROGIF; |
| 255 | id4 = 0; |
247 | id4 = 0; |
| 256 | break; |
248 | break; |
| Line 339... | Line 331... | ||
| 339 | if (num) |
331 | if (num) |
| 340 | res = snprintf(buf, size, "%04x", iv); |
332 | res = snprintf(buf, size, "%04x", iv); |
| 341 | else if (v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0)) |
333 | else if (v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0)) |
| 342 | return (char *) v->name; |
334 | return (char *) v->name; |
| 343 | else |
335 | else |
| 344 | res = |
- | |
| 345 | snprintf(buf, size, "Unknown vendor %04x", iv); |
336 | res = snprintf(buf, size, "Unknown vendor %04x", iv); |
| 346 | break; |
337 | break; |
| 347 | case PCI_LOOKUP_DEVICE: |
338 | case PCI_LOOKUP_DEVICE: |
| 348 | iv = va_arg(args, int); |
339 | iv = va_arg(args, int); |
| 349 | id = va_arg(args, int); |
340 | id = va_arg(args, int); |
| 350 | if (num) |
341 | if (num) |
| 351 | res = snprintf(buf, size, "%04x", id); |
342 | res = snprintf(buf, size, "%04x", id); |
| 352 | else if (d = id_lookup(a, ID_DEVICE, iv, id, 0, 0)) |
343 | else if (d = id_lookup(a, ID_DEVICE, iv, id, 0, 0)) |
| 353 | return (char *) d->name; |
344 | return (char *) d->name; |
| 354 | else if (synth) |
345 | else if (synth) |
| 355 | res = |
- | |
| 356 | snprintf(buf, size, "Unknown device %04x", id); |
346 | res = snprintf(buf, size, "Unknown device %04x", id); |
| 357 | else |
347 | else |
| 358 | return NULL; |
348 | return NULL; |
| 359 | break; |
349 | break; |
| 360 | case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE: |
350 | case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE: |
| 361 | iv = va_arg(args, int); |
351 | iv = va_arg(args, int); |
| Line 364... | Line 354... | ||
| 364 | res = snprintf(buf, size, "%04x:%04x", iv, id); |
354 | res = snprintf(buf, size, "%04x:%04x", iv, id); |
| 365 | else { |
355 | else { |
| 366 | v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0); |
356 | v = id_lookup(a, ID_VENDOR, iv, 0, 0, 0); |
| 367 | d = id_lookup(a, ID_DEVICE, iv, id, 0, 0); |
357 | d = id_lookup(a, ID_DEVICE, iv, id, 0, 0); |
| 368 | if (v && d) |
358 | if (v && d) |
| 369 | res = |
- | |
| 370 | snprintf(buf, size, "%s %s", v->name, |
359 | res = snprintf(buf, size, "%s %s", v->name, |
| 371 | d->name); |
360 | d->name); |
| 372 | else if (!synth) |
361 | else if (!synth) |
| 373 | return NULL; |
362 | return NULL; |
| 374 | else if (!v) |
363 | else if (!v) |
| 375 | res = |
- | |
| 376 | snprintf(buf, size, |
- | |
| 377 | "Unknown device %04x:%04x", |
364 | res = snprintf(buf, size, "Unknown device %04x:%04x", iv, id); |
| 378 | iv, id); |
- | |
| 379 | else /* !d */ |
365 | else /* !d */ |
| 380 | res = |
- | |
| 381 | snprintf(buf, size, |
- | |
| 382 | "%s Unknown device %04x", |
366 | res = snprintf(buf, size, "%s Unknown device %04x", v->name, id); |
| 383 | v->name, id); |
- | |
| 384 | } |
367 | } |
| 385 | break; |
368 | break; |
| 386 | case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR: |
369 | case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_VENDOR: |
| 387 | isv = va_arg(args, int); |
370 | isv = va_arg(args, int); |
| 388 | if (num) |
371 | if (num) |
| 389 | res = snprintf(buf, size, "%04x", isv); |
372 | res = snprintf(buf, size, "%04x", isv); |
| 390 | else if (v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0)) |
373 | else if (v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0)) |
| 391 | return (char *) v->name; |
374 | return (char *) v->name; |
| 392 | else if (synth) |
375 | else if (synth) |
| 393 | res = |
- | |
| 394 | snprintf(buf, size, "Unknown vendor %04x", |
376 | res = snprintf(buf, size, "Unknown vendor %04x", isv); |
| 395 | isv); |
- | |
| 396 | else |
377 | else |
| 397 | return NULL; |
378 | return NULL; |
| 398 | break; |
379 | break; |
| 399 | case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE: |
380 | case PCI_LOOKUP_SUBSYSTEM | PCI_LOOKUP_DEVICE: |
| 400 | iv = va_arg(args, int); |
381 | iv = va_arg(args, int); |
| Line 404... | Line 385... | ||
| 404 | if (num) |
385 | if (num) |
| 405 | res = snprintf(buf, size, "%04x", isd); |
386 | res = snprintf(buf, size, "%04x", isd); |
| 406 | else if (d = id_lookup_subsys(a, iv, id, isv, isd)) |
387 | else if (d = id_lookup_subsys(a, iv, id, isv, isd)) |
| 407 | return (char *) d->name; |
388 | return (char *) d->name; |
| 408 | else if (synth) |
389 | else if (synth) |
| 409 | res = |
- | |
| 410 | snprintf(buf, size, "Unknown device %04x", |
390 | res = snprintf(buf, size, "Unknown device %04x", isd); |
| 411 | isd); |
- | |
| 412 | else |
391 | else |
| 413 | return NULL; |
392 | return NULL; |
| 414 | break; |
393 | break; |
| 415 | case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM: |
394 | case PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM: |
| 416 | iv = va_arg(args, int); |
395 | iv = va_arg(args, int); |
| Line 421... | Line 400... | ||
| 421 | res = snprintf(buf, size, "%04x:%04x", isv, isd); |
400 | res = snprintf(buf, size, "%04x:%04x", isv, isd); |
| 422 | else { |
401 | else { |
| 423 | v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0); |
402 | v = id_lookup(a, ID_VENDOR, isv, 0, 0, 0); |
| 424 | d = id_lookup_subsys(a, iv, id, isv, isd); |
403 | d = id_lookup_subsys(a, iv, id, isv, isd); |
| 425 | if (v && d) |
404 | if (v && d) |
| 426 | res = |
- | |
| 427 | snprintf(buf, size, "%s %s", v->name, |
405 | res = snprintf(buf, size, "%s %s", v->name, d->name); |
| 428 | d->name); |
- | |
| 429 | else if (!synth) |
406 | else if (!synth) |
| 430 | return NULL; |
407 | return NULL; |
| 431 | else if (!v) |
408 | else if (!v) |
| 432 | res = |
- | |
| 433 | snprintf(buf, size, |
- | |
| 434 | "Unknown device %04x:%04x", |
409 | res = snprintf(buf, size, "Unknown device %04x:%04x", isv, isd); |
| 435 | isv, isd); |
- | |
| 436 | else /* !d */ |
410 | else /* !d */ |
| 437 | res = |
- | |
| 438 | snprintf(buf, size, |
- | |
| 439 | "%s Unknown device %04x", |
411 | res = snprintf(buf, size, "%s Unknown device %04x", v->name, isd); |
| 440 | v->name, isd); |
- | |
| 441 | } |
412 | } |
| 442 | break; |
413 | break; |
| 443 | case PCI_LOOKUP_CLASS: |
414 | case PCI_LOOKUP_CLASS: |
| 444 | icls = va_arg(args, int); |
415 | icls = va_arg(args, int); |
| 445 | if (num) |
416 | if (num) |
| 446 | res = snprintf(buf, size, "%04x", icls); |
417 | res = snprintf(buf, size, "%04x", icls); |
| 447 | else if (cls = |
- | |
| 448 | id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, |
418 | else if (cls = id_lookup(a, ID_SUBCLASS, icls >> 8, icls & 0xff, 0, 0)) |
| 449 | 0, 0)) |
- | |
| 450 | return (char *) cls->name; |
419 | return (char *) cls->name; |
| 451 | else if (cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0)) |
420 | else if (cls = id_lookup(a, ID_CLASS, icls, 0, 0, 0)) |
| 452 | res = |
- | |
| 453 | snprintf(buf, size, "%s [%04x]", cls->name, |
421 | res = snprintf(buf, size, "%s [%04x]", cls->name, icls); |
| 454 | icls); |
- | |
| 455 | else if (synth) |
422 | else if (synth) |
| 456 | res = snprintf(buf, size, "Class %04x", icls); |
423 | res = snprintf(buf, size, "Class %04x", icls); |
| 457 | else |
424 | else |
| 458 | return NULL; |
425 | return NULL; |
| 459 | break; |
426 | break; |
| 460 | case PCI_LOOKUP_PROGIF: |
427 | case PCI_LOOKUP_PROGIF: |
| 461 | icls = va_arg(args, int); |
428 | icls = va_arg(args, int); |
| 462 | ipif = va_arg(args, int); |
429 | ipif = va_arg(args, int); |
| 463 | if (num) |
430 | if (num) |
| 464 | res = snprintf(buf, size, "%02x", ipif); |
431 | res = snprintf(buf, size, "%02x", ipif); |
| 465 | else if (pif = |
- | |
| 466 | id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, |
432 | else if (pif = id_lookup(a, ID_PROGIF, icls >> 8, icls & 0xff, ipif, 0)) |
| 467 | ipif, 0)) |
- | |
| 468 | return (char *) pif->name; |
433 | return (char *) pif->name; |
| 469 | else if (icls == 0x0101 && !(ipif & 0x70)) { |
434 | else if (icls == 0x0101 && !(ipif & 0x70)) { |
| 470 | /* IDE controllers have complex prog-if semantics */ |
435 | /* IDE controllers have complex prog-if semantics */ |
| 471 | res = snprintf(buf, size, "%s%s%s%s%s", |
436 | res = snprintf(buf, size, "%s%s%s%s%s", |
| 472 | (ipif & 0x80) ? "Master " : "", |
437 | (ipif & 0x80) ? "Master " : "", |