diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
| -rw-r--r-- | arch/x86/pci/acpi.c | 41 | ||||
| -rw-r--r-- | arch/x86/pci/common.c | 58 | ||||
| -rw-r--r-- | arch/x86/pci/fixup.c | 2 | ||||
| -rw-r--r-- | arch/x86/pci/init.c | 4 | ||||
| -rw-r--r-- | arch/x86/pci/pci.h | 3 | ||||
| -rw-r--r-- | drivers/pci/probe.c | 33 | ||||
| -rw-r--r-- | include/linux/pci.h | 5 |
8 files changed, 84 insertions, 64 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b2dd3dc32fd3..cdd5b934f43e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1522,6 +1522,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 1522 | This is normally done in pci_enable_device(), | 1522 | This is normally done in pci_enable_device(), |
| 1523 | so this option is a temporary workaround | 1523 | so this option is a temporary workaround |
| 1524 | for broken drivers that don't call it. | 1524 | for broken drivers that don't call it. |
| 1525 | skip_isa_align [X86] do not align io start addr, so can | ||
| 1526 | handle more pci cards | ||
| 1525 | firmware [ARM] Do not re-enumerate the bus but instead | 1527 | firmware [ARM] Do not re-enumerate the bus but instead |
| 1526 | just use the configuration from the | 1528 | just use the configuration from the |
| 1527 | bootloader. This is currently used on | 1529 | bootloader. This is currently used on |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 1a9c0c6a1a18..d95de2f199cd 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
| @@ -6,45 +6,6 @@ | |||
| 6 | #include <asm/numa.h> | 6 | #include <asm/numa.h> |
| 7 | #include "pci.h" | 7 | #include "pci.h" |
| 8 | 8 | ||
| 9 | static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) | ||
| 10 | { | ||
| 11 | pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; | ||
| 12 | printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); | ||
| 13 | return 0; | ||
| 14 | } | ||
| 15 | |||
| 16 | static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = { | ||
| 17 | /* | ||
| 18 | * Systems where PCI IO resource ISA alignment can be skipped | ||
| 19 | * when the ISA enable bit in the bridge control is not set | ||
| 20 | */ | ||
| 21 | { | ||
| 22 | .callback = can_skip_ioresource_align, | ||
| 23 | .ident = "IBM System x3800", | ||
| 24 | .matches = { | ||
| 25 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 26 | DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), | ||
| 27 | }, | ||
| 28 | }, | ||
| 29 | { | ||
| 30 | .callback = can_skip_ioresource_align, | ||
| 31 | .ident = "IBM System x3850", | ||
| 32 | .matches = { | ||
| 33 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 34 | DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), | ||
| 35 | }, | ||
| 36 | }, | ||
| 37 | { | ||
| 38 | .callback = can_skip_ioresource_align, | ||
| 39 | .ident = "IBM System x3950", | ||
| 40 | .matches = { | ||
| 41 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 42 | DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), | ||
| 43 | }, | ||
| 44 | }, | ||
| 45 | {} | ||
| 46 | }; | ||
| 47 | |||
| 48 | struct pci_root_info { | 9 | struct pci_root_info { |
| 49 | char *name; | 10 | char *name; |
| 50 | unsigned int res_num; | 11 | unsigned int res_num; |
| @@ -196,8 +157,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
| 196 | int pxm; | 157 | int pxm; |
| 197 | #endif | 158 | #endif |
| 198 | 159 | ||
| 199 | dmi_check_system(acpi_pciprobe_dmi_table); | ||
| 200 | |||
| 201 | if (domain && !pci_domains_supported) { | 160 | if (domain && !pci_domains_supported) { |
| 202 | printk(KERN_WARNING "PCI: Multiple domains not supported " | 161 | printk(KERN_WARNING "PCI: Multiple domains not supported " |
| 203 | "(dom %d, bus %d)\n", domain, busnum); | 162 | "(dom %d, bus %d)\n", domain, busnum); |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 2a4d751818b7..bfa72a9475b3 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
| @@ -90,6 +90,50 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
| 90 | rom_r->start = rom_r->end = rom_r->flags = 0; | 90 | rom_r->start = rom_r->end = rom_r->flags = 0; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d) | ||
| 94 | { | ||
| 95 | pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; | ||
| 96 | printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = { | ||
| 101 | /* | ||
| 102 | * Systems where PCI IO resource ISA alignment can be skipped | ||
| 103 | * when the ISA enable bit in the bridge control is not set | ||
| 104 | */ | ||
| 105 | { | ||
| 106 | .callback = can_skip_ioresource_align, | ||
| 107 | .ident = "IBM System x3800", | ||
| 108 | .matches = { | ||
| 109 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 110 | DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), | ||
| 111 | }, | ||
| 112 | }, | ||
| 113 | { | ||
| 114 | .callback = can_skip_ioresource_align, | ||
| 115 | .ident = "IBM System x3850", | ||
| 116 | .matches = { | ||
| 117 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 118 | DMI_MATCH(DMI_PRODUCT_NAME, "x3850"), | ||
| 119 | }, | ||
| 120 | }, | ||
| 121 | { | ||
| 122 | .callback = can_skip_ioresource_align, | ||
| 123 | .ident = "IBM System x3950", | ||
| 124 | .matches = { | ||
| 125 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | ||
| 126 | DMI_MATCH(DMI_PRODUCT_NAME, "x3950"), | ||
| 127 | }, | ||
| 128 | }, | ||
| 129 | {} | ||
| 130 | }; | ||
| 131 | |||
| 132 | void __init dmi_check_skip_isa_align(void) | ||
| 133 | { | ||
| 134 | dmi_check_system(can_skip_pciprobe_dmi_table); | ||
| 135 | } | ||
| 136 | |||
| 93 | /* | 137 | /* |
| 94 | * Called after each bus is probed, but before its children | 138 | * Called after each bus is probed, but before its children |
| 95 | * are examined. | 139 | * are examined. |
| @@ -318,13 +362,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | |||
| 318 | {} | 362 | {} |
| 319 | }; | 363 | }; |
| 320 | 364 | ||
| 365 | void __init dmi_check_pciprobe(void) | ||
| 366 | { | ||
| 367 | dmi_check_system(pciprobe_dmi_table); | ||
| 368 | } | ||
| 369 | |||
| 321 | struct pci_bus * __devinit pcibios_scan_root(int busnum) | 370 | struct pci_bus * __devinit pcibios_scan_root(int busnum) |
| 322 | { | 371 | { |
| 323 | struct pci_bus *bus = NULL; | 372 | struct pci_bus *bus = NULL; |
| 324 | struct pci_sysdata *sd; | 373 | struct pci_sysdata *sd; |
| 325 | 374 | ||
| 326 | dmi_check_system(pciprobe_dmi_table); | ||
| 327 | |||
| 328 | while ((bus = pci_find_next_bus(bus)) != NULL) { | 375 | while ((bus = pci_find_next_bus(bus)) != NULL) { |
| 329 | if (bus->number == busnum) { | 376 | if (bus->number == busnum) { |
| 330 | /* Already scanned */ | 377 | /* Already scanned */ |
| @@ -462,6 +509,9 @@ char * __devinit pcibios_setup(char *str) | |||
| 462 | } else if (!strcmp(str, "routeirq")) { | 509 | } else if (!strcmp(str, "routeirq")) { |
| 463 | pci_routeirq = 1; | 510 | pci_routeirq = 1; |
| 464 | return NULL; | 511 | return NULL; |
| 512 | } else if (!strcmp(str, "skip_isa_align")) { | ||
| 513 | pci_probe |= PCI_CAN_SKIP_ISA_ALIGN; | ||
| 514 | return NULL; | ||
| 465 | } | 515 | } |
| 466 | return str; | 516 | return str; |
| 467 | } | 517 | } |
| @@ -489,7 +539,7 @@ void pcibios_disable_device (struct pci_dev *dev) | |||
| 489 | pcibios_disable_irq(dev); | 539 | pcibios_disable_irq(dev); |
| 490 | } | 540 | } |
| 491 | 541 | ||
| 492 | struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) | 542 | struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) |
| 493 | { | 543 | { |
| 494 | struct pci_bus *bus = NULL; | 544 | struct pci_bus *bus = NULL; |
| 495 | struct pci_sysdata *sd; | 545 | struct pci_sysdata *sd; |
| @@ -512,7 +562,7 @@ struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) | |||
| 512 | return bus; | 562 | return bus; |
| 513 | } | 563 | } |
| 514 | 564 | ||
| 515 | struct pci_bus *pci_scan_bus_with_sysdata(int busno) | 565 | struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno) |
| 516 | { | 566 | { |
| 517 | return pci_scan_bus_on_node(busno, &pci_root_ops, -1); | 567 | return pci_scan_bus_on_node(busno, &pci_root_ops, -1); |
| 518 | } | 568 | } |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index b60b2abd480c..ff3a6a336342 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
| @@ -502,7 +502,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, | |||
| 502 | */ | 502 | */ |
| 503 | static void fam10h_pci_cfg_space_size(struct pci_dev *dev) | 503 | static void fam10h_pci_cfg_space_size(struct pci_dev *dev) |
| 504 | { | 504 | { |
| 505 | dev->cfg_size = pci_cfg_space_size_ext(dev, 0); | 505 | dev->cfg_size = pci_cfg_space_size_ext(dev); |
| 506 | } | 506 | } |
| 507 | 507 | ||
| 508 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size); | 508 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size); |
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c index dd30c6076b5d..e70b9c57b88e 100644 --- a/arch/x86/pci/init.c +++ b/arch/x86/pci/init.c | |||
| @@ -33,6 +33,10 @@ static __init int pci_access_init(void) | |||
| 33 | printk(KERN_ERR | 33 | printk(KERN_ERR |
| 34 | "PCI: Fatal: No config space access function found\n"); | 34 | "PCI: Fatal: No config space access function found\n"); |
| 35 | 35 | ||
| 36 | dmi_check_pciprobe(); | ||
| 37 | |||
| 38 | dmi_check_skip_isa_align(); | ||
| 39 | |||
| 36 | return 0; | 40 | return 0; |
| 37 | } | 41 | } |
| 38 | arch_initcall(pci_access_init); | 42 | arch_initcall(pci_access_init); |
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index c58805a92db5..f3972b12c60a 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h | |||
| @@ -38,6 +38,9 @@ enum pci_bf_sort_state { | |||
| 38 | pci_dmi_bf, | 38 | pci_dmi_bf, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | extern void __init dmi_check_pciprobe(void); | ||
| 42 | extern void __init dmi_check_skip_isa_align(void); | ||
| 43 | |||
| 41 | /* pci-i386.c */ | 44 | /* pci-i386.c */ |
| 42 | 45 | ||
| 43 | extern unsigned int pcibios_max_latency; | 46 | extern unsigned int pcibios_max_latency; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 4a55bf380957..3706ce7972dd 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
| @@ -842,13 +842,25 @@ static void set_pcie_port_type(struct pci_dev *pdev) | |||
| 842 | * reading the dword at 0x100 which must either be 0 or a valid extended | 842 | * reading the dword at 0x100 which must either be 0 or a valid extended |
| 843 | * capability header. | 843 | * capability header. |
| 844 | */ | 844 | */ |
| 845 | int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix) | 845 | int pci_cfg_space_size_ext(struct pci_dev *dev) |
| 846 | { | 846 | { |
| 847 | int pos; | ||
| 848 | u32 status; | 847 | u32 status; |
| 849 | 848 | ||
| 850 | if (!check_exp_pcix) | 849 | if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) |
| 851 | goto skip; | 850 | goto fail; |
| 851 | if (status == 0xffffffff) | ||
| 852 | goto fail; | ||
| 853 | |||
| 854 | return PCI_CFG_SPACE_EXP_SIZE; | ||
| 855 | |||
| 856 | fail: | ||
| 857 | return PCI_CFG_SPACE_SIZE; | ||
| 858 | } | ||
| 859 | |||
| 860 | int pci_cfg_space_size(struct pci_dev *dev) | ||
| 861 | { | ||
| 862 | int pos; | ||
| 863 | u32 status; | ||
| 852 | 864 | ||
| 853 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 865 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); |
| 854 | if (!pos) { | 866 | if (!pos) { |
| @@ -861,23 +873,12 @@ int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix) | |||
| 861 | goto fail; | 873 | goto fail; |
| 862 | } | 874 | } |
| 863 | 875 | ||
| 864 | skip: | 876 | return pci_cfg_space_size_ext(dev); |
| 865 | if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL) | ||
| 866 | goto fail; | ||
| 867 | if (status == 0xffffffff) | ||
| 868 | goto fail; | ||
| 869 | |||
| 870 | return PCI_CFG_SPACE_EXP_SIZE; | ||
| 871 | 877 | ||
| 872 | fail: | 878 | fail: |
| 873 | return PCI_CFG_SPACE_SIZE; | 879 | return PCI_CFG_SPACE_SIZE; |
| 874 | } | 880 | } |
| 875 | 881 | ||
| 876 | int pci_cfg_space_size(struct pci_dev *dev) | ||
| 877 | { | ||
| 878 | return pci_cfg_space_size_ext(dev, 1); | ||
| 879 | } | ||
| 880 | |||
| 881 | static void pci_release_bus_bridge_dev(struct device *dev) | 882 | static void pci_release_bus_bridge_dev(struct device *dev) |
| 882 | { | 883 | { |
| 883 | kfree(dev); | 884 | kfree(dev); |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 96acd0dae241..509159bcd4e7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/mod_devicetable.h> | 44 | #include <linux/mod_devicetable.h> |
| 45 | 45 | ||
| 46 | #include <linux/types.h> | 46 | #include <linux/types.h> |
| 47 | #include <linux/init.h> | ||
| 47 | #include <linux/ioport.h> | 48 | #include <linux/ioport.h> |
| 48 | #include <linux/list.h> | 49 | #include <linux/list.h> |
| 49 | #include <linux/compiler.h> | 50 | #include <linux/compiler.h> |
| @@ -474,7 +475,7 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr); | |||
| 474 | void pci_bus_add_devices(struct pci_bus *bus); | 475 | void pci_bus_add_devices(struct pci_bus *bus); |
| 475 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, | 476 | struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, |
| 476 | struct pci_ops *ops, void *sysdata); | 477 | struct pci_ops *ops, void *sysdata); |
| 477 | static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, | 478 | static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops, |
| 478 | void *sysdata) | 479 | void *sysdata) |
| 479 | { | 480 | { |
| 480 | struct pci_bus *root_bus; | 481 | struct pci_bus *root_bus; |
| @@ -666,7 +667,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
| 666 | 667 | ||
| 667 | void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), | 668 | void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), |
| 668 | void *userdata); | 669 | void *userdata); |
| 669 | int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix); | 670 | int pci_cfg_space_size_ext(struct pci_dev *dev); |
| 670 | int pci_cfg_space_size(struct pci_dev *dev); | 671 | int pci_cfg_space_size(struct pci_dev *dev); |
| 671 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); | 672 | unsigned char pci_bus_max_busnr(struct pci_bus *bus); |
| 672 | 673 | ||
