Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: Make early dump functionality generic

Move early dump functionality into common code so that it is available for
all architectures. No need to carry arch-specific reads around as the read
hooks are already initialized by the time pci_setup_device() is getting
called during scan.

Tested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

authored by

Sinan Kaya and committed by
Bjorn Helgaas
11eb0e0e b1277a22

+24 -58
+1 -1
Documentation/admin-guide/kernel-parameters.txt
··· 2995 2995 See also Documentation/blockdev/paride.txt. 2996 2996 2997 2997 pci=option[,option...] [PCI] various PCI subsystem options: 2998 - earlydump [X86] dump PCI config space before the kernel 2998 + earlydump dump PCI config space before the kernel 2999 2999 changes anything 3000 3000 off [X86] don't probe for the PCI bus 3001 3001 bios [X86-32] force use of PCI BIOS, don't access
-4
arch/x86/include/asm/pci-direct.h
··· 15 15 extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val); 16 16 17 17 extern int early_pci_allowed(void); 18 - 19 - extern unsigned int pci_early_dump_regs; 20 - extern void early_dump_pci_device(u8 bus, u8 slot, u8 func); 21 - extern void early_dump_pci_devices(void); 22 18 #endif /* _ASM_X86_PCI_DIRECT_H */
-5
arch/x86/kernel/setup.c
··· 991 991 setup_clear_cpu_cap(X86_FEATURE_APIC); 992 992 } 993 993 994 - #ifdef CONFIG_PCI 995 - if (pci_early_dump_regs) 996 - early_dump_pci_devices(); 997 - #endif 998 - 999 994 e820__reserve_setup_data(); 1000 995 e820__finish_early_params(); 1001 996
-4
arch/x86/pci/common.c
··· 22 22 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | 23 23 PCI_PROBE_MMCONF; 24 24 25 - unsigned int pci_early_dump_regs; 26 25 static int pci_bf_sort; 27 26 int pci_routeirq; 28 27 int noioapicquirk; ··· 598 599 pci_probe |= PCI_BIG_ROOT_WINDOW; 599 600 return NULL; 600 601 #endif 601 - } else if (!strcmp(str, "earlydump")) { 602 - pci_early_dump_regs = 1; 603 - return NULL; 604 602 } else if (!strcmp(str, "routeirq")) { 605 603 pci_routeirq = 1; 606 604 return NULL;
-44
arch/x86/pci/early.c
··· 57 57 PCI_PROBE_CONF1; 58 58 } 59 59 60 - void early_dump_pci_device(u8 bus, u8 slot, u8 func) 61 - { 62 - u32 value[256 / 4]; 63 - int i; 64 - 65 - pr_info("pci 0000:%02x:%02x.%d config space:\n", bus, slot, func); 66 - 67 - for (i = 0; i < 256; i += 4) 68 - value[i / 4] = read_pci_config(bus, slot, func, i); 69 - 70 - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, value, 256, false); 71 - } 72 - 73 - void early_dump_pci_devices(void) 74 - { 75 - unsigned bus, slot, func; 76 - 77 - if (!early_pci_allowed()) 78 - return; 79 - 80 - for (bus = 0; bus < 256; bus++) { 81 - for (slot = 0; slot < 32; slot++) { 82 - for (func = 0; func < 8; func++) { 83 - u32 class; 84 - u8 type; 85 - 86 - class = read_pci_config(bus, slot, func, 87 - PCI_CLASS_REVISION); 88 - if (class == 0xffffffff) 89 - continue; 90 - 91 - early_dump_pci_device(bus, slot, func); 92 - 93 - if (func == 0) { 94 - type = read_pci_config_byte(bus, slot, 95 - func, 96 - PCI_HEADER_TYPE); 97 - if (!(type & 0x80)) 98 - break; 99 - } 100 - } 101 - } 102 - } 103 - }
+5
drivers/pci/pci.c
··· 115 115 /* If set, the PCIe ATS capability will not be used. */ 116 116 static bool pcie_ats_disabled; 117 117 118 + /* If set, the PCI config space of each device is printed during boot. */ 119 + bool pci_early_dump; 120 + 118 121 bool pci_ats_disabled(void) 119 122 { 120 123 return pcie_ats_disabled; ··· 5836 5833 pcie_ats_disabled = true; 5837 5834 } else if (!strcmp(str, "noaer")) { 5838 5835 pci_no_aer(); 5836 + } else if (!strcmp(str, "earlydump")) { 5837 + pci_early_dump = true; 5839 5838 } else if (!strncmp(str, "realloc=", 8)) { 5840 5839 pci_realloc_get_opt(str + 8); 5841 5840 } else if (!strncmp(str, "realloc", 7)) {
+1
drivers/pci/pci.h
··· 7 7 #define PCI_VSEC_ID_INTEL_TBT 0x1234 /* Thunderbolt */ 8 8 9 9 extern const unsigned char pcie_link_speed[]; 10 + extern bool pci_early_dump; 10 11 11 12 bool pcie_cap_has_lnkctl(const struct pci_dev *dev); 12 13
+17
drivers/pci/probe.c
··· 1549 1549 return 0; 1550 1550 } 1551 1551 1552 + static void early_dump_pci_device(struct pci_dev *pdev) 1553 + { 1554 + u32 value[256 / 4]; 1555 + int i; 1556 + 1557 + pci_info(pdev, "config space:\n"); 1558 + 1559 + for (i = 0; i < 256; i += 4) 1560 + pci_read_config_dword(pdev, i, &value[i / 4]); 1561 + 1562 + print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, 1563 + value, 256, false); 1564 + } 1565 + 1552 1566 /** 1553 1567 * pci_setup_device - Fill in class and map information of a device 1554 1568 * @dev: the device structure to fill ··· 1611 1597 1612 1598 pci_printk(KERN_DEBUG, dev, "[%04x:%04x] type %02x class %#08x\n", 1613 1599 dev->vendor, dev->device, dev->hdr_type, dev->class); 1600 + 1601 + if (pci_early_dump) 1602 + early_dump_pci_device(dev); 1614 1603 1615 1604 /* Need to have dev->class ready */ 1616 1605 dev->cfg_size = pci_cfg_space_size(dev);