diff options
Diffstat (limited to 'cmd/pci.c')
-rw-r--r-- | cmd/pci.c | 56 |
1 files changed, 44 insertions, 12 deletions
diff --git a/cmd/pci.c b/cmd/pci.c index 389b41ccc38..a99e8f8ad6e 100644 --- a/cmd/pci.c +++ b/cmd/pci.c @@ -256,10 +256,8 @@ static void pci_header_show(struct udevice *dev) } } -static void pciinfo_header(int busnum, bool short_listing) +static void pciinfo_header(bool short_listing) { - printf("Scanning PCI devices on bus %d\n", busnum); - if (short_listing) { printf("BusDevFun VendorId DeviceId Device Class Sub-Class\n"); printf("_____________________________________________________________\n"); @@ -288,11 +286,15 @@ static void pci_header_show_brief(struct udevice *dev) pci_class_str(class), subclass); } -static void pciinfo(struct udevice *bus, bool short_listing) +static void pciinfo(struct udevice *bus, bool short_listing, bool multi) { struct udevice *dev; - pciinfo_header(dev_seq(bus), short_listing); + if (!multi) + printf("Scanning PCI devices on bus %d\n", dev_seq(bus)); + + if (!multi || dev_seq(bus) == 0) + pciinfo_header(short_listing); for (device_find_first_child(bus, &dev); dev; @@ -443,7 +445,7 @@ static const struct pci_flag_info { static void pci_show_regions(struct udevice *bus) { - struct pci_controller *hose = dev_get_uclass_priv(bus); + struct pci_controller *hose = dev_get_uclass_priv(pci_get_controller(bus)); const struct pci_region *reg; int i, j; @@ -452,6 +454,7 @@ static void pci_show_regions(struct udevice *bus) return; } + printf("Buses %02x-%02x\n", hose->first_busno, hose->last_busno); printf("# %-18s %-18s %-18s %s\n", "Bus start", "Phys start", "Size", "Flags"); for (i = 0, reg = hose->regions; i < hose->region_count; i++, reg++) { @@ -482,10 +485,11 @@ static int do_pci(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ulong addr = 0, value = 0, cmd_size = 0; enum pci_size_t size = PCI_SIZE_32; struct udevice *dev, *bus; - int busnum = 0; + int busnum = -1; pci_dev_t bdf = 0; char cmd = 's'; int ret = 0; + char *endp; if (argc > 1) cmd = argv[1][0]; @@ -520,8 +524,36 @@ static int do_pci(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) value = 0; argc--; } - if (argc > 1) - busnum = hextoul(argv[1], NULL); + if (argc > 2 || (argc > 1 && cmd != 'r' && argv[1][0] != 's')) { + if (argv[argc - 1][0] != '*') { + busnum = hextoul(argv[argc - 1], &endp); + if (*endp) + goto usage; + } + argc--; + } + if (cmd == 'r' && argc > 2) + goto usage; + else if (cmd != 'r' && (argc > 2 || (argc == 2 && argv[1][0] != 's'))) + goto usage; + } + if (busnum == -1) { + if (cmd != 'r') { + for (busnum = 0; + uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus) == 0; + busnum++) + pciinfo(bus, value, true); + } else { + for (busnum = 0; + uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus) == 0; + busnum++) { + /* Regions are controller specific so skip non-root buses */ + if (device_is_on_pci_bus(bus)) + continue; + pci_show_regions(bus); + } + } + return 0; } ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus); if (ret) { @@ -531,7 +563,7 @@ static int do_pci(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (cmd == 'r') pci_show_regions(bus); else - pciinfo(bus, value); + pciinfo(bus, value, false); return 0; } @@ -578,7 +610,7 @@ static int do_pci(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #ifdef CONFIG_SYS_LONGHELP static char pci_help_text[] = - "[bus] [long]\n" + "[bus|*] [long]\n" " - short or long list of PCI devices on bus 'bus'\n" "pci enum\n" " - Enumerate PCI buses\n" @@ -586,7 +618,7 @@ static char pci_help_text[] = " - show header of PCI device 'bus.device.function'\n" "pci bar b.d.f\n" " - show BARs base and size for device b.d.f'\n" - "pci regions\n" + "pci regions [bus|*]\n" " - show PCI regions\n" "pci display[.b, .w, .l] b.d.f [address] [# of objects]\n" " - display PCI configuration space (CFG)\n" |