提交 108c1961 编写于 作者: L Linus Torvalds

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
...@@ -1522,6 +1522,8 @@ and is between 256 and 4096 characters. It is defined in the file ...@@ -1522,6 +1522,8 @@ and is between 256 and 4096 characters. It is defined in the file
This is normally done in pci_enable_device(), This is normally done in pci_enable_device(),
so this option is a temporary workaround so this option is a temporary workaround
for broken drivers that don't call it. for broken drivers that don't call it.
skip_isa_align [X86] do not align io start addr, so can
handle more pci cards
firmware [ARM] Do not re-enumerate the bus but instead firmware [ARM] Do not re-enumerate the bus but instead
just use the configuration from the just use the configuration from the
bootloader. This is currently used on bootloader. This is currently used on
......
...@@ -6,45 +6,6 @@ ...@@ -6,45 +6,6 @@
#include <asm/numa.h> #include <asm/numa.h>
#include "pci.h" #include "pci.h"
static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
{
pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
return 0;
}
static struct dmi_system_id acpi_pciprobe_dmi_table[] __devinitdata = {
/*
* Systems where PCI IO resource ISA alignment can be skipped
* when the ISA enable bit in the bridge control is not set
*/
{
.callback = can_skip_ioresource_align,
.ident = "IBM System x3800",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
},
},
{
.callback = can_skip_ioresource_align,
.ident = "IBM System x3850",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
},
},
{
.callback = can_skip_ioresource_align,
.ident = "IBM System x3950",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
},
},
{}
};
struct pci_root_info { struct pci_root_info {
char *name; char *name;
unsigned int res_num; unsigned int res_num;
...@@ -196,8 +157,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do ...@@ -196,8 +157,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
int pxm; int pxm;
#endif #endif
dmi_check_system(acpi_pciprobe_dmi_table);
if (domain && !pci_domains_supported) { if (domain && !pci_domains_supported) {
printk(KERN_WARNING "PCI: Multiple domains not supported " printk(KERN_WARNING "PCI: Multiple domains not supported "
"(dom %d, bus %d)\n", domain, busnum); "(dom %d, bus %d)\n", domain, busnum);
......
...@@ -90,6 +90,50 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) ...@@ -90,6 +90,50 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
rom_r->start = rom_r->end = rom_r->flags = 0; rom_r->start = rom_r->end = rom_r->flags = 0;
} }
static int __devinit can_skip_ioresource_align(const struct dmi_system_id *d)
{
pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
printk(KERN_INFO "PCI: %s detected, can skip ISA alignment\n", d->ident);
return 0;
}
static struct dmi_system_id can_skip_pciprobe_dmi_table[] __devinitdata = {
/*
* Systems where PCI IO resource ISA alignment can be skipped
* when the ISA enable bit in the bridge control is not set
*/
{
.callback = can_skip_ioresource_align,
.ident = "IBM System x3800",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
},
},
{
.callback = can_skip_ioresource_align,
.ident = "IBM System x3850",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3850"),
},
},
{
.callback = can_skip_ioresource_align,
.ident = "IBM System x3950",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
DMI_MATCH(DMI_PRODUCT_NAME, "x3950"),
},
},
{}
};
void __init dmi_check_skip_isa_align(void)
{
dmi_check_system(can_skip_pciprobe_dmi_table);
}
/* /*
* Called after each bus is probed, but before its children * Called after each bus is probed, but before its children
* are examined. * are examined.
...@@ -318,13 +362,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { ...@@ -318,13 +362,16 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
{} {}
}; };
void __init dmi_check_pciprobe(void)
{
dmi_check_system(pciprobe_dmi_table);
}
struct pci_bus * __devinit pcibios_scan_root(int busnum) struct pci_bus * __devinit pcibios_scan_root(int busnum)
{ {
struct pci_bus *bus = NULL; struct pci_bus *bus = NULL;
struct pci_sysdata *sd; struct pci_sysdata *sd;
dmi_check_system(pciprobe_dmi_table);
while ((bus = pci_find_next_bus(bus)) != NULL) { while ((bus = pci_find_next_bus(bus)) != NULL) {
if (bus->number == busnum) { if (bus->number == busnum) {
/* Already scanned */ /* Already scanned */
...@@ -462,6 +509,9 @@ char * __devinit pcibios_setup(char *str) ...@@ -462,6 +509,9 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "routeirq")) { } else if (!strcmp(str, "routeirq")) {
pci_routeirq = 1; pci_routeirq = 1;
return NULL; return NULL;
} else if (!strcmp(str, "skip_isa_align")) {
pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
return NULL;
} }
return str; return str;
} }
...@@ -489,7 +539,7 @@ void pcibios_disable_device (struct pci_dev *dev) ...@@ -489,7 +539,7 @@ void pcibios_disable_device (struct pci_dev *dev)
pcibios_disable_irq(dev); pcibios_disable_irq(dev);
} }
struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node) struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
{ {
struct pci_bus *bus = NULL; struct pci_bus *bus = NULL;
struct pci_sysdata *sd; 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,7 +562,7 @@ struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
return bus; return bus;
} }
struct pci_bus *pci_scan_bus_with_sysdata(int busno) struct pci_bus * __devinit pci_scan_bus_with_sysdata(int busno)
{ {
return pci_scan_bus_on_node(busno, &pci_root_ops, -1); return pci_scan_bus_on_node(busno, &pci_root_ops, -1);
} }
...@@ -502,7 +502,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, ...@@ -502,7 +502,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
*/ */
static void fam10h_pci_cfg_space_size(struct pci_dev *dev) static void fam10h_pci_cfg_space_size(struct pci_dev *dev)
{ {
dev->cfg_size = pci_cfg_space_size_ext(dev, 0); dev->cfg_size = pci_cfg_space_size_ext(dev);
} }
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size);
......
...@@ -33,6 +33,10 @@ static __init int pci_access_init(void) ...@@ -33,6 +33,10 @@ static __init int pci_access_init(void)
printk(KERN_ERR printk(KERN_ERR
"PCI: Fatal: No config space access function found\n"); "PCI: Fatal: No config space access function found\n");
dmi_check_pciprobe();
dmi_check_skip_isa_align();
return 0; return 0;
} }
arch_initcall(pci_access_init); arch_initcall(pci_access_init);
...@@ -38,6 +38,9 @@ enum pci_bf_sort_state { ...@@ -38,6 +38,9 @@ enum pci_bf_sort_state {
pci_dmi_bf, pci_dmi_bf,
}; };
extern void __init dmi_check_pciprobe(void);
extern void __init dmi_check_skip_isa_align(void);
/* pci-i386.c */ /* pci-i386.c */
extern unsigned int pcibios_max_latency; extern unsigned int pcibios_max_latency;
......
...@@ -842,13 +842,25 @@ static void set_pcie_port_type(struct pci_dev *pdev) ...@@ -842,13 +842,25 @@ static void set_pcie_port_type(struct pci_dev *pdev)
* reading the dword at 0x100 which must either be 0 or a valid extended * reading the dword at 0x100 which must either be 0 or a valid extended
* capability header. * capability header.
*/ */
int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix) int pci_cfg_space_size_ext(struct pci_dev *dev)
{ {
int pos;
u32 status; u32 status;
if (!check_exp_pcix) if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
goto skip; goto fail;
if (status == 0xffffffff)
goto fail;
return PCI_CFG_SPACE_EXP_SIZE;
fail:
return PCI_CFG_SPACE_SIZE;
}
int pci_cfg_space_size(struct pci_dev *dev)
{
int pos;
u32 status;
pos = pci_find_capability(dev, PCI_CAP_ID_EXP); pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos) { if (!pos) {
...@@ -861,23 +873,12 @@ int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix) ...@@ -861,23 +873,12 @@ int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix)
goto fail; goto fail;
} }
skip: return pci_cfg_space_size_ext(dev);
if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
goto fail;
if (status == 0xffffffff)
goto fail;
return PCI_CFG_SPACE_EXP_SIZE;
fail: fail:
return PCI_CFG_SPACE_SIZE; return PCI_CFG_SPACE_SIZE;
} }
int pci_cfg_space_size(struct pci_dev *dev)
{
return pci_cfg_space_size_ext(dev, 1);
}
static void pci_release_bus_bridge_dev(struct device *dev) static void pci_release_bus_bridge_dev(struct device *dev)
{ {
kfree(dev); kfree(dev);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <linux/mod_devicetable.h> #include <linux/mod_devicetable.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/compiler.h> #include <linux/compiler.h>
...@@ -474,7 +475,7 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr); ...@@ -474,7 +475,7 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr);
void pci_bus_add_devices(struct pci_bus *bus); void pci_bus_add_devices(struct pci_bus *bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata); struct pci_ops *ops, void *sysdata);
static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, static inline struct pci_bus * __devinit pci_scan_bus(int bus, struct pci_ops *ops,
void *sysdata) void *sysdata)
{ {
struct pci_bus *root_bus; struct pci_bus *root_bus;
...@@ -666,7 +667,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, ...@@ -666,7 +667,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
void *userdata); void *userdata);
int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix); int pci_cfg_space_size_ext(struct pci_dev *dev);
int pci_cfg_space_size(struct pci_dev *dev); int pci_cfg_space_size(struct pci_dev *dev);
unsigned char pci_bus_max_busnr(struct pci_bus *bus); unsigned char pci_bus_max_busnr(struct pci_bus *bus);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册