diff options
Diffstat (limited to 'drivers/pci')
36 files changed, 140 insertions, 68 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 3d102dd87c9f..0b51857fbaf7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_PPC) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o +obj-$(CONFIG_MICROBLAZE) += setup-bus.o # # ACPI Related PCI FW Functions diff --git a/drivers/pci/access.c b/drivers/pci/access.c index db23200c4874..2f646fe1260f 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -2,6 +2,7 @@ #include <linux/pci.h> #include <linux/module.h> #include <linux/sched.h> +#include <linux/slab.h> #include <linux/ioport.h> #include <linux/wait.h> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 26301cb25e7f..628ea20a8841 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -14,6 +14,7 @@ #include <linux/ioport.h> #include <linux/proc_fs.h> #include <linux/init.h> +#include <linux/slab.h> #include "pci.h" diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 83aae4747594..33ead97f0c4b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c @@ -35,6 +35,7 @@ #include <linux/interrupt.h> #include <linux/tboot.h> #include <linux/dmi.h> +#include <linux/slab.h> #define PREFIX "DMAR: " diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 3c76fc67cf0e..45fcc1e96df9 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -32,6 +32,7 @@ #include <linux/pci_hotplug.h> #include <linux/acpi.h> #include <linux/pci-acpi.h> +#include <linux/slab.h> #define MY_NAME "acpi_pcihp" diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index cb2fd01eddae..cb23aa2ebf96 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -47,6 +47,7 @@ #include <linux/pci_hotplug.h> #include <linux/pci-acpi.h> #include <linux/mutex.h> +#include <linux/slab.h> #include "../pci.h" #include "acpiphp.h" @@ -749,6 +750,24 @@ static int acpiphp_bus_trim(acpi_handle handle) return retval; } +static void acpiphp_set_acpi_region(struct acpiphp_slot *slot) +{ + struct acpiphp_func *func; + union acpi_object params[2]; + struct acpi_object_list arg_list; + + list_for_each_entry(func, &slot->funcs, sibling) { + arg_list.count = 2; + arg_list.pointer = params; + params[0].type = ACPI_TYPE_INTEGER; + params[0].integer.value = ACPI_ADR_SPACE_PCI_CONFIG; + params[1].type = ACPI_TYPE_INTEGER; + params[1].integer.value = 1; + /* _REG is optional, we don't care about if there is failure */ + acpi_evaluate_object(func->handle, "_REG", &arg_list, NULL); + } +} + /** * enable_device - enable, configure a slot * @slot: slot to be enabled @@ -805,6 +824,7 @@ static int __ref enable_device(struct acpiphp_slot *slot) pci_bus_assign_resources(bus); acpiphp_sanitize_bus(bus); acpiphp_set_hpp_values(bus); + acpiphp_set_acpi_region(slot); pci_enable_bridges(bus); pci_bus_add_devices(bus); diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index aa5df485f8cf..6ecbfb27db9d 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -26,6 +26,7 @@ */ #include <linux/init.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> #include <acpi/acpi_bus.h> diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index e6089bdb6e5b..56215322930a 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c @@ -28,6 +28,7 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/types.h> #include <linux/proc_fs.h> #include <linux/workqueue.h> diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 0a894efd4b9b..5317e4d7d96e 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/device.h> +#include <linux/slab.h> #include "../pci.h" struct legacy_slot { diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 728b119f71ad..6d2eea93298f 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -33,7 +33,6 @@ #include <linux/kobject.h> #include <linux/sysfs.h> #include <linux/pagemap.h> -#include <linux/slab.h> #include <linux/init.h> #include <linux/mount.h> #include <linux/namei.h> diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index b09b083011d6..1f4000a5a108 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c @@ -26,6 +26,7 @@ #include <linux/acpi.h> #include <linux/pci.h> #include <linux/pci_hotplug.h> +#include <linux/slab.h> #include "pciehp.h" #define PCIEHP_DETECT_PCIE (0) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 920f820edf87..3588ea61b0dd 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/types.h> #include <linux/pci.h> #include "pciehp.h" diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 9a7f247e8ac1..8f58148be044 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/pci.h> #include <linux/workqueue.h> #include "../pci.h" diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 40b48f569b1e..0cd42047d89b 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -36,6 +36,7 @@ #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/time.h> +#include <linux/slab.h> #include "../pci.h" #include "pciehp.h" @@ -832,9 +833,8 @@ static inline void dbg_ctrl(struct controller *ctrl) for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { if (!pci_resource_len(pdev, i)) continue; - ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n", - i, (unsigned long long)pci_resource_len(pdev, i), - (unsigned long long)pci_resource_start(pdev, i)); + ctrl_info(ctrl, " PCI resource [%d] : %pR\n", + i, &pdev->resource[i]); } ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap); ctrl_info(ctrl, " Physical Slot Number : %d\n", PSN(ctrl)); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index dcaae725fd79..719702240780 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -27,7 +27,6 @@ #include <linux/moduleparam.h> #include <linux/pci.h> #include <linux/pci_hotplug.h> -#include <linux/slab.h> #include <linux/smp.h> #include <linux/init.h> #include <asm/eeh.h> /* for eeh_add_device() */ diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 8aebe1e9d3d6..72d507b6a2aa 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c @@ -15,6 +15,7 @@ #include <linux/pci.h> #include <linux/pci_hotplug.h> #include <linux/proc_fs.h> +#include <linux/slab.h> #include <linux/types.h> #include <linux/mutex.h> diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index a5062297f488..a7bd5048396e 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -31,6 +31,7 @@ #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/pci.h> #include <linux/workqueue.h> #include "shpchp.h" diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 3bba0c0888ff..3387fbfb0c54 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -30,6 +30,7 @@ #include <linux/module.h> #include <linux/kernel.h> #include <linux/types.h> +#include <linux/slab.h> #include <linux/pci.h> #include <linux/workqueue.h> #include "../pci.h" diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c index 737a1c44b07a..98abf8b91294 100644 --- a/drivers/pci/htirq.c +++ b/drivers/pci/htirq.c @@ -10,7 +10,6 @@ #include <linux/pci.h> #include <linux/spinlock.h> #include <linux/slab.h> -#include <linux/gfp.h> #include <linux/htirq.h> /* Global ht irq lock. diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 95b849130ad4..6ee98a56946f 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c @@ -1,6 +1,7 @@ #include <linux/interrupt.h> #include <linux/dmar.h> #include <linux/spinlock.h> +#include <linux/slab.h> #include <linux/jiffies.h> #include <linux/hpet.h> #include <linux/pci.h> diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 3e0d7b5dd1b9..203508b227b7 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c @@ -18,6 +18,7 @@ #include <linux/pci.h> #include <linux/acpi.h> +#include <linux/slab.h> #include <acpi/acpi_bus.h> struct ioapic { @@ -31,9 +32,9 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) acpi_status status; unsigned long long gsb; struct ioapic *ioapic; - u64 addr; int ret; char *type; + struct resource *res; handle = DEVICE_ACPI_HANDLE(&dev->dev); if (!handle) @@ -69,13 +70,12 @@ static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) if (pci_request_region(dev, 0, type)) goto exit_disable; - addr = pci_resource_start(dev, 0); - if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) + res = &dev->resource[0]; + if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) goto exit_release; pci_set_drvdata(dev, ioapic); - dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, - ioapic->gsi_base); + dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); return 0; exit_release: diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 3e5ab2bf6a5c..ce6a3666b3d9 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -9,6 +9,7 @@ */ #include <linux/pci.h> +#include <linux/slab.h> #include <linux/mutex.h> #include <linux/string.h> #include <linux/delay.h> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index f9cf3173b23d..77b68eaf021e 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -18,6 +18,7 @@ #include <linux/smp.h> #include <linux/errno.h> #include <linux/io.h> +#include <linux/slab.h> #include "pci.h" #include "msi.h" diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index de296452c957..fad93983bfed 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -23,6 +23,7 @@ #include <linux/mm.h> #include <linux/capability.h> #include <linux/pci-aspm.h> +#include <linux/slab.h> #include "pci.h" static int sysfs_initialized; /* = 0 */ @@ -655,8 +656,8 @@ void pci_create_legacy_files(struct pci_bus *b) goto legacy_io_err; /* Allocated above after the legacy_io struct */ - sysfs_bin_attr_init(b->legacy_mem); b->legacy_mem = b->legacy_io + 1; + sysfs_bin_attr_init(b->legacy_mem); b->legacy_mem->attr.name = "legacy_mem"; b->legacy_mem->size = 1024*1024; b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index ddd55dc927f7..9a3d3309f896 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/pci.h> #include <linux/pm.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/spinlock.h> #include <linux/string.h> @@ -2576,18 +2577,17 @@ EXPORT_SYMBOL_GPL(pci_reset_function); */ int pcix_get_max_mmrbc(struct pci_dev *dev) { - int err, cap; + int cap; u32 stat; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); - if (err) + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) return -EINVAL; - return (stat & PCI_X_STATUS_MAX_READ) >> 12; + return 512 << ((stat & PCI_X_STATUS_MAX_READ) >> 21); } EXPORT_SYMBOL(pcix_get_max_mmrbc); @@ -2600,18 +2600,17 @@ EXPORT_SYMBOL(pcix_get_max_mmrbc); */ int pcix_get_mmrbc(struct pci_dev *dev) { - int ret, cap; - u32 cmd; + int cap; + u16 cmd; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) return -EINVAL; - ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); - if (!ret) - ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) + return -EINVAL; - return ret; + return 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); } EXPORT_SYMBOL(pcix_get_mmrbc); @@ -2626,28 +2625,27 @@ EXPORT_SYMBOL(pcix_get_mmrbc); */ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) { - int cap, err = -EINVAL; - u32 stat, cmd, v, o; + int cap; + u32 stat, v, o; + u16 cmd; if (mmrbc < 512 || mmrbc > 4096 || !is_power_of_2(mmrbc)) - goto out; + return -EINVAL; v = ffs(mmrbc) - 10; cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!cap) - goto out; + return -EINVAL; - err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); - if (err) - goto out; + if (pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat)) + return -EINVAL; if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) return -E2BIG; - err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); - if (err) - goto out; + if (pci_read_config_word(dev, cap + PCI_X_CMD, &cmd)) + return -EINVAL; o = (cmd & PCI_X_CMD_MAX_READ) >> 2; if (o != v) { @@ -2657,10 +2655,10 @@ int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) cmd &= ~PCI_X_CMD_MAX_READ; cmd |= v << 2; - err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); + if (pci_write_config_word(dev, cap + PCI_X_CMD, cmd)) + return -EIO; } -out: - return err; + return 0; } EXPORT_SYMBOL(pcix_set_mmrbc); @@ -3023,7 +3021,6 @@ EXPORT_SYMBOL(pcim_pin_device); EXPORT_SYMBOL(pci_disable_device); EXPORT_SYMBOL(pci_find_capability); EXPORT_SYMBOL(pci_bus_find_capability); -EXPORT_SYMBOL(pci_register_set_vga_state); EXPORT_SYMBOL(pci_release_regions); EXPORT_SYMBOL(pci_request_regions); EXPORT_SYMBOL(pci_request_regions_exclusive); diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 223052b73563..f8f425b8731d 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/stddef.h> diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 21f215f4daa3..aa495ad9bbd4 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -25,6 +25,7 @@ #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/pcieport_if.h> +#include <linux/slab.h> #include "aerdrv.h" #include "../../pci.h" diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index c843a799814d..aceb04b67b60 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c @@ -23,6 +23,7 @@ #include <linux/pm.h> #include <linux/suspend.h> #include <linux/delay.h> +#include <linux/slab.h> #include "aerdrv.h" static int forceload; diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c index 7b3cbff547ee..aac285a16b62 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme/pcie_pme.c @@ -14,6 +14,7 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/errno.h> +#include <linux/slab.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/device.h> diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 127e8f169d9c..3debed25e46b 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -12,7 +12,6 @@ #include <linux/errno.h> #include <linux/pm.h> #include <linux/init.h> -#include <linux/slab.h> #include <linux/pcieport_if.h> #include <linux/aer.h> #include <linux/dmi.h> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2a943090a3b7..882bd8d29fe3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -174,14 +174,19 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, pci_read_config_dword(dev, pos, &sz); pci_write_config_dword(dev, pos, l); + if (!sz) + goto fail; /* BAR not implemented */ + /* * All bits set in sz means the device isn't working properly. - * If the BAR isn't implemented, all bits must be 0. If it's a - * memory BAR or a ROM, bit 0 must be clear; if it's an io BAR, bit - * 1 must be clear. + * If it's a memory BAR or a ROM, bit 0 must be clear; if it's + * an io BAR, bit 1 must be clear. */ - if (!sz || sz == 0xffffffff) + if (sz == 0xffffffff) { + dev_err(&dev->dev, "reg %x: invalid size %#x; broken device?\n", + pos, sz); goto fail; + } /* * I don't know how l can have all bits set. Copied from old code. @@ -244,13 +249,17 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, pos, res); } } else { - sz = pci_size(l, sz, mask); + u32 size = pci_size(l, sz, mask); - if (!sz) + if (!size) { + dev_err(&dev->dev, "reg %x: invalid size " + "(l %#x sz %#x mask %#x); broken device?", + pos, l, sz, mask); goto fail; + } res->start = l; - res->end = l + sz; + res->end = l + size; dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); } @@ -312,7 +321,7 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); } else { dev_printk(KERN_DEBUG, &dev->dev, - " bridge window [io %04lx - %04lx] reg reading\n", + " bridge window [io %#06lx-%#06lx] (disabled)\n", base, limit); } } @@ -336,7 +345,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); } else { dev_printk(KERN_DEBUG, &dev->dev, - " bridge window [mem 0x%08lx - 0x%08lx] reg reading\n", + " bridge window [mem %#010lx-%#010lx] (disabled)\n", base, limit + 0xfffff); } } @@ -387,7 +396,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); } else { dev_printk(KERN_DEBUG, &dev->dev, - " bridge window [mem 0x%08lx - %08lx pref] reg reading\n", + " bridge window [mem %#010lx-%#010lx pref] (disabled)\n", base, limit + 0xfffff); } } @@ -673,16 +682,20 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); u32 buses, i, j = 0; u16 bctl; + u8 primary, secondary, subordinate; int broken = 0; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); + primary = buses & 0xFF; + secondary = (buses >> 8) & 0xFF; + subordinate = (buses >> 16) & 0xFF; - dev_dbg(&dev->dev, "scanning behind bridge, config %06x, pass %d\n", - buses & 0xffffff, pass); + dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", + secondary, subordinate, pass); /* Check if setup is sensible at all */ if (!pass && - ((buses & 0xff) != bus->number || ((buses >> 8) & 0xff) <= bus->number)) { + (primary != bus->number || secondary <= bus->number)) { dev_dbg(&dev->dev, "bus configuration invalid, reconfiguring\n"); broken = 1; } @@ -693,15 +706,15 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT); - if ((buses & 0xffff00) && !pcibios_assign_all_busses() && !is_cardbus && !broken) { - unsigned int cmax, busnr; + if ((secondary || subordinate) && !pcibios_assign_all_busses() && + !is_cardbus && !broken) { + unsigned int cmax; /* * Bus already configured by firmware, process it in the first * pass and just note the configuration. */ if (pass) goto out; - busnr = (buses >> 8) & 0xFF; /* * If we already got to this bus through a different bridge, @@ -710,13 +723,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, * However, we continue to descend down the hierarchy and * scan remaining child buses. */ - child = pci_find_bus(pci_domain_nr(bus), busnr); + child = pci_find_bus(pci_domain_nr(bus), secondary); if (!child) { - child = pci_add_new_bus(bus, dev, busnr); + child = pci_add_new_bus(bus, dev, secondary); if (!child) goto out; - child->primary = buses & 0xFF; - child->subordinate = (buses >> 16) & 0xFF; + child->primary = primary; + child->subordinate = subordinate; child->bridge_ctl = bctl; } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 593bb844b8db..449e890267a2 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -6,6 +6,7 @@ #include <linux/init.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 81d19d5683ac..27c0e6eb7136 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -368,8 +368,9 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, bus_region.end = res->end; pcibios_bus_to_resource(dev, res, &bus_region); - pci_claim_resource(dev, nr); - dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); + if (pci_claim_resource(dev, nr) == 0) + dev_info(&dev->dev, "quirk: %pR claimed by %s\n", + res, name); } } @@ -1977,11 +1978,25 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) /* * Disable PCI Bus Parking and PCI Master read caching on CX700 * which causes unspecified timing errors with a VT6212L on the PCI - * bus leading to USB2.0 packet loss. The defaults are that these - * features are turned off but some BIOSes turn them on. + * bus leading to USB2.0 packet loss. + * + * This quirk is only enabled if a second (on the external PCI bus) + * VT6212L is found -- the CX700 core itself also contains a USB + * host controller with the same PCI ID as the VT6212L. */ + /* Count VT6212L instances */ + struct pci_dev *p = pci_get_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_8235_USB_2, NULL); uint8_t b; + + /* p should contain the first (internal) VT6212L -- see if we have + an external one by searching again */ + p = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, p); + if (!p) + return; + pci_dev_put(p); + if (pci_read_config_byte(dev, 0x76, &b) == 0) { if (b & 0x40) { /* Turn off PCI Bus Parking */ @@ -2008,7 +2023,7 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev) } } } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0x324e, quirk_via_cx700_pci_parking_caching); /* * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the @@ -2108,6 +2123,10 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi); /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 4a471dc4f4b9..20d03f772289 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -9,6 +9,7 @@ #include <linux/init.h> #include <linux/pci.h> +#include <linux/slab.h> #include <linux/module.h> #include <linux/interrupt.h> #include "pci.h" diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 7d678bb15ffb..17bed18d24ad 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -93,8 +93,7 @@ void pci_update_resource(struct pci_dev *dev, int resno) int pci_claim_resource(struct pci_dev *dev, int resource) { struct resource *res = &dev->resource[resource]; - struct resource *root; - int err; + struct resource *root, *conflict; root = pci_find_parent_resource(dev, res); if (!root) { @@ -103,12 +102,15 @@ int pci_claim_resource(struct pci_dev *dev, int resource) return -EINVAL; } - err = request_resource(root, res); - if (err) + conflict = request_resource_conflict(root, res); + if (conflict) { dev_err(&dev->dev, - "address space collision: %pR already in use\n", res); + "address space collision: %pR conflicts with %s %pR\n", + res, conflict->name, conflict); + return -EBUSY; + } - return err; + return 0; } EXPORT_SYMBOL(pci_claim_resource); diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index f75a44d37fbe..659eaa0fc48f 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -6,6 +6,7 @@ */ #include <linux/kobject.h> +#include <linux/slab.h> #include <linux/pci.h> #include <linux/err.h> #include "pci.h" |