15
votes

The first few fields of 'cat /proc/bus/pci/devices' are understandable.

Field 1 - BusDevFunc
Field 2 - Vendor Id + Device Id
Field 3 - Interrupt Line
Field 4 - BAR 0
and the rest of the BAR registers (0 - 5) after that.

After the BAR registers are printed out, what are the other fields? Specifically, what PCI configuration space registers(offsets) are printed out?

1
I did serverfault.com/questions/139670/… Should this be closed out?vivekian2
You should remove your doubled question entirely from serverfault.com; afterwards feel free to flag this question here to be moved over to serverfault. (As an incentive, I downvoted you there. – When you remove your q/a on serverfault, you regain the reputation.)Robert Siemer
Why would you want the question to be moved to serverfault? This is a programming question. I can remove it from serverfault if required or point to this answer here. But moving it makes no sense.vivekian2
Well you know it already points to stackoverflow answer. So, I don't know why you did a downvote. Whatever.vivekian2

1 Answers

20
votes

This is the corresponding code in the kernel:

static int show_device(struct seq_file *m, void *v)
{
    const struct pci_dev *dev = v;
    const struct pci_driver *drv;
    int i;

    if (dev == NULL)
        return 0;

    drv = pci_dev_driver(dev);
    seq_printf(m, "%02x%02x\t%04x%04x\t%x",
            dev->bus->number,
            dev->devfn,
            dev->vendor,
            dev->device,
            dev->irq);
    /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */
    for (i=0; i<7; i++) {
        resource_size_t start, end;
        pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
        seq_printf(m, "\t%16llx",
            (unsigned long long)(start |
            (dev->resource[i].flags & PCI_REGION_FLAG_MASK)));
    }
    for (i=0; i<7; i++) {
        resource_size_t start, end;
        pci_resource_to_user(dev, i, &dev->resource[i], &start, &end);
        seq_printf(m, "\t%16llx",
            dev->resource[i].start < dev->resource[i].end ?
            (unsigned long long)(end - start) + 1 : 0);
    }
    seq_putc(m, '\t');
    if (drv)
        seq_printf(m, "%s", drv->name);
    seq_putc(m, '\n');
    return 0;
}

After the IRQ, it appears to be the start addresses combined with the flags of the first 6 resource regions, followed by the lengths of those resource regions, followed by the name of the driver that has claimed the device.