X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fpci%2Fproc.c;h=92a8857608329f26892c990e6425be88020df5c3;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=54b2ebc9c91a4b4e18dead4f363b0c9c5150d2a5;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 54b2ebc9c..92a885760 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -458,6 +458,131 @@ int pci_proc_detach_bus(struct pci_bus* bus) return 0; } +#ifdef CONFIG_PCI_LEGACY_PROC + +/* + * Backward compatible /proc/pci interface. + */ + +/* + * Convert some of the configuration space registers of the device at + * address (bus,devfn) into a string (possibly several lines each). + * The configuration string is stored starting at buf[len]. If the + * string would exceed the size of the buffer (SIZE), 0 is returned. + */ +static int show_dev_config(struct seq_file *m, void *v) +{ + struct pci_dev *dev = v; + struct pci_dev *first_dev; + struct pci_driver *drv; + u32 class_rev; + unsigned char latency, min_gnt, max_lat; + int reg; + + first_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev == first_dev) + seq_puts(m, "PCI devices found:\n"); + pci_dev_put(first_dev); + + drv = pci_dev_driver(dev); + + pci_user_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + pci_user_read_config_byte (dev, PCI_LATENCY_TIMER, &latency); + pci_user_read_config_byte (dev, PCI_MIN_GNT, &min_gnt); + pci_user_read_config_byte (dev, PCI_MAX_LAT, &max_lat); + seq_printf(m, " Bus %2d, device %3d, function %2d:\n", + dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); + seq_printf(m, " Class %04x", class_rev >> 16); + seq_printf(m, ": PCI device %04x:%04x", dev->vendor, dev->device); + seq_printf(m, " (rev %d).\n", class_rev & 0xff); + + if (dev->irq) + seq_printf(m, " IRQ %d.\n", dev->irq); + + if (latency || min_gnt || max_lat) { + seq_printf(m, " Master Capable. "); + if (latency) + seq_printf(m, "Latency=%d. ", latency); + else + seq_puts(m, "No bursts. "); + if (min_gnt) + seq_printf(m, "Min Gnt=%d.", min_gnt); + if (max_lat) + seq_printf(m, "Max Lat=%d.", max_lat); + seq_putc(m, '\n'); + } + + for (reg = 0; reg < 6; reg++) { + struct resource *res = dev->resource + reg; + unsigned long base, end, flags; + + base = res->start; + end = res->end; + flags = res->flags; + if (!end) + continue; + + if (flags & PCI_BASE_ADDRESS_SPACE_IO) { + seq_printf(m, " I/O at 0x%lx [0x%lx].\n", + base, end); + } else { + const char *pref, *type = "unknown"; + + if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH) + pref = "P"; + else + pref = "Non-p"; + switch (flags & PCI_BASE_ADDRESS_MEM_TYPE_MASK) { + case PCI_BASE_ADDRESS_MEM_TYPE_32: + type = "32 bit"; break; + case PCI_BASE_ADDRESS_MEM_TYPE_1M: + type = "20 bit"; break; + case PCI_BASE_ADDRESS_MEM_TYPE_64: + type = "64 bit"; break; + } + seq_printf(m, " %srefetchable %s memory at " + "0x%lx [0x%lx].\n", pref, type, + base, + end); + } + } + return 0; +} + +static struct seq_operations proc_pci_op = { + .start = pci_seq_start, + .next = pci_seq_next, + .stop = pci_seq_stop, + .show = show_dev_config +}; + +static int proc_pci_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &proc_pci_op); +} +static struct file_operations proc_pci_operations = { + .open = proc_pci_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static void legacy_proc_init(void) +{ + struct proc_dir_entry * entry = create_proc_entry("pci", 0, NULL); + if (entry) + entry->proc_fops = &proc_pci_operations; +} + +#else + +static void legacy_proc_init(void) +{ + +} + +#endif /* CONFIG_PCI_LEGACY_PROC */ + static int proc_bus_pci_dev_open(struct inode *inode, struct file *file) { return seq_open(file, &proc_bus_pci_devices_op); @@ -481,6 +606,7 @@ static int __init pci_proc_init(void) while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { pci_proc_attach_device(dev); } + legacy_proc_init(); return 0; }