aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-12-22 12:57:02 -0500
committerJiri Kosina <jkosina@suse.cz>2010-12-22 12:57:02 -0500
commit4b7bd364700d9ac8372eff48832062b936d0793b (patch)
tree0dbf78c95456a0b02d07fcd473281f04a87e266d /drivers/pci
parentc0d8768af260e2cbb4bf659ae6094a262c86b085 (diff)
parent90a8a73c06cc32b609a880d48449d7083327e11a (diff)
Merge branch 'master' into for-next
Conflicts: MAINTAINERS arch/arm/mach-omap2/pm24xx.c drivers/scsi/bfa/bfa_fcpim.c Needed to update to apply fixes for which the old branch was too outdated.
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/bus.c53
-rw-r--r--drivers/pci/dmar.c5
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c6
-rw-r--r--drivers/pci/pci-sysfs.c23
-rw-r--r--drivers/pci/pci.c12
-rw-r--r--drivers/pci/pci.h7
-rw-r--r--drivers/pci/proc.c3
-rw-r--r--drivers/pci/quirks.c44
-rw-r--r--drivers/pci/xen-pcifront.c6
10 files changed, 100 insertions, 60 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index f01e344cf4bd..98e6fdf34d30 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
49obj-$(CONFIG_X86_VISWS) += setup-irq.o 49obj-$(CONFIG_X86_VISWS) += setup-irq.o
50obj-$(CONFIG_MN10300) += setup-bus.o 50obj-$(CONFIG_MN10300) += setup-bus.o
51obj-$(CONFIG_MICROBLAZE) += setup-bus.o 51obj-$(CONFIG_MICROBLAZE) += setup-bus.o
52obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o
52 53
53# 54#
54# ACPI Related PCI FW Functions 55# ACPI Related PCI FW Functions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 5624db8c9ad0..69546e9213dd 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -64,49 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus)
64 } 64 }
65} 65}
66 66
67/*
68 * Find the highest-address bus resource below the cursor "res". If the
69 * cursor is NULL, return the highest resource.
70 */
71static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus,
72 unsigned int type,
73 struct resource *res)
74{
75 struct resource *r, *prev = NULL;
76 int i;
77
78 pci_bus_for_each_resource(bus, r, i) {
79 if (!r)
80 continue;
81
82 if ((r->flags & IORESOURCE_TYPE_BITS) != type)
83 continue;
84
85 /* If this resource is at or past the cursor, skip it */
86 if (res) {
87 if (r == res)
88 continue;
89 if (r->end > res->end)
90 continue;
91 if (r->end == res->end && r->start > res->start)
92 continue;
93 }
94
95 if (!prev)
96 prev = r;
97
98 /*
99 * A small resource is higher than a large one that ends at
100 * the same address.
101 */
102 if (r->end > prev->end ||
103 (r->end == prev->end && r->start > prev->start))
104 prev = r;
105 }
106
107 return prev;
108}
109
110/** 67/**
111 * pci_bus_alloc_resource - allocate a resource from a parent bus 68 * pci_bus_alloc_resource - allocate a resource from a parent bus
112 * @bus: PCI bus 69 * @bus: PCI bus
@@ -132,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
132 resource_size_t), 89 resource_size_t),
133 void *alignf_data) 90 void *alignf_data)
134{ 91{
135 int ret = -ENOMEM; 92 int i, ret = -ENOMEM;
136 struct resource *r; 93 struct resource *r;
137 resource_size_t max = -1; 94 resource_size_t max = -1;
138 unsigned int type = res->flags & IORESOURCE_TYPE_BITS;
139 95
140 type_mask |= IORESOURCE_IO | IORESOURCE_MEM; 96 type_mask |= IORESOURCE_IO | IORESOURCE_MEM;
141 97
@@ -143,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
143 if (!(res->flags & IORESOURCE_MEM_64)) 99 if (!(res->flags & IORESOURCE_MEM_64))
144 max = PCIBIOS_MAX_MEM_32; 100 max = PCIBIOS_MAX_MEM_32;
145 101
146 /* Look for space at highest addresses first */ 102 pci_bus_for_each_resource(bus, r, i) {
147 r = pci_bus_find_resource_prev(bus, type, NULL); 103 if (!r)
148 for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { 104 continue;
105
149 /* type_mask must match */ 106 /* type_mask must match */
150 if ((res->flags ^ r->flags) & type_mask) 107 if ((res->flags ^ r->flags) & type_mask)
151 continue; 108 continue;
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 0157708d474d..09933eb9126b 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void)
1417 (unsigned long long)drhd->reg_base_addr, ret); 1417 (unsigned long long)drhd->reg_base_addr, ret);
1418 return -1; 1418 return -1;
1419 } 1419 }
1420
1421 /*
1422 * Clear any previous faults.
1423 */
1424 dmar_fault(iommu->irq, iommu);
1420 } 1425 }
1421 1426
1422 return 0; 1427 return 0;
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index 5becbdee4027..2850e64dedae 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -276,6 +276,12 @@ int __init ibmphp_access_ebda (void)
276 276
277 for (;;) { 277 for (;;) {
278 offset = next_offset; 278 offset = next_offset;
279
280 /* Make sure what we read is still in the mapped section */
281 if (WARN(offset > (ebda_sz * 1024 - 4),
282 "ibmphp_ebda: next read is beyond ebda_sz\n"))
283 break;
284
279 next_offset = readw (io_mem + offset); /* offset of next blk */ 285 next_offset = readw (io_mem + offset); /* offset of next blk */
280 286
281 offset += 2; 287 offset += 2;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index b5a7d9bfcb24..63d5042f2079 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -705,17 +705,21 @@ void pci_remove_legacy_files(struct pci_bus *b)
705 705
706#ifdef HAVE_PCI_MMAP 706#ifdef HAVE_PCI_MMAP
707 707
708int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) 708int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
709 enum pci_mmap_api mmap_api)
709{ 710{
710 unsigned long nr, start, size; 711 unsigned long nr, start, size, pci_start;
711 712
713 if (pci_resource_len(pdev, resno) == 0)
714 return 0;
712 nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 715 nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
713 start = vma->vm_pgoff; 716 start = vma->vm_pgoff;
714 size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1; 717 size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
715 if (start < size && size - start >= nr) 718 pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
719 pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
720 if (start >= pci_start && start < pci_start + size &&
721 start + nr <= pci_start + size)
716 return 1; 722 return 1;
717 WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n",
718 current->comm, start, start+nr, pci_name(pdev), resno, size);
719 return 0; 723 return 0;
720} 724}
721 725
@@ -745,8 +749,15 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
745 if (i >= PCI_ROM_RESOURCE) 749 if (i >= PCI_ROM_RESOURCE)
746 return -ENODEV; 750 return -ENODEV;
747 751
748 if (!pci_mmap_fits(pdev, i, vma)) 752 if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
753 WARN(1, "process \"%s\" tried to map 0x%08lx bytes "
754 "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
755 current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
756 pci_name(pdev), i,
757 (u64)pci_resource_start(pdev, i),
758 (u64)pci_resource_len(pdev, i));
749 return -EINVAL; 759 return -EINVAL;
760 }
750 761
751 /* pci_mmap_page_range() expects the same kind of entry as coming 762 /* pci_mmap_page_range() expects the same kind of entry as coming
752 * from /proc/bus/pci/ which is a "user visible" value. If this is 763 * from /proc/bus/pci/ which is a "user visible" value. If this is
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e98c8104297b..710c8a29be0d 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1007,6 +1007,18 @@ static int __pci_enable_device_flags(struct pci_dev *dev,
1007 int err; 1007 int err;
1008 int i, bars = 0; 1008 int i, bars = 0;
1009 1009
1010 /*
1011 * Power state could be unknown at this point, either due to a fresh
1012 * boot or a device removal call. So get the current power state
1013 * so that things like MSI message writing will behave as expected
1014 * (e.g. if the device really is in D0 at enable time).
1015 */
1016 if (dev->pm_cap) {
1017 u16 pmcsr;
1018 pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
1019 dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
1020 }
1021
1010 if (atomic_add_return(1, &dev->enable_cnt) > 1) 1022 if (atomic_add_return(1, &dev->enable_cnt) > 1)
1011 return 0; /* already enabled */ 1023 return 0; /* already enabled */
1012 1024
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index f5c7c382765f..7d33f6673868 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -22,8 +22,13 @@ extern void pci_remove_firmware_label_files(struct pci_dev *pdev);
22#endif 22#endif
23extern void pci_cleanup_rom(struct pci_dev *dev); 23extern void pci_cleanup_rom(struct pci_dev *dev);
24#ifdef HAVE_PCI_MMAP 24#ifdef HAVE_PCI_MMAP
25enum pci_mmap_api {
26 PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
27 PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */
28};
25extern int pci_mmap_fits(struct pci_dev *pdev, int resno, 29extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
26 struct vm_area_struct *vma); 30 struct vm_area_struct *vmai,
31 enum pci_mmap_api mmap_api);
27#endif 32#endif
28int pci_probe_reset_function(struct pci_dev *dev); 33int pci_probe_reset_function(struct pci_dev *dev);
29 34
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 297b72c880a1..27911b55c2a5 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -10,7 +10,6 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/proc_fs.h> 11#include <linux/proc_fs.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/smp_lock.h>
14#include <linux/capability.h> 13#include <linux/capability.h>
15#include <asm/uaccess.h> 14#include <asm/uaccess.h>
16#include <asm/byteorder.h> 15#include <asm/byteorder.h>
@@ -257,7 +256,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
257 256
258 /* Make sure the caller is mapping a real resource for this device */ 257 /* Make sure the caller is mapping a real resource for this device */
259 for (i = 0; i < PCI_ROM_RESOURCE; i++) { 258 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
260 if (pci_mmap_fits(dev, i, vma)) 259 if (pci_mmap_fits(dev, i, vma, PCI_MMAP_PROCFS))
261 break; 260 break;
262 } 261 }
263 262
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index f5c63fe9db5c..53a786fd0d40 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2136,6 +2136,24 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
2136DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, 2136DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
2137 quirk_unhide_mch_dev6); 2137 quirk_unhide_mch_dev6);
2138 2138
2139#ifdef CONFIG_TILE
2140/*
2141 * The Tilera TILEmpower platform needs to set the link speed
2142 * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed
2143 * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe
2144 * capability register of the PEX8624 PCIe switch. The switch
2145 * supports link speed auto negotiation, but falsely sets
2146 * the link speed to 5GT/s.
2147 */
2148static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev)
2149{
2150 if (tile_plx_gen1) {
2151 pci_write_config_dword(dev, 0x98, 0x1);
2152 mdelay(50);
2153 }
2154}
2155DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
2156#endif /* CONFIG_TILE */
2139 2157
2140#ifdef CONFIG_PCI_MSI 2158#ifdef CONFIG_PCI_MSI
2141/* Some chipsets do not support MSI. We cannot easily rely on setting 2159/* Some chipsets do not support MSI. We cannot easily rely on setting
@@ -2311,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev)
2311{ 2329{
2312 u32 cfg; 2330 u32 cfg;
2313 2331
2332 if (!pci_find_capability(dev, PCI_CAP_ID_HT))
2333 return;
2334
2314 pci_read_config_dword(dev, 0x74, &cfg); 2335 pci_read_config_dword(dev, 0x74, &cfg);
2315 2336
2316 if (cfg & ((1 << 2) | (1 << 15))) { 2337 if (cfg & ((1 << 2) | (1 << 15))) {
@@ -2746,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m
2746DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); 2767DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
2747#endif /*CONFIG_MMC_RICOH_MMC*/ 2768#endif /*CONFIG_MMC_RICOH_MMC*/
2748 2769
2770#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
2771#define VTUNCERRMSK_REG 0x1ac
2772#define VTD_MSK_SPEC_ERRORS (1 << 31)
2773/*
2774 * This is a quirk for masking vt-d spec defined errors to platform error
2775 * handling logic. With out this, platforms using Intel 7500, 5500 chipsets
2776 * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based
2777 * on the RAS config settings of the platform) when a vt-d fault happens.
2778 * The resulting SMI caused the system to hang.
2779 *
2780 * VT-d spec related errors are already handled by the VT-d OS code, so no
2781 * need to report the same error through other channels.
2782 */
2783static void vtd_mask_spec_errors(struct pci_dev *dev)
2784{
2785 u32 word;
2786
2787 pci_read_config_dword(dev, VTUNCERRMSK_REG, &word);
2788 pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS);
2789}
2790DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors);
2791DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
2792#endif
2749 2793
2750static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, 2794static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
2751 struct pci_fixup *end) 2795 struct pci_fixup *end)
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index a87c4985326e..3a5a6fcc0ead 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -13,7 +13,6 @@
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/msi.h> 15#include <linux/msi.h>
16#include <xen/xenbus.h>
17#include <xen/interface/io/pciif.h> 16#include <xen/interface/io/pciif.h>
18#include <asm/xen/pci.h> 17#include <asm/xen/pci.h>
19#include <linux/interrupt.h> 18#include <linux/interrupt.h>
@@ -576,8 +575,9 @@ static pci_ers_result_t pcifront_common_process(int cmd,
576 575
577 pcidev = pci_get_bus_and_slot(bus, devfn); 576 pcidev = pci_get_bus_and_slot(bus, devfn);
578 if (!pcidev || !pcidev->driver) { 577 if (!pcidev || !pcidev->driver) {
579 dev_err(&pcidev->dev, 578 dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
580 "device or driver is NULL\n"); 579 if (pcidev)
580 pci_dev_put(pcidev);
581 return result; 581 return result;
582 } 582 }
583 pdrv = pcidev->driver; 583 pdrv = pcidev->driver;