Convert CONFIG_SYS_MONITOR_LEN to Kconfig
[platform/kernel/u-boot.git] / cmd / pci.c
index 389b41c..58a7475 100644 (file)
--- 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;
@@ -356,6 +358,9 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
        if (length == 0)
                length = 0x40 / byte_size; /* Standard PCI config space */
 
+       if (addr >= 4096)
+               return 1;
+
        /* Print the lines.
         * once, and all accesses are with the specified bus width.
         */
@@ -376,7 +381,10 @@ static int pci_cfg_display(struct udevice *dev, ulong addr,
                        rc = 1;
                        break;
                }
-       } while (nbytes > 0);
+       } while (nbytes > 0 && addr < 4096);
+
+       if (rc == 0 && nbytes > 0)
+               return 1;
 
        return (rc);
 }
@@ -388,6 +396,9 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
        int     nbytes;
        ulong val;
 
+       if (addr >= 4096)
+               return 1;
+
        /* Print the address, followed by value.  Then accept input for
         * the next value.  A non-converted value exits.
         */
@@ -425,7 +436,10 @@ static int pci_cfg_modify(struct udevice *dev, ulong addr, ulong size,
                                        addr += size;
                        }
                }
-       } while (nbytes);
+       } while (nbytes && addr < 4096);
+
+       if (nbytes)
+               return 1;
 
        return 0;
 }
@@ -438,12 +452,11 @@ static const struct pci_flag_info {
        { PCI_REGION_PREFETCH, "prefetch" },
        { PCI_REGION_SYS_MEMORY, "sysmem" },
        { PCI_REGION_RO, "readonly" },
-       { PCI_REGION_IO, "io" },
 };
 
 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 +465,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 +496,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 +535,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 +574,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 +621,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 +629,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"