aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-05-05 15:39:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-05-05 15:39:10 -0400
commit108c1961847df2a875047c0fd27b419cb817d213 (patch)
tree5138948168df7043b1d39a1dbeb4a472f1cd66da
parent48fc8de9cd093b8c9e2cfa339421862bae3a6cad (diff)
parent0df18ff366853cdf31e5238764ec5c63e6b5a398 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: x86 PCI: call dmi_check_pciprobe() x86/pci: add pci=skip_isa_align command lines. x86/pci: remove flag in pci_cfg_space_size_ext x86: fix section mismatch in pci_scan_bus
-rw-r--r--Documentation/kernel-parameters.txt2
-rw-r--r--arch/x86/pci/acpi.c41
-rw-r--r--arch/x86/pci/common.c58
-rw-r--r--arch/x86/pci/fixup.c2
-rw-r--r--arch/x86/pci/init.c4
-rw-r--r--arch/x86/pci/pci.h3
-rw-r--r--drivers/pci/probe.c33
-rw-r--r--include/linux/pci.h5
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
9static 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
16static 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
48struct pci_root_info { 9struct 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
93static 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
100static 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
132void __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
365void __init dmi_check_pciprobe(void)
366{
367 dmi_check_system(pciprobe_dmi_table);
368}
369
321struct pci_bus * __devinit pcibios_scan_root(int busnum) 370struct 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
492struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) 542struct 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
515struct pci_bus *pci_scan_bus_with_sysdata(int busno) 565struct 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 */
503static void fam10h_pci_cfg_space_size(struct pci_dev *dev) 503static 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
508DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size); 508DECLARE_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}
38arch_initcall(pci_access_init); 42arch_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
41extern void __init dmi_check_pciprobe(void);
42extern void __init dmi_check_skip_isa_align(void);
43
41/* pci-i386.c */ 44/* pci-i386.c */
42 45
43extern unsigned int pcibios_max_latency; 46extern 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 */
845int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix) 845int 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
860int 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
876int pci_cfg_space_size(struct pci_dev *dev)
877{
878 return pci_cfg_space_size_ext(dev, 1);
879}
880
881static void pci_release_bus_bridge_dev(struct device *dev) 882static 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);
474void pci_bus_add_devices(struct pci_bus *bus); 475void pci_bus_add_devices(struct pci_bus *bus);
475struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, 476struct 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);
477static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, 478static 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
667void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), 668void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
668 void *userdata); 669 void *userdata);
669int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix); 670int pci_cfg_space_size_ext(struct pci_dev *dev);
670int pci_cfg_space_size(struct pci_dev *dev); 671int pci_cfg_space_size(struct pci_dev *dev);
671unsigned char pci_bus_max_busnr(struct pci_bus *bus); 672unsigned char pci_bus_max_busnr(struct pci_bus *bus);
672 673