X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lspci.c;h=7418b072c0c23783e5763a4b8091b9cc24d6f793;hb=25f2e4db6ecad1868302bc27d5b1ec7d74a59c19;hp=e207e03e366e4d4a8bd46042a4e4ef7425dfe1e3;hpb=6d701ce33eb2a420ce196be731ddf11d2d1fcc7f;p=pciutils.git diff --git a/lspci.c b/lspci.c index e207e03..7418b07 100644 --- a/lspci.c +++ b/lspci.c @@ -1,7 +1,7 @@ /* * The PCI Utilities -- List All PCI Devices * - * Copyright (c) 1997--2016 Martin Mares + * Copyright (c) 1997--2018 Martin Mares * * Can be freely distributed and used under the terms of the GNU GPL. */ @@ -18,7 +18,9 @@ int verbose; /* Show detailed information */ static int opt_hex; /* Show contents of config space as hexadecimal numbers */ struct pci_filter filter; /* Device filter */ +static int opt_filter; /* Any filter was given */ static int opt_tree; /* Show bus tree */ +static int opt_path; /* Show bridge path */ static int opt_machine; /* Generate machine-readable output */ static int opt_map_mode; /* Bus mapping mode enabled */ static int opt_domains; /* Show domain numbers (0=disabled, 1=auto-detected, 2=requested) */ @@ -29,7 +31,7 @@ char *opt_pcimap; /* Override path to Linux modules.pcimap */ const char program_name[] = "lspci"; -static char options[] = "nvbxs:d:ti:mgp:qkMDQ" GENERIC_OPTIONS ; +static char options[] = "nvbxs:d:tPi:mgp:qkMDQ" GENERIC_OPTIONS ; static char help_msg[] = "Usage: lspci []\n" @@ -39,7 +41,7 @@ static char help_msg[] = "-t\t\tShow bus tree\n" "\n" "Display options:\n" -"-v\t\tBe verbose (-vv for very verbose)\n" +"-v\t\tBe verbose (-vv or -vvv for higher verbosity)\n" #ifdef PCI_OS_LINUX "-k\t\tShow kernel drivers handling each device\n" #endif @@ -48,6 +50,8 @@ static char help_msg[] = "-xxxx\t\tShow hex-dump of the 4096-byte extended config space (root only)\n" "-b\t\tBus-centric view (addresses and IRQ's as seen by the bus)\n" "-D\t\tAlways show domain numbers\n" +"-P\t\tDisplay bridge path in addition to bus and device number\n" +"-PP\t\tDisplay bus path in addition to bus and device number\n" "\n" "Resolving of device ID's to names:\n" "-n\t\tShow numeric ID's\n" @@ -78,6 +82,7 @@ GENERIC_HELP struct pci_access *pacc; struct device *first_dev; static int seen_errors; +static int need_topology; int config_fetch(struct device *d, unsigned int pos, unsigned int len) @@ -114,7 +119,7 @@ scan_device(struct pci_dev *p) if (p->domain && !opt_domains) opt_domains = 1; - if (!pci_filter_match(&filter, p)) + if (!pci_filter_match(&filter, p) && !need_topology) return NULL; d = xmalloc(sizeof(struct device)); memset(d, 0, sizeof(*d)); @@ -247,6 +252,29 @@ sort_them(void) /*** Normal output ***/ +static void +show_slot_path(struct device *d) +{ + struct pci_dev *p = d->dev; + + if (opt_path) + { + struct bus *bus = d->parent_bus; + struct bridge *br = bus->parent_bridge; + + if (br && br->br_dev) + { + show_slot_path(br->br_dev); + if (opt_path > 1) + printf("/%02x:%02x.%d", p->bus, p->dev, p->func); + else + printf("/%02x.%d", p->dev, p->func); + return; + } + } + printf("%02x:%02x.%d", p->bus, p->dev, p->func); +} + static void show_slot_name(struct device *d) { @@ -254,7 +282,7 @@ show_slot_name(struct device *d) if (!opt_machine ? opt_domains : (p->domain || opt_domains >= 2)) printf("%04x:", p->domain); - printf("%02x:%02x.%d", p->bus, p->dev, p->func); + show_slot_path(d); } void @@ -348,17 +376,11 @@ show_size(u64 x) static void show_range(char *prefix, u64 base, u64 limit, int is_64bit) { - if (base > limit) + if (base > limit && verbose < 3) { - if (!verbose) - return; - else if (verbose < 3) - { - printf("%s: None\n", prefix); - return; - } + printf("%s: None\n", prefix); + return; } - printf("%s: ", prefix); if (is_64bit) printf("%016" PCI_U64_FMT_X "-%016" PCI_U64_FMT_X, base, limit); @@ -682,6 +704,7 @@ show_verbose(struct device *d) byte max_lat, min_gnt; byte int_pin = get_conf_byte(d, PCI_INTERRUPT_PIN); unsigned int irq; + char *dt_node; show_terse(d); @@ -715,10 +738,11 @@ show_verbose(struct device *d) if (p->phy_slot) printf("\tPhysical Slot: %s\n", p->phy_slot); + if (dt_node = pci_get_string_property(p, PCI_FILL_DT_NODE)) + printf("\tDevice tree node: %s\n", dt_node); + if (verbose > 1) { - if (p->dt_node) - printf("\tDT Node: %s\n", p->dt_node); printf("\tControl: I/O%c Mem%c BusMaster%c SpecCycle%c MemWINV%c VGASnoop%c ParErr%c Stepping%c SERR%c FastB2B%c DisINTx%c\n", FLAG(cmd, PCI_COMMAND_IO), FLAG(cmd, PCI_COMMAND_MEMORY), @@ -772,8 +796,6 @@ show_verbose(struct device *d) } else { - if (p->dt_node) - printf("\tDT Node: %s\n", p->dt_node); printf("\tFlags: "); if (cmd & PCI_COMMAND_MASTER) printf("bus master, "); @@ -867,6 +889,7 @@ show_machine(struct device *d) int c; word sv_id, sd_id; char classbuf[128], vendbuf[128], devbuf[128], svbuf[128], sdbuf[128]; + char *dt_node; get_subid(d, &sv_id, &sd_id); @@ -899,8 +922,8 @@ show_machine(struct device *d) show_kernel_machine(d); if (p->numa_node != -1) printf("NUMANode:\t%d\n", p->numa_node); - if (p->dt_node) - printf("DTNode:\t%s\n", p->dt_node); + if (dt_node = pci_get_string_property(p, PCI_FILL_DT_NODE)) + printf("DTNode:\t%s\n", dt_node); } else { @@ -951,7 +974,8 @@ show(void) struct device *d; for (d=first_dev; d; d=d->next) - show_device(d); + if (pci_filter_match(&filter, d->dev)) + show_device(d); } /* Main */ @@ -987,16 +1011,23 @@ main(int argc, char **argv) case 's': if (msg = pci_filter_parse_slot(&filter, optarg)) die("-s: %s", msg); + opt_filter = 1; break; case 'd': if (msg = pci_filter_parse_id(&filter, optarg)) die("-d: %s", msg); + opt_filter = 1; break; case 'x': opt_hex++; break; + case 'P': + opt_path++; + need_topology = 1; + break; case 't': opt_tree++; + need_topology = 1; break; case 'i': pci_set_name_list_path(pacc, optarg, 0); @@ -1051,13 +1082,19 @@ main(int argc, char **argv) pci_init(pacc); if (opt_map_mode) - map_the_bus(); + { + if (need_topology) + die("Bus mapping mode does not recognize bus topology"); + map_the_bus(); + } else { scan_devices(); sort_them(); + if (need_topology) + grow_tree(); if (opt_tree) - show_forest(); + show_forest(opt_filter ? &filter : NULL); else show(); }