Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed May 5, 2008
2 parents 48fc8de + 0df18ff commit 108c196
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 64 deletions.
2 changes: 2 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
so this option is a temporary workaround
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
just use the configuration from the
bootloader. This is currently used on
Expand Down
41 changes: 0 additions & 41 deletions arch/x86/pci/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,6 @@
#include <asm/numa.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 {
char *name;
unsigned int res_num;
Expand Down Expand Up @@ -196,8 +157,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
int pxm;
#endif

dmi_check_system(acpi_pciprobe_dmi_table);

if (domain && !pci_domains_supported) {
printk(KERN_WARNING "PCI: Multiple domains not supported "
"(dom %d, bus %d)\n", domain, busnum);
Expand Down
58 changes: 54 additions & 4 deletions arch/x86/pci/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

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
* are examined.
Expand Down Expand Up @@ -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 *bus = NULL;
struct pci_sysdata *sd;

dmi_check_system(pciprobe_dmi_table);

while ((bus = pci_find_next_bus(bus)) != NULL) {
if (bus->number == busnum) {
/* Already scanned */
Expand Down Expand Up @@ -462,6 +509,9 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "routeirq")) {
pci_routeirq = 1;
return NULL;
} else if (!strcmp(str, "skip_isa_align")) {
pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
return NULL;
}
return str;
}
Expand Down Expand Up @@ -489,7 +539,7 @@ void pcibios_disable_device (struct pci_dev *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_sysdata *sd;
Expand All @@ -512,7 +562,7 @@ struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops, int node)
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);
}
2 changes: 1 addition & 1 deletion arch/x86/pci/fixup.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
*/
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);
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/pci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ static __init int pci_access_init(void)
printk(KERN_ERR
"PCI: Fatal: No config space access function found\n");

dmi_check_pciprobe();

dmi_check_skip_isa_align();

return 0;
}
arch_initcall(pci_access_init);
3 changes: 3 additions & 0 deletions arch/x86/pci/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ enum pci_bf_sort_state {
pci_dmi_bf,
};

extern void __init dmi_check_pciprobe(void);
extern void __init dmi_check_skip_isa_align(void);

/* pci-i386.c */

extern unsigned int pcibios_max_latency;
Expand Down
33 changes: 17 additions & 16 deletions drivers/pci/probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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;

if (!check_exp_pcix)
goto skip;
if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
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);
if (!pos) {
Expand All @@ -861,23 +873,12 @@ int pci_cfg_space_size_ext(struct pci_dev *dev, unsigned check_exp_pcix)
goto fail;
}

skip:
if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
goto fail;
if (status == 0xffffffff)
goto fail;

return PCI_CFG_SPACE_EXP_SIZE;
return pci_cfg_space_size_ext(dev);

fail:
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)
{
kfree(dev);
Expand Down
5 changes: 3 additions & 2 deletions include/linux/pci.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <linux/mod_devicetable.h>

#include <linux/types.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/list.h>
#include <linux/compiler.h>
Expand Down Expand Up @@ -474,7 +475,7 @@ extern struct pci_bus *pci_find_bus(int domain, int busnr);
void pci_bus_add_devices(struct pci_bus *bus);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus,
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)
{
struct pci_bus *root_bus;
Expand Down Expand Up @@ -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 *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);
unsigned char pci_bus_max_busnr(struct pci_bus *bus);

Expand Down

0 comments on commit 108c196

Please sign in to comment.