/* 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 */
#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);
{
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);
}
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;
}
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));
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);
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);
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",
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,
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))