From: Martin Mares Date: Tue, 27 Jun 2006 13:13:20 +0000 (+0200) Subject: Add and use PCI_FILL_CLASS. X-Git-Tag: v3.0.0~54 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=c2b144efd9a82291ca7b1bb4f561f427ff18ed7e;p=pciutils.git Add and use PCI_FILL_CLASS. --- diff --git a/ChangeLog b/ChangeLog index 6247337..02f9953 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-06-27 Martin Mares + + * lib/pci.h, lib/generic.c: Added PCI_FILL_CLASS. + + * lib/sysfs.c: Fetch device ID and class from sysfs, because they can + be modified by kernel fixups. + + * lspci.c: Use PCI_FILL_CLASS. Thanks to Matthew Willcox for the patch. + 2006-06-03 Martin Mares * lspci.c: Introduced the -nn switch. Thanks to David N. Welton diff --git a/lib/generic.c b/lib/generic.c index a47bc15..b1b1c8e 100644 --- a/lib/generic.c +++ b/lib/generic.c @@ -86,6 +86,8 @@ pci_generic_fill_info(struct pci_dev *d, int flags) d->vendor_id = pci_read_word(d, PCI_VENDOR_ID); d->device_id = pci_read_word(d, PCI_DEVICE_ID); } + if (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); if (flags & PCI_FILL_BASES) diff --git a/lib/pci.h b/lib/pci.h index 22c336b..8c208b4 100644 --- a/lib/pci.h +++ b/lib/pci.h @@ -86,6 +86,7 @@ struct pci_dev { /* These fields are set by pci_fill_info() */ int known_fields; /* Set of info fields already known */ u16 vendor_id, device_id; /* Identity of the device */ + u16 device_class; /* PCI device class */ int irq; /* IRQ number */ pciaddr_t base_addr[6]; /* Base addresses */ pciaddr_t size[6]; /* Region sizes */ @@ -120,6 +121,7 @@ int pci_fill_info(struct pci_dev *, int flags); /* Fill in device information */ #define PCI_FILL_BASES 4 #define PCI_FILL_ROM_BASE 8 #define PCI_FILL_SIZES 16 +#define PCI_FILL_CLASS 32 #define PCI_FILL_RESCAN 0x10000 void pci_setup_cache(struct pci_dev *, u8 *cache, int len); diff --git a/lib/sysfs.c b/lib/sysfs.c index 70419ec..a6cbd57 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -163,18 +163,14 @@ static void sysfs_scan(struct pci_access *a) { sysfs_get_resources(d); d->irq = sysfs_get_value(d, "irq"); - d->known_fields = PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES; -#if 0 /* - * We prefer reading these from the config registers, it's faster. - * However, it would be possible and maybe even useful to hack the kernel - * to believe that some device has a different ID. If you do it, just - * enable this piece of code. --mj + * We could read these faster from the config registers, but we want to give + * the kernel a chance to fix up ID's and especially classes of broken devices. */ d->vendor_id = sysfs_get_value(d, "vendor"); d->device_id = sysfs_get_value(d, "device"); - d->known_fields |= PCI_FILL_IDENT; -#endif + d->device_class = sysfs_get_value(d, "class") >> 8; + d->known_fields = PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES; } pci_link_dev(a, d); } diff --git a/lspci.c b/lspci.c index 84a23e5..0d7c3a8 100644 --- a/lspci.c +++ b/lspci.c @@ -130,7 +130,7 @@ scan_device(struct pci_dev *p) d->config_cached += 64; } pci_setup_cache(p, d->config, d->config_cached); - pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); + pci_fill_info(p, PCI_FILL_IDENT | PCI_FILL_CLASS | PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE | PCI_FILL_SIZES); return d; } @@ -262,7 +262,7 @@ show_terse(struct device *d) printf(" %s: %s", pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, - get_conf_word(d, PCI_CLASS_DEVICE)), + p->device_class), pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, p->vendor_id, p->device_id)); @@ -274,7 +274,7 @@ show_terse(struct device *d) c = get_conf_byte(d, PCI_CLASS_PROG); x = pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_PROGIF | PCI_LOOKUP_NO_NUMBERS, - get_conf_word(d, PCI_CLASS_DEVICE), c); + p->device_class, c); if (c || x) { printf(" (prog-if %02x", c); @@ -1592,7 +1592,7 @@ show_verbose(struct device *d) struct pci_dev *p = d->dev; word status = get_conf_word(d, PCI_STATUS); word cmd = get_conf_word(d, PCI_COMMAND); - word class = get_conf_word(d, PCI_CLASS_DEVICE); + word class = p->device_class; byte bist = get_conf_byte(d, PCI_BIST); byte htype = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; byte latency = get_conf_byte(d, PCI_LATENCY_TIMER); @@ -1790,7 +1790,7 @@ show_machine(struct device *d) show_slot_name(d); putchar('\n'); printf("Class:\t%s\n", - pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, get_conf_word(d, PCI_CLASS_DEVICE))); + pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, p->device_class)); printf("Vendor:\t%s\n", pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id)); printf("Device:\t%s\n", @@ -1812,7 +1812,7 @@ show_machine(struct device *d) show_slot_name(d); printf(" \"%s\" \"%s\" \"%s\"", pci_lookup_name(pacc, classbuf, sizeof(classbuf), PCI_LOOKUP_CLASS, - get_conf_word(d, PCI_CLASS_DEVICE)), + p->device_class), pci_lookup_name(pacc, vendbuf, sizeof(vendbuf), PCI_LOOKUP_VENDOR, p->vendor_id, p->device_id), pci_lookup_name(pacc, devbuf, sizeof(devbuf), PCI_LOOKUP_DEVICE, @@ -1936,7 +1936,7 @@ grow_tree(void) last_br = &host_bridge.chain; for(d=first_dev; d; d=d->next) { - word class = get_conf_word(d, PCI_CLASS_DEVICE); + word class = d->dev->device_class; byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f; if (class == PCI_CLASS_BRIDGE_PCI && (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS))