diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 15:18:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-11 15:18:16 -0500 |
commit | 11bd04f6f35621193311c32e0721142b073a7794 (patch) | |
tree | 00979740582bb26e8d3756bf3526c85f19f66a46 | |
parent | 4e2ccdb0409146f8cf64a11b6ef82a9c928ced2a (diff) | |
parent | 9e0b5b2c447ad0caa075a5cfef86def62e1782ff (diff) |
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (109 commits)
PCI: fix coding style issue in pci_save_state()
PCI: add pci_request_acs
PCI: fix BUG_ON triggered by logical PCIe root port removal
PCI: remove ifdefed pci_cleanup_aer_correct_error_status
PCI: unconditionally clear AER uncorr status register during cleanup
x86/PCI: claim SR-IOV BARs in pcibios_allocate_resource
PCI: portdrv: remove redundant definitions
PCI: portdrv: remove unnecessary struct pcie_port_data
PCI: portdrv: minor cleanup for pcie_port_device_register
PCI: portdrv: add missing irq cleanup
PCI: portdrv: enable device before irq initialization
PCI: portdrv: cleanup service irqs initialization
PCI: portdrv: check capabilities first
PCI: portdrv: move PME capability check
PCI: portdrv: remove redundant pcie type calculation
PCI: portdrv: cleanup pcie_device registration
PCI: portdrv: remove redundant pcie_port_device_probe
PCI: Always set prefetchable base/limit upper32 registers
PCI: read-modify-write the pcie device control register when initiating pcie flr
PCI: show dma_mask bits in /sys
...
Fixed up conflicts in:
arch/x86/kernel/amd_iommu_init.c
drivers/pci/dmar.c
drivers/pci/hotplug/acpiphp_glue.c
83 files changed, 1787 insertions, 1564 deletions
diff --git a/arch/ia64/include/asm/xen/hypervisor.h b/arch/ia64/include/asm/xen/hypervisor.h index 88afb54501e4..67455c2ed2b1 100644 --- a/arch/ia64/include/asm/xen/hypervisor.h +++ b/arch/ia64/include/asm/xen/hypervisor.h | |||
@@ -37,35 +37,9 @@ | |||
37 | #include <xen/interface/xen.h> | 37 | #include <xen/interface/xen.h> |
38 | #include <xen/interface/version.h> /* to compile feature.c */ | 38 | #include <xen/interface/version.h> /* to compile feature.c */ |
39 | #include <xen/features.h> /* to comiple xen-netfront.c */ | 39 | #include <xen/features.h> /* to comiple xen-netfront.c */ |
40 | #include <xen/xen.h> | ||
40 | #include <asm/xen/hypercall.h> | 41 | #include <asm/xen/hypercall.h> |
41 | 42 | ||
42 | /* xen_domain_type is set before executing any C code by early_xen_setup */ | ||
43 | enum xen_domain_type { | ||
44 | XEN_NATIVE, /* running on bare hardware */ | ||
45 | XEN_PV_DOMAIN, /* running in a PV domain */ | ||
46 | XEN_HVM_DOMAIN, /* running in a Xen hvm domain*/ | ||
47 | }; | ||
48 | |||
49 | #ifdef CONFIG_XEN | ||
50 | extern enum xen_domain_type xen_domain_type; | ||
51 | #else | ||
52 | #define xen_domain_type XEN_NATIVE | ||
53 | #endif | ||
54 | |||
55 | #define xen_domain() (xen_domain_type != XEN_NATIVE) | ||
56 | #define xen_pv_domain() (xen_domain() && \ | ||
57 | xen_domain_type == XEN_PV_DOMAIN) | ||
58 | #define xen_hvm_domain() (xen_domain() && \ | ||
59 | xen_domain_type == XEN_HVM_DOMAIN) | ||
60 | |||
61 | #ifdef CONFIG_XEN_DOM0 | ||
62 | #define xen_initial_domain() (xen_pv_domain() && \ | ||
63 | (xen_start_info->flags & SIF_INITDOMAIN)) | ||
64 | #else | ||
65 | #define xen_initial_domain() (0) | ||
66 | #endif | ||
67 | |||
68 | |||
69 | #ifdef CONFIG_XEN | 43 | #ifdef CONFIG_XEN |
70 | extern struct shared_info *HYPERVISOR_shared_info; | 44 | extern struct shared_info *HYPERVISOR_shared_info; |
71 | extern struct start_info *xen_start_info; | 45 | extern struct start_info *xen_start_info; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index c0fca2c1c858..df639db779f9 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -131,6 +131,7 @@ alloc_pci_controller (int seg) | |||
131 | } | 131 | } |
132 | 132 | ||
133 | struct pci_root_info { | 133 | struct pci_root_info { |
134 | struct acpi_device *bridge; | ||
134 | struct pci_controller *controller; | 135 | struct pci_controller *controller; |
135 | char *name; | 136 | char *name; |
136 | }; | 137 | }; |
@@ -297,9 +298,20 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
297 | window->offset = offset; | 298 | window->offset = offset; |
298 | 299 | ||
299 | if (insert_resource(root, &window->resource)) { | 300 | if (insert_resource(root, &window->resource)) { |
300 | printk(KERN_ERR "alloc 0x%llx-0x%llx from %s for %s failed\n", | 301 | dev_err(&info->bridge->dev, |
301 | window->resource.start, window->resource.end, | 302 | "can't allocate host bridge window %pR\n", |
302 | root->name, info->name); | 303 | &window->resource); |
304 | } else { | ||
305 | if (offset) | ||
306 | dev_info(&info->bridge->dev, "host bridge window %pR " | ||
307 | "(PCI address [%#llx-%#llx])\n", | ||
308 | &window->resource, | ||
309 | window->resource.start - offset, | ||
310 | window->resource.end - offset); | ||
311 | else | ||
312 | dev_info(&info->bridge->dev, | ||
313 | "host bridge window %pR\n", | ||
314 | &window->resource); | ||
303 | } | 315 | } |
304 | 316 | ||
305 | return AE_OK; | 317 | return AE_OK; |
@@ -319,8 +331,9 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl) | |||
319 | (res->end - res->start < 16)) | 331 | (res->end - res->start < 16)) |
320 | continue; | 332 | continue; |
321 | if (j >= PCI_BUS_NUM_RESOURCES) { | 333 | if (j >= PCI_BUS_NUM_RESOURCES) { |
322 | printk("Ignoring range [%#llx-%#llx] (%lx)\n", | 334 | dev_warn(&bus->dev, |
323 | res->start, res->end, res->flags); | 335 | "ignoring host bridge window %pR (no space)\n", |
336 | res); | ||
324 | continue; | 337 | continue; |
325 | } | 338 | } |
326 | bus->resource[j++] = res; | 339 | bus->resource[j++] = res; |
@@ -364,6 +377,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
364 | goto out3; | 377 | goto out3; |
365 | 378 | ||
366 | sprintf(name, "PCI Bus %04x:%02x", domain, bus); | 379 | sprintf(name, "PCI Bus %04x:%02x", domain, bus); |
380 | info.bridge = device; | ||
367 | info.controller = controller; | 381 | info.controller = controller; |
368 | info.name = name; | 382 | info.name = name; |
369 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, | 383 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, |
@@ -720,9 +734,6 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) | |||
720 | return ret; | 734 | return ret; |
721 | } | 735 | } |
722 | 736 | ||
723 | /* It's defined in drivers/pci/pci.c */ | ||
724 | extern u8 pci_cache_line_size; | ||
725 | |||
726 | /** | 737 | /** |
727 | * set_pci_cacheline_size - determine cacheline size for PCI devices | 738 | * set_pci_cacheline_size - determine cacheline size for PCI devices |
728 | * | 739 | * |
@@ -731,7 +742,7 @@ extern u8 pci_cache_line_size; | |||
731 | * | 742 | * |
732 | * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). | 743 | * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). |
733 | */ | 744 | */ |
734 | static void __init set_pci_cacheline_size(void) | 745 | static void __init set_pci_dfl_cacheline_size(void) |
735 | { | 746 | { |
736 | unsigned long levels, unique_caches; | 747 | unsigned long levels, unique_caches; |
737 | long status; | 748 | long status; |
@@ -751,7 +762,7 @@ static void __init set_pci_cacheline_size(void) | |||
751 | "(status=%ld)\n", __func__, status); | 762 | "(status=%ld)\n", __func__, status); |
752 | return; | 763 | return; |
753 | } | 764 | } |
754 | pci_cache_line_size = (1 << cci.pcci_line_size) / 4; | 765 | pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4; |
755 | } | 766 | } |
756 | 767 | ||
757 | u64 ia64_dma_get_required_mask(struct device *dev) | 768 | u64 ia64_dma_get_required_mask(struct device *dev) |
@@ -782,7 +793,7 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask); | |||
782 | 793 | ||
783 | static int __init pcibios_init(void) | 794 | static int __init pcibios_init(void) |
784 | { | 795 | { |
785 | set_pci_cacheline_size(); | 796 | set_pci_dfl_cacheline_size(); |
786 | return 0; | 797 | return 0; |
787 | } | 798 | } |
788 | 799 | ||
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index b63e51c3c3ee..b0576df6ec83 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
@@ -16,8 +16,6 @@ | |||
16 | 16 | ||
17 | #define PCI_IRQ_NONE 0xffffffff | 17 | #define PCI_IRQ_NONE 0xffffffff |
18 | 18 | ||
19 | #define PCI_CACHE_LINE_BYTES 64 | ||
20 | |||
21 | static inline void pcibios_set_master(struct pci_dev *dev) | 19 | static inline void pcibios_set_master(struct pci_dev *dev) |
22 | { | 20 | { |
23 | /* No special bus mastering setup handling */ | 21 | /* No special bus mastering setup handling */ |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index c68648662802..b85374f7cf94 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -1081,3 +1081,10 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, | |||
1081 | *start = rp->start - offset; | 1081 | *start = rp->start - offset; |
1082 | *end = rp->end - offset; | 1082 | *end = rp->end - offset; |
1083 | } | 1083 | } |
1084 | |||
1085 | static int __init pcibios_init(void) | ||
1086 | { | ||
1087 | pci_dfl_cache_line_size = 64 >> 2; | ||
1088 | return 0; | ||
1089 | } | ||
1090 | subsys_initcall(pcibios_init); | ||
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index b399988eee3a..b4bf9a942ed0 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -118,11 +118,27 @@ extern int __init pcibios_init(void); | |||
118 | 118 | ||
119 | /* pci-mmconfig.c */ | 119 | /* pci-mmconfig.c */ |
120 | 120 | ||
121 | /* "PCI MMCONFIG %04x [bus %02x-%02x]" */ | ||
122 | #define PCI_MMCFG_RESOURCE_NAME_LEN (22 + 4 + 2 + 2) | ||
123 | |||
124 | struct pci_mmcfg_region { | ||
125 | struct list_head list; | ||
126 | struct resource res; | ||
127 | u64 address; | ||
128 | char __iomem *virt; | ||
129 | u16 segment; | ||
130 | u8 start_bus; | ||
131 | u8 end_bus; | ||
132 | char name[PCI_MMCFG_RESOURCE_NAME_LEN]; | ||
133 | }; | ||
134 | |||
121 | extern int __init pci_mmcfg_arch_init(void); | 135 | extern int __init pci_mmcfg_arch_init(void); |
122 | extern void __init pci_mmcfg_arch_free(void); | 136 | extern void __init pci_mmcfg_arch_free(void); |
137 | extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); | ||
138 | |||
139 | extern struct list_head pci_mmcfg_list; | ||
123 | 140 | ||
124 | extern struct acpi_mcfg_allocation *pci_mmcfg_config; | 141 | #define PCI_MMCFG_BUS_OFFSET(bus) ((bus) << 20) |
125 | extern int pci_mmcfg_config_num; | ||
126 | 142 | ||
127 | /* | 143 | /* |
128 | * AMD Fam10h CPUs are buggy, and cannot access MMIO config space | 144 | * AMD Fam10h CPUs are buggy, and cannot access MMIO config space |
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h index d5b7e90c0edf..396ff4cc8ed4 100644 --- a/arch/x86/include/asm/xen/hypervisor.h +++ b/arch/x86/include/asm/xen/hypervisor.h | |||
@@ -37,31 +37,4 @@ | |||
37 | extern struct shared_info *HYPERVISOR_shared_info; | 37 | extern struct shared_info *HYPERVISOR_shared_info; |
38 | extern struct start_info *xen_start_info; | 38 | extern struct start_info *xen_start_info; |
39 | 39 | ||
40 | enum xen_domain_type { | ||
41 | XEN_NATIVE, /* running on bare hardware */ | ||
42 | XEN_PV_DOMAIN, /* running in a PV domain */ | ||
43 | XEN_HVM_DOMAIN, /* running in a Xen hvm domain */ | ||
44 | }; | ||
45 | |||
46 | #ifdef CONFIG_XEN | ||
47 | extern enum xen_domain_type xen_domain_type; | ||
48 | #else | ||
49 | #define xen_domain_type XEN_NATIVE | ||
50 | #endif | ||
51 | |||
52 | #define xen_domain() (xen_domain_type != XEN_NATIVE) | ||
53 | #define xen_pv_domain() (xen_domain() && \ | ||
54 | xen_domain_type == XEN_PV_DOMAIN) | ||
55 | #define xen_hvm_domain() (xen_domain() && \ | ||
56 | xen_domain_type == XEN_HVM_DOMAIN) | ||
57 | |||
58 | #ifdef CONFIG_XEN_DOM0 | ||
59 | #include <xen/interface/xen.h> | ||
60 | |||
61 | #define xen_initial_domain() (xen_pv_domain() && \ | ||
62 | xen_start_info->flags & SIF_INITDOMAIN) | ||
63 | #else /* !CONFIG_XEN_DOM0 */ | ||
64 | #define xen_initial_domain() (0) | ||
65 | #endif /* CONFIG_XEN_DOM0 */ | ||
66 | |||
67 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ | 40 | #endif /* _ASM_X86_XEN_HYPERVISOR_H */ |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 7ffc39965233..9c4a6f747552 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -1336,6 +1336,9 @@ void __init amd_iommu_detect(void) | |||
1336 | iommu_detected = 1; | 1336 | iommu_detected = 1; |
1337 | amd_iommu_detected = 1; | 1337 | amd_iommu_detected = 1; |
1338 | x86_init.iommu.iommu_init = amd_iommu_init; | 1338 | x86_init.iommu.iommu_init = amd_iommu_init; |
1339 | |||
1340 | /* Make sure ACS will be enabled */ | ||
1341 | pci_request_acs(); | ||
1339 | } | 1342 | } |
1340 | } | 1343 | } |
1341 | 1344 | ||
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile index d49202e740ea..564b008a51c7 100644 --- a/arch/x86/pci/Makefile +++ b/arch/x86/pci/Makefile | |||
@@ -15,3 +15,8 @@ obj-$(CONFIG_X86_NUMAQ) += numaq_32.o | |||
15 | 15 | ||
16 | obj-y += common.o early.o | 16 | obj-y += common.o early.o |
17 | obj-y += amd_bus.o | 17 | obj-y += amd_bus.o |
18 | obj-$(CONFIG_X86_64) += bus_numa.o intel_bus.o | ||
19 | |||
20 | ifeq ($(CONFIG_PCI_DEBUG),y) | ||
21 | EXTRA_CFLAGS += -DDEBUG | ||
22 | endif | ||
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 1014eb4bfc37..959e548a7039 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm/pci_x86.h> | 7 | #include <asm/pci_x86.h> |
8 | 8 | ||
9 | struct pci_root_info { | 9 | struct pci_root_info { |
10 | struct acpi_device *bridge; | ||
10 | char *name; | 11 | char *name; |
11 | unsigned int res_num; | 12 | unsigned int res_num; |
12 | struct resource *res; | 13 | struct resource *res; |
@@ -58,6 +59,30 @@ bus_has_transparent_bridge(struct pci_bus *bus) | |||
58 | return false; | 59 | return false; |
59 | } | 60 | } |
60 | 61 | ||
62 | static void | ||
63 | align_resource(struct acpi_device *bridge, struct resource *res) | ||
64 | { | ||
65 | int align = (res->flags & IORESOURCE_MEM) ? 16 : 4; | ||
66 | |||
67 | /* | ||
68 | * Host bridge windows are not BARs, but the decoders on the PCI side | ||
69 | * that claim this address space have starting alignment and length | ||
70 | * constraints, so fix any obvious BIOS goofs. | ||
71 | */ | ||
72 | if (!IS_ALIGNED(res->start, align)) { | ||
73 | dev_printk(KERN_DEBUG, &bridge->dev, | ||
74 | "host bridge window %pR invalid; " | ||
75 | "aligning start to %d-byte boundary\n", res, align); | ||
76 | res->start &= ~(align - 1); | ||
77 | } | ||
78 | if (!IS_ALIGNED(res->end + 1, align)) { | ||
79 | dev_printk(KERN_DEBUG, &bridge->dev, | ||
80 | "host bridge window %pR invalid; " | ||
81 | "aligning end to %d-byte boundary\n", res, align); | ||
82 | res->end = ALIGN(res->end, align) - 1; | ||
83 | } | ||
84 | } | ||
85 | |||
61 | static acpi_status | 86 | static acpi_status |
62 | setup_resource(struct acpi_resource *acpi_res, void *data) | 87 | setup_resource(struct acpi_resource *acpi_res, void *data) |
63 | { | 88 | { |
@@ -91,11 +116,12 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
91 | start = addr.minimum + addr.translation_offset; | 116 | start = addr.minimum + addr.translation_offset; |
92 | end = start + addr.address_length - 1; | 117 | end = start + addr.address_length - 1; |
93 | if (info->res_num >= max_root_bus_resources) { | 118 | if (info->res_num >= max_root_bus_resources) { |
94 | printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx " | 119 | if (pci_probe & PCI_USE__CRS) |
95 | "from %s for %s due to _CRS returning more than " | 120 | printk(KERN_WARNING "PCI: Failed to allocate " |
96 | "%d resource descriptors\n", (unsigned long) start, | 121 | "0x%lx-0x%lx from %s for %s due to _CRS " |
97 | (unsigned long) end, root->name, info->name, | 122 | "returning more than %d resource descriptors\n", |
98 | max_root_bus_resources); | 123 | (unsigned long) start, (unsigned long) end, |
124 | root->name, info->name, max_root_bus_resources); | ||
99 | return AE_OK; | 125 | return AE_OK; |
100 | } | 126 | } |
101 | 127 | ||
@@ -105,14 +131,28 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
105 | res->start = start; | 131 | res->start = start; |
106 | res->end = end; | 132 | res->end = end; |
107 | res->child = NULL; | 133 | res->child = NULL; |
134 | align_resource(info->bridge, res); | ||
135 | |||
136 | if (!(pci_probe & PCI_USE__CRS)) { | ||
137 | dev_printk(KERN_DEBUG, &info->bridge->dev, | ||
138 | "host bridge window %pR (ignored)\n", res); | ||
139 | return AE_OK; | ||
140 | } | ||
108 | 141 | ||
109 | if (insert_resource(root, res)) { | 142 | if (insert_resource(root, res)) { |
110 | printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " | 143 | dev_err(&info->bridge->dev, |
111 | "from %s for %s\n", (unsigned long) res->start, | 144 | "can't allocate host bridge window %pR\n", res); |
112 | (unsigned long) res->end, root->name, info->name); | ||
113 | } else { | 145 | } else { |
114 | info->bus->resource[info->res_num] = res; | 146 | info->bus->resource[info->res_num] = res; |
115 | info->res_num++; | 147 | info->res_num++; |
148 | if (addr.translation_offset) | ||
149 | dev_info(&info->bridge->dev, "host bridge window %pR " | ||
150 | "(PCI address [%#llx-%#llx])\n", | ||
151 | res, res->start - addr.translation_offset, | ||
152 | res->end - addr.translation_offset); | ||
153 | else | ||
154 | dev_info(&info->bridge->dev, | ||
155 | "host bridge window %pR\n", res); | ||
116 | } | 156 | } |
117 | return AE_OK; | 157 | return AE_OK; |
118 | } | 158 | } |
@@ -124,6 +164,12 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
124 | struct pci_root_info info; | 164 | struct pci_root_info info; |
125 | size_t size; | 165 | size_t size; |
126 | 166 | ||
167 | if (!(pci_probe & PCI_USE__CRS)) | ||
168 | dev_info(&device->dev, | ||
169 | "ignoring host bridge windows from ACPI; " | ||
170 | "boot with \"pci=use_crs\" to use them\n"); | ||
171 | |||
172 | info.bridge = device; | ||
127 | info.bus = bus; | 173 | info.bus = bus; |
128 | info.res_num = 0; | 174 | info.res_num = 0; |
129 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, | 175 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, |
@@ -163,8 +209,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
163 | #endif | 209 | #endif |
164 | 210 | ||
165 | if (domain && !pci_domains_supported) { | 211 | if (domain && !pci_domains_supported) { |
166 | printk(KERN_WARNING "PCI: Multiple domains not supported " | 212 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
167 | "(dom %d, bus %d)\n", domain, busnum); | 213 | "ignored (multiple domains not supported)\n", |
214 | domain, busnum); | ||
168 | return NULL; | 215 | return NULL; |
169 | } | 216 | } |
170 | 217 | ||
@@ -188,7 +235,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
188 | */ | 235 | */ |
189 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); | 236 | sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
190 | if (!sd) { | 237 | if (!sd) { |
191 | printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); | 238 | printk(KERN_WARNING "pci_bus %04x:%02x: " |
239 | "ignored (out of memory)\n", domain, busnum); | ||
192 | return NULL; | 240 | return NULL; |
193 | } | 241 | } |
194 | 242 | ||
@@ -209,9 +257,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
209 | } else { | 257 | } else { |
210 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); | 258 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); |
211 | if (bus) { | 259 | if (bus) { |
212 | if (pci_probe & PCI_USE__CRS) | 260 | get_current_resources(device, busnum, domain, bus); |
213 | get_current_resources(device, busnum, domain, | ||
214 | bus); | ||
215 | bus->subordinate = pci_scan_child_bus(bus); | 261 | bus->subordinate = pci_scan_child_bus(bus); |
216 | } | 262 | } |
217 | } | 263 | } |
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 572ee9782f2a..95ecbd495955 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -6,10 +6,10 @@ | |||
6 | 6 | ||
7 | #ifdef CONFIG_X86_64 | 7 | #ifdef CONFIG_X86_64 |
8 | #include <asm/pci-direct.h> | 8 | #include <asm/pci-direct.h> |
9 | #include <asm/mpspec.h> | ||
10 | #include <linux/cpumask.h> | ||
11 | #endif | 9 | #endif |
12 | 10 | ||
11 | #include "bus_numa.h" | ||
12 | |||
13 | /* | 13 | /* |
14 | * This discovers the pcibus <-> node mapping on AMD K8. | 14 | * This discovers the pcibus <-> node mapping on AMD K8. |
15 | * also get peer root bus resource for io,mmio | 15 | * also get peer root bus resource for io,mmio |
@@ -17,67 +17,6 @@ | |||
17 | 17 | ||
18 | #ifdef CONFIG_X86_64 | 18 | #ifdef CONFIG_X86_64 |
19 | 19 | ||
20 | /* | ||
21 | * sub bus (transparent) will use entres from 3 to store extra from root, | ||
22 | * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? | ||
23 | */ | ||
24 | #define RES_NUM 16 | ||
25 | struct pci_root_info { | ||
26 | char name[12]; | ||
27 | unsigned int res_num; | ||
28 | struct resource res[RES_NUM]; | ||
29 | int bus_min; | ||
30 | int bus_max; | ||
31 | int node; | ||
32 | int link; | ||
33 | }; | ||
34 | |||
35 | /* 4 at this time, it may become to 32 */ | ||
36 | #define PCI_ROOT_NR 4 | ||
37 | static int pci_root_num; | ||
38 | static struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
39 | |||
40 | void x86_pci_root_bus_res_quirks(struct pci_bus *b) | ||
41 | { | ||
42 | int i; | ||
43 | int j; | ||
44 | struct pci_root_info *info; | ||
45 | |||
46 | /* don't go for it if _CRS is used already */ | ||
47 | if (b->resource[0] != &ioport_resource || | ||
48 | b->resource[1] != &iomem_resource) | ||
49 | return; | ||
50 | |||
51 | /* if only one root bus, don't need to anything */ | ||
52 | if (pci_root_num < 2) | ||
53 | return; | ||
54 | |||
55 | for (i = 0; i < pci_root_num; i++) { | ||
56 | if (pci_root_info[i].bus_min == b->number) | ||
57 | break; | ||
58 | } | ||
59 | |||
60 | if (i == pci_root_num) | ||
61 | return; | ||
62 | |||
63 | printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n", | ||
64 | b->number); | ||
65 | |||
66 | info = &pci_root_info[i]; | ||
67 | for (j = 0; j < info->res_num; j++) { | ||
68 | struct resource *res; | ||
69 | struct resource *root; | ||
70 | |||
71 | res = &info->res[j]; | ||
72 | b->resource[j] = res; | ||
73 | if (res->flags & IORESOURCE_IO) | ||
74 | root = &ioport_resource; | ||
75 | else | ||
76 | root = &iomem_resource; | ||
77 | insert_resource(root, res); | ||
78 | } | ||
79 | } | ||
80 | |||
81 | #define RANGE_NUM 16 | 20 | #define RANGE_NUM 16 |
82 | 21 | ||
83 | struct res_range { | 22 | struct res_range { |
@@ -130,52 +69,6 @@ static void __init update_range(struct res_range *range, size_t start, | |||
130 | } | 69 | } |
131 | } | 70 | } |
132 | 71 | ||
133 | static void __init update_res(struct pci_root_info *info, size_t start, | ||
134 | size_t end, unsigned long flags, int merge) | ||
135 | { | ||
136 | int i; | ||
137 | struct resource *res; | ||
138 | |||
139 | if (!merge) | ||
140 | goto addit; | ||
141 | |||
142 | /* try to merge it with old one */ | ||
143 | for (i = 0; i < info->res_num; i++) { | ||
144 | size_t final_start, final_end; | ||
145 | size_t common_start, common_end; | ||
146 | |||
147 | res = &info->res[i]; | ||
148 | if (res->flags != flags) | ||
149 | continue; | ||
150 | |||
151 | common_start = max((size_t)res->start, start); | ||
152 | common_end = min((size_t)res->end, end); | ||
153 | if (common_start > common_end + 1) | ||
154 | continue; | ||
155 | |||
156 | final_start = min((size_t)res->start, start); | ||
157 | final_end = max((size_t)res->end, end); | ||
158 | |||
159 | res->start = final_start; | ||
160 | res->end = final_end; | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | addit: | ||
165 | |||
166 | /* need to add that */ | ||
167 | if (info->res_num >= RES_NUM) | ||
168 | return; | ||
169 | |||
170 | res = &info->res[info->res_num]; | ||
171 | res->name = info->name; | ||
172 | res->flags = flags; | ||
173 | res->start = start; | ||
174 | res->end = end; | ||
175 | res->child = NULL; | ||
176 | info->res_num++; | ||
177 | } | ||
178 | |||
179 | struct pci_hostbridge_probe { | 72 | struct pci_hostbridge_probe { |
180 | u32 bus; | 73 | u32 bus; |
181 | u32 slot; | 74 | u32 slot; |
@@ -230,7 +123,6 @@ static int __init early_fill_mp_bus_info(void) | |||
230 | int j; | 123 | int j; |
231 | unsigned bus; | 124 | unsigned bus; |
232 | unsigned slot; | 125 | unsigned slot; |
233 | int found; | ||
234 | int node; | 126 | int node; |
235 | int link; | 127 | int link; |
236 | int def_node; | 128 | int def_node; |
@@ -247,7 +139,7 @@ static int __init early_fill_mp_bus_info(void) | |||
247 | if (!early_pci_allowed()) | 139 | if (!early_pci_allowed()) |
248 | return -1; | 140 | return -1; |
249 | 141 | ||
250 | found = 0; | 142 | found_all_numa_early = 0; |
251 | for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { | 143 | for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { |
252 | u32 id; | 144 | u32 id; |
253 | u16 device; | 145 | u16 device; |
@@ -261,12 +153,12 @@ static int __init early_fill_mp_bus_info(void) | |||
261 | device = (id>>16) & 0xffff; | 153 | device = (id>>16) & 0xffff; |
262 | if (pci_probes[i].vendor == vendor && | 154 | if (pci_probes[i].vendor == vendor && |
263 | pci_probes[i].device == device) { | 155 | pci_probes[i].device == device) { |
264 | found = 1; | 156 | found_all_numa_early = 1; |
265 | break; | 157 | break; |
266 | } | 158 | } |
267 | } | 159 | } |
268 | 160 | ||
269 | if (!found) | 161 | if (!found_all_numa_early) |
270 | return 0; | 162 | return 0; |
271 | 163 | ||
272 | pci_root_num = 0; | 164 | pci_root_num = 0; |
@@ -488,7 +380,7 @@ static int __init early_fill_mp_bus_info(void) | |||
488 | info = &pci_root_info[i]; | 380 | info = &pci_root_info[i]; |
489 | res_num = info->res_num; | 381 | res_num = info->res_num; |
490 | busnum = info->bus_min; | 382 | busnum = info->bus_min; |
491 | printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n", | 383 | printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", |
492 | info->bus_min, info->bus_max, info->node, info->link); | 384 | info->bus_min, info->bus_max, info->node, info->link); |
493 | for (j = 0; j < res_num; j++) { | 385 | for (j = 0; j < res_num; j++) { |
494 | res = &info->res[j]; | 386 | res = &info->res[j]; |
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c new file mode 100644 index 000000000000..145df00e0387 --- /dev/null +++ b/arch/x86/pci/bus_numa.c | |||
@@ -0,0 +1,101 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/pci.h> | ||
3 | |||
4 | #include "bus_numa.h" | ||
5 | |||
6 | int pci_root_num; | ||
7 | struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
8 | int found_all_numa_early; | ||
9 | |||
10 | void x86_pci_root_bus_res_quirks(struct pci_bus *b) | ||
11 | { | ||
12 | int i; | ||
13 | int j; | ||
14 | struct pci_root_info *info; | ||
15 | |||
16 | /* don't go for it if _CRS is used already */ | ||
17 | if (b->resource[0] != &ioport_resource || | ||
18 | b->resource[1] != &iomem_resource) | ||
19 | return; | ||
20 | |||
21 | if (!pci_root_num) | ||
22 | return; | ||
23 | |||
24 | /* for amd, if only one root bus, don't need to do anything */ | ||
25 | if (pci_root_num < 2 && found_all_numa_early) | ||
26 | return; | ||
27 | |||
28 | for (i = 0; i < pci_root_num; i++) { | ||
29 | if (pci_root_info[i].bus_min == b->number) | ||
30 | break; | ||
31 | } | ||
32 | |||
33 | if (i == pci_root_num) | ||
34 | return; | ||
35 | |||
36 | printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n", | ||
37 | b->number); | ||
38 | |||
39 | info = &pci_root_info[i]; | ||
40 | for (j = 0; j < info->res_num; j++) { | ||
41 | struct resource *res; | ||
42 | struct resource *root; | ||
43 | |||
44 | res = &info->res[j]; | ||
45 | b->resource[j] = res; | ||
46 | if (res->flags & IORESOURCE_IO) | ||
47 | root = &ioport_resource; | ||
48 | else | ||
49 | root = &iomem_resource; | ||
50 | insert_resource(root, res); | ||
51 | } | ||
52 | } | ||
53 | |||
54 | void __init update_res(struct pci_root_info *info, size_t start, | ||
55 | size_t end, unsigned long flags, int merge) | ||
56 | { | ||
57 | int i; | ||
58 | struct resource *res; | ||
59 | |||
60 | if (start > end) | ||
61 | return; | ||
62 | |||
63 | if (!merge) | ||
64 | goto addit; | ||
65 | |||
66 | /* try to merge it with old one */ | ||
67 | for (i = 0; i < info->res_num; i++) { | ||
68 | size_t final_start, final_end; | ||
69 | size_t common_start, common_end; | ||
70 | |||
71 | res = &info->res[i]; | ||
72 | if (res->flags != flags) | ||
73 | continue; | ||
74 | |||
75 | common_start = max((size_t)res->start, start); | ||
76 | common_end = min((size_t)res->end, end); | ||
77 | if (common_start > common_end + 1) | ||
78 | continue; | ||
79 | |||
80 | final_start = min((size_t)res->start, start); | ||
81 | final_end = max((size_t)res->end, end); | ||
82 | |||
83 | res->start = final_start; | ||
84 | res->end = final_end; | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | addit: | ||
89 | |||
90 | /* need to add that */ | ||
91 | if (info->res_num >= RES_NUM) | ||
92 | return; | ||
93 | |||
94 | res = &info->res[info->res_num]; | ||
95 | res->name = info->name; | ||
96 | res->flags = flags; | ||
97 | res->start = start; | ||
98 | res->end = end; | ||
99 | res->child = NULL; | ||
100 | info->res_num++; | ||
101 | } | ||
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h new file mode 100644 index 000000000000..adbc23fe82ac --- /dev/null +++ b/arch/x86/pci/bus_numa.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifdef CONFIG_X86_64 | ||
2 | |||
3 | /* | ||
4 | * sub bus (transparent) will use entres from 3 to store extra from | ||
5 | * root, so need to make sure we have enough slot there, Should we | ||
6 | * increase PCI_BUS_NUM_RESOURCES? | ||
7 | */ | ||
8 | #define RES_NUM 16 | ||
9 | struct pci_root_info { | ||
10 | char name[12]; | ||
11 | unsigned int res_num; | ||
12 | struct resource res[RES_NUM]; | ||
13 | int bus_min; | ||
14 | int bus_max; | ||
15 | int node; | ||
16 | int link; | ||
17 | }; | ||
18 | |||
19 | /* 4 at this time, it may become to 32 */ | ||
20 | #define PCI_ROOT_NR 4 | ||
21 | extern int pci_root_num; | ||
22 | extern struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
23 | extern int found_all_numa_early; | ||
24 | |||
25 | extern void update_res(struct pci_root_info *info, size_t start, | ||
26 | size_t end, unsigned long flags, int merge); | ||
27 | #endif | ||
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 1331fcf26143..d2552c68e94d 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -410,8 +410,6 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) | |||
410 | return bus; | 410 | return bus; |
411 | } | 411 | } |
412 | 412 | ||
413 | extern u8 pci_cache_line_size; | ||
414 | |||
415 | int __init pcibios_init(void) | 413 | int __init pcibios_init(void) |
416 | { | 414 | { |
417 | struct cpuinfo_x86 *c = &boot_cpu_data; | 415 | struct cpuinfo_x86 *c = &boot_cpu_data; |
@@ -422,15 +420,19 @@ int __init pcibios_init(void) | |||
422 | } | 420 | } |
423 | 421 | ||
424 | /* | 422 | /* |
425 | * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8 | 423 | * Set PCI cacheline size to that of the CPU if the CPU has reported it. |
426 | * and P4. It's also good for 386/486s (which actually have 16) | 424 | * (For older CPUs that don't support cpuid, we se it to 32 bytes |
425 | * It's also good for 386/486s (which actually have 16) | ||
427 | * as quite a few PCI devices do not support smaller values. | 426 | * as quite a few PCI devices do not support smaller values. |
428 | */ | 427 | */ |
429 | pci_cache_line_size = 32 >> 2; | 428 | if (c->x86_clflush_size > 0) { |
430 | if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) | 429 | pci_dfl_cache_line_size = c->x86_clflush_size >> 2; |
431 | pci_cache_line_size = 64 >> 2; /* K7 & K8 */ | 430 | printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n", |
432 | else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) | 431 | pci_dfl_cache_line_size << 2); |
433 | pci_cache_line_size = 128 >> 2; /* P4 */ | 432 | } else { |
433 | pci_dfl_cache_line_size = 32 >> 2; | ||
434 | printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); | ||
435 | } | ||
434 | 436 | ||
435 | pcibios_resource_survey(); | 437 | pcibios_resource_survey(); |
436 | 438 | ||
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c index aaf26ae58cd5..d1067d539bee 100644 --- a/arch/x86/pci/early.c +++ b/arch/x86/pci/early.c | |||
@@ -12,8 +12,6 @@ u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) | |||
12 | u32 v; | 12 | u32 v; |
13 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 13 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
14 | v = inl(0xcfc); | 14 | v = inl(0xcfc); |
15 | if (v != 0xffffffff) | ||
16 | pr_debug("%x reading 4 from %x: %x\n", slot, offset, v); | ||
17 | return v; | 15 | return v; |
18 | } | 16 | } |
19 | 17 | ||
@@ -22,7 +20,6 @@ u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) | |||
22 | u8 v; | 20 | u8 v; |
23 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 21 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
24 | v = inb(0xcfc + (offset&3)); | 22 | v = inb(0xcfc + (offset&3)); |
25 | pr_debug("%x reading 1 from %x: %x\n", slot, offset, v); | ||
26 | return v; | 23 | return v; |
27 | } | 24 | } |
28 | 25 | ||
@@ -31,28 +28,24 @@ u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) | |||
31 | u16 v; | 28 | u16 v; |
32 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 29 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
33 | v = inw(0xcfc + (offset&2)); | 30 | v = inw(0xcfc + (offset&2)); |
34 | pr_debug("%x reading 2 from %x: %x\n", slot, offset, v); | ||
35 | return v; | 31 | return v; |
36 | } | 32 | } |
37 | 33 | ||
38 | void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, | 34 | void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, |
39 | u32 val) | 35 | u32 val) |
40 | { | 36 | { |
41 | pr_debug("%x writing to %x: %x\n", slot, offset, val); | ||
42 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 37 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
43 | outl(val, 0xcfc); | 38 | outl(val, 0xcfc); |
44 | } | 39 | } |
45 | 40 | ||
46 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) | 41 | void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) |
47 | { | 42 | { |
48 | pr_debug("%x writing to %x: %x\n", slot, offset, val); | ||
49 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 43 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
50 | outb(val, 0xcfc + (offset&3)); | 44 | outb(val, 0xcfc + (offset&3)); |
51 | } | 45 | } |
52 | 46 | ||
53 | void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) | 47 | void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) |
54 | { | 48 | { |
55 | pr_debug("%x writing to %x: %x\n", slot, offset, val); | ||
56 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); | 49 | outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); |
57 | outw(val, 0xcfc + (offset&2)); | 50 | outw(val, 0xcfc + (offset&2)); |
58 | } | 51 | } |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index b22d13b0c71d..5dc9e8c63fcd 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -129,7 +129,9 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
129 | continue; | 129 | continue; |
130 | if (!r->start || | 130 | if (!r->start || |
131 | pci_claim_resource(dev, idx) < 0) { | 131 | pci_claim_resource(dev, idx) < 0) { |
132 | dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx); | 132 | dev_info(&dev->dev, |
133 | "can't reserve window %pR\n", | ||
134 | r); | ||
133 | /* | 135 | /* |
134 | * Something is wrong with the region. | 136 | * Something is wrong with the region. |
135 | * Invalidate the resource to prevent | 137 | * Invalidate the resource to prevent |
@@ -144,16 +146,29 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) | |||
144 | } | 146 | } |
145 | } | 147 | } |
146 | 148 | ||
149 | struct pci_check_idx_range { | ||
150 | int start; | ||
151 | int end; | ||
152 | }; | ||
153 | |||
147 | static void __init pcibios_allocate_resources(int pass) | 154 | static void __init pcibios_allocate_resources(int pass) |
148 | { | 155 | { |
149 | struct pci_dev *dev = NULL; | 156 | struct pci_dev *dev = NULL; |
150 | int idx, disabled; | 157 | int idx, disabled, i; |
151 | u16 command; | 158 | u16 command; |
152 | struct resource *r; | 159 | struct resource *r; |
153 | 160 | ||
161 | struct pci_check_idx_range idx_range[] = { | ||
162 | { PCI_STD_RESOURCES, PCI_STD_RESOURCE_END }, | ||
163 | #ifdef CONFIG_PCI_IOV | ||
164 | { PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END }, | ||
165 | #endif | ||
166 | }; | ||
167 | |||
154 | for_each_pci_dev(dev) { | 168 | for_each_pci_dev(dev) { |
155 | pci_read_config_word(dev, PCI_COMMAND, &command); | 169 | pci_read_config_word(dev, PCI_COMMAND, &command); |
156 | for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { | 170 | for (i = 0; i < ARRAY_SIZE(idx_range); i++) |
171 | for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) { | ||
157 | r = &dev->resource[idx]; | 172 | r = &dev->resource[idx]; |
158 | if (r->parent) /* Already allocated */ | 173 | if (r->parent) /* Already allocated */ |
159 | continue; | 174 | continue; |
@@ -164,12 +179,12 @@ static void __init pcibios_allocate_resources(int pass) | |||
164 | else | 179 | else |
165 | disabled = !(command & PCI_COMMAND_MEMORY); | 180 | disabled = !(command & PCI_COMMAND_MEMORY); |
166 | if (pass == disabled) { | 181 | if (pass == disabled) { |
167 | dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n", | 182 | dev_dbg(&dev->dev, |
168 | (unsigned long long) r->start, | 183 | "BAR %d: reserving %pr (d=%d, p=%d)\n", |
169 | (unsigned long long) r->end, | 184 | idx, r, disabled, pass); |
170 | r->flags, disabled, pass); | ||
171 | if (pci_claim_resource(dev, idx) < 0) { | 185 | if (pci_claim_resource(dev, idx) < 0) { |
172 | dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx); | 186 | dev_info(&dev->dev, |
187 | "can't reserve %pR\n", r); | ||
173 | /* We'll assign a new address later */ | 188 | /* We'll assign a new address later */ |
174 | r->end -= r->start; | 189 | r->end -= r->start; |
175 | r->start = 0; | 190 | r->start = 0; |
@@ -182,7 +197,7 @@ static void __init pcibios_allocate_resources(int pass) | |||
182 | /* Turn the ROM off, leave the resource region, | 197 | /* Turn the ROM off, leave the resource region, |
183 | * but keep it unregistered. */ | 198 | * but keep it unregistered. */ |
184 | u32 reg; | 199 | u32 reg; |
185 | dev_dbg(&dev->dev, "disabling ROM\n"); | 200 | dev_dbg(&dev->dev, "disabling ROM %pR\n", r); |
186 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 201 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
187 | pci_read_config_dword(dev, | 202 | pci_read_config_dword(dev, |
188 | dev->rom_base_reg, ®); | 203 | dev->rom_base_reg, ®); |
@@ -282,6 +297,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
282 | return -EINVAL; | 297 | return -EINVAL; |
283 | 298 | ||
284 | prot = pgprot_val(vma->vm_page_prot); | 299 | prot = pgprot_val(vma->vm_page_prot); |
300 | |||
301 | /* | ||
302 | * Return error if pat is not enabled and write_combine is requested. | ||
303 | * Caller can followup with UC MINUS request and add a WC mtrr if there | ||
304 | * is a free mtrr slot. | ||
305 | */ | ||
306 | if (!pat_enabled && write_combine) | ||
307 | return -EINVAL; | ||
308 | |||
285 | if (pat_enabled && write_combine) | 309 | if (pat_enabled && write_combine) |
286 | prot |= _PAGE_CACHE_WC; | 310 | prot |= _PAGE_CACHE_WC; |
287 | else if (pat_enabled || boot_cpu_data.x86 > 3) | 311 | else if (pat_enabled || boot_cpu_data.x86 > 3) |
diff --git a/arch/x86/pci/intel_bus.c b/arch/x86/pci/intel_bus.c new file mode 100644 index 000000000000..b7a55dc55d13 --- /dev/null +++ b/arch/x86/pci/intel_bus.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * to read io range from IOH pci conf, need to do it after mmconfig is there | ||
3 | */ | ||
4 | |||
5 | #include <linux/delay.h> | ||
6 | #include <linux/dmi.h> | ||
7 | #include <linux/pci.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <asm/pci_x86.h> | ||
10 | |||
11 | #include "bus_numa.h" | ||
12 | |||
13 | static inline void print_ioh_resources(struct pci_root_info *info) | ||
14 | { | ||
15 | int res_num; | ||
16 | int busnum; | ||
17 | int i; | ||
18 | |||
19 | printk(KERN_DEBUG "IOH bus: [%02x, %02x]\n", | ||
20 | info->bus_min, info->bus_max); | ||
21 | res_num = info->res_num; | ||
22 | busnum = info->bus_min; | ||
23 | for (i = 0; i < res_num; i++) { | ||
24 | struct resource *res; | ||
25 | |||
26 | res = &info->res[i]; | ||
27 | printk(KERN_DEBUG "IOH bus: %02x index %x %s: [%llx, %llx]\n", | ||
28 | busnum, i, | ||
29 | (res->flags & IORESOURCE_IO) ? "io port" : | ||
30 | "mmio", | ||
31 | res->start, res->end); | ||
32 | } | ||
33 | } | ||
34 | |||
35 | #define IOH_LIO 0x108 | ||
36 | #define IOH_LMMIOL 0x10c | ||
37 | #define IOH_LMMIOH 0x110 | ||
38 | #define IOH_LMMIOH_BASEU 0x114 | ||
39 | #define IOH_LMMIOH_LIMITU 0x118 | ||
40 | #define IOH_LCFGBUS 0x11c | ||
41 | |||
42 | static void __devinit pci_root_bus_res(struct pci_dev *dev) | ||
43 | { | ||
44 | u16 word; | ||
45 | u32 dword; | ||
46 | struct pci_root_info *info; | ||
47 | u16 io_base, io_end; | ||
48 | u32 mmiol_base, mmiol_end; | ||
49 | u64 mmioh_base, mmioh_end; | ||
50 | int bus_base, bus_end; | ||
51 | |||
52 | if (pci_root_num >= PCI_ROOT_NR) { | ||
53 | printk(KERN_DEBUG "intel_bus.c: PCI_ROOT_NR is too small\n"); | ||
54 | return; | ||
55 | } | ||
56 | |||
57 | info = &pci_root_info[pci_root_num]; | ||
58 | pci_root_num++; | ||
59 | |||
60 | pci_read_config_word(dev, IOH_LCFGBUS, &word); | ||
61 | bus_base = (word & 0xff); | ||
62 | bus_end = (word & 0xff00) >> 8; | ||
63 | sprintf(info->name, "PCI Bus #%02x", bus_base); | ||
64 | info->bus_min = bus_base; | ||
65 | info->bus_max = bus_end; | ||
66 | |||
67 | pci_read_config_word(dev, IOH_LIO, &word); | ||
68 | io_base = (word & 0xf0) << (12 - 4); | ||
69 | io_end = (word & 0xf000) | 0xfff; | ||
70 | update_res(info, io_base, io_end, IORESOURCE_IO, 0); | ||
71 | |||
72 | pci_read_config_dword(dev, IOH_LMMIOL, &dword); | ||
73 | mmiol_base = (dword & 0xff00) << (24 - 8); | ||
74 | mmiol_end = (dword & 0xff000000) | 0xffffff; | ||
75 | update_res(info, mmiol_base, mmiol_end, IORESOURCE_MEM, 0); | ||
76 | |||
77 | pci_read_config_dword(dev, IOH_LMMIOH, &dword); | ||
78 | mmioh_base = ((u64)(dword & 0xfc00)) << (26 - 10); | ||
79 | mmioh_end = ((u64)(dword & 0xfc000000) | 0x3ffffff); | ||
80 | pci_read_config_dword(dev, IOH_LMMIOH_BASEU, &dword); | ||
81 | mmioh_base |= ((u64)(dword & 0x7ffff)) << 32; | ||
82 | pci_read_config_dword(dev, IOH_LMMIOH_LIMITU, &dword); | ||
83 | mmioh_end |= ((u64)(dword & 0x7ffff)) << 32; | ||
84 | update_res(info, mmioh_base, mmioh_end, IORESOURCE_MEM, 0); | ||
85 | |||
86 | print_ioh_resources(info); | ||
87 | } | ||
88 | |||
89 | /* intel IOH */ | ||
90 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, pci_root_bus_res); | ||
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 602c172d3bd5..b19d1e54201e 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c | |||
@@ -15,48 +15,98 @@ | |||
15 | #include <linux/acpi.h> | 15 | #include <linux/acpi.h> |
16 | #include <linux/sfi_acpi.h> | 16 | #include <linux/sfi_acpi.h> |
17 | #include <linux/bitmap.h> | 17 | #include <linux/bitmap.h> |
18 | #include <linux/sort.h> | 18 | #include <linux/dmi.h> |
19 | #include <asm/e820.h> | 19 | #include <asm/e820.h> |
20 | #include <asm/pci_x86.h> | 20 | #include <asm/pci_x86.h> |
21 | #include <asm/acpi.h> | 21 | #include <asm/acpi.h> |
22 | 22 | ||
23 | #define PREFIX "PCI: " | 23 | #define PREFIX "PCI: " |
24 | 24 | ||
25 | /* aperture is up to 256MB but BIOS may reserve less */ | ||
26 | #define MMCONFIG_APER_MIN (2 * 1024*1024) | ||
27 | #define MMCONFIG_APER_MAX (256 * 1024*1024) | ||
28 | |||
29 | /* Indicate if the mmcfg resources have been placed into the resource table. */ | 25 | /* Indicate if the mmcfg resources have been placed into the resource table. */ |
30 | static int __initdata pci_mmcfg_resources_inserted; | 26 | static int __initdata pci_mmcfg_resources_inserted; |
31 | 27 | ||
32 | static __init int extend_mmcfg(int num) | 28 | LIST_HEAD(pci_mmcfg_list); |
29 | |||
30 | static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg) | ||
33 | { | 31 | { |
34 | struct acpi_mcfg_allocation *new; | 32 | if (cfg->res.parent) |
35 | int new_num = pci_mmcfg_config_num + num; | 33 | release_resource(&cfg->res); |
34 | list_del(&cfg->list); | ||
35 | kfree(cfg); | ||
36 | } | ||
36 | 37 | ||
37 | new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL); | 38 | static __init void free_all_mmcfg(void) |
38 | if (!new) | 39 | { |
39 | return -1; | 40 | struct pci_mmcfg_region *cfg, *tmp; |
40 | 41 | ||
41 | if (pci_mmcfg_config) { | 42 | pci_mmcfg_arch_free(); |
42 | memcpy(new, pci_mmcfg_config, | 43 | list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list) |
43 | sizeof(pci_mmcfg_config[0]) * new_num); | 44 | pci_mmconfig_remove(cfg); |
44 | kfree(pci_mmcfg_config); | 45 | } |
46 | |||
47 | static __init void list_add_sorted(struct pci_mmcfg_region *new) | ||
48 | { | ||
49 | struct pci_mmcfg_region *cfg; | ||
50 | |||
51 | /* keep list sorted by segment and starting bus number */ | ||
52 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { | ||
53 | if (cfg->segment > new->segment || | ||
54 | (cfg->segment == new->segment && | ||
55 | cfg->start_bus >= new->start_bus)) { | ||
56 | list_add_tail(&new->list, &cfg->list); | ||
57 | return; | ||
58 | } | ||
45 | } | 59 | } |
46 | pci_mmcfg_config = new; | 60 | list_add_tail(&new->list, &pci_mmcfg_list); |
61 | } | ||
47 | 62 | ||
48 | return 0; | 63 | static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start, |
64 | int end, u64 addr) | ||
65 | { | ||
66 | struct pci_mmcfg_region *new; | ||
67 | int num_buses; | ||
68 | struct resource *res; | ||
69 | |||
70 | if (addr == 0) | ||
71 | return NULL; | ||
72 | |||
73 | new = kzalloc(sizeof(*new), GFP_KERNEL); | ||
74 | if (!new) | ||
75 | return NULL; | ||
76 | |||
77 | new->address = addr; | ||
78 | new->segment = segment; | ||
79 | new->start_bus = start; | ||
80 | new->end_bus = end; | ||
81 | |||
82 | list_add_sorted(new); | ||
83 | |||
84 | num_buses = end - start + 1; | ||
85 | res = &new->res; | ||
86 | res->start = addr + PCI_MMCFG_BUS_OFFSET(start); | ||
87 | res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1; | ||
88 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
89 | snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN, | ||
90 | "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end); | ||
91 | res->name = new->name; | ||
92 | |||
93 | printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at " | ||
94 | "%pR (base %#lx)\n", segment, start, end, &new->res, | ||
95 | (unsigned long) addr); | ||
96 | |||
97 | return new; | ||
49 | } | 98 | } |
50 | 99 | ||
51 | static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end) | 100 | struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus) |
52 | { | 101 | { |
53 | int i = pci_mmcfg_config_num; | 102 | struct pci_mmcfg_region *cfg; |
54 | 103 | ||
55 | pci_mmcfg_config_num++; | 104 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
56 | pci_mmcfg_config[i].address = addr; | 105 | if (cfg->segment == segment && |
57 | pci_mmcfg_config[i].pci_segment = segment; | 106 | cfg->start_bus <= bus && bus <= cfg->end_bus) |
58 | pci_mmcfg_config[i].start_bus_number = start; | 107 | return cfg; |
59 | pci_mmcfg_config[i].end_bus_number = end; | 108 | |
109 | return NULL; | ||
60 | } | 110 | } |
61 | 111 | ||
62 | static const char __init *pci_mmcfg_e7520(void) | 112 | static const char __init *pci_mmcfg_e7520(void) |
@@ -68,11 +118,9 @@ static const char __init *pci_mmcfg_e7520(void) | |||
68 | if (win == 0x0000 || win == 0xf000) | 118 | if (win == 0x0000 || win == 0xf000) |
69 | return NULL; | 119 | return NULL; |
70 | 120 | ||
71 | if (extend_mmcfg(1) == -1) | 121 | if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL) |
72 | return NULL; | 122 | return NULL; |
73 | 123 | ||
74 | fill_one_mmcfg(win << 16, 0, 0, 255); | ||
75 | |||
76 | return "Intel Corporation E7520 Memory Controller Hub"; | 124 | return "Intel Corporation E7520 Memory Controller Hub"; |
77 | } | 125 | } |
78 | 126 | ||
@@ -114,11 +162,9 @@ static const char __init *pci_mmcfg_intel_945(void) | |||
114 | if ((pciexbar & mask) >= 0xf0000000U) | 162 | if ((pciexbar & mask) >= 0xf0000000U) |
115 | return NULL; | 163 | return NULL; |
116 | 164 | ||
117 | if (extend_mmcfg(1) == -1) | 165 | if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL) |
118 | return NULL; | 166 | return NULL; |
119 | 167 | ||
120 | fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1); | ||
121 | |||
122 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; | 168 | return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; |
123 | } | 169 | } |
124 | 170 | ||
@@ -127,7 +173,7 @@ static const char __init *pci_mmcfg_amd_fam10h(void) | |||
127 | u32 low, high, address; | 173 | u32 low, high, address; |
128 | u64 base, msr; | 174 | u64 base, msr; |
129 | int i; | 175 | int i; |
130 | unsigned segnbits = 0, busnbits; | 176 | unsigned segnbits = 0, busnbits, end_bus; |
131 | 177 | ||
132 | if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF)) | 178 | if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF)) |
133 | return NULL; | 179 | return NULL; |
@@ -161,11 +207,13 @@ static const char __init *pci_mmcfg_amd_fam10h(void) | |||
161 | busnbits = 8; | 207 | busnbits = 8; |
162 | } | 208 | } |
163 | 209 | ||
164 | if (extend_mmcfg(1 << segnbits) == -1) | 210 | end_bus = (1 << busnbits) - 1; |
165 | return NULL; | ||
166 | |||
167 | for (i = 0; i < (1 << segnbits); i++) | 211 | for (i = 0; i < (1 << segnbits); i++) |
168 | fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1); | 212 | if (pci_mmconfig_add(i, 0, end_bus, |
213 | base + (1<<28) * i) == NULL) { | ||
214 | free_all_mmcfg(); | ||
215 | return NULL; | ||
216 | } | ||
169 | 217 | ||
170 | return "AMD Family 10h NB"; | 218 | return "AMD Family 10h NB"; |
171 | } | 219 | } |
@@ -190,7 +238,7 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void) | |||
190 | /* | 238 | /* |
191 | * do check if amd fam10h already took over | 239 | * do check if amd fam10h already took over |
192 | */ | 240 | */ |
193 | if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked) | 241 | if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked) |
194 | return NULL; | 242 | return NULL; |
195 | 243 | ||
196 | mcp55_checked = true; | 244 | mcp55_checked = true; |
@@ -213,16 +261,14 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void) | |||
213 | if (!(extcfg & extcfg_enable_mask)) | 261 | if (!(extcfg & extcfg_enable_mask)) |
214 | continue; | 262 | continue; |
215 | 263 | ||
216 | if (extend_mmcfg(1) == -1) | ||
217 | continue; | ||
218 | |||
219 | size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; | 264 | size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; |
220 | base = extcfg & extcfg_base_mask[size_index]; | 265 | base = extcfg & extcfg_base_mask[size_index]; |
221 | /* base could > 4G */ | 266 | /* base could > 4G */ |
222 | base <<= extcfg_base_lshift; | 267 | base <<= extcfg_base_lshift; |
223 | start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; | 268 | start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; |
224 | end = start + extcfg_sizebus[size_index] - 1; | 269 | end = start + extcfg_sizebus[size_index] - 1; |
225 | fill_one_mmcfg(base, 0, start, end); | 270 | if (pci_mmconfig_add(0, start, end, base) == NULL) |
271 | continue; | ||
226 | mcp55_mmconf_found++; | 272 | mcp55_mmconf_found++; |
227 | } | 273 | } |
228 | 274 | ||
@@ -253,45 +299,27 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = { | |||
253 | 0x0369, pci_mmcfg_nvidia_mcp55 }, | 299 | 0x0369, pci_mmcfg_nvidia_mcp55 }, |
254 | }; | 300 | }; |
255 | 301 | ||
256 | static int __init cmp_mmcfg(const void *x1, const void *x2) | ||
257 | { | ||
258 | const typeof(pci_mmcfg_config[0]) *m1 = x1; | ||
259 | const typeof(pci_mmcfg_config[0]) *m2 = x2; | ||
260 | int start1, start2; | ||
261 | |||
262 | start1 = m1->start_bus_number; | ||
263 | start2 = m2->start_bus_number; | ||
264 | |||
265 | return start1 - start2; | ||
266 | } | ||
267 | |||
268 | static void __init pci_mmcfg_check_end_bus_number(void) | 302 | static void __init pci_mmcfg_check_end_bus_number(void) |
269 | { | 303 | { |
270 | int i; | 304 | struct pci_mmcfg_region *cfg, *cfgx; |
271 | typeof(pci_mmcfg_config[0]) *cfg, *cfgx; | ||
272 | |||
273 | /* sort them at first */ | ||
274 | sort(pci_mmcfg_config, pci_mmcfg_config_num, | ||
275 | sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL); | ||
276 | 305 | ||
277 | /* last one*/ | 306 | /* last one*/ |
278 | if (pci_mmcfg_config_num > 0) { | 307 | cfg = list_entry(pci_mmcfg_list.prev, typeof(*cfg), list); |
279 | i = pci_mmcfg_config_num - 1; | 308 | if (cfg) |
280 | cfg = &pci_mmcfg_config[i]; | 309 | if (cfg->end_bus < cfg->start_bus) |
281 | if (cfg->end_bus_number < cfg->start_bus_number) | 310 | cfg->end_bus = 255; |
282 | cfg->end_bus_number = 255; | ||
283 | } | ||
284 | 311 | ||
285 | /* don't overlap please */ | 312 | if (list_is_singular(&pci_mmcfg_list)) |
286 | for (i = 0; i < pci_mmcfg_config_num - 1; i++) { | 313 | return; |
287 | cfg = &pci_mmcfg_config[i]; | ||
288 | cfgx = &pci_mmcfg_config[i+1]; | ||
289 | 314 | ||
290 | if (cfg->end_bus_number < cfg->start_bus_number) | 315 | /* don't overlap please */ |
291 | cfg->end_bus_number = 255; | 316 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
317 | if (cfg->end_bus < cfg->start_bus) | ||
318 | cfg->end_bus = 255; | ||
292 | 319 | ||
293 | if (cfg->end_bus_number >= cfgx->start_bus_number) | 320 | cfgx = list_entry(cfg->list.next, typeof(*cfg), list); |
294 | cfg->end_bus_number = cfgx->start_bus_number - 1; | 321 | if (cfg != cfgx && cfg->end_bus >= cfgx->start_bus) |
322 | cfg->end_bus = cfgx->start_bus - 1; | ||
295 | } | 323 | } |
296 | } | 324 | } |
297 | 325 | ||
@@ -306,8 +334,7 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
306 | if (!raw_pci_ops) | 334 | if (!raw_pci_ops) |
307 | return 0; | 335 | return 0; |
308 | 336 | ||
309 | pci_mmcfg_config_num = 0; | 337 | free_all_mmcfg(); |
310 | pci_mmcfg_config = NULL; | ||
311 | 338 | ||
312 | for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { | 339 | for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { |
313 | bus = pci_mmcfg_probes[i].bus; | 340 | bus = pci_mmcfg_probes[i].bus; |
@@ -322,45 +349,22 @@ static int __init pci_mmcfg_check_hostbridge(void) | |||
322 | name = pci_mmcfg_probes[i].probe(); | 349 | name = pci_mmcfg_probes[i].probe(); |
323 | 350 | ||
324 | if (name) | 351 | if (name) |
325 | printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", | 352 | printk(KERN_INFO PREFIX "%s with MMCONFIG support\n", |
326 | name); | 353 | name); |
327 | } | 354 | } |
328 | 355 | ||
329 | /* some end_bus_number is crazy, fix it */ | 356 | /* some end_bus_number is crazy, fix it */ |
330 | pci_mmcfg_check_end_bus_number(); | 357 | pci_mmcfg_check_end_bus_number(); |
331 | 358 | ||
332 | return pci_mmcfg_config_num != 0; | 359 | return !list_empty(&pci_mmcfg_list); |
333 | } | 360 | } |
334 | 361 | ||
335 | static void __init pci_mmcfg_insert_resources(void) | 362 | static void __init pci_mmcfg_insert_resources(void) |
336 | { | 363 | { |
337 | #define PCI_MMCFG_RESOURCE_NAME_LEN 24 | 364 | struct pci_mmcfg_region *cfg; |
338 | int i; | ||
339 | struct resource *res; | ||
340 | char *names; | ||
341 | unsigned num_buses; | ||
342 | |||
343 | res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), | ||
344 | pci_mmcfg_config_num, GFP_KERNEL); | ||
345 | if (!res) { | ||
346 | printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); | ||
347 | return; | ||
348 | } | ||
349 | 365 | ||
350 | names = (void *)&res[pci_mmcfg_config_num]; | 366 | list_for_each_entry(cfg, &pci_mmcfg_list, list) |
351 | for (i = 0; i < pci_mmcfg_config_num; i++, res++) { | 367 | insert_resource(&iomem_resource, &cfg->res); |
352 | struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i]; | ||
353 | num_buses = cfg->end_bus_number - cfg->start_bus_number + 1; | ||
354 | res->name = names; | ||
355 | snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, | ||
356 | "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment, | ||
357 | cfg->start_bus_number, cfg->end_bus_number); | ||
358 | res->start = cfg->address + (cfg->start_bus_number << 20); | ||
359 | res->end = res->start + (num_buses << 20) - 1; | ||
360 | res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
361 | insert_resource(&iomem_resource, res); | ||
362 | names += PCI_MMCFG_RESOURCE_NAME_LEN; | ||
363 | } | ||
364 | 368 | ||
365 | /* Mark that the resources have been inserted. */ | 369 | /* Mark that the resources have been inserted. */ |
366 | pci_mmcfg_resources_inserted = 1; | 370 | pci_mmcfg_resources_inserted = 1; |
@@ -437,11 +441,12 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) | |||
437 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); | 441 | typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); |
438 | 442 | ||
439 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, | 443 | static int __init is_mmconf_reserved(check_reserved_t is_reserved, |
440 | u64 addr, u64 size, int i, | 444 | struct pci_mmcfg_region *cfg, int with_e820) |
441 | typeof(pci_mmcfg_config[0]) *cfg, int with_e820) | ||
442 | { | 445 | { |
446 | u64 addr = cfg->res.start; | ||
447 | u64 size = resource_size(&cfg->res); | ||
443 | u64 old_size = size; | 448 | u64 old_size = size; |
444 | int valid = 0; | 449 | int valid = 0, num_buses; |
445 | 450 | ||
446 | while (!is_reserved(addr, addr + size, E820_RESERVED)) { | 451 | while (!is_reserved(addr, addr + size, E820_RESERVED)) { |
447 | size >>= 1; | 452 | size >>= 1; |
@@ -450,19 +455,25 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, | |||
450 | } | 455 | } |
451 | 456 | ||
452 | if (size >= (16UL<<20) || size == old_size) { | 457 | if (size >= (16UL<<20) || size == old_size) { |
453 | printk(KERN_NOTICE | 458 | printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n", |
454 | "PCI: MCFG area at %Lx reserved in %s\n", | 459 | &cfg->res, |
455 | addr, with_e820?"E820":"ACPI motherboard resources"); | 460 | with_e820 ? "E820" : "ACPI motherboard resources"); |
456 | valid = 1; | 461 | valid = 1; |
457 | 462 | ||
458 | if (old_size != size) { | 463 | if (old_size != size) { |
459 | /* update end_bus_number */ | 464 | /* update end_bus */ |
460 | cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1); | 465 | cfg->end_bus = cfg->start_bus + ((size>>20) - 1); |
461 | printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx " | 466 | num_buses = cfg->end_bus - cfg->start_bus + 1; |
462 | "segment %hu buses %u - %u\n", | 467 | cfg->res.end = cfg->res.start + |
463 | i, (unsigned long)cfg->address, cfg->pci_segment, | 468 | PCI_MMCFG_BUS_OFFSET(num_buses) - 1; |
464 | (unsigned int)cfg->start_bus_number, | 469 | snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN, |
465 | (unsigned int)cfg->end_bus_number); | 470 | "PCI MMCONFIG %04x [bus %02x-%02x]", |
471 | cfg->segment, cfg->start_bus, cfg->end_bus); | ||
472 | printk(KERN_INFO PREFIX | ||
473 | "MMCONFIG for %04x [bus%02x-%02x] " | ||
474 | "at %pR (base %#lx) (size reduced!)\n", | ||
475 | cfg->segment, cfg->start_bus, cfg->end_bus, | ||
476 | &cfg->res, (unsigned long) cfg->address); | ||
466 | } | 477 | } |
467 | } | 478 | } |
468 | 479 | ||
@@ -471,45 +482,26 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved, | |||
471 | 482 | ||
472 | static void __init pci_mmcfg_reject_broken(int early) | 483 | static void __init pci_mmcfg_reject_broken(int early) |
473 | { | 484 | { |
474 | typeof(pci_mmcfg_config[0]) *cfg; | 485 | struct pci_mmcfg_region *cfg; |
475 | int i; | ||
476 | 486 | ||
477 | if ((pci_mmcfg_config_num == 0) || | 487 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
478 | (pci_mmcfg_config == NULL) || | ||
479 | (pci_mmcfg_config[0].address == 0)) | ||
480 | return; | ||
481 | |||
482 | for (i = 0; i < pci_mmcfg_config_num; i++) { | ||
483 | int valid = 0; | 488 | int valid = 0; |
484 | u64 addr, size; | ||
485 | |||
486 | cfg = &pci_mmcfg_config[i]; | ||
487 | addr = cfg->start_bus_number; | ||
488 | addr <<= 20; | ||
489 | addr += cfg->address; | ||
490 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
491 | size <<= 20; | ||
492 | printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx " | ||
493 | "segment %hu buses %u - %u\n", | ||
494 | i, (unsigned long)cfg->address, cfg->pci_segment, | ||
495 | (unsigned int)cfg->start_bus_number, | ||
496 | (unsigned int)cfg->end_bus_number); | ||
497 | 489 | ||
498 | if (!early && !acpi_disabled) | 490 | if (!early && !acpi_disabled) |
499 | valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0); | 491 | valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0); |
500 | 492 | ||
501 | if (valid) | 493 | if (valid) |
502 | continue; | 494 | continue; |
503 | 495 | ||
504 | if (!early) | 496 | if (!early) |
505 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" | 497 | printk(KERN_ERR FW_BUG PREFIX |
506 | " reserved in ACPI motherboard resources\n", | 498 | "MMCONFIG at %pR not reserved in " |
507 | cfg->address); | 499 | "ACPI motherboard resources\n", &cfg->res); |
508 | 500 | ||
509 | /* Don't try to do this check unless configuration | 501 | /* Don't try to do this check unless configuration |
510 | type 1 is available. how about type 2 ?*/ | 502 | type 1 is available. how about type 2 ?*/ |
511 | if (raw_pci_ops) | 503 | if (raw_pci_ops) |
512 | valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1); | 504 | valid = is_mmconf_reserved(e820_all_mapped, cfg, 1); |
513 | 505 | ||
514 | if (!valid) | 506 | if (!valid) |
515 | goto reject; | 507 | goto reject; |
@@ -518,34 +510,41 @@ static void __init pci_mmcfg_reject_broken(int early) | |||
518 | return; | 510 | return; |
519 | 511 | ||
520 | reject: | 512 | reject: |
521 | printk(KERN_INFO "PCI: Not using MMCONFIG.\n"); | 513 | printk(KERN_INFO PREFIX "not using MMCONFIG\n"); |
522 | pci_mmcfg_arch_free(); | 514 | free_all_mmcfg(); |
523 | kfree(pci_mmcfg_config); | ||
524 | pci_mmcfg_config = NULL; | ||
525 | pci_mmcfg_config_num = 0; | ||
526 | } | 515 | } |
527 | 516 | ||
528 | static int __initdata known_bridge; | 517 | static int __initdata known_bridge; |
529 | 518 | ||
530 | static int acpi_mcfg_64bit_base_addr __initdata = FALSE; | 519 | static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, |
520 | struct acpi_mcfg_allocation *cfg) | ||
521 | { | ||
522 | int year; | ||
531 | 523 | ||
532 | /* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ | 524 | if (cfg->address < 0xFFFFFFFF) |
533 | struct acpi_mcfg_allocation *pci_mmcfg_config; | 525 | return 0; |
534 | int pci_mmcfg_config_num; | ||
535 | 526 | ||
536 | static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg) | ||
537 | { | ||
538 | if (!strcmp(mcfg->header.oem_id, "SGI")) | 527 | if (!strcmp(mcfg->header.oem_id, "SGI")) |
539 | acpi_mcfg_64bit_base_addr = TRUE; | 528 | return 0; |
540 | 529 | ||
541 | return 0; | 530 | if (mcfg->header.revision >= 1) { |
531 | if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && | ||
532 | year >= 2010) | ||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " | ||
537 | "is above 4GB, ignored\n", cfg->pci_segment, | ||
538 | cfg->start_bus_number, cfg->end_bus_number, cfg->address); | ||
539 | return -EINVAL; | ||
542 | } | 540 | } |
543 | 541 | ||
544 | static int __init pci_parse_mcfg(struct acpi_table_header *header) | 542 | static int __init pci_parse_mcfg(struct acpi_table_header *header) |
545 | { | 543 | { |
546 | struct acpi_table_mcfg *mcfg; | 544 | struct acpi_table_mcfg *mcfg; |
545 | struct acpi_mcfg_allocation *cfg_table, *cfg; | ||
547 | unsigned long i; | 546 | unsigned long i; |
548 | int config_size; | 547 | int entries; |
549 | 548 | ||
550 | if (!header) | 549 | if (!header) |
551 | return -EINVAL; | 550 | return -EINVAL; |
@@ -553,38 +552,33 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header) | |||
553 | mcfg = (struct acpi_table_mcfg *)header; | 552 | mcfg = (struct acpi_table_mcfg *)header; |
554 | 553 | ||
555 | /* how many config structures do we have */ | 554 | /* how many config structures do we have */ |
556 | pci_mmcfg_config_num = 0; | 555 | free_all_mmcfg(); |
556 | entries = 0; | ||
557 | i = header->length - sizeof(struct acpi_table_mcfg); | 557 | i = header->length - sizeof(struct acpi_table_mcfg); |
558 | while (i >= sizeof(struct acpi_mcfg_allocation)) { | 558 | while (i >= sizeof(struct acpi_mcfg_allocation)) { |
559 | ++pci_mmcfg_config_num; | 559 | entries++; |
560 | i -= sizeof(struct acpi_mcfg_allocation); | 560 | i -= sizeof(struct acpi_mcfg_allocation); |
561 | }; | 561 | }; |
562 | if (pci_mmcfg_config_num == 0) { | 562 | if (entries == 0) { |
563 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); | 563 | printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); |
564 | return -ENODEV; | 564 | return -ENODEV; |
565 | } | 565 | } |
566 | 566 | ||
567 | config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); | 567 | cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1]; |
568 | pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); | 568 | for (i = 0; i < entries; i++) { |
569 | if (!pci_mmcfg_config) { | 569 | cfg = &cfg_table[i]; |
570 | printk(KERN_WARNING PREFIX | 570 | if (acpi_mcfg_check_entry(mcfg, cfg)) { |
571 | "No memory for MCFG config tables\n"); | 571 | free_all_mmcfg(); |
572 | return -ENOMEM; | ||
573 | } | ||
574 | |||
575 | memcpy(pci_mmcfg_config, &mcfg[1], config_size); | ||
576 | |||
577 | acpi_mcfg_oem_check(mcfg); | ||
578 | |||
579 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | ||
580 | if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) && | ||
581 | !acpi_mcfg_64bit_base_addr) { | ||
582 | printk(KERN_ERR PREFIX | ||
583 | "MMCONFIG not in low 4GB of memory\n"); | ||
584 | kfree(pci_mmcfg_config); | ||
585 | pci_mmcfg_config_num = 0; | ||
586 | return -ENODEV; | 572 | return -ENODEV; |
587 | } | 573 | } |
574 | |||
575 | if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number, | ||
576 | cfg->end_bus_number, cfg->address) == NULL) { | ||
577 | printk(KERN_WARNING PREFIX | ||
578 | "no memory for MCFG entries\n"); | ||
579 | free_all_mmcfg(); | ||
580 | return -ENOMEM; | ||
581 | } | ||
588 | } | 582 | } |
589 | 583 | ||
590 | return 0; | 584 | return 0; |
@@ -614,9 +608,7 @@ static void __init __pci_mmcfg_init(int early) | |||
614 | 608 | ||
615 | pci_mmcfg_reject_broken(early); | 609 | pci_mmcfg_reject_broken(early); |
616 | 610 | ||
617 | if ((pci_mmcfg_config_num == 0) || | 611 | if (list_empty(&pci_mmcfg_list)) |
618 | (pci_mmcfg_config == NULL) || | ||
619 | (pci_mmcfg_config[0].address == 0)) | ||
620 | return; | 612 | return; |
621 | 613 | ||
622 | if (pci_mmcfg_arch_init()) | 614 | if (pci_mmcfg_arch_init()) |
@@ -648,9 +640,7 @@ static int __init pci_mmcfg_late_insert_resources(void) | |||
648 | */ | 640 | */ |
649 | if ((pci_mmcfg_resources_inserted == 1) || | 641 | if ((pci_mmcfg_resources_inserted == 1) || |
650 | (pci_probe & PCI_PROBE_MMCONF) == 0 || | 642 | (pci_probe & PCI_PROBE_MMCONF) == 0 || |
651 | (pci_mmcfg_config_num == 0) || | 643 | list_empty(&pci_mmcfg_list)) |
652 | (pci_mmcfg_config == NULL) || | ||
653 | (pci_mmcfg_config[0].address == 0)) | ||
654 | return 1; | 644 | return 1; |
655 | 645 | ||
656 | /* | 646 | /* |
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c index f10a7e94a84c..90d5fd476ed4 100644 --- a/arch/x86/pci/mmconfig_32.c +++ b/arch/x86/pci/mmconfig_32.c | |||
@@ -27,18 +27,10 @@ static int mmcfg_last_accessed_cpu; | |||
27 | */ | 27 | */ |
28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | 28 | static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) |
29 | { | 29 | { |
30 | struct acpi_mcfg_allocation *cfg; | 30 | struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); |
31 | int cfg_num; | ||
32 | |||
33 | for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { | ||
34 | cfg = &pci_mmcfg_config[cfg_num]; | ||
35 | if (cfg->pci_segment == seg && | ||
36 | (cfg->start_bus_number <= bus) && | ||
37 | (cfg->end_bus_number >= bus)) | ||
38 | return cfg->address; | ||
39 | } | ||
40 | 31 | ||
41 | /* Fall back to type 0 */ | 32 | if (cfg) |
33 | return cfg->address; | ||
42 | return 0; | 34 | return 0; |
43 | } | 35 | } |
44 | 36 | ||
@@ -47,7 +39,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) | |||
47 | */ | 39 | */ |
48 | static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) | 40 | static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) |
49 | { | 41 | { |
50 | u32 dev_base = base | (bus << 20) | (devfn << 12); | 42 | u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12); |
51 | int cpu = smp_processor_id(); | 43 | int cpu = smp_processor_id(); |
52 | if (dev_base != mmcfg_last_accessed_device || | 44 | if (dev_base != mmcfg_last_accessed_device || |
53 | cpu != mmcfg_last_accessed_cpu) { | 45 | cpu != mmcfg_last_accessed_cpu) { |
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c index 94349f8b2f96..e783841bd1d7 100644 --- a/arch/x86/pci/mmconfig_64.c +++ b/arch/x86/pci/mmconfig_64.c | |||
@@ -12,38 +12,15 @@ | |||
12 | #include <asm/e820.h> | 12 | #include <asm/e820.h> |
13 | #include <asm/pci_x86.h> | 13 | #include <asm/pci_x86.h> |
14 | 14 | ||
15 | /* Static virtual mapping of the MMCONFIG aperture */ | 15 | #define PREFIX "PCI: " |
16 | struct mmcfg_virt { | ||
17 | struct acpi_mcfg_allocation *cfg; | ||
18 | char __iomem *virt; | ||
19 | }; | ||
20 | static struct mmcfg_virt *pci_mmcfg_virt; | ||
21 | |||
22 | static char __iomem *get_virt(unsigned int seg, unsigned bus) | ||
23 | { | ||
24 | struct acpi_mcfg_allocation *cfg; | ||
25 | int cfg_num; | ||
26 | |||
27 | for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) { | ||
28 | cfg = pci_mmcfg_virt[cfg_num].cfg; | ||
29 | if (cfg->pci_segment == seg && | ||
30 | (cfg->start_bus_number <= bus) && | ||
31 | (cfg->end_bus_number >= bus)) | ||
32 | return pci_mmcfg_virt[cfg_num].virt; | ||
33 | } | ||
34 | |||
35 | /* Fall back to type 0 */ | ||
36 | return NULL; | ||
37 | } | ||
38 | 16 | ||
39 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 17 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
40 | { | 18 | { |
41 | char __iomem *addr; | 19 | struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus); |
42 | 20 | ||
43 | addr = get_virt(seg, bus); | 21 | if (cfg && cfg->virt) |
44 | if (!addr) | 22 | return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12)); |
45 | return NULL; | 23 | return NULL; |
46 | return addr + ((bus << 20) | (devfn << 12)); | ||
47 | } | 24 | } |
48 | 25 | ||
49 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, | 26 | static int pci_mmcfg_read(unsigned int seg, unsigned int bus, |
@@ -109,42 +86,30 @@ static struct pci_raw_ops pci_mmcfg = { | |||
109 | .write = pci_mmcfg_write, | 86 | .write = pci_mmcfg_write, |
110 | }; | 87 | }; |
111 | 88 | ||
112 | static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) | 89 | static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg) |
113 | { | 90 | { |
114 | void __iomem *addr; | 91 | void __iomem *addr; |
115 | u64 start, size; | 92 | u64 start, size; |
93 | int num_buses; | ||
116 | 94 | ||
117 | start = cfg->start_bus_number; | 95 | start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus); |
118 | start <<= 20; | 96 | num_buses = cfg->end_bus - cfg->start_bus + 1; |
119 | start += cfg->address; | 97 | size = PCI_MMCFG_BUS_OFFSET(num_buses); |
120 | size = cfg->end_bus_number + 1 - cfg->start_bus_number; | ||
121 | size <<= 20; | ||
122 | addr = ioremap_nocache(start, size); | 98 | addr = ioremap_nocache(start, size); |
123 | if (addr) { | 99 | if (addr) |
124 | printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", | 100 | addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus); |
125 | start, start + size - 1); | ||
126 | addr -= cfg->start_bus_number << 20; | ||
127 | } | ||
128 | return addr; | 101 | return addr; |
129 | } | 102 | } |
130 | 103 | ||
131 | int __init pci_mmcfg_arch_init(void) | 104 | int __init pci_mmcfg_arch_init(void) |
132 | { | 105 | { |
133 | int i; | 106 | struct pci_mmcfg_region *cfg; |
134 | pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) * | ||
135 | pci_mmcfg_config_num, GFP_KERNEL); | ||
136 | if (pci_mmcfg_virt == NULL) { | ||
137 | printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n"); | ||
138 | return 0; | ||
139 | } | ||
140 | 107 | ||
141 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 108 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
142 | pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; | 109 | cfg->virt = mcfg_ioremap(cfg); |
143 | pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]); | 110 | if (!cfg->virt) { |
144 | if (!pci_mmcfg_virt[i].virt) { | 111 | printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n", |
145 | printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " | 112 | &cfg->res); |
146 | "segment %d\n", | ||
147 | pci_mmcfg_config[i].pci_segment); | ||
148 | pci_mmcfg_arch_free(); | 113 | pci_mmcfg_arch_free(); |
149 | return 0; | 114 | return 0; |
150 | } | 115 | } |
@@ -155,19 +120,12 @@ int __init pci_mmcfg_arch_init(void) | |||
155 | 120 | ||
156 | void __init pci_mmcfg_arch_free(void) | 121 | void __init pci_mmcfg_arch_free(void) |
157 | { | 122 | { |
158 | int i; | 123 | struct pci_mmcfg_region *cfg; |
159 | |||
160 | if (pci_mmcfg_virt == NULL) | ||
161 | return; | ||
162 | 124 | ||
163 | for (i = 0; i < pci_mmcfg_config_num; ++i) { | 125 | list_for_each_entry(cfg, &pci_mmcfg_list, list) { |
164 | if (pci_mmcfg_virt[i].virt) { | 126 | if (cfg->virt) { |
165 | iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20)); | 127 | iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus)); |
166 | pci_mmcfg_virt[i].virt = NULL; | 128 | cfg->virt = NULL; |
167 | pci_mmcfg_virt[i].cfg = NULL; | ||
168 | } | 129 | } |
169 | } | 130 | } |
170 | |||
171 | kfree(pci_mmcfg_virt); | ||
172 | pci_mmcfg_virt = NULL; | ||
173 | } | 131 | } |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index b8e45f164e2a..2b26dd5930c6 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -27,7 +27,9 @@ | |||
27 | #include <linux/page-flags.h> | 27 | #include <linux/page-flags.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | #include <linux/console.h> | 29 | #include <linux/console.h> |
30 | #include <linux/pci.h> | ||
30 | 31 | ||
32 | #include <xen/xen.h> | ||
31 | #include <xen/interface/xen.h> | 33 | #include <xen/interface/xen.h> |
32 | #include <xen/interface/version.h> | 34 | #include <xen/interface/version.h> |
33 | #include <xen/interface/physdev.h> | 35 | #include <xen/interface/physdev.h> |
@@ -1175,7 +1177,11 @@ asmlinkage void __init xen_start_kernel(void) | |||
1175 | add_preferred_console("xenboot", 0, NULL); | 1177 | add_preferred_console("xenboot", 0, NULL); |
1176 | add_preferred_console("tty", 0, NULL); | 1178 | add_preferred_console("tty", 0, NULL); |
1177 | add_preferred_console("hvc", 0, NULL); | 1179 | add_preferred_console("hvc", 0, NULL); |
1180 | } else { | ||
1181 | /* Make sure ACS will be enabled */ | ||
1182 | pci_request_acs(); | ||
1178 | } | 1183 | } |
1184 | |||
1179 | 1185 | ||
1180 | xen_raw_console_write("about to get started...\n"); | 1186 | xen_raw_console_write("about to get started...\n"); |
1181 | 1187 | ||
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 7702118509a0..c7b10b4298e9 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -19,6 +19,7 @@ obj-y += acpi.o \ | |||
19 | 19 | ||
20 | # All the builtin files are in the "acpi." module_param namespace. | 20 | # All the builtin files are in the "acpi." module_param namespace. |
21 | acpi-y += osl.o utils.o reboot.o | 21 | acpi-y += osl.o utils.o reboot.o |
22 | acpi-y += hest.o | ||
22 | 23 | ||
23 | # sleep related files | 24 | # sleep related files |
24 | acpi-y += wakeup.o | 25 | acpi-y += wakeup.o |
diff --git a/drivers/acpi/hest.c b/drivers/acpi/hest.c new file mode 100644 index 000000000000..4bb18c980ac6 --- /dev/null +++ b/drivers/acpi/hest.c | |||
@@ -0,0 +1,135 @@ | |||
1 | #include <linux/acpi.h> | ||
2 | #include <linux/pci.h> | ||
3 | |||
4 | #define PREFIX "ACPI: " | ||
5 | |||
6 | static inline unsigned long parse_acpi_hest_ia_machine_check(struct acpi_hest_ia_machine_check *p) | ||
7 | { | ||
8 | return sizeof(*p) + | ||
9 | (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); | ||
10 | } | ||
11 | |||
12 | static inline unsigned long parse_acpi_hest_ia_corrected(struct acpi_hest_ia_corrected *p) | ||
13 | { | ||
14 | return sizeof(*p) + | ||
15 | (sizeof(struct acpi_hest_ia_error_bank) * p->num_hardware_banks); | ||
16 | } | ||
17 | |||
18 | static inline unsigned long parse_acpi_hest_ia_nmi(struct acpi_hest_ia_nmi *p) | ||
19 | { | ||
20 | return sizeof(*p); | ||
21 | } | ||
22 | |||
23 | static inline unsigned long parse_acpi_hest_generic(struct acpi_hest_generic *p) | ||
24 | { | ||
25 | return sizeof(*p); | ||
26 | } | ||
27 | |||
28 | static inline unsigned int hest_match_pci(struct acpi_hest_aer_common *p, struct pci_dev *pci) | ||
29 | { | ||
30 | return (0 == pci_domain_nr(pci->bus) && | ||
31 | p->bus == pci->bus->number && | ||
32 | p->device == PCI_SLOT(pci->devfn) && | ||
33 | p->function == PCI_FUNC(pci->devfn)); | ||
34 | } | ||
35 | |||
36 | static unsigned long parse_acpi_hest_aer(void *hdr, int type, struct pci_dev *pci, int *firmware_first) | ||
37 | { | ||
38 | struct acpi_hest_aer_common *p = hdr + sizeof(struct acpi_hest_header); | ||
39 | unsigned long rc=0; | ||
40 | u8 pcie_type = 0; | ||
41 | u8 bridge = 0; | ||
42 | switch (type) { | ||
43 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
44 | rc = sizeof(struct acpi_hest_aer_root); | ||
45 | pcie_type = PCI_EXP_TYPE_ROOT_PORT; | ||
46 | break; | ||
47 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
48 | rc = sizeof(struct acpi_hest_aer); | ||
49 | pcie_type = PCI_EXP_TYPE_ENDPOINT; | ||
50 | break; | ||
51 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
52 | rc = sizeof(struct acpi_hest_aer_bridge); | ||
53 | if ((pci->class >> 16) == PCI_BASE_CLASS_BRIDGE) | ||
54 | bridge = 1; | ||
55 | break; | ||
56 | } | ||
57 | |||
58 | if (p->flags & ACPI_HEST_GLOBAL) { | ||
59 | if ((pci->is_pcie && (pci->pcie_type == pcie_type)) || bridge) | ||
60 | *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
61 | } | ||
62 | else | ||
63 | if (hest_match_pci(p, pci)) | ||
64 | *firmware_first = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); | ||
65 | return rc; | ||
66 | } | ||
67 | |||
68 | static int acpi_hest_firmware_first(struct acpi_table_header *stdheader, struct pci_dev *pci) | ||
69 | { | ||
70 | struct acpi_table_hest *hest = (struct acpi_table_hest *)stdheader; | ||
71 | void *p = (void *)hest + sizeof(*hest); /* defined by the ACPI 4.0 spec */ | ||
72 | struct acpi_hest_header *hdr = p; | ||
73 | |||
74 | int i; | ||
75 | int firmware_first = 0; | ||
76 | static unsigned char printed_unused = 0; | ||
77 | static unsigned char printed_reserved = 0; | ||
78 | |||
79 | for (i=0, hdr=p; p < (((void *)hest) + hest->header.length) && i < hest->error_source_count; i++) { | ||
80 | switch (hdr->type) { | ||
81 | case ACPI_HEST_TYPE_IA32_CHECK: | ||
82 | p += parse_acpi_hest_ia_machine_check(p); | ||
83 | break; | ||
84 | case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: | ||
85 | p += parse_acpi_hest_ia_corrected(p); | ||
86 | break; | ||
87 | case ACPI_HEST_TYPE_IA32_NMI: | ||
88 | p += parse_acpi_hest_ia_nmi(p); | ||
89 | break; | ||
90 | /* These three should never appear */ | ||
91 | case ACPI_HEST_TYPE_NOT_USED3: | ||
92 | case ACPI_HEST_TYPE_NOT_USED4: | ||
93 | case ACPI_HEST_TYPE_NOT_USED5: | ||
94 | if (!printed_unused) { | ||
95 | printk(KERN_DEBUG PREFIX | ||
96 | "HEST Error Source list contains an obsolete type (%d).\n", hdr->type); | ||
97 | printed_unused = 1; | ||
98 | } | ||
99 | break; | ||
100 | case ACPI_HEST_TYPE_AER_ROOT_PORT: | ||
101 | case ACPI_HEST_TYPE_AER_ENDPOINT: | ||
102 | case ACPI_HEST_TYPE_AER_BRIDGE: | ||
103 | p += parse_acpi_hest_aer(p, hdr->type, pci, &firmware_first); | ||
104 | break; | ||
105 | case ACPI_HEST_TYPE_GENERIC_ERROR: | ||
106 | p += parse_acpi_hest_generic(p); | ||
107 | break; | ||
108 | /* These should never appear either */ | ||
109 | case ACPI_HEST_TYPE_RESERVED: | ||
110 | default: | ||
111 | if (!printed_reserved) { | ||
112 | printk(KERN_DEBUG PREFIX | ||
113 | "HEST Error Source list contains a reserved type (%d).\n", hdr->type); | ||
114 | printed_reserved = 1; | ||
115 | } | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | return firmware_first; | ||
120 | } | ||
121 | |||
122 | int acpi_hest_firmware_first_pci(struct pci_dev *pci) | ||
123 | { | ||
124 | acpi_status status = AE_NOT_FOUND; | ||
125 | struct acpi_table_header *hest = NULL; | ||
126 | status = acpi_get_table(ACPI_SIG_HEST, 1, &hest); | ||
127 | |||
128 | if (ACPI_SUCCESS(status)) { | ||
129 | if (acpi_hest_firmware_first(hest, pci)) { | ||
130 | return 1; | ||
131 | } | ||
132 | } | ||
133 | return 0; | ||
134 | } | ||
135 | EXPORT_SYMBOL_GPL(acpi_hest_firmware_first_pci); | ||
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index b8578bb3f4c9..05a31e55d278 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/module.h> | 42 | #include <linux/module.h> |
43 | #include <linux/scatterlist.h> | 43 | #include <linux/scatterlist.h> |
44 | 44 | ||
45 | #include <xen/xen.h> | ||
45 | #include <xen/xenbus.h> | 46 | #include <xen/xenbus.h> |
46 | #include <xen/grant_table.h> | 47 | #include <xen/grant_table.h> |
47 | #include <xen/events.h> | 48 | #include <xen/events.h> |
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c index a6ee32b599a8..b1a71638c772 100644 --- a/drivers/char/hvc_xen.c +++ b/drivers/char/hvc_xen.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/types.h> | 25 | #include <linux/types.h> |
26 | 26 | ||
27 | #include <asm/xen/hypervisor.h> | 27 | #include <asm/xen/hypervisor.h> |
28 | |||
29 | #include <xen/xen.h> | ||
28 | #include <xen/page.h> | 30 | #include <xen/page.h> |
29 | #include <xen/events.h> | 31 | #include <xen/events.h> |
30 | #include <xen/interface/io/console.h> | 32 | #include <xen/interface/io/console.h> |
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c index b115726dc088..c721c0a23eb8 100644 --- a/drivers/input/xen-kbdfront.c +++ b/drivers/input/xen-kbdfront.c | |||
@@ -21,7 +21,10 @@ | |||
21 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
24 | |||
24 | #include <asm/xen/hypervisor.h> | 25 | #include <asm/xen/hypervisor.h> |
26 | |||
27 | #include <xen/xen.h> | ||
25 | #include <xen/events.h> | 28 | #include <xen/events.h> |
26 | #include <xen/page.h> | 29 | #include <xen/page.h> |
27 | #include <xen/interface/io/fbif.h> | 30 | #include <xen/interface/io/fbif.h> |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index baa051d5bfbe..a869b45d3d37 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/mm.h> | 42 | #include <linux/mm.h> |
43 | #include <net/ip.h> | 43 | #include <net/ip.h> |
44 | 44 | ||
45 | #include <xen/xen.h> | ||
45 | #include <xen/xenbus.h> | 46 | #include <xen/xenbus.h> |
46 | #include <xen/events.h> | 47 | #include <xen/events.h> |
47 | #include <xen/page.h> | 48 | #include <xen/page.h> |
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index fdc864f9cf23..b1ecefa2a23d 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -27,10 +27,10 @@ config PCI_LEGACY | |||
27 | default y | 27 | default y |
28 | help | 28 | help |
29 | Say Y here if you want to include support for the deprecated | 29 | Say Y here if you want to include support for the deprecated |
30 | pci_find_slot() and pci_find_device() APIs. Most drivers have | 30 | pci_find_device() API. Most drivers have been converted over |
31 | been converted over to using the proper hotplug APIs, so this | 31 | to using the proper hotplug APIs, so this option serves to |
32 | option serves to include/exclude only a few drivers that are | 32 | include/exclude only a few drivers that are still using this |
33 | still using this API. | 33 | API. |
34 | 34 | ||
35 | config PCI_DEBUG | 35 | config PCI_DEBUG |
36 | bool "PCI Debugging" | 36 | bool "PCI Debugging" |
@@ -69,3 +69,10 @@ config PCI_IOV | |||
69 | physical resources. | 69 | physical resources. |
70 | 70 | ||
71 | If unsure, say N. | 71 | If unsure, say N. |
72 | |||
73 | config PCI_IOAPIC | ||
74 | bool | ||
75 | depends on PCI | ||
76 | depends on ACPI | ||
77 | depends on HOTPLUG | ||
78 | default y | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 4a7f11d8f432..4df48d58eaa6 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -14,6 +14,8 @@ CFLAGS_legacy.o += -Wno-deprecated-declarations | |||
14 | # Build PCI Express stuff if needed | 14 | # Build PCI Express stuff if needed |
15 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ | 15 | obj-$(CONFIG_PCIEPORTBUS) += pcie/ |
16 | 16 | ||
17 | obj-$(CONFIG_PCI_IOAPIC) += ioapic.o | ||
18 | |||
17 | obj-$(CONFIG_HOTPLUG) += hotplug.o | 19 | obj-$(CONFIG_HOTPLUG) += hotplug.o |
18 | 20 | ||
19 | # Build the PCI Hotplug drivers if we were asked to | 21 | # Build the PCI Hotplug drivers if we were asked to |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 416f6ac65b76..6cdc931f7c17 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -320,7 +320,7 @@ found: | |||
320 | for (bus = dev->bus; bus; bus = bus->parent) { | 320 | for (bus = dev->bus; bus; bus = bus->parent) { |
321 | struct pci_dev *bridge = bus->self; | 321 | struct pci_dev *bridge = bus->self; |
322 | 322 | ||
323 | if (!bridge || !bridge->is_pcie || | 323 | if (!bridge || !pci_is_pcie(bridge) || |
324 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) | 324 | bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) |
325 | return 0; | 325 | return 0; |
326 | 326 | ||
@@ -645,8 +645,11 @@ void __init detect_intel_iommu(void) | |||
645 | "x2apic and Intr-remapping.\n"); | 645 | "x2apic and Intr-remapping.\n"); |
646 | #endif | 646 | #endif |
647 | #ifdef CONFIG_DMAR | 647 | #ifdef CONFIG_DMAR |
648 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) | 648 | if (ret && !no_iommu && !iommu_detected && !dmar_disabled) { |
649 | iommu_detected = 1; | 649 | iommu_detected = 1; |
650 | /* Make sure ACS will be enabled */ | ||
651 | pci_request_acs(); | ||
652 | } | ||
650 | #endif | 653 | #endif |
651 | #ifdef CONFIG_X86 | 654 | #ifdef CONFIG_X86 |
652 | if (ret) | 655 | if (ret) |
diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 3625b094bf7e..6cd9f3c9887d 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile | |||
@@ -6,18 +6,22 @@ obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o | |||
6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o | 6 | obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o |
7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o | 7 | obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o |
8 | 8 | ||
9 | # pciehp should be linked before acpiphp in order to allow the native driver | 9 | # native drivers should be linked before acpiphp in order to allow the |
10 | # to attempt to bind first. We can then fall back to generic support. | 10 | # native driver to attempt to bind first. We can then fall back to |
11 | # generic support. | ||
11 | 12 | ||
12 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o | 13 | obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o |
13 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | ||
14 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | ||
15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o | 14 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o |
16 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o | 15 | obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o |
17 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o | 16 | obj-$(CONFIG_HOTPLUG_PCI_SHPC) += shpchp.o |
18 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o | 17 | obj-$(CONFIG_HOTPLUG_PCI_RPA) += rpaphp.o |
19 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o | 18 | obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o |
20 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o | 19 | obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o |
20 | obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o | ||
21 | |||
22 | # acpiphp_ibm extends acpiphp, so should be linked afterwards. | ||
23 | |||
24 | obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o | ||
21 | 25 | ||
22 | # Link this last so it doesn't claim devices that have a real hotplug driver | 26 | # Link this last so it doesn't claim devices that have a real hotplug driver |
23 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o | 27 | obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 0f32571b94df..3c76fc67cf0e 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -362,6 +362,8 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
362 | status = acpi_pci_osc_control_set(handle, flags); | 362 | status = acpi_pci_osc_control_set(handle, flags); |
363 | if (ACPI_SUCCESS(status)) | 363 | if (ACPI_SUCCESS(status)) |
364 | goto got_one; | 364 | goto got_one; |
365 | if (status == AE_SUPPORT) | ||
366 | goto no_control; | ||
365 | kfree(string.pointer); | 367 | kfree(string.pointer); |
366 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; | 368 | string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL }; |
367 | } | 369 | } |
@@ -394,10 +396,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
394 | if (ACPI_FAILURE(status)) | 396 | if (ACPI_FAILURE(status)) |
395 | break; | 397 | break; |
396 | } | 398 | } |
397 | 399 | no_control: | |
398 | dbg("Cannot get control of hotplug hardware for pci %s\n", | 400 | dbg("Cannot get control of hotplug hardware for pci %s\n", |
399 | pci_name(pdev)); | 401 | pci_name(pdev)); |
400 | |||
401 | kfree(string.pointer); | 402 | kfree(string.pointer); |
402 | return -ENODEV; | 403 | return -ENODEV; |
403 | got_one: | 404 | got_one: |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index 7d938df79206..bab52047baa8 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -146,12 +146,6 @@ struct acpiphp_attention_info | |||
146 | struct module *owner; | 146 | struct module *owner; |
147 | }; | 147 | }; |
148 | 148 | ||
149 | struct acpiphp_ioapic { | ||
150 | struct pci_dev *dev; | ||
151 | u32 gsi_base; | ||
152 | struct list_head list; | ||
153 | }; | ||
154 | |||
155 | /* PCI bus bridge HID */ | 149 | /* PCI bus bridge HID */ |
156 | #define ACPI_PCI_HOST_HID "PNP0A03" | 150 | #define ACPI_PCI_HOST_HID "PNP0A03" |
157 | 151 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index df1b0ea089d1..8e952fdab764 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -52,8 +52,6 @@ | |||
52 | #include "acpiphp.h" | 52 | #include "acpiphp.h" |
53 | 53 | ||
54 | static LIST_HEAD(bridge_list); | 54 | static LIST_HEAD(bridge_list); |
55 | static LIST_HEAD(ioapic_list); | ||
56 | static DEFINE_SPINLOCK(ioapic_list_lock); | ||
57 | 55 | ||
58 | #define MY_NAME "acpiphp_glue" | 56 | #define MY_NAME "acpiphp_glue" |
59 | 57 | ||
@@ -311,17 +309,13 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) | |||
311 | /* find acpiphp_func from acpiphp_bridge */ | 309 | /* find acpiphp_func from acpiphp_bridge */ |
312 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) | 310 | static struct acpiphp_func *acpiphp_bridge_handle_to_function(acpi_handle handle) |
313 | { | 311 | { |
314 | struct list_head *node, *l; | ||
315 | struct acpiphp_bridge *bridge; | 312 | struct acpiphp_bridge *bridge; |
316 | struct acpiphp_slot *slot; | 313 | struct acpiphp_slot *slot; |
317 | struct acpiphp_func *func; | 314 | struct acpiphp_func *func; |
318 | 315 | ||
319 | list_for_each(node, &bridge_list) { | 316 | list_for_each_entry(bridge, &bridge_list, list) { |
320 | bridge = list_entry(node, struct acpiphp_bridge, list); | ||
321 | for (slot = bridge->slots; slot; slot = slot->next) { | 317 | for (slot = bridge->slots; slot; slot = slot->next) { |
322 | list_for_each(l, &slot->funcs) { | 318 | list_for_each_entry(func, &slot->funcs, sibling) { |
323 | func = list_entry(l, struct acpiphp_func, | ||
324 | sibling); | ||
325 | if (func->handle == handle) | 319 | if (func->handle == handle) |
326 | return func; | 320 | return func; |
327 | } | 321 | } |
@@ -495,21 +489,19 @@ static int add_bridge(acpi_handle handle) | |||
495 | 489 | ||
496 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) | 490 | static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) |
497 | { | 491 | { |
498 | struct list_head *head; | 492 | struct acpiphp_bridge *bridge; |
499 | list_for_each(head, &bridge_list) { | 493 | |
500 | struct acpiphp_bridge *bridge = list_entry(head, | 494 | list_for_each_entry(bridge, &bridge_list, list) |
501 | struct acpiphp_bridge, list); | ||
502 | if (bridge->handle == handle) | 495 | if (bridge->handle == handle) |
503 | return bridge; | 496 | return bridge; |
504 | } | ||
505 | 497 | ||
506 | return NULL; | 498 | return NULL; |
507 | } | 499 | } |
508 | 500 | ||
509 | static void cleanup_bridge(struct acpiphp_bridge *bridge) | 501 | static void cleanup_bridge(struct acpiphp_bridge *bridge) |
510 | { | 502 | { |
511 | struct list_head *list, *tmp; | 503 | struct acpiphp_slot *slot, *next; |
512 | struct acpiphp_slot *slot; | 504 | struct acpiphp_func *func, *tmp; |
513 | acpi_status status; | 505 | acpi_status status; |
514 | acpi_handle handle = bridge->handle; | 506 | acpi_handle handle = bridge->handle; |
515 | 507 | ||
@@ -530,10 +522,8 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
530 | 522 | ||
531 | slot = bridge->slots; | 523 | slot = bridge->slots; |
532 | while (slot) { | 524 | while (slot) { |
533 | struct acpiphp_slot *next = slot->next; | 525 | next = slot->next; |
534 | list_for_each_safe (list, tmp, &slot->funcs) { | 526 | list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) { |
535 | struct acpiphp_func *func; | ||
536 | func = list_entry(list, struct acpiphp_func, sibling); | ||
537 | if (is_dock_device(func->handle)) { | 527 | if (is_dock_device(func->handle)) { |
538 | unregister_hotplug_dock_device(func->handle); | 528 | unregister_hotplug_dock_device(func->handle); |
539 | unregister_dock_notifier(&func->nb); | 529 | unregister_dock_notifier(&func->nb); |
@@ -545,7 +535,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) | |||
545 | if (ACPI_FAILURE(status)) | 535 | if (ACPI_FAILURE(status)) |
546 | err("failed to remove notify handler\n"); | 536 | err("failed to remove notify handler\n"); |
547 | } | 537 | } |
548 | list_del(list); | 538 | list_del(&func->sibling); |
549 | kfree(func); | 539 | kfree(func); |
550 | } | 540 | } |
551 | acpiphp_unregister_hotplug_slot(slot); | 541 | acpiphp_unregister_hotplug_slot(slot); |
@@ -606,204 +596,17 @@ static void remove_bridge(acpi_handle handle) | |||
606 | handle_hotplug_event_bridge); | 596 | handle_hotplug_event_bridge); |
607 | } | 597 | } |
608 | 598 | ||
609 | static struct pci_dev * get_apic_pci_info(acpi_handle handle) | ||
610 | { | ||
611 | struct pci_dev *dev; | ||
612 | |||
613 | dev = acpi_get_pci_dev(handle); | ||
614 | if (!dev) | ||
615 | return NULL; | ||
616 | |||
617 | if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) && | ||
618 | (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC)) | ||
619 | { | ||
620 | pci_dev_put(dev); | ||
621 | return NULL; | ||
622 | } | ||
623 | |||
624 | return dev; | ||
625 | } | ||
626 | |||
627 | static int get_gsi_base(acpi_handle handle, u32 *gsi_base) | ||
628 | { | ||
629 | acpi_status status; | ||
630 | int result = -1; | ||
631 | unsigned long long gsb; | ||
632 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
633 | union acpi_object *obj; | ||
634 | void *table; | ||
635 | |||
636 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
637 | if (ACPI_SUCCESS(status)) { | ||
638 | *gsi_base = (u32)gsb; | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer); | ||
643 | if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer) | ||
644 | return -1; | ||
645 | |||
646 | obj = buffer.pointer; | ||
647 | if (obj->type != ACPI_TYPE_BUFFER) | ||
648 | goto out; | ||
649 | |||
650 | table = obj->buffer.pointer; | ||
651 | switch (((struct acpi_subtable_header *)table)->type) { | ||
652 | case ACPI_MADT_TYPE_IO_SAPIC: | ||
653 | *gsi_base = ((struct acpi_madt_io_sapic *)table)->global_irq_base; | ||
654 | result = 0; | ||
655 | break; | ||
656 | case ACPI_MADT_TYPE_IO_APIC: | ||
657 | *gsi_base = ((struct acpi_madt_io_apic *)table)->global_irq_base; | ||
658 | result = 0; | ||
659 | break; | ||
660 | default: | ||
661 | break; | ||
662 | } | ||
663 | out: | ||
664 | kfree(buffer.pointer); | ||
665 | return result; | ||
666 | } | ||
667 | |||
668 | static acpi_status | ||
669 | ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
670 | { | ||
671 | acpi_status status; | ||
672 | unsigned long long sta; | ||
673 | acpi_handle tmp; | ||
674 | struct pci_dev *pdev; | ||
675 | u32 gsi_base; | ||
676 | u64 phys_addr; | ||
677 | struct acpiphp_ioapic *ioapic; | ||
678 | |||
679 | /* Evaluate _STA if present */ | ||
680 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
681 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
682 | return AE_CTRL_DEPTH; | ||
683 | |||
684 | /* Scan only PCI bus scope */ | ||
685 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
686 | if (ACPI_SUCCESS(status)) | ||
687 | return AE_CTRL_DEPTH; | ||
688 | |||
689 | if (get_gsi_base(handle, &gsi_base)) | ||
690 | return AE_OK; | ||
691 | |||
692 | ioapic = kmalloc(sizeof(*ioapic), GFP_KERNEL); | ||
693 | if (!ioapic) | ||
694 | return AE_NO_MEMORY; | ||
695 | |||
696 | pdev = get_apic_pci_info(handle); | ||
697 | if (!pdev) | ||
698 | goto exit_kfree; | ||
699 | |||
700 | if (pci_enable_device(pdev)) | ||
701 | goto exit_pci_dev_put; | ||
702 | |||
703 | pci_set_master(pdev); | ||
704 | |||
705 | if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) | ||
706 | goto exit_pci_disable_device; | ||
707 | |||
708 | phys_addr = pci_resource_start(pdev, 0); | ||
709 | if (acpi_register_ioapic(handle, phys_addr, gsi_base)) | ||
710 | goto exit_pci_release_region; | ||
711 | |||
712 | ioapic->gsi_base = gsi_base; | ||
713 | ioapic->dev = pdev; | ||
714 | spin_lock(&ioapic_list_lock); | ||
715 | list_add_tail(&ioapic->list, &ioapic_list); | ||
716 | spin_unlock(&ioapic_list_lock); | ||
717 | |||
718 | return AE_OK; | ||
719 | |||
720 | exit_pci_release_region: | ||
721 | pci_release_region(pdev, 0); | ||
722 | exit_pci_disable_device: | ||
723 | pci_disable_device(pdev); | ||
724 | exit_pci_dev_put: | ||
725 | pci_dev_put(pdev); | ||
726 | exit_kfree: | ||
727 | kfree(ioapic); | ||
728 | |||
729 | return AE_OK; | ||
730 | } | ||
731 | |||
732 | static acpi_status | ||
733 | ioapic_remove(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
734 | { | ||
735 | acpi_status status; | ||
736 | unsigned long long sta; | ||
737 | acpi_handle tmp; | ||
738 | u32 gsi_base; | ||
739 | struct acpiphp_ioapic *pos, *n, *ioapic = NULL; | ||
740 | |||
741 | /* Evaluate _STA if present */ | ||
742 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
743 | if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) | ||
744 | return AE_CTRL_DEPTH; | ||
745 | |||
746 | /* Scan only PCI bus scope */ | ||
747 | status = acpi_get_handle(handle, "_HID", &tmp); | ||
748 | if (ACPI_SUCCESS(status)) | ||
749 | return AE_CTRL_DEPTH; | ||
750 | |||
751 | if (get_gsi_base(handle, &gsi_base)) | ||
752 | return AE_OK; | ||
753 | |||
754 | acpi_unregister_ioapic(handle, gsi_base); | ||
755 | |||
756 | spin_lock(&ioapic_list_lock); | ||
757 | list_for_each_entry_safe(pos, n, &ioapic_list, list) { | ||
758 | if (pos->gsi_base != gsi_base) | ||
759 | continue; | ||
760 | ioapic = pos; | ||
761 | list_del(&ioapic->list); | ||
762 | break; | ||
763 | } | ||
764 | spin_unlock(&ioapic_list_lock); | ||
765 | |||
766 | if (!ioapic) | ||
767 | return AE_OK; | ||
768 | |||
769 | pci_release_region(ioapic->dev, 0); | ||
770 | pci_disable_device(ioapic->dev); | ||
771 | pci_dev_put(ioapic->dev); | ||
772 | kfree(ioapic); | ||
773 | |||
774 | return AE_OK; | ||
775 | } | ||
776 | |||
777 | static int acpiphp_configure_ioapics(acpi_handle handle) | ||
778 | { | ||
779 | ioapic_add(handle, 0, NULL, NULL); | ||
780 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
781 | ACPI_UINT32_MAX, ioapic_add, NULL, NULL, NULL); | ||
782 | return 0; | ||
783 | } | ||
784 | |||
785 | static int acpiphp_unconfigure_ioapics(acpi_handle handle) | ||
786 | { | ||
787 | ioapic_remove(handle, 0, NULL, NULL); | ||
788 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
789 | ACPI_UINT32_MAX, ioapic_remove, NULL, NULL, NULL); | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | static int power_on_slot(struct acpiphp_slot *slot) | 599 | static int power_on_slot(struct acpiphp_slot *slot) |
794 | { | 600 | { |
795 | acpi_status status; | 601 | acpi_status status; |
796 | struct acpiphp_func *func; | 602 | struct acpiphp_func *func; |
797 | struct list_head *l; | ||
798 | int retval = 0; | 603 | int retval = 0; |
799 | 604 | ||
800 | /* if already enabled, just skip */ | 605 | /* if already enabled, just skip */ |
801 | if (slot->flags & SLOT_POWEREDON) | 606 | if (slot->flags & SLOT_POWEREDON) |
802 | goto err_exit; | 607 | goto err_exit; |
803 | 608 | ||
804 | list_for_each (l, &slot->funcs) { | 609 | list_for_each_entry(func, &slot->funcs, sibling) { |
805 | func = list_entry(l, struct acpiphp_func, sibling); | ||
806 | |||
807 | if (func->flags & FUNC_HAS_PS0) { | 610 | if (func->flags & FUNC_HAS_PS0) { |
808 | dbg("%s: executing _PS0\n", __func__); | 611 | dbg("%s: executing _PS0\n", __func__); |
809 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); | 612 | status = acpi_evaluate_object(func->handle, "_PS0", NULL, NULL); |
@@ -829,7 +632,6 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
829 | { | 632 | { |
830 | acpi_status status; | 633 | acpi_status status; |
831 | struct acpiphp_func *func; | 634 | struct acpiphp_func *func; |
832 | struct list_head *l; | ||
833 | 635 | ||
834 | int retval = 0; | 636 | int retval = 0; |
835 | 637 | ||
@@ -837,9 +639,7 @@ static int power_off_slot(struct acpiphp_slot *slot) | |||
837 | if ((slot->flags & SLOT_POWEREDON) == 0) | 639 | if ((slot->flags & SLOT_POWEREDON) == 0) |
838 | goto err_exit; | 640 | goto err_exit; |
839 | 641 | ||
840 | list_for_each (l, &slot->funcs) { | 642 | list_for_each_entry(func, &slot->funcs, sibling) { |
841 | func = list_entry(l, struct acpiphp_func, sibling); | ||
842 | |||
843 | if (func->flags & FUNC_HAS_PS3) { | 643 | if (func->flags & FUNC_HAS_PS3) { |
844 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); | 644 | status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); |
845 | if (ACPI_FAILURE(status)) { | 645 | if (ACPI_FAILURE(status)) { |
@@ -966,7 +766,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
966 | { | 766 | { |
967 | struct pci_dev *dev; | 767 | struct pci_dev *dev; |
968 | struct pci_bus *bus = slot->bridge->pci_bus; | 768 | struct pci_bus *bus = slot->bridge->pci_bus; |
969 | struct list_head *l; | ||
970 | struct acpiphp_func *func; | 769 | struct acpiphp_func *func; |
971 | int retval = 0; | 770 | int retval = 0; |
972 | int num, max, pass; | 771 | int num, max, pass; |
@@ -1006,21 +805,16 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
1006 | } | 805 | } |
1007 | } | 806 | } |
1008 | 807 | ||
1009 | list_for_each (l, &slot->funcs) { | 808 | list_for_each_entry(func, &slot->funcs, sibling) |
1010 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1011 | acpiphp_bus_add(func); | 809 | acpiphp_bus_add(func); |
1012 | } | ||
1013 | 810 | ||
1014 | pci_bus_assign_resources(bus); | 811 | pci_bus_assign_resources(bus); |
1015 | acpiphp_sanitize_bus(bus); | 812 | acpiphp_sanitize_bus(bus); |
1016 | acpiphp_set_hpp_values(bus); | 813 | acpiphp_set_hpp_values(bus); |
1017 | list_for_each_entry(func, &slot->funcs, sibling) | ||
1018 | acpiphp_configure_ioapics(func->handle); | ||
1019 | pci_enable_bridges(bus); | 814 | pci_enable_bridges(bus); |
1020 | pci_bus_add_devices(bus); | 815 | pci_bus_add_devices(bus); |
1021 | 816 | ||
1022 | list_for_each (l, &slot->funcs) { | 817 | list_for_each_entry(func, &slot->funcs, sibling) { |
1023 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1024 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | 818 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, |
1025 | func->function)); | 819 | func->function)); |
1026 | if (!dev) | 820 | if (!dev) |
@@ -1091,7 +885,6 @@ static int disable_device(struct acpiphp_slot *slot) | |||
1091 | } | 885 | } |
1092 | 886 | ||
1093 | list_for_each_entry(func, &slot->funcs, sibling) { | 887 | list_for_each_entry(func, &slot->funcs, sibling) { |
1094 | acpiphp_unconfigure_ioapics(func->handle); | ||
1095 | acpiphp_bus_trim(func->handle); | 888 | acpiphp_bus_trim(func->handle); |
1096 | } | 889 | } |
1097 | 890 | ||
@@ -1119,12 +912,9 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
1119 | acpi_status status; | 912 | acpi_status status; |
1120 | unsigned long long sta = 0; | 913 | unsigned long long sta = 0; |
1121 | u32 dvid; | 914 | u32 dvid; |
1122 | struct list_head *l; | ||
1123 | struct acpiphp_func *func; | 915 | struct acpiphp_func *func; |
1124 | 916 | ||
1125 | list_for_each (l, &slot->funcs) { | 917 | list_for_each_entry(func, &slot->funcs, sibling) { |
1126 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1127 | |||
1128 | if (func->flags & FUNC_HAS_STA) { | 918 | if (func->flags & FUNC_HAS_STA) { |
1129 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); | 919 | status = acpi_evaluate_integer(func->handle, "_STA", NULL, &sta); |
1130 | if (ACPI_SUCCESS(status) && sta) | 920 | if (ACPI_SUCCESS(status) && sta) |
@@ -1152,13 +942,10 @@ int acpiphp_eject_slot(struct acpiphp_slot *slot) | |||
1152 | { | 942 | { |
1153 | acpi_status status; | 943 | acpi_status status; |
1154 | struct acpiphp_func *func; | 944 | struct acpiphp_func *func; |
1155 | struct list_head *l; | ||
1156 | struct acpi_object_list arg_list; | 945 | struct acpi_object_list arg_list; |
1157 | union acpi_object arg; | 946 | union acpi_object arg; |
1158 | 947 | ||
1159 | list_for_each (l, &slot->funcs) { | 948 | list_for_each_entry(func, &slot->funcs, sibling) { |
1160 | func = list_entry(l, struct acpiphp_func, sibling); | ||
1161 | |||
1162 | /* We don't want to call _EJ0 on non-existing functions. */ | 949 | /* We don't want to call _EJ0 on non-existing functions. */ |
1163 | if ((func->flags & FUNC_HAS_EJ0)) { | 950 | if ((func->flags & FUNC_HAS_EJ0)) { |
1164 | /* _EJ0 method take one argument */ | 951 | /* _EJ0 method take one argument */ |
@@ -1275,7 +1062,6 @@ static int acpiphp_configure_bridge (acpi_handle handle) | |||
1275 | acpiphp_sanitize_bus(bus); | 1062 | acpiphp_sanitize_bus(bus); |
1276 | acpiphp_set_hpp_values(bus); | 1063 | acpiphp_set_hpp_values(bus); |
1277 | pci_enable_bridges(bus); | 1064 | pci_enable_bridges(bus); |
1278 | acpiphp_configure_ioapics(handle); | ||
1279 | return 0; | 1065 | return 0; |
1280 | } | 1066 | } |
1281 | 1067 | ||
@@ -1542,7 +1328,7 @@ int __init acpiphp_get_num_slots(void) | |||
1542 | struct acpiphp_bridge *bridge; | 1328 | struct acpiphp_bridge *bridge; |
1543 | int num_slots = 0; | 1329 | int num_slots = 0; |
1544 | 1330 | ||
1545 | list_for_each_entry (bridge, &bridge_list, list) { | 1331 | list_for_each_entry(bridge, &bridge_list, list) { |
1546 | dbg("Bus %04x:%02x has %d slot%s\n", | 1332 | dbg("Bus %04x:%02x has %d slot%s\n", |
1547 | pci_domain_nr(bridge->pci_bus), | 1333 | pci_domain_nr(bridge->pci_bus), |
1548 | bridge->pci_bus->number, bridge->nr_slots, | 1334 | bridge->pci_bus->number, bridge->nr_slots, |
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c index 83f337c891a9..c7084f0eca5a 100644 --- a/drivers/pci/hotplug/ibmphp_hpc.c +++ b/drivers/pci/hotplug/ibmphp_hpc.c | |||
@@ -890,7 +890,7 @@ static int poll_hpc(void *data) | |||
890 | msleep(POLL_INTERVAL_SEC * 1000); | 890 | msleep(POLL_INTERVAL_SEC * 1000); |
891 | 891 | ||
892 | if (kthread_should_stop()) | 892 | if (kthread_should_stop()) |
893 | break; | 893 | goto out_sleep; |
894 | 894 | ||
895 | down (&semOperations); | 895 | down (&semOperations); |
896 | 896 | ||
@@ -904,6 +904,7 @@ static int poll_hpc(void *data) | |||
904 | /* give up the hardware semaphore */ | 904 | /* give up the hardware semaphore */ |
905 | up (&semOperations); | 905 | up (&semOperations); |
906 | /* sleep for a short time just for good measure */ | 906 | /* sleep for a short time just for good measure */ |
907 | out_sleep: | ||
907 | msleep(100); | 908 | msleep(100); |
908 | } | 909 | } |
909 | up (&sem_exit); | 910 | up (&sem_exit); |
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 0325d989bb46..38183a534b65 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -68,26 +68,26 @@ static DEFINE_MUTEX(pci_hp_mutex); | |||
68 | static char *pci_bus_speed_strings[] = { | 68 | static char *pci_bus_speed_strings[] = { |
69 | "33 MHz PCI", /* 0x00 */ | 69 | "33 MHz PCI", /* 0x00 */ |
70 | "66 MHz PCI", /* 0x01 */ | 70 | "66 MHz PCI", /* 0x01 */ |
71 | "66 MHz PCIX", /* 0x02 */ | 71 | "66 MHz PCI-X", /* 0x02 */ |
72 | "100 MHz PCIX", /* 0x03 */ | 72 | "100 MHz PCI-X", /* 0x03 */ |
73 | "133 MHz PCIX", /* 0x04 */ | 73 | "133 MHz PCI-X", /* 0x04 */ |
74 | NULL, /* 0x05 */ | 74 | NULL, /* 0x05 */ |
75 | NULL, /* 0x06 */ | 75 | NULL, /* 0x06 */ |
76 | NULL, /* 0x07 */ | 76 | NULL, /* 0x07 */ |
77 | NULL, /* 0x08 */ | 77 | NULL, /* 0x08 */ |
78 | "66 MHz PCIX 266", /* 0x09 */ | 78 | "66 MHz PCI-X 266", /* 0x09 */ |
79 | "100 MHz PCIX 266", /* 0x0a */ | 79 | "100 MHz PCI-X 266", /* 0x0a */ |
80 | "133 MHz PCIX 266", /* 0x0b */ | 80 | "133 MHz PCI-X 266", /* 0x0b */ |
81 | NULL, /* 0x0c */ | 81 | NULL, /* 0x0c */ |
82 | NULL, /* 0x0d */ | 82 | NULL, /* 0x0d */ |
83 | NULL, /* 0x0e */ | 83 | NULL, /* 0x0e */ |
84 | NULL, /* 0x0f */ | 84 | NULL, /* 0x0f */ |
85 | NULL, /* 0x10 */ | 85 | NULL, /* 0x10 */ |
86 | "66 MHz PCIX 533", /* 0x11 */ | 86 | "66 MHz PCI-X 533", /* 0x11 */ |
87 | "100 MHz PCIX 533", /* 0x12 */ | 87 | "100 MHz PCI-X 533", /* 0x12 */ |
88 | "133 MHz PCIX 533", /* 0x13 */ | 88 | "133 MHz PCI-X 533", /* 0x13 */ |
89 | "2.5 GT/s PCI-E", /* 0x14 */ | 89 | "2.5 GT/s PCIe", /* 0x14 */ |
90 | "5.0 GT/s PCI-E", /* 0x15 */ | 90 | "5.0 GT/s PCIe", /* 0x15 */ |
91 | }; | 91 | }; |
92 | 92 | ||
93 | #ifdef CONFIG_HOTPLUG_PCI_CPCI | 93 | #ifdef CONFIG_HOTPLUG_PCI_CPCI |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 3070f77eb56a..4ed76b47b6dc 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -91,7 +91,6 @@ struct controller { | |||
91 | struct slot *slot; | 91 | struct slot *slot; |
92 | wait_queue_head_t queue; /* sleep & wake process */ | 92 | wait_queue_head_t queue; /* sleep & wake process */ |
93 | u32 slot_cap; | 93 | u32 slot_cap; |
94 | u8 cap_base; | ||
95 | struct timer_list poll_timer; | 94 | struct timer_list poll_timer; |
96 | unsigned int cmd_busy:1; | 95 | unsigned int cmd_busy:1; |
97 | unsigned int no_cmd_complete:1; | 96 | unsigned int no_cmd_complete:1; |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 37c8d3d0323e..b09b083011d6 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -87,7 +87,8 @@ static int __init dummy_probe(struct pcie_device *dev) | |||
87 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ | 87 | /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ |
88 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 88 | if (pciehp_get_hp_hw_control_from_firmware(pdev)) |
89 | return -ENODEV; | 89 | return -ENODEV; |
90 | if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP))) | 90 | pos = pci_pcie_cap(pdev); |
91 | if (!pos) | ||
91 | return -ENODEV; | 92 | return -ENODEV; |
92 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); | 93 | pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); |
93 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | 94 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index bc234719b1df..5674b2075bdc 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -72,18 +72,6 @@ static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | |||
72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 72 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
74 | 74 | ||
75 | static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | ||
76 | .set_attention_status = set_attention_status, | ||
77 | .enable_slot = enable_slot, | ||
78 | .disable_slot = disable_slot, | ||
79 | .get_power_status = get_power_status, | ||
80 | .get_attention_status = get_attention_status, | ||
81 | .get_latch_status = get_latch_status, | ||
82 | .get_adapter_status = get_adapter_status, | ||
83 | .get_max_bus_speed = get_max_bus_speed, | ||
84 | .get_cur_bus_speed = get_cur_bus_speed, | ||
85 | }; | ||
86 | |||
87 | /** | 75 | /** |
88 | * release_slot - free up the memory used by a slot | 76 | * release_slot - free up the memory used by a slot |
89 | * @hotplug_slot: slot to free | 77 | * @hotplug_slot: slot to free |
@@ -95,6 +83,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
95 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 83 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
96 | __func__, hotplug_slot_name(hotplug_slot)); | 84 | __func__, hotplug_slot_name(hotplug_slot)); |
97 | 85 | ||
86 | kfree(hotplug_slot->ops); | ||
98 | kfree(hotplug_slot->info); | 87 | kfree(hotplug_slot->info); |
99 | kfree(hotplug_slot); | 88 | kfree(hotplug_slot); |
100 | } | 89 | } |
@@ -104,6 +93,7 @@ static int init_slot(struct controller *ctrl) | |||
104 | struct slot *slot = ctrl->slot; | 93 | struct slot *slot = ctrl->slot; |
105 | struct hotplug_slot *hotplug = NULL; | 94 | struct hotplug_slot *hotplug = NULL; |
106 | struct hotplug_slot_info *info = NULL; | 95 | struct hotplug_slot_info *info = NULL; |
96 | struct hotplug_slot_ops *ops = NULL; | ||
107 | char name[SLOT_NAME_SIZE]; | 97 | char name[SLOT_NAME_SIZE]; |
108 | int retval = -ENOMEM; | 98 | int retval = -ENOMEM; |
109 | 99 | ||
@@ -115,11 +105,28 @@ static int init_slot(struct controller *ctrl) | |||
115 | if (!info) | 105 | if (!info) |
116 | goto out; | 106 | goto out; |
117 | 107 | ||
108 | /* Setup hotplug slot ops */ | ||
109 | ops = kzalloc(sizeof(*ops), GFP_KERNEL); | ||
110 | if (!ops) | ||
111 | goto out; | ||
112 | ops->enable_slot = enable_slot; | ||
113 | ops->disable_slot = disable_slot; | ||
114 | ops->get_power_status = get_power_status; | ||
115 | ops->get_adapter_status = get_adapter_status; | ||
116 | ops->get_max_bus_speed = get_max_bus_speed; | ||
117 | ops->get_cur_bus_speed = get_cur_bus_speed; | ||
118 | if (MRL_SENS(ctrl)) | ||
119 | ops->get_latch_status = get_latch_status; | ||
120 | if (ATTN_LED(ctrl)) { | ||
121 | ops->get_attention_status = get_attention_status; | ||
122 | ops->set_attention_status = set_attention_status; | ||
123 | } | ||
124 | |||
118 | /* register this slot with the hotplug pci core */ | 125 | /* register this slot with the hotplug pci core */ |
119 | hotplug->info = info; | 126 | hotplug->info = info; |
120 | hotplug->private = slot; | 127 | hotplug->private = slot; |
121 | hotplug->release = &release_slot; | 128 | hotplug->release = &release_slot; |
122 | hotplug->ops = &pciehp_hotplug_slot_ops; | 129 | hotplug->ops = ops; |
123 | slot->hotplug_slot = hotplug; | 130 | slot->hotplug_slot = hotplug; |
124 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); | 131 | snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); |
125 | 132 | ||
@@ -128,17 +135,12 @@ static int init_slot(struct controller *ctrl) | |||
128 | ctrl->pcie->port->subordinate->number, PSN(ctrl)); | 135 | ctrl->pcie->port->subordinate->number, PSN(ctrl)); |
129 | retval = pci_hp_register(hotplug, | 136 | retval = pci_hp_register(hotplug, |
130 | ctrl->pcie->port->subordinate, 0, name); | 137 | ctrl->pcie->port->subordinate, 0, name); |
131 | if (retval) { | 138 | if (retval) |
132 | ctrl_err(ctrl, | 139 | ctrl_err(ctrl, |
133 | "pci_hp_register failed with error %d\n", retval); | 140 | "pci_hp_register failed with error %d\n", retval); |
134 | goto out; | ||
135 | } | ||
136 | get_power_status(hotplug, &info->power_status); | ||
137 | get_attention_status(hotplug, &info->attention_status); | ||
138 | get_latch_status(hotplug, &info->latch_status); | ||
139 | get_adapter_status(hotplug, &info->adapter_status); | ||
140 | out: | 141 | out: |
141 | if (retval) { | 142 | if (retval) { |
143 | kfree(ops); | ||
142 | kfree(info); | 144 | kfree(info); |
143 | kfree(hotplug); | 145 | kfree(hotplug); |
144 | } | 146 | } |
@@ -160,12 +162,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
160 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 162 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
161 | __func__, slot_name(slot)); | 163 | __func__, slot_name(slot)); |
162 | 164 | ||
163 | hotplug_slot->info->attention_status = status; | 165 | return pciehp_set_attention_status(slot, status); |
164 | |||
165 | if (ATTN_LED(slot->ctrl)) | ||
166 | pciehp_set_attention_status(slot, status); | ||
167 | |||
168 | return 0; | ||
169 | } | 166 | } |
170 | 167 | ||
171 | 168 | ||
@@ -193,92 +190,62 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
193 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) | 190 | static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) |
194 | { | 191 | { |
195 | struct slot *slot = hotplug_slot->private; | 192 | struct slot *slot = hotplug_slot->private; |
196 | int retval; | ||
197 | 193 | ||
198 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 194 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
199 | __func__, slot_name(slot)); | 195 | __func__, slot_name(slot)); |
200 | 196 | ||
201 | retval = pciehp_get_power_status(slot, value); | 197 | return pciehp_get_power_status(slot, value); |
202 | if (retval < 0) | ||
203 | *value = hotplug_slot->info->power_status; | ||
204 | |||
205 | return 0; | ||
206 | } | 198 | } |
207 | 199 | ||
208 | static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) | 200 | static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) |
209 | { | 201 | { |
210 | struct slot *slot = hotplug_slot->private; | 202 | struct slot *slot = hotplug_slot->private; |
211 | int retval; | ||
212 | 203 | ||
213 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 204 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
214 | __func__, slot_name(slot)); | 205 | __func__, slot_name(slot)); |
215 | 206 | ||
216 | retval = pciehp_get_attention_status(slot, value); | 207 | return pciehp_get_attention_status(slot, value); |
217 | if (retval < 0) | ||
218 | *value = hotplug_slot->info->attention_status; | ||
219 | |||
220 | return 0; | ||
221 | } | 208 | } |
222 | 209 | ||
223 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) | 210 | static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) |
224 | { | 211 | { |
225 | struct slot *slot = hotplug_slot->private; | 212 | struct slot *slot = hotplug_slot->private; |
226 | int retval; | ||
227 | 213 | ||
228 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 214 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
229 | __func__, slot_name(slot)); | 215 | __func__, slot_name(slot)); |
230 | 216 | ||
231 | retval = pciehp_get_latch_status(slot, value); | 217 | return pciehp_get_latch_status(slot, value); |
232 | if (retval < 0) | ||
233 | *value = hotplug_slot->info->latch_status; | ||
234 | |||
235 | return 0; | ||
236 | } | 218 | } |
237 | 219 | ||
238 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) | 220 | static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) |
239 | { | 221 | { |
240 | struct slot *slot = hotplug_slot->private; | 222 | struct slot *slot = hotplug_slot->private; |
241 | int retval; | ||
242 | 223 | ||
243 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 224 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
244 | __func__, slot_name(slot)); | 225 | __func__, slot_name(slot)); |
245 | 226 | ||
246 | retval = pciehp_get_adapter_status(slot, value); | 227 | return pciehp_get_adapter_status(slot, value); |
247 | if (retval < 0) | ||
248 | *value = hotplug_slot->info->adapter_status; | ||
249 | |||
250 | return 0; | ||
251 | } | 228 | } |
252 | 229 | ||
253 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, | 230 | static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, |
254 | enum pci_bus_speed *value) | 231 | enum pci_bus_speed *value) |
255 | { | 232 | { |
256 | struct slot *slot = hotplug_slot->private; | 233 | struct slot *slot = hotplug_slot->private; |
257 | int retval; | ||
258 | 234 | ||
259 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 235 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
260 | __func__, slot_name(slot)); | 236 | __func__, slot_name(slot)); |
261 | 237 | ||
262 | retval = pciehp_get_max_link_speed(slot, value); | 238 | return pciehp_get_max_link_speed(slot, value); |
263 | if (retval < 0) | ||
264 | *value = PCI_SPEED_UNKNOWN; | ||
265 | |||
266 | return 0; | ||
267 | } | 239 | } |
268 | 240 | ||
269 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) | 241 | static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) |
270 | { | 242 | { |
271 | struct slot *slot = hotplug_slot->private; | 243 | struct slot *slot = hotplug_slot->private; |
272 | int retval; | ||
273 | 244 | ||
274 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", | 245 | ctrl_dbg(slot->ctrl, "%s: physical_slot = %s\n", |
275 | __func__, slot_name(slot)); | 246 | __func__, slot_name(slot)); |
276 | 247 | ||
277 | retval = pciehp_get_cur_link_speed(slot, value); | 248 | return pciehp_get_cur_link_speed(slot, value); |
278 | if (retval < 0) | ||
279 | *value = PCI_SPEED_UNKNOWN; | ||
280 | |||
281 | return 0; | ||
282 | } | 249 | } |
283 | 250 | ||
284 | static int pciehp_probe(struct pcie_device *dev) | 251 | static int pciehp_probe(struct pcie_device *dev) |
@@ -286,14 +253,13 @@ static int pciehp_probe(struct pcie_device *dev) | |||
286 | int rc; | 253 | int rc; |
287 | struct controller *ctrl; | 254 | struct controller *ctrl; |
288 | struct slot *slot; | 255 | struct slot *slot; |
289 | u8 value; | 256 | u8 occupied, poweron; |
290 | struct pci_dev *pdev = dev->port; | ||
291 | 257 | ||
292 | if (pciehp_force) | 258 | if (pciehp_force) |
293 | dev_info(&dev->device, | 259 | dev_info(&dev->device, |
294 | "Bypassing BIOS check for pciehp use on %s\n", | 260 | "Bypassing BIOS check for pciehp use on %s\n", |
295 | pci_name(pdev)); | 261 | pci_name(dev->port)); |
296 | else if (pciehp_get_hp_hw_control_from_firmware(pdev)) | 262 | else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) |
297 | goto err_out_none; | 263 | goto err_out_none; |
298 | 264 | ||
299 | ctrl = pcie_init(dev); | 265 | ctrl = pcie_init(dev); |
@@ -318,23 +284,18 @@ static int pciehp_probe(struct pcie_device *dev) | |||
318 | rc = pcie_init_notification(ctrl); | 284 | rc = pcie_init_notification(ctrl); |
319 | if (rc) { | 285 | if (rc) { |
320 | ctrl_err(ctrl, "Notification initialization failed\n"); | 286 | ctrl_err(ctrl, "Notification initialization failed\n"); |
321 | goto err_out_release_ctlr; | 287 | goto err_out_free_ctrl_slot; |
322 | } | 288 | } |
323 | 289 | ||
324 | /* Check if slot is occupied */ | 290 | /* Check if slot is occupied */ |
325 | slot = ctrl->slot; | 291 | slot = ctrl->slot; |
326 | pciehp_get_adapter_status(slot, &value); | 292 | pciehp_get_adapter_status(slot, &occupied); |
327 | if (value) { | 293 | pciehp_get_power_status(slot, &poweron); |
328 | if (pciehp_force) | 294 | if (occupied && pciehp_force) |
329 | pciehp_enable_slot(slot); | 295 | pciehp_enable_slot(slot); |
330 | } else { | 296 | /* If empty slot's power status is on, turn power off */ |
331 | /* Power off slot if not occupied */ | 297 | if (!occupied && poweron && POWER_CTRL(ctrl)) |
332 | if (POWER_CTRL(ctrl)) { | 298 | pciehp_power_off_slot(slot); |
333 | rc = pciehp_power_off_slot(slot); | ||
334 | if (rc) | ||
335 | goto err_out_free_ctrl_slot; | ||
336 | } | ||
337 | } | ||
338 | 299 | ||
339 | return 0; | 300 | return 0; |
340 | 301 | ||
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 84487d126e4d..d6ac1b261dd9 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -142,23 +142,9 @@ u8 pciehp_handle_power_fault(struct slot *p_slot) | |||
142 | 142 | ||
143 | /* power fault */ | 143 | /* power fault */ |
144 | ctrl_dbg(ctrl, "Power fault interrupt received\n"); | 144 | ctrl_dbg(ctrl, "Power fault interrupt received\n"); |
145 | 145 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); | |
146 | if (!pciehp_query_power_fault(p_slot)) { | 146 | event_type = INT_POWER_FAULT; |
147 | /* | 147 | ctrl_info(ctrl, "Power fault bit %x set\n", 0); |
148 | * power fault Cleared | ||
149 | */ | ||
150 | ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n", | ||
151 | slot_name(p_slot)); | ||
152 | event_type = INT_POWER_FAULT_CLEAR; | ||
153 | } else { | ||
154 | /* | ||
155 | * power fault | ||
156 | */ | ||
157 | ctrl_info(ctrl, "Power fault on Slot(%s)\n", slot_name(p_slot)); | ||
158 | event_type = INT_POWER_FAULT; | ||
159 | ctrl_info(ctrl, "Power fault bit %x set\n", 0); | ||
160 | } | ||
161 | |||
162 | queue_interrupt_event(p_slot, event_type); | 148 | queue_interrupt_event(p_slot, event_type); |
163 | 149 | ||
164 | return 1; | 150 | return 1; |
@@ -224,13 +210,12 @@ static int board_added(struct slot *p_slot) | |||
224 | retval = pciehp_check_link_status(ctrl); | 210 | retval = pciehp_check_link_status(ctrl); |
225 | if (retval) { | 211 | if (retval) { |
226 | ctrl_err(ctrl, "Failed to check link status\n"); | 212 | ctrl_err(ctrl, "Failed to check link status\n"); |
227 | set_slot_off(ctrl, p_slot); | 213 | goto err_exit; |
228 | return retval; | ||
229 | } | 214 | } |
230 | 215 | ||
231 | /* Check for a power fault */ | 216 | /* Check for a power fault */ |
232 | if (pciehp_query_power_fault(p_slot)) { | 217 | if (ctrl->power_fault_detected || pciehp_query_power_fault(p_slot)) { |
233 | ctrl_dbg(ctrl, "Power fault detected\n"); | 218 | ctrl_err(ctrl, "Power fault on slot %s\n", slot_name(p_slot)); |
234 | retval = -EIO; | 219 | retval = -EIO; |
235 | goto err_exit; | 220 | goto err_exit; |
236 | } | 221 | } |
@@ -363,25 +348,6 @@ void pciehp_queue_pushbutton_work(struct work_struct *work) | |||
363 | mutex_unlock(&p_slot->lock); | 348 | mutex_unlock(&p_slot->lock); |
364 | } | 349 | } |
365 | 350 | ||
366 | static int update_slot_info(struct slot *slot) | ||
367 | { | ||
368 | struct hotplug_slot_info *info; | ||
369 | int result; | ||
370 | |||
371 | info = kmalloc(sizeof(*info), GFP_KERNEL); | ||
372 | if (!info) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | pciehp_get_power_status(slot, &info->power_status); | ||
376 | pciehp_get_attention_status(slot, &info->attention_status); | ||
377 | pciehp_get_latch_status(slot, &info->latch_status); | ||
378 | pciehp_get_adapter_status(slot, &info->adapter_status); | ||
379 | |||
380 | result = pci_hp_change_slot_info(slot->hotplug_slot, info); | ||
381 | kfree (info); | ||
382 | return result; | ||
383 | } | ||
384 | |||
385 | /* | 351 | /* |
386 | * Note: This function must be called with slot->lock held | 352 | * Note: This function must be called with slot->lock held |
387 | */ | 353 | */ |
@@ -442,7 +408,6 @@ static void handle_button_press_event(struct slot *p_slot) | |||
442 | * to hot-add or hot-remove is undergoing | 408 | * to hot-add or hot-remove is undergoing |
443 | */ | 409 | */ |
444 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); | 410 | ctrl_info(ctrl, "Button ignore on Slot(%s)\n", slot_name(p_slot)); |
445 | update_slot_info(p_slot); | ||
446 | break; | 411 | break; |
447 | default: | 412 | default: |
448 | ctrl_warn(ctrl, "Not a valid state\n"); | 413 | ctrl_warn(ctrl, "Not a valid state\n"); |
@@ -500,11 +465,9 @@ static void interrupt_event_handler(struct work_struct *work) | |||
500 | if (!HP_SUPR_RM(ctrl)) | 465 | if (!HP_SUPR_RM(ctrl)) |
501 | break; | 466 | break; |
502 | ctrl_dbg(ctrl, "Surprise Removal\n"); | 467 | ctrl_dbg(ctrl, "Surprise Removal\n"); |
503 | update_slot_info(p_slot); | ||
504 | handle_surprise_event(p_slot); | 468 | handle_surprise_event(p_slot); |
505 | break; | 469 | break; |
506 | default: | 470 | default: |
507 | update_slot_info(p_slot); | ||
508 | break; | 471 | break; |
509 | } | 472 | } |
510 | mutex_unlock(&p_slot->lock); | 473 | mutex_unlock(&p_slot->lock); |
@@ -547,9 +510,6 @@ int pciehp_enable_slot(struct slot *p_slot) | |||
547 | if (rc) { | 510 | if (rc) { |
548 | pciehp_get_latch_status(p_slot, &getstatus); | 511 | pciehp_get_latch_status(p_slot, &getstatus); |
549 | } | 512 | } |
550 | |||
551 | update_slot_info(p_slot); | ||
552 | |||
553 | return rc; | 513 | return rc; |
554 | } | 514 | } |
555 | 515 | ||
@@ -590,10 +550,7 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
590 | } | 550 | } |
591 | } | 551 | } |
592 | 552 | ||
593 | ret = remove_board(p_slot); | 553 | return remove_board(p_slot); |
594 | update_slot_info(p_slot); | ||
595 | |||
596 | return ret; | ||
597 | } | 554 | } |
598 | 555 | ||
599 | int pciehp_sysfs_enable_slot(struct slot *p_slot) | 556 | int pciehp_sysfs_enable_slot(struct slot *p_slot) |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9ef4605c1ef6..10040d58c8ef 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -45,25 +45,25 @@ static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); | |||
45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) | 45 | static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) |
46 | { | 46 | { |
47 | struct pci_dev *dev = ctrl->pcie->port; | 47 | struct pci_dev *dev = ctrl->pcie->port; |
48 | return pci_read_config_word(dev, ctrl->cap_base + reg, value); | 48 | return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) | 51 | static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) |
52 | { | 52 | { |
53 | struct pci_dev *dev = ctrl->pcie->port; | 53 | struct pci_dev *dev = ctrl->pcie->port; |
54 | return pci_read_config_dword(dev, ctrl->cap_base + reg, value); | 54 | return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) | 57 | static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) |
58 | { | 58 | { |
59 | struct pci_dev *dev = ctrl->pcie->port; | 59 | struct pci_dev *dev = ctrl->pcie->port; |
60 | return pci_write_config_word(dev, ctrl->cap_base + reg, value); | 60 | return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value); |
61 | } | 61 | } |
62 | 62 | ||
63 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) | 63 | static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) |
64 | { | 64 | { |
65 | struct pci_dev *dev = ctrl->pcie->port; | 65 | struct pci_dev *dev = ctrl->pcie->port; |
66 | return pci_write_config_dword(dev, ctrl->cap_base + reg, value); | 66 | return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value); |
67 | } | 67 | } |
68 | 68 | ||
69 | /* Power Control Command */ | 69 | /* Power Control Command */ |
@@ -318,8 +318,8 @@ int pciehp_get_attention_status(struct slot *slot, u8 *status) | |||
318 | return retval; | 318 | return retval; |
319 | } | 319 | } |
320 | 320 | ||
321 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", | 321 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__, |
322 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); | 322 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
323 | 323 | ||
324 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; | 324 | atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; |
325 | 325 | ||
@@ -356,8 +356,8 @@ int pciehp_get_power_status(struct slot *slot, u8 *status) | |||
356 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); | 356 | ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); |
357 | return retval; | 357 | return retval; |
358 | } | 358 | } |
359 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", | 359 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__, |
360 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); | 360 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl); |
361 | 361 | ||
362 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; | 362 | pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; |
363 | 363 | ||
@@ -427,27 +427,24 @@ int pciehp_set_attention_status(struct slot *slot, u8 value) | |||
427 | struct controller *ctrl = slot->ctrl; | 427 | struct controller *ctrl = slot->ctrl; |
428 | u16 slot_cmd; | 428 | u16 slot_cmd; |
429 | u16 cmd_mask; | 429 | u16 cmd_mask; |
430 | int rc; | ||
431 | 430 | ||
432 | cmd_mask = PCI_EXP_SLTCTL_AIC; | 431 | cmd_mask = PCI_EXP_SLTCTL_AIC; |
433 | switch (value) { | 432 | switch (value) { |
434 | case 0 : /* turn off */ | 433 | case 0 : /* turn off */ |
435 | slot_cmd = 0x00C0; | 434 | slot_cmd = 0x00C0; |
436 | break; | 435 | break; |
437 | case 1: /* turn on */ | 436 | case 1: /* turn on */ |
438 | slot_cmd = 0x0040; | 437 | slot_cmd = 0x0040; |
439 | break; | 438 | break; |
440 | case 2: /* turn blink */ | 439 | case 2: /* turn blink */ |
441 | slot_cmd = 0x0080; | 440 | slot_cmd = 0x0080; |
442 | break; | 441 | break; |
443 | default: | 442 | default: |
444 | return -1; | 443 | return -EINVAL; |
445 | } | 444 | } |
446 | rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 445 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
447 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 446 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
448 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 447 | return pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
449 | |||
450 | return rc; | ||
451 | } | 448 | } |
452 | 449 | ||
453 | void pciehp_green_led_on(struct slot *slot) | 450 | void pciehp_green_led_on(struct slot *slot) |
@@ -459,8 +456,8 @@ void pciehp_green_led_on(struct slot *slot) | |||
459 | slot_cmd = 0x0100; | 456 | slot_cmd = 0x0100; |
460 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 457 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
461 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 458 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
462 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 459 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
463 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 460 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
464 | } | 461 | } |
465 | 462 | ||
466 | void pciehp_green_led_off(struct slot *slot) | 463 | void pciehp_green_led_off(struct slot *slot) |
@@ -472,8 +469,8 @@ void pciehp_green_led_off(struct slot *slot) | |||
472 | slot_cmd = 0x0300; | 469 | slot_cmd = 0x0300; |
473 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 470 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
474 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 471 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
475 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 472 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
476 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 473 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
477 | } | 474 | } |
478 | 475 | ||
479 | void pciehp_green_led_blink(struct slot *slot) | 476 | void pciehp_green_led_blink(struct slot *slot) |
@@ -485,8 +482,8 @@ void pciehp_green_led_blink(struct slot *slot) | |||
485 | slot_cmd = 0x0200; | 482 | slot_cmd = 0x0200; |
486 | cmd_mask = PCI_EXP_SLTCTL_PIC; | 483 | cmd_mask = PCI_EXP_SLTCTL_PIC; |
487 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 484 | pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
488 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 485 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
489 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 486 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
490 | } | 487 | } |
491 | 488 | ||
492 | int pciehp_power_on_slot(struct slot * slot) | 489 | int pciehp_power_on_slot(struct slot * slot) |
@@ -514,97 +511,38 @@ int pciehp_power_on_slot(struct slot * slot) | |||
514 | return retval; | 511 | return retval; |
515 | } | 512 | } |
516 | } | 513 | } |
514 | ctrl->power_fault_detected = 0; | ||
517 | 515 | ||
518 | slot_cmd = POWER_ON; | 516 | slot_cmd = POWER_ON; |
519 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 517 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
520 | if (!pciehp_poll_mode) { | ||
521 | /* Enable power fault detection turned off at power off time */ | ||
522 | slot_cmd |= PCI_EXP_SLTCTL_PFDE; | ||
523 | cmd_mask |= PCI_EXP_SLTCTL_PFDE; | ||
524 | } | ||
525 | |||
526 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 518 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
527 | if (retval) { | 519 | if (retval) { |
528 | ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); | 520 | ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); |
529 | return retval; | 521 | return retval; |
530 | } | 522 | } |
531 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 523 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
532 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 524 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
533 | 525 | ||
534 | ctrl->power_fault_detected = 0; | ||
535 | return retval; | 526 | return retval; |
536 | } | 527 | } |
537 | 528 | ||
538 | static inline int pcie_mask_bad_dllp(struct controller *ctrl) | ||
539 | { | ||
540 | struct pci_dev *dev = ctrl->pcie->port; | ||
541 | int pos; | ||
542 | u32 reg; | ||
543 | |||
544 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
545 | if (!pos) | ||
546 | return 0; | ||
547 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
548 | if (reg & PCI_ERR_COR_BAD_DLLP) | ||
549 | return 0; | ||
550 | reg |= PCI_ERR_COR_BAD_DLLP; | ||
551 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
552 | return 1; | ||
553 | } | ||
554 | |||
555 | static inline void pcie_unmask_bad_dllp(struct controller *ctrl) | ||
556 | { | ||
557 | struct pci_dev *dev = ctrl->pcie->port; | ||
558 | u32 reg; | ||
559 | int pos; | ||
560 | |||
561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
562 | if (!pos) | ||
563 | return; | ||
564 | pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, ®); | ||
565 | if (!(reg & PCI_ERR_COR_BAD_DLLP)) | ||
566 | return; | ||
567 | reg &= ~PCI_ERR_COR_BAD_DLLP; | ||
568 | pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg); | ||
569 | } | ||
570 | |||
571 | int pciehp_power_off_slot(struct slot * slot) | 529 | int pciehp_power_off_slot(struct slot * slot) |
572 | { | 530 | { |
573 | struct controller *ctrl = slot->ctrl; | 531 | struct controller *ctrl = slot->ctrl; |
574 | u16 slot_cmd; | 532 | u16 slot_cmd; |
575 | u16 cmd_mask; | 533 | u16 cmd_mask; |
576 | int retval = 0; | 534 | int retval; |
577 | int changed; | ||
578 | |||
579 | /* | ||
580 | * Set Bad DLLP Mask bit in Correctable Error Mask | ||
581 | * Register. This is the workaround against Bad DLLP error | ||
582 | * that sometimes happens during turning power off the slot | ||
583 | * which conforms to PCI Express 1.0a spec. | ||
584 | */ | ||
585 | changed = pcie_mask_bad_dllp(ctrl); | ||
586 | 535 | ||
587 | slot_cmd = POWER_OFF; | 536 | slot_cmd = POWER_OFF; |
588 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 537 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
589 | if (!pciehp_poll_mode) { | ||
590 | /* Disable power fault detection */ | ||
591 | slot_cmd &= ~PCI_EXP_SLTCTL_PFDE; | ||
592 | cmd_mask |= PCI_EXP_SLTCTL_PFDE; | ||
593 | } | ||
594 | |||
595 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 538 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
596 | if (retval) { | 539 | if (retval) { |
597 | ctrl_err(ctrl, "Write command failed!\n"); | 540 | ctrl_err(ctrl, "Write command failed!\n"); |
598 | retval = -1; | 541 | return retval; |
599 | goto out; | ||
600 | } | 542 | } |
601 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", | 543 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
602 | __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); | 544 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
603 | out: | 545 | return 0; |
604 | if (changed) | ||
605 | pcie_unmask_bad_dllp(ctrl); | ||
606 | |||
607 | return retval; | ||
608 | } | 546 | } |
609 | 547 | ||
610 | static irqreturn_t pcie_isr(int irq, void *dev_id) | 548 | static irqreturn_t pcie_isr(int irq, void *dev_id) |
@@ -840,11 +778,19 @@ int pcie_enable_notification(struct controller *ctrl) | |||
840 | { | 778 | { |
841 | u16 cmd, mask; | 779 | u16 cmd, mask; |
842 | 780 | ||
781 | /* | ||
782 | * TBD: Power fault detected software notification support. | ||
783 | * | ||
784 | * Power fault detected software notification is not enabled | ||
785 | * now, because it caused power fault detected interrupt storm | ||
786 | * on some machines. On those machines, power fault detected | ||
787 | * bit in the slot status register was set again immediately | ||
788 | * when it is cleared in the interrupt service routine, and | ||
789 | * next power fault detected interrupt was notified again. | ||
790 | */ | ||
843 | cmd = PCI_EXP_SLTCTL_PDCE; | 791 | cmd = PCI_EXP_SLTCTL_PDCE; |
844 | if (ATTN_BUTTN(ctrl)) | 792 | if (ATTN_BUTTN(ctrl)) |
845 | cmd |= PCI_EXP_SLTCTL_ABPE; | 793 | cmd |= PCI_EXP_SLTCTL_ABPE; |
846 | if (POWER_CTRL(ctrl)) | ||
847 | cmd |= PCI_EXP_SLTCTL_PFDE; | ||
848 | if (MRL_SENS(ctrl)) | 794 | if (MRL_SENS(ctrl)) |
849 | cmd |= PCI_EXP_SLTCTL_MRLSCE; | 795 | cmd |= PCI_EXP_SLTCTL_MRLSCE; |
850 | if (!pciehp_poll_mode) | 796 | if (!pciehp_poll_mode) |
@@ -866,7 +812,8 @@ static void pcie_disable_notification(struct controller *ctrl) | |||
866 | u16 mask; | 812 | u16 mask; |
867 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | | 813 | mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | |
868 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | | 814 | PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | |
869 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); | 815 | PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE | |
816 | PCI_EXP_SLTCTL_DLLSCE); | ||
870 | if (pcie_write_cmd(ctrl, 0, mask)) | 817 | if (pcie_write_cmd(ctrl, 0, mask)) |
871 | ctrl_warn(ctrl, "Cannot disable software notification\n"); | 818 | ctrl_warn(ctrl, "Cannot disable software notification\n"); |
872 | } | 819 | } |
@@ -934,7 +881,8 @@ static inline void dbg_ctrl(struct controller *ctrl) | |||
934 | pdev->subsystem_device); | 881 | pdev->subsystem_device); |
935 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", | 882 | ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", |
936 | pdev->subsystem_vendor); | 883 | pdev->subsystem_vendor); |
937 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base); | 884 | ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", |
885 | pci_pcie_cap(pdev)); | ||
938 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 886 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
939 | if (!pci_resource_len(pdev, i)) | 887 | if (!pci_resource_len(pdev, i)) |
940 | continue; | 888 | continue; |
@@ -978,8 +926,7 @@ struct controller *pcie_init(struct pcie_device *dev) | |||
978 | goto abort; | 926 | goto abort; |
979 | } | 927 | } |
980 | ctrl->pcie = dev; | 928 | ctrl->pcie = dev; |
981 | ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 929 | if (!pci_pcie_cap(pdev)) { |
982 | if (!ctrl->cap_base) { | ||
983 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); | 930 | ctrl_err(ctrl, "Cannot find PCI Express capability\n"); |
984 | goto abort_ctrl; | 931 | goto abort_ctrl; |
985 | } | 932 | } |
diff --git a/drivers/pci/hotplug/pcihp_slot.c b/drivers/pci/hotplug/pcihp_slot.c index cc8ec3aa41a7..80b461c98557 100644 --- a/drivers/pci/hotplug/pcihp_slot.c +++ b/drivers/pci/hotplug/pcihp_slot.c | |||
@@ -43,7 +43,7 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp) | |||
43 | * Perhaps we *should* use default settings for PCIe, but | 43 | * Perhaps we *should* use default settings for PCIe, but |
44 | * pciehp didn't, so we won't either. | 44 | * pciehp didn't, so we won't either. |
45 | */ | 45 | */ |
46 | if (dev->is_pcie) | 46 | if (pci_is_pcie(dev)) |
47 | return; | 47 | return; |
48 | dev_info(&dev->dev, "using default PCI settings\n"); | 48 | dev_info(&dev->dev, "using default PCI settings\n"); |
49 | hpp = &pci_default_type0; | 49 | hpp = &pci_default_type0; |
@@ -102,7 +102,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) | |||
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Find PCI Express capability */ | 104 | /* Find PCI Express capability */ |
105 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 105 | pos = pci_pcie_cap(dev); |
106 | if (!pos) | 106 | if (!pos) |
107 | return; | 107 | return; |
108 | 108 | ||
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 9261327b49f3..8d6159426311 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1611,7 +1611,7 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev, | |||
1611 | return ret; | 1611 | return ret; |
1612 | parent = parent->bus->self; | 1612 | parent = parent->bus->self; |
1613 | } | 1613 | } |
1614 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | 1614 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ |
1615 | return domain_context_mapping_one(domain, | 1615 | return domain_context_mapping_one(domain, |
1616 | pci_domain_nr(tmp->subordinate), | 1616 | pci_domain_nr(tmp->subordinate), |
1617 | tmp->subordinate->number, 0, | 1617 | tmp->subordinate->number, 0, |
@@ -1651,7 +1651,7 @@ static int domain_context_mapped(struct pci_dev *pdev) | |||
1651 | return ret; | 1651 | return ret; |
1652 | parent = parent->bus->self; | 1652 | parent = parent->bus->self; |
1653 | } | 1653 | } |
1654 | if (tmp->is_pcie) | 1654 | if (pci_is_pcie(tmp)) |
1655 | return device_context_mapped(iommu, tmp->subordinate->number, | 1655 | return device_context_mapped(iommu, tmp->subordinate->number, |
1656 | 0); | 1656 | 0); |
1657 | else | 1657 | else |
@@ -1821,7 +1821,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
1821 | 1821 | ||
1822 | dev_tmp = pci_find_upstream_pcie_bridge(pdev); | 1822 | dev_tmp = pci_find_upstream_pcie_bridge(pdev); |
1823 | if (dev_tmp) { | 1823 | if (dev_tmp) { |
1824 | if (dev_tmp->is_pcie) { | 1824 | if (pci_is_pcie(dev_tmp)) { |
1825 | bus = dev_tmp->subordinate->number; | 1825 | bus = dev_tmp->subordinate->number; |
1826 | devfn = 0; | 1826 | devfn = 0; |
1827 | } else { | 1827 | } else { |
@@ -2182,7 +2182,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) | |||
2182 | * the 1:1 domain, just in _case_ one of their siblings turns out | 2182 | * the 1:1 domain, just in _case_ one of their siblings turns out |
2183 | * not to be able to map all of memory. | 2183 | * not to be able to map all of memory. |
2184 | */ | 2184 | */ |
2185 | if (!pdev->is_pcie) { | 2185 | if (!pci_is_pcie(pdev)) { |
2186 | if (!pci_is_root_bus(pdev->bus)) | 2186 | if (!pci_is_root_bus(pdev->bus)) |
2187 | return 0; | 2187 | return 0; |
2188 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) | 2188 | if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) |
@@ -3319,7 +3319,7 @@ static void iommu_detach_dependent_devices(struct intel_iommu *iommu, | |||
3319 | parent->devfn); | 3319 | parent->devfn); |
3320 | parent = parent->bus->self; | 3320 | parent = parent->bus->self; |
3321 | } | 3321 | } |
3322 | if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */ | 3322 | if (pci_is_pcie(tmp)) /* this is a PCIE-to-PCI bridge */ |
3323 | iommu_detach_dev(iommu, | 3323 | iommu_detach_dev(iommu, |
3324 | tmp->subordinate->number, 0); | 3324 | tmp->subordinate->number, 0); |
3325 | else /* this is a legacy PCI bridge */ | 3325 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c index 3b3658669bee..1487bf2be863 100644 --- a/drivers/pci/intr_remapping.c +++ b/drivers/pci/intr_remapping.c | |||
@@ -520,7 +520,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
520 | return -1; | 520 | return -1; |
521 | 521 | ||
522 | /* PCIe device or Root Complex integrated PCI device */ | 522 | /* PCIe device or Root Complex integrated PCI device */ |
523 | if (dev->is_pcie || !dev->bus->parent) { | 523 | if (pci_is_pcie(dev) || !dev->bus->parent) { |
524 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, | 524 | set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, |
525 | (dev->bus->number << 8) | dev->devfn); | 525 | (dev->bus->number << 8) | dev->devfn); |
526 | return 0; | 526 | return 0; |
@@ -528,7 +528,7 @@ int set_msi_sid(struct irte *irte, struct pci_dev *dev) | |||
528 | 528 | ||
529 | bridge = pci_find_upstream_pcie_bridge(dev); | 529 | bridge = pci_find_upstream_pcie_bridge(dev); |
530 | if (bridge) { | 530 | if (bridge) { |
531 | if (bridge->is_pcie) /* this is a PCIE-to-PCI/PCIX bridge */ | 531 | if (pci_is_pcie(bridge))/* this is a PCIE-to-PCI/PCIX bridge */ |
532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, | 532 | set_irte_sid(irte, SVT_VERIFY_BUS, SQ_ALL_16, |
533 | (bridge->bus->number << 8) | dev->bus->number); | 533 | (bridge->bus->number << 8) | dev->bus->number); |
534 | else /* this is a legacy PCI bridge */ | 534 | else /* this is a legacy PCI bridge */ |
diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c new file mode 100644 index 000000000000..3e0d7b5dd1b9 --- /dev/null +++ b/drivers/pci/ioapic.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * IOAPIC/IOxAPIC/IOSAPIC driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Fujitsu Limited. | ||
5 | * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This driver manages PCI I/O APICs added by hotplug after boot. We try to | ||
14 | * claim all I/O APIC PCI devices, but those present at boot were registered | ||
15 | * when we parsed the ACPI MADT, so we'll fail when we try to re-register | ||
16 | * them. | ||
17 | */ | ||
18 | |||
19 | #include <linux/pci.h> | ||
20 | #include <linux/acpi.h> | ||
21 | #include <acpi/acpi_bus.h> | ||
22 | |||
23 | struct ioapic { | ||
24 | acpi_handle handle; | ||
25 | u32 gsi_base; | ||
26 | }; | ||
27 | |||
28 | static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) | ||
29 | { | ||
30 | acpi_handle handle; | ||
31 | acpi_status status; | ||
32 | unsigned long long gsb; | ||
33 | struct ioapic *ioapic; | ||
34 | u64 addr; | ||
35 | int ret; | ||
36 | char *type; | ||
37 | |||
38 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
39 | if (!handle) | ||
40 | return -EINVAL; | ||
41 | |||
42 | status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); | ||
43 | if (ACPI_FAILURE(status)) | ||
44 | return -EINVAL; | ||
45 | |||
46 | /* | ||
47 | * The previous code in acpiphp evaluated _MAT if _GSB failed, but | ||
48 | * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs. | ||
49 | */ | ||
50 | |||
51 | ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); | ||
52 | if (!ioapic) | ||
53 | return -ENOMEM; | ||
54 | |||
55 | ioapic->handle = handle; | ||
56 | ioapic->gsi_base = (u32) gsb; | ||
57 | |||
58 | if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) | ||
59 | type = "IOAPIC"; | ||
60 | else | ||
61 | type = "IOxAPIC"; | ||
62 | |||
63 | ret = pci_enable_device(dev); | ||
64 | if (ret < 0) | ||
65 | goto exit_free; | ||
66 | |||
67 | pci_set_master(dev); | ||
68 | |||
69 | if (pci_request_region(dev, 0, type)) | ||
70 | goto exit_disable; | ||
71 | |||
72 | addr = pci_resource_start(dev, 0); | ||
73 | if (acpi_register_ioapic(ioapic->handle, addr, ioapic->gsi_base)) | ||
74 | goto exit_release; | ||
75 | |||
76 | pci_set_drvdata(dev, ioapic); | ||
77 | dev_info(&dev->dev, "%s at %#llx, GSI %u\n", type, addr, | ||
78 | ioapic->gsi_base); | ||
79 | return 0; | ||
80 | |||
81 | exit_release: | ||
82 | pci_release_region(dev, 0); | ||
83 | exit_disable: | ||
84 | pci_disable_device(dev); | ||
85 | exit_free: | ||
86 | kfree(ioapic); | ||
87 | return -ENODEV; | ||
88 | } | ||
89 | |||
90 | static void ioapic_remove(struct pci_dev *dev) | ||
91 | { | ||
92 | struct ioapic *ioapic = pci_get_drvdata(dev); | ||
93 | |||
94 | acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base); | ||
95 | pci_release_region(dev, 0); | ||
96 | pci_disable_device(dev); | ||
97 | kfree(ioapic); | ||
98 | } | ||
99 | |||
100 | |||
101 | static struct pci_device_id ioapic_devices[] = { | ||
102 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
103 | PCI_CLASS_SYSTEM_PIC_IOAPIC << 8, 0xffff00, }, | ||
104 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
105 | PCI_CLASS_SYSTEM_PIC_IOXAPIC << 8, 0xffff00, }, | ||
106 | { } | ||
107 | }; | ||
108 | |||
109 | static struct pci_driver ioapic_driver = { | ||
110 | .name = "ioapic", | ||
111 | .id_table = ioapic_devices, | ||
112 | .probe = ioapic_probe, | ||
113 | .remove = __devexit_p(ioapic_remove), | ||
114 | }; | ||
115 | |||
116 | static int __init ioapic_init(void) | ||
117 | { | ||
118 | return pci_register_driver(&ioapic_driver); | ||
119 | } | ||
120 | |||
121 | static void __exit ioapic_exit(void) | ||
122 | { | ||
123 | pci_unregister_driver(&ioapic_driver); | ||
124 | } | ||
125 | |||
126 | module_init(ioapic_init); | ||
127 | module_exit(ioapic_exit); | ||
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index e03fe98f0619..b2a448e19fe6 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -555,7 +555,7 @@ int pci_iov_init(struct pci_dev *dev) | |||
555 | { | 555 | { |
556 | int pos; | 556 | int pos; |
557 | 557 | ||
558 | if (!dev->is_pcie) | 558 | if (!pci_is_pcie(dev)) |
559 | return -ENODEV; | 559 | return -ENODEV; |
560 | 560 | ||
561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); | 561 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 33317df47699..cc617ddd33d0 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -116,7 +116,7 @@ static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) | |||
116 | int ret; | 116 | int ret; |
117 | 117 | ||
118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); | 118 | ret = acpi_pm_device_sleep_wake(&bridge->dev, enable); |
119 | if (!ret || bridge->is_pcie) | 119 | if (!ret || pci_is_pcie(bridge)) |
120 | return; | 120 | return; |
121 | bus = bus->parent; | 121 | bus = bus->parent; |
122 | } | 122 | } |
@@ -131,7 +131,7 @@ static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) | |||
131 | if (acpi_pci_can_wakeup(dev)) | 131 | if (acpi_pci_can_wakeup(dev)) |
132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); | 132 | return acpi_pm_device_sleep_wake(&dev->dev, enable); |
133 | 133 | ||
134 | if (!dev->is_pcie) | 134 | if (!pci_is_pcie(dev)) |
135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); | 135 | acpi_pci_propagate_wakeup_enable(dev->bus, enable); |
136 | 136 | ||
137 | return 0; | 137 | return 0; |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 0f6382f090ee..c5df94e86678 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -74,7 +74,11 @@ static ssize_t local_cpus_show(struct device *dev, | |||
74 | const struct cpumask *mask; | 74 | const struct cpumask *mask; |
75 | int len; | 75 | int len; |
76 | 76 | ||
77 | #ifdef CONFIG_NUMA | ||
78 | mask = cpumask_of_node(dev_to_node(dev)); | ||
79 | #else | ||
77 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 80 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
81 | #endif | ||
78 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); | 82 | len = cpumask_scnprintf(buf, PAGE_SIZE-2, mask); |
79 | buf[len++] = '\n'; | 83 | buf[len++] = '\n'; |
80 | buf[len] = '\0'; | 84 | buf[len] = '\0'; |
@@ -88,7 +92,11 @@ static ssize_t local_cpulist_show(struct device *dev, | |||
88 | const struct cpumask *mask; | 92 | const struct cpumask *mask; |
89 | int len; | 93 | int len; |
90 | 94 | ||
95 | #ifdef CONFIG_NUMA | ||
96 | mask = cpumask_of_node(dev_to_node(dev)); | ||
97 | #else | ||
91 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); | 98 | mask = cpumask_of_pcibus(to_pci_dev(dev)->bus); |
99 | #endif | ||
92 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); | 100 | len = cpulist_scnprintf(buf, PAGE_SIZE-2, mask); |
93 | buf[len++] = '\n'; | 101 | buf[len++] = '\n'; |
94 | buf[len] = '\0'; | 102 | buf[len] = '\0'; |
@@ -176,6 +184,21 @@ numa_node_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
176 | #endif | 184 | #endif |
177 | 185 | ||
178 | static ssize_t | 186 | static ssize_t |
187 | dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
188 | { | ||
189 | struct pci_dev *pdev = to_pci_dev(dev); | ||
190 | |||
191 | return sprintf (buf, "%d\n", fls64(pdev->dma_mask)); | ||
192 | } | ||
193 | |||
194 | static ssize_t | ||
195 | consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr, | ||
196 | char *buf) | ||
197 | { | ||
198 | return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask)); | ||
199 | } | ||
200 | |||
201 | static ssize_t | ||
179 | msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) | 202 | msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) |
180 | { | 203 | { |
181 | struct pci_dev *pdev = to_pci_dev(dev); | 204 | struct pci_dev *pdev = to_pci_dev(dev); |
@@ -306,6 +329,8 @@ struct device_attribute pci_dev_attrs[] = { | |||
306 | #ifdef CONFIG_NUMA | 329 | #ifdef CONFIG_NUMA |
307 | __ATTR_RO(numa_node), | 330 | __ATTR_RO(numa_node), |
308 | #endif | 331 | #endif |
332 | __ATTR_RO(dma_mask_bits), | ||
333 | __ATTR_RO(consistent_dma_mask_bits), | ||
309 | __ATTR(enable, 0600, is_enabled_show, is_enabled_store), | 334 | __ATTR(enable, 0600, is_enabled_show, is_enabled_store), |
310 | __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), | 335 | __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), |
311 | broken_parity_status_show,broken_parity_status_store), | 336 | broken_parity_status_show,broken_parity_status_store), |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 4e4c295a049f..0bc27e059019 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -47,6 +47,15 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; | |||
47 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; | 47 | unsigned long pci_hotplug_io_size = DEFAULT_HOTPLUG_IO_SIZE; |
48 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; | 48 | unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE; |
49 | 49 | ||
50 | /* | ||
51 | * The default CLS is used if arch didn't set CLS explicitly and not | ||
52 | * all pci devices agree on the same value. Arch can override either | ||
53 | * the dfl or actual value as it sees fit. Don't forget this is | ||
54 | * measured in 32-bit words, not bytes. | ||
55 | */ | ||
56 | u8 pci_dfl_cache_line_size __devinitdata = L1_CACHE_BYTES >> 2; | ||
57 | u8 pci_cache_line_size; | ||
58 | |||
50 | /** | 59 | /** |
51 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 60 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
52 | * @bus: pointer to PCI bus structure to search | 61 | * @bus: pointer to PCI bus structure to search |
@@ -373,8 +382,12 @@ pci_find_parent_resource(const struct pci_dev *dev, struct resource *res) | |||
373 | continue; /* Wrong type */ | 382 | continue; /* Wrong type */ |
374 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) | 383 | if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) |
375 | return r; /* Exact match */ | 384 | return r; /* Exact match */ |
376 | if ((res->flags & IORESOURCE_PREFETCH) && !(r->flags & IORESOURCE_PREFETCH)) | 385 | /* We can't insert a non-prefetch resource inside a prefetchable parent .. */ |
377 | best = r; /* Approximating prefetchable by non-prefetchable */ | 386 | if (r->flags & IORESOURCE_PREFETCH) |
387 | continue; | ||
388 | /* .. but we can put a prefetchable resource inside a non-prefetchable one */ | ||
389 | if (!best) | ||
390 | best = r; | ||
378 | } | 391 | } |
379 | return best; | 392 | return best; |
380 | } | 393 | } |
@@ -728,8 +741,8 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
728 | u16 *cap; | 741 | u16 *cap; |
729 | u16 flags; | 742 | u16 flags; |
730 | 743 | ||
731 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 744 | pos = pci_pcie_cap(dev); |
732 | if (pos <= 0) | 745 | if (!pos) |
733 | return 0; | 746 | return 0; |
734 | 747 | ||
735 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); | 748 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
@@ -837,7 +850,7 @@ pci_save_state(struct pci_dev *dev) | |||
837 | int i; | 850 | int i; |
838 | /* XXX: 100% dword access ok here? */ | 851 | /* XXX: 100% dword access ok here? */ |
839 | for (i = 0; i < 16; i++) | 852 | for (i = 0; i < 16; i++) |
840 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 853 | pci_read_config_dword(dev, i * 4, &dev->saved_config_space[i]); |
841 | dev->state_saved = true; | 854 | dev->state_saved = true; |
842 | if ((i = pci_save_pcie_state(dev)) != 0) | 855 | if ((i = pci_save_pcie_state(dev)) != 0) |
843 | return i; | 856 | return i; |
@@ -1202,7 +1215,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) | |||
1202 | 1215 | ||
1203 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); | 1216 | pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); |
1204 | 1217 | ||
1205 | dev_printk(KERN_INFO, &dev->dev, "PME# %s\n", | 1218 | dev_printk(KERN_DEBUG, &dev->dev, "PME# %s\n", |
1206 | enable ? "enabled" : "disabled"); | 1219 | enable ? "enabled" : "disabled"); |
1207 | } | 1220 | } |
1208 | 1221 | ||
@@ -1413,7 +1426,8 @@ void pci_pm_init(struct pci_dev *dev) | |||
1413 | 1426 | ||
1414 | pmc &= PCI_PM_CAP_PME_MASK; | 1427 | pmc &= PCI_PM_CAP_PME_MASK; |
1415 | if (pmc) { | 1428 | if (pmc) { |
1416 | dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n", | 1429 | dev_printk(KERN_DEBUG, &dev->dev, |
1430 | "PME# supported from%s%s%s%s%s\n", | ||
1417 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", | 1431 | (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", |
1418 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", | 1432 | (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", |
1419 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", | 1433 | (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", |
@@ -1510,7 +1524,7 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1510 | u16 ctrl; | 1524 | u16 ctrl; |
1511 | struct pci_dev *bridge; | 1525 | struct pci_dev *bridge; |
1512 | 1526 | ||
1513 | if (!dev->is_pcie || dev->devfn) | 1527 | if (!pci_is_pcie(dev) || dev->devfn) |
1514 | return; | 1528 | return; |
1515 | 1529 | ||
1516 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1530 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); |
@@ -1518,10 +1532,10 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1518 | return; | 1532 | return; |
1519 | 1533 | ||
1520 | bridge = dev->bus->self; | 1534 | bridge = dev->bus->self; |
1521 | if (!bridge || !bridge->is_pcie) | 1535 | if (!bridge || !pci_is_pcie(bridge)) |
1522 | return; | 1536 | return; |
1523 | 1537 | ||
1524 | pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); | 1538 | pos = pci_pcie_cap(bridge); |
1525 | if (!pos) | 1539 | if (!pos) |
1526 | return; | 1540 | return; |
1527 | 1541 | ||
@@ -1536,6 +1550,54 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1536 | bridge->ari_enabled = 1; | 1550 | bridge->ari_enabled = 1; |
1537 | } | 1551 | } |
1538 | 1552 | ||
1553 | static int pci_acs_enable; | ||
1554 | |||
1555 | /** | ||
1556 | * pci_request_acs - ask for ACS to be enabled if supported | ||
1557 | */ | ||
1558 | void pci_request_acs(void) | ||
1559 | { | ||
1560 | pci_acs_enable = 1; | ||
1561 | } | ||
1562 | |||
1563 | /** | ||
1564 | * pci_enable_acs - enable ACS if hardware support it | ||
1565 | * @dev: the PCI device | ||
1566 | */ | ||
1567 | void pci_enable_acs(struct pci_dev *dev) | ||
1568 | { | ||
1569 | int pos; | ||
1570 | u16 cap; | ||
1571 | u16 ctrl; | ||
1572 | |||
1573 | if (!pci_acs_enable) | ||
1574 | return; | ||
1575 | |||
1576 | if (!pci_is_pcie(dev)) | ||
1577 | return; | ||
1578 | |||
1579 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); | ||
1580 | if (!pos) | ||
1581 | return; | ||
1582 | |||
1583 | pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap); | ||
1584 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl); | ||
1585 | |||
1586 | /* Source Validation */ | ||
1587 | ctrl |= (cap & PCI_ACS_SV); | ||
1588 | |||
1589 | /* P2P Request Redirect */ | ||
1590 | ctrl |= (cap & PCI_ACS_RR); | ||
1591 | |||
1592 | /* P2P Completion Redirect */ | ||
1593 | ctrl |= (cap & PCI_ACS_CR); | ||
1594 | |||
1595 | /* Upstream Forwarding */ | ||
1596 | ctrl |= (cap & PCI_ACS_UF); | ||
1597 | |||
1598 | pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); | ||
1599 | } | ||
1600 | |||
1539 | /** | 1601 | /** |
1540 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge | 1602 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge |
1541 | * @dev: the PCI device | 1603 | * @dev: the PCI device |
@@ -1669,9 +1731,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, const char *res_n | |||
1669 | return 0; | 1731 | return 0; |
1670 | 1732 | ||
1671 | err_out: | 1733 | err_out: |
1672 | dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n", | 1734 | dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar, |
1673 | bar, | ||
1674 | pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", | ||
1675 | &pdev->resource[bar]); | 1735 | &pdev->resource[bar]); |
1676 | return -EBUSY; | 1736 | return -EBUSY; |
1677 | } | 1737 | } |
@@ -1866,31 +1926,6 @@ void pci_clear_master(struct pci_dev *dev) | |||
1866 | __pci_set_master(dev, false); | 1926 | __pci_set_master(dev, false); |
1867 | } | 1927 | } |
1868 | 1928 | ||
1869 | #ifdef PCI_DISABLE_MWI | ||
1870 | int pci_set_mwi(struct pci_dev *dev) | ||
1871 | { | ||
1872 | return 0; | ||
1873 | } | ||
1874 | |||
1875 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1876 | { | ||
1877 | return 0; | ||
1878 | } | ||
1879 | |||
1880 | void pci_clear_mwi(struct pci_dev *dev) | ||
1881 | { | ||
1882 | } | ||
1883 | |||
1884 | #else | ||
1885 | |||
1886 | #ifndef PCI_CACHE_LINE_BYTES | ||
1887 | #define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES | ||
1888 | #endif | ||
1889 | |||
1890 | /* This can be overridden by arch code. */ | ||
1891 | /* Don't forget this is measured in 32-bit words, not bytes */ | ||
1892 | u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; | ||
1893 | |||
1894 | /** | 1929 | /** |
1895 | * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed | 1930 | * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed |
1896 | * @dev: the PCI device for which MWI is to be enabled | 1931 | * @dev: the PCI device for which MWI is to be enabled |
@@ -1901,13 +1936,12 @@ u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4; | |||
1901 | * | 1936 | * |
1902 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 1937 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
1903 | */ | 1938 | */ |
1904 | static int | 1939 | int pci_set_cacheline_size(struct pci_dev *dev) |
1905 | pci_set_cacheline_size(struct pci_dev *dev) | ||
1906 | { | 1940 | { |
1907 | u8 cacheline_size; | 1941 | u8 cacheline_size; |
1908 | 1942 | ||
1909 | if (!pci_cache_line_size) | 1943 | if (!pci_cache_line_size) |
1910 | return -EINVAL; /* The system doesn't support MWI. */ | 1944 | return -EINVAL; |
1911 | 1945 | ||
1912 | /* Validate current setting: the PCI_CACHE_LINE_SIZE must be | 1946 | /* Validate current setting: the PCI_CACHE_LINE_SIZE must be |
1913 | equal to or multiple of the right value. */ | 1947 | equal to or multiple of the right value. */ |
@@ -1928,6 +1962,24 @@ pci_set_cacheline_size(struct pci_dev *dev) | |||
1928 | 1962 | ||
1929 | return -EINVAL; | 1963 | return -EINVAL; |
1930 | } | 1964 | } |
1965 | EXPORT_SYMBOL_GPL(pci_set_cacheline_size); | ||
1966 | |||
1967 | #ifdef PCI_DISABLE_MWI | ||
1968 | int pci_set_mwi(struct pci_dev *dev) | ||
1969 | { | ||
1970 | return 0; | ||
1971 | } | ||
1972 | |||
1973 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1974 | { | ||
1975 | return 0; | ||
1976 | } | ||
1977 | |||
1978 | void pci_clear_mwi(struct pci_dev *dev) | ||
1979 | { | ||
1980 | } | ||
1981 | |||
1982 | #else | ||
1931 | 1983 | ||
1932 | /** | 1984 | /** |
1933 | * pci_set_mwi - enables memory-write-invalidate PCI transaction | 1985 | * pci_set_mwi - enables memory-write-invalidate PCI transaction |
@@ -2062,6 +2114,7 @@ pci_set_dma_mask(struct pci_dev *dev, u64 mask) | |||
2062 | return -EIO; | 2114 | return -EIO; |
2063 | 2115 | ||
2064 | dev->dma_mask = mask; | 2116 | dev->dma_mask = mask; |
2117 | dev_dbg(&dev->dev, "using %dbit DMA mask\n", fls64(mask)); | ||
2065 | 2118 | ||
2066 | return 0; | 2119 | return 0; |
2067 | } | 2120 | } |
@@ -2073,6 +2126,7 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | |||
2073 | return -EIO; | 2126 | return -EIO; |
2074 | 2127 | ||
2075 | dev->dev.coherent_dma_mask = mask; | 2128 | dev->dev.coherent_dma_mask = mask; |
2129 | dev_dbg(&dev->dev, "using %dbit consistent DMA mask\n", fls64(mask)); | ||
2076 | 2130 | ||
2077 | return 0; | 2131 | return 0; |
2078 | } | 2132 | } |
@@ -2099,9 +2153,9 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
2099 | int i; | 2153 | int i; |
2100 | int pos; | 2154 | int pos; |
2101 | u32 cap; | 2155 | u32 cap; |
2102 | u16 status; | 2156 | u16 status, control; |
2103 | 2157 | ||
2104 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2158 | pos = pci_pcie_cap(dev); |
2105 | if (!pos) | 2159 | if (!pos) |
2106 | return -ENOTTY; | 2160 | return -ENOTTY; |
2107 | 2161 | ||
@@ -2126,8 +2180,10 @@ static int pcie_flr(struct pci_dev *dev, int probe) | |||
2126 | "proceeding with reset anyway\n"); | 2180 | "proceeding with reset anyway\n"); |
2127 | 2181 | ||
2128 | clear: | 2182 | clear: |
2129 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, | 2183 | pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control); |
2130 | PCI_EXP_DEVCTL_BCR_FLR); | 2184 | control |= PCI_EXP_DEVCTL_BCR_FLR; |
2185 | pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control); | ||
2186 | |||
2131 | msleep(100); | 2187 | msleep(100); |
2132 | 2188 | ||
2133 | return 0; | 2189 | return 0; |
@@ -2450,7 +2506,7 @@ int pcie_get_readrq(struct pci_dev *dev) | |||
2450 | int ret, cap; | 2506 | int ret, cap; |
2451 | u16 ctl; | 2507 | u16 ctl; |
2452 | 2508 | ||
2453 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2509 | cap = pci_pcie_cap(dev); |
2454 | if (!cap) | 2510 | if (!cap) |
2455 | return -EINVAL; | 2511 | return -EINVAL; |
2456 | 2512 | ||
@@ -2480,7 +2536,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) | |||
2480 | 2536 | ||
2481 | v = (ffs(rq) - 8) << 12; | 2537 | v = (ffs(rq) - 8) << 12; |
2482 | 2538 | ||
2483 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | 2539 | cap = pci_pcie_cap(dev); |
2484 | if (!cap) | 2540 | if (!cap) |
2485 | goto out; | 2541 | goto out; |
2486 | 2542 | ||
@@ -2540,7 +2596,7 @@ int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type) | |||
2540 | return reg; | 2596 | return reg; |
2541 | } | 2597 | } |
2542 | 2598 | ||
2543 | dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno); | 2599 | dev_err(&dev->dev, "BAR %d: invalid resource\n", resno); |
2544 | return 0; | 2600 | return 0; |
2545 | } | 2601 | } |
2546 | 2602 | ||
@@ -2590,7 +2646,7 @@ int pci_set_vga_state(struct pci_dev *dev, bool decode, | |||
2590 | 2646 | ||
2591 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE | 2647 | #define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE |
2592 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; | 2648 | static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0}; |
2593 | spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED; | 2649 | static DEFINE_SPINLOCK(resource_alignment_lock); |
2594 | 2650 | ||
2595 | /** | 2651 | /** |
2596 | * pci_specified_resource_alignment - get resource alignment specified by user. | 2652 | * pci_specified_resource_alignment - get resource alignment specified by user. |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d92d1954a2fb..33ed8e0aba1e 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -311,4 +311,6 @@ static inline int pci_resource_alignment(struct pci_dev *dev, | |||
311 | return resource_alignment(res); | 311 | return resource_alignment(res); |
312 | } | 312 | } |
313 | 313 | ||
314 | extern void pci_enable_acs(struct pci_dev *dev); | ||
315 | |||
314 | #endif /* DRIVERS_PCI_H */ | 316 | #endif /* DRIVERS_PCI_H */ |
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c index 62d15f652bb6..7fcd5331b14c 100644 --- a/drivers/pci/pcie/aer/aer_inject.c +++ b/drivers/pci/pcie/aer/aer_inject.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
24 | #include <linux/fs.h> | 24 | #include <linux/fs.h> |
25 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
26 | #include <linux/stddef.h> | ||
26 | #include "aerdrv.h" | 27 | #include "aerdrv.h" |
27 | 28 | ||
28 | struct aer_error_inj { | 29 | struct aer_error_inj { |
@@ -35,10 +36,12 @@ struct aer_error_inj { | |||
35 | u32 header_log1; | 36 | u32 header_log1; |
36 | u32 header_log2; | 37 | u32 header_log2; |
37 | u32 header_log3; | 38 | u32 header_log3; |
39 | u16 domain; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | struct aer_error { | 42 | struct aer_error { |
41 | struct list_head list; | 43 | struct list_head list; |
44 | u16 domain; | ||
42 | unsigned int bus; | 45 | unsigned int bus; |
43 | unsigned int devfn; | 46 | unsigned int devfn; |
44 | int pos_cap_err; | 47 | int pos_cap_err; |
@@ -66,22 +69,27 @@ static LIST_HEAD(pci_bus_ops_list); | |||
66 | /* Protect einjected and pci_bus_ops_list */ | 69 | /* Protect einjected and pci_bus_ops_list */ |
67 | static DEFINE_SPINLOCK(inject_lock); | 70 | static DEFINE_SPINLOCK(inject_lock); |
68 | 71 | ||
69 | static void aer_error_init(struct aer_error *err, unsigned int bus, | 72 | static void aer_error_init(struct aer_error *err, u16 domain, |
70 | unsigned int devfn, int pos_cap_err) | 73 | unsigned int bus, unsigned int devfn, |
74 | int pos_cap_err) | ||
71 | { | 75 | { |
72 | INIT_LIST_HEAD(&err->list); | 76 | INIT_LIST_HEAD(&err->list); |
77 | err->domain = domain; | ||
73 | err->bus = bus; | 78 | err->bus = bus; |
74 | err->devfn = devfn; | 79 | err->devfn = devfn; |
75 | err->pos_cap_err = pos_cap_err; | 80 | err->pos_cap_err = pos_cap_err; |
76 | } | 81 | } |
77 | 82 | ||
78 | /* inject_lock must be held before calling */ | 83 | /* inject_lock must be held before calling */ |
79 | static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) | 84 | static struct aer_error *__find_aer_error(u16 domain, unsigned int bus, |
85 | unsigned int devfn) | ||
80 | { | 86 | { |
81 | struct aer_error *err; | 87 | struct aer_error *err; |
82 | 88 | ||
83 | list_for_each_entry(err, &einjected, list) { | 89 | list_for_each_entry(err, &einjected, list) { |
84 | if (bus == err->bus && devfn == err->devfn) | 90 | if (domain == err->domain && |
91 | bus == err->bus && | ||
92 | devfn == err->devfn) | ||
85 | return err; | 93 | return err; |
86 | } | 94 | } |
87 | return NULL; | 95 | return NULL; |
@@ -90,7 +98,10 @@ static struct aer_error *__find_aer_error(unsigned int bus, unsigned int devfn) | |||
90 | /* inject_lock must be held before calling */ | 98 | /* inject_lock must be held before calling */ |
91 | static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) | 99 | static struct aer_error *__find_aer_error_by_dev(struct pci_dev *dev) |
92 | { | 100 | { |
93 | return __find_aer_error(dev->bus->number, dev->devfn); | 101 | int domain = pci_domain_nr(dev->bus); |
102 | if (domain < 0) | ||
103 | return NULL; | ||
104 | return __find_aer_error((u16)domain, dev->bus->number, dev->devfn); | ||
94 | } | 105 | } |
95 | 106 | ||
96 | /* inject_lock must be held before calling */ | 107 | /* inject_lock must be held before calling */ |
@@ -172,11 +183,15 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, | |||
172 | struct aer_error *err; | 183 | struct aer_error *err; |
173 | unsigned long flags; | 184 | unsigned long flags; |
174 | struct pci_ops *ops; | 185 | struct pci_ops *ops; |
186 | int domain; | ||
175 | 187 | ||
176 | spin_lock_irqsave(&inject_lock, flags); | 188 | spin_lock_irqsave(&inject_lock, flags); |
177 | if (size != sizeof(u32)) | 189 | if (size != sizeof(u32)) |
178 | goto out; | 190 | goto out; |
179 | err = __find_aer_error(bus->number, devfn); | 191 | domain = pci_domain_nr(bus); |
192 | if (domain < 0) | ||
193 | goto out; | ||
194 | err = __find_aer_error((u16)domain, bus->number, devfn); | ||
180 | if (!err) | 195 | if (!err) |
181 | goto out; | 196 | goto out; |
182 | 197 | ||
@@ -200,11 +215,15 @@ int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, int size, | |||
200 | unsigned long flags; | 215 | unsigned long flags; |
201 | int rw1cs; | 216 | int rw1cs; |
202 | struct pci_ops *ops; | 217 | struct pci_ops *ops; |
218 | int domain; | ||
203 | 219 | ||
204 | spin_lock_irqsave(&inject_lock, flags); | 220 | spin_lock_irqsave(&inject_lock, flags); |
205 | if (size != sizeof(u32)) | 221 | if (size != sizeof(u32)) |
206 | goto out; | 222 | goto out; |
207 | err = __find_aer_error(bus->number, devfn); | 223 | domain = pci_domain_nr(bus); |
224 | if (domain < 0) | ||
225 | goto out; | ||
226 | err = __find_aer_error((u16)domain, bus->number, devfn); | ||
208 | if (!err) | 227 | if (!err) |
209 | goto out; | 228 | goto out; |
210 | 229 | ||
@@ -262,7 +281,7 @@ out: | |||
262 | static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) | 281 | static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) |
263 | { | 282 | { |
264 | while (1) { | 283 | while (1) { |
265 | if (!dev->is_pcie) | 284 | if (!pci_is_pcie(dev)) |
266 | break; | 285 | break; |
267 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | 286 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) |
268 | return dev; | 287 | return dev; |
@@ -305,25 +324,25 @@ static int aer_inject(struct aer_error_inj *einj) | |||
305 | u32 sever; | 324 | u32 sever; |
306 | int ret = 0; | 325 | int ret = 0; |
307 | 326 | ||
308 | dev = pci_get_bus_and_slot(einj->bus, devfn); | 327 | dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn); |
309 | if (!dev) | 328 | if (!dev) |
310 | return -EINVAL; | 329 | return -ENODEV; |
311 | rpdev = pcie_find_root_port(dev); | 330 | rpdev = pcie_find_root_port(dev); |
312 | if (!rpdev) { | 331 | if (!rpdev) { |
313 | ret = -EINVAL; | 332 | ret = -ENOTTY; |
314 | goto out_put; | 333 | goto out_put; |
315 | } | 334 | } |
316 | 335 | ||
317 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 336 | pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
318 | if (!pos_cap_err) { | 337 | if (!pos_cap_err) { |
319 | ret = -EIO; | 338 | ret = -ENOTTY; |
320 | goto out_put; | 339 | goto out_put; |
321 | } | 340 | } |
322 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); | 341 | pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); |
323 | 342 | ||
324 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); | 343 | rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); |
325 | if (!rp_pos_cap_err) { | 344 | if (!rp_pos_cap_err) { |
326 | ret = -EIO; | 345 | ret = -ENOTTY; |
327 | goto out_put; | 346 | goto out_put; |
328 | } | 347 | } |
329 | 348 | ||
@@ -344,7 +363,8 @@ static int aer_inject(struct aer_error_inj *einj) | |||
344 | if (!err) { | 363 | if (!err) { |
345 | err = err_alloc; | 364 | err = err_alloc; |
346 | err_alloc = NULL; | 365 | err_alloc = NULL; |
347 | aer_error_init(err, einj->bus, devfn, pos_cap_err); | 366 | aer_error_init(err, einj->domain, einj->bus, devfn, |
367 | pos_cap_err); | ||
348 | list_add(&err->list, &einjected); | 368 | list_add(&err->list, &einjected); |
349 | } | 369 | } |
350 | err->uncor_status |= einj->uncor_status; | 370 | err->uncor_status |= einj->uncor_status; |
@@ -358,7 +378,8 @@ static int aer_inject(struct aer_error_inj *einj) | |||
358 | if (!rperr) { | 378 | if (!rperr) { |
359 | rperr = rperr_alloc; | 379 | rperr = rperr_alloc; |
360 | rperr_alloc = NULL; | 380 | rperr_alloc = NULL; |
361 | aer_error_init(rperr, rpdev->bus->number, rpdev->devfn, | 381 | aer_error_init(rperr, pci_domain_nr(rpdev->bus), |
382 | rpdev->bus->number, rpdev->devfn, | ||
362 | rp_pos_cap_err); | 383 | rp_pos_cap_err); |
363 | list_add(&rperr->list, &einjected); | 384 | list_add(&rperr->list, &einjected); |
364 | } | 385 | } |
@@ -411,10 +432,11 @@ static ssize_t aer_inject_write(struct file *filp, const char __user *ubuf, | |||
411 | 432 | ||
412 | if (!capable(CAP_SYS_ADMIN)) | 433 | if (!capable(CAP_SYS_ADMIN)) |
413 | return -EPERM; | 434 | return -EPERM; |
414 | 435 | if (usize < offsetof(struct aer_error_inj, domain) || | |
415 | if (usize != sizeof(struct aer_error_inj)) | 436 | usize > sizeof(einj)) |
416 | return -EINVAL; | 437 | return -EINVAL; |
417 | 438 | ||
439 | memset(&einj, 0, sizeof(einj)); | ||
418 | if (copy_from_user(&einj, ubuf, usize)) | 440 | if (copy_from_user(&einj, ubuf, usize)) |
419 | return -EFAULT; | 441 | return -EFAULT; |
420 | 442 | ||
@@ -452,7 +474,7 @@ static void __exit aer_inject_exit(void) | |||
452 | } | 474 | } |
453 | 475 | ||
454 | spin_lock_irqsave(&inject_lock, flags); | 476 | spin_lock_irqsave(&inject_lock, flags); |
455 | list_for_each_entry_safe(err, err_next, &pci_bus_ops_list, list) { | 477 | list_for_each_entry_safe(err, err_next, &einjected, list) { |
456 | list_del(&err->list); | 478 | list_del(&err->list); |
457 | kfree(err); | 479 | kfree(err); |
458 | } | 480 | } |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 40c3cc5d1caf..97a345927b55 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -53,7 +53,7 @@ static struct pci_error_handlers aer_error_handlers = { | |||
53 | 53 | ||
54 | static struct pcie_port_service_driver aerdriver = { | 54 | static struct pcie_port_service_driver aerdriver = { |
55 | .name = "aer", | 55 | .name = "aer", |
56 | .port_type = PCIE_RC_PORT, | 56 | .port_type = PCI_EXP_TYPE_ROOT_PORT, |
57 | .service = PCIE_PORT_SERVICE_AER, | 57 | .service = PCIE_PORT_SERVICE_AER, |
58 | 58 | ||
59 | .probe = aer_probe, | 59 | .probe = aer_probe, |
@@ -295,7 +295,7 @@ static void aer_error_resume(struct pci_dev *dev) | |||
295 | u16 reg16; | 295 | u16 reg16; |
296 | 296 | ||
297 | /* Clean up Root device status */ | 297 | /* Clean up Root device status */ |
298 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 298 | pos = pci_pcie_cap(dev); |
299 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); | 299 | pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); |
300 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); | 300 | pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); |
301 | 301 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 9f5ccbeb4fa5..ae672ca80333 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -35,11 +35,14 @@ int pci_enable_pcie_error_reporting(struct pci_dev *dev) | |||
35 | u16 reg16 = 0; | 35 | u16 reg16 = 0; |
36 | int pos; | 36 | int pos; |
37 | 37 | ||
38 | if (dev->aer_firmware_first) | ||
39 | return -EIO; | ||
40 | |||
38 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 41 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
39 | if (!pos) | 42 | if (!pos) |
40 | return -EIO; | 43 | return -EIO; |
41 | 44 | ||
42 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 45 | pos = pci_pcie_cap(dev); |
43 | if (!pos) | 46 | if (!pos) |
44 | return -EIO; | 47 | return -EIO; |
45 | 48 | ||
@@ -60,7 +63,10 @@ int pci_disable_pcie_error_reporting(struct pci_dev *dev) | |||
60 | u16 reg16 = 0; | 63 | u16 reg16 = 0; |
61 | int pos; | 64 | int pos; |
62 | 65 | ||
63 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 66 | if (dev->aer_firmware_first) |
67 | return -EIO; | ||
68 | |||
69 | pos = pci_pcie_cap(dev); | ||
64 | if (!pos) | 70 | if (!pos) |
65 | return -EIO; | 71 | return -EIO; |
66 | 72 | ||
@@ -78,48 +84,27 @@ EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); | |||
78 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) | 84 | int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) |
79 | { | 85 | { |
80 | int pos; | 86 | int pos; |
81 | u32 status, mask; | 87 | u32 status; |
82 | 88 | ||
83 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 89 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
84 | if (!pos) | 90 | if (!pos) |
85 | return -EIO; | 91 | return -EIO; |
86 | 92 | ||
87 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); | 93 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status); |
88 | pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask); | 94 | if (status) |
89 | if (dev->error_state == pci_channel_io_normal) | 95 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); |
90 | status &= ~mask; /* Clear corresponding nonfatal bits */ | ||
91 | else | ||
92 | status &= mask; /* Clear corresponding fatal bits */ | ||
93 | pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, status); | ||
94 | 96 | ||
95 | return 0; | 97 | return 0; |
96 | } | 98 | } |
97 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); | 99 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); |
98 | 100 | ||
99 | #if 0 | ||
100 | int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | ||
101 | { | ||
102 | int pos; | ||
103 | u32 status; | ||
104 | |||
105 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | ||
106 | if (!pos) | ||
107 | return -EIO; | ||
108 | |||
109 | pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); | ||
110 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | #endif /* 0 */ | ||
115 | |||
116 | static int set_device_error_reporting(struct pci_dev *dev, void *data) | 101 | static int set_device_error_reporting(struct pci_dev *dev, void *data) |
117 | { | 102 | { |
118 | bool enable = *((bool *)data); | 103 | bool enable = *((bool *)data); |
119 | 104 | ||
120 | if (dev->pcie_type == PCIE_RC_PORT || | 105 | if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) || |
121 | dev->pcie_type == PCIE_SW_UPSTREAM_PORT || | 106 | (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) || |
122 | dev->pcie_type == PCIE_SW_DOWNSTREAM_PORT) { | 107 | (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) { |
123 | if (enable) | 108 | if (enable) |
124 | pci_enable_pcie_error_reporting(dev); | 109 | pci_enable_pcie_error_reporting(dev); |
125 | else | 110 | else |
@@ -218,7 +203,7 @@ static int find_device_iter(struct pci_dev *dev, void *data) | |||
218 | */ | 203 | */ |
219 | if (atomic_read(&dev->enable_cnt) == 0) | 204 | if (atomic_read(&dev->enable_cnt) == 0) |
220 | return 0; | 205 | return 0; |
221 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 206 | pos = pci_pcie_cap(dev); |
222 | if (!pos) | 207 | if (!pos) |
223 | return 0; | 208 | return 0; |
224 | /* Check if AER is enabled */ | 209 | /* Check if AER is enabled */ |
@@ -431,10 +416,9 @@ static int find_aer_service_iter(struct device *device, void *data) | |||
431 | result = (struct find_aer_service_data *) data; | 416 | result = (struct find_aer_service_data *) data; |
432 | 417 | ||
433 | if (device->bus == &pcie_port_bus_type) { | 418 | if (device->bus == &pcie_port_bus_type) { |
434 | struct pcie_port_data *port_data; | 419 | struct pcie_device *pcie = to_pcie_device(device); |
435 | 420 | ||
436 | port_data = pci_get_drvdata(to_pcie_device(device)->port); | 421 | if (pcie->port->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
437 | if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT) | ||
438 | result->is_downstream = 1; | 422 | result->is_downstream = 1; |
439 | 423 | ||
440 | driver = device->driver; | 424 | driver = device->driver; |
@@ -612,7 +596,7 @@ void aer_enable_rootport(struct aer_rpc *rpc) | |||
612 | u16 reg16; | 596 | u16 reg16; |
613 | u32 reg32; | 597 | u32 reg32; |
614 | 598 | ||
615 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 599 | pos = pci_pcie_cap(pdev); |
616 | /* Clear PCIE Capability's Device Status */ | 600 | /* Clear PCIE Capability's Device Status */ |
617 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); | 601 | pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); |
618 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); | 602 | pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); |
@@ -874,8 +858,22 @@ void aer_delete_rootport(struct aer_rpc *rpc) | |||
874 | */ | 858 | */ |
875 | int aer_init(struct pcie_device *dev) | 859 | int aer_init(struct pcie_device *dev) |
876 | { | 860 | { |
877 | if (aer_osc_setup(dev) && !forceload) | 861 | if (dev->port->aer_firmware_first) { |
878 | return -ENXIO; | 862 | dev_printk(KERN_DEBUG, &dev->device, |
863 | "PCIe errors handled by platform firmware.\n"); | ||
864 | goto out; | ||
865 | } | ||
866 | |||
867 | if (aer_osc_setup(dev)) | ||
868 | goto out; | ||
879 | 869 | ||
880 | return 0; | 870 | return 0; |
871 | out: | ||
872 | if (forceload) { | ||
873 | dev_printk(KERN_DEBUG, &dev->device, | ||
874 | "aerdrv forceload requested.\n"); | ||
875 | dev->port->aer_firmware_first = 0; | ||
876 | return 0; | ||
877 | } | ||
878 | return -ENXIO; | ||
881 | } | 879 | } |
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c index a928d8ab6bda..a2747a663bc9 100644 --- a/drivers/pci/pcie/aer/ecrc.c +++ b/drivers/pci/pcie/aer/ecrc.c | |||
@@ -51,7 +51,7 @@ static int enable_ecrc_checking(struct pci_dev *dev) | |||
51 | int pos; | 51 | int pos; |
52 | u32 reg32; | 52 | u32 reg32; |
53 | 53 | ||
54 | if (!dev->is_pcie) | 54 | if (!pci_is_pcie(dev)) |
55 | return -ENODEV; | 55 | return -ENODEV; |
56 | 56 | ||
57 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 57 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
@@ -79,7 +79,7 @@ static int disable_ecrc_checking(struct pci_dev *dev) | |||
79 | int pos; | 79 | int pos; |
80 | u32 reg32; | 80 | u32 reg32; |
81 | 81 | ||
82 | if (!dev->is_pcie) | 82 | if (!pci_is_pcie(dev)) |
83 | return -ENODEV; | 83 | return -ENODEV; |
84 | 84 | ||
85 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); | 85 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 5b7056cec00c..5a01fc7fbf05 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -122,7 +122,7 @@ static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) | |||
122 | struct pci_bus *linkbus = link->pdev->subordinate; | 122 | struct pci_bus *linkbus = link->pdev->subordinate; |
123 | 123 | ||
124 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 124 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
125 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 125 | pos = pci_pcie_cap(child); |
126 | if (!pos) | 126 | if (!pos) |
127 | return; | 127 | return; |
128 | pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); | 128 | pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); |
@@ -156,7 +156,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) | |||
156 | 156 | ||
157 | /* All functions should have the same cap and state, take the worst */ | 157 | /* All functions should have the same cap and state, take the worst */ |
158 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 158 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
159 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 159 | pos = pci_pcie_cap(child); |
160 | if (!pos) | 160 | if (!pos) |
161 | return; | 161 | return; |
162 | pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); | 162 | pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); |
@@ -191,23 +191,23 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
191 | * Configuration, so just check one function | 191 | * Configuration, so just check one function |
192 | */ | 192 | */ |
193 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); | 193 | child = list_entry(linkbus->devices.next, struct pci_dev, bus_list); |
194 | BUG_ON(!child->is_pcie); | 194 | BUG_ON(!pci_is_pcie(child)); |
195 | 195 | ||
196 | /* Check downstream component if bit Slot Clock Configuration is 1 */ | 196 | /* Check downstream component if bit Slot Clock Configuration is 1 */ |
197 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 197 | cpos = pci_pcie_cap(child); |
198 | pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); | 198 | pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); |
199 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | 199 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) |
200 | same_clock = 0; | 200 | same_clock = 0; |
201 | 201 | ||
202 | /* Check upstream component if bit Slot Clock Configuration is 1 */ | 202 | /* Check upstream component if bit Slot Clock Configuration is 1 */ |
203 | ppos = pci_find_capability(parent, PCI_CAP_ID_EXP); | 203 | ppos = pci_pcie_cap(parent); |
204 | pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); | 204 | pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); |
205 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) | 205 | if (!(reg16 & PCI_EXP_LNKSTA_SLC)) |
206 | same_clock = 0; | 206 | same_clock = 0; |
207 | 207 | ||
208 | /* Configure downstream component, all functions */ | 208 | /* Configure downstream component, all functions */ |
209 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 209 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
210 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 210 | cpos = pci_pcie_cap(child); |
211 | pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); | 211 | pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); |
212 | child_reg[PCI_FUNC(child->devfn)] = reg16; | 212 | child_reg[PCI_FUNC(child->devfn)] = reg16; |
213 | if (same_clock) | 213 | if (same_clock) |
@@ -247,7 +247,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) | |||
247 | dev_printk(KERN_ERR, &parent->dev, | 247 | dev_printk(KERN_ERR, &parent->dev, |
248 | "ASPM: Could not configure common clock\n"); | 248 | "ASPM: Could not configure common clock\n"); |
249 | list_for_each_entry(child, &linkbus->devices, bus_list) { | 249 | list_for_each_entry(child, &linkbus->devices, bus_list) { |
250 | cpos = pci_find_capability(child, PCI_CAP_ID_EXP); | 250 | cpos = pci_pcie_cap(child); |
251 | pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, | 251 | pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, |
252 | child_reg[PCI_FUNC(child->devfn)]); | 252 | child_reg[PCI_FUNC(child->devfn)]); |
253 | } | 253 | } |
@@ -300,7 +300,7 @@ static void pcie_get_aspm_reg(struct pci_dev *pdev, | |||
300 | u16 reg16; | 300 | u16 reg16; |
301 | u32 reg32; | 301 | u32 reg32; |
302 | 302 | ||
303 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 303 | pos = pci_pcie_cap(pdev); |
304 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); | 304 | pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); |
305 | info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; | 305 | info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; |
306 | info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; | 306 | info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; |
@@ -420,7 +420,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
420 | child->pcie_type != PCI_EXP_TYPE_LEG_END) | 420 | child->pcie_type != PCI_EXP_TYPE_LEG_END) |
421 | continue; | 421 | continue; |
422 | 422 | ||
423 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 423 | pos = pci_pcie_cap(child); |
424 | pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); | 424 | pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); |
425 | /* Calculate endpoint L0s acceptable latency */ | 425 | /* Calculate endpoint L0s acceptable latency */ |
426 | encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; | 426 | encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; |
@@ -436,7 +436,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) | |||
436 | static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) | 436 | static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) |
437 | { | 437 | { |
438 | u16 reg16; | 438 | u16 reg16; |
439 | int pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 439 | int pos = pci_pcie_cap(pdev); |
440 | 440 | ||
441 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); | 441 | pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); |
442 | reg16 &= ~0x3; | 442 | reg16 &= ~0x3; |
@@ -503,7 +503,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
503 | * very strange. Disable ASPM for the whole slot | 503 | * very strange. Disable ASPM for the whole slot |
504 | */ | 504 | */ |
505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { | 505 | list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { |
506 | pos = pci_find_capability(child, PCI_CAP_ID_EXP); | 506 | pos = pci_pcie_cap(child); |
507 | if (!pos) | 507 | if (!pos) |
508 | return -EINVAL; | 508 | return -EINVAL; |
509 | /* | 509 | /* |
@@ -563,7 +563,7 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) | |||
563 | struct pcie_link_state *link; | 563 | struct pcie_link_state *link; |
564 | int blacklist = !!pcie_aspm_sanity_check(pdev); | 564 | int blacklist = !!pcie_aspm_sanity_check(pdev); |
565 | 565 | ||
566 | if (aspm_disabled || !pdev->is_pcie || pdev->link_state) | 566 | if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) |
567 | return; | 567 | return; |
568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 568 | if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) | 569 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) |
@@ -629,7 +629,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) | |||
629 | struct pci_dev *parent = pdev->bus->self; | 629 | struct pci_dev *parent = pdev->bus->self; |
630 | struct pcie_link_state *link, *root, *parent_link; | 630 | struct pcie_link_state *link, *root, *parent_link; |
631 | 631 | ||
632 | if (aspm_disabled || !pdev->is_pcie || !parent || !parent->link_state) | 632 | if (aspm_disabled || !pci_is_pcie(pdev) || |
633 | !parent || !parent->link_state) | ||
633 | return; | 634 | return; |
634 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 635 | if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
635 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 636 | (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -670,7 +671,7 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) | |||
670 | { | 671 | { |
671 | struct pcie_link_state *link = pdev->link_state; | 672 | struct pcie_link_state *link = pdev->link_state; |
672 | 673 | ||
673 | if (aspm_disabled || !pdev->is_pcie || !link) | 674 | if (aspm_disabled || !pci_is_pcie(pdev) || !link) |
674 | return; | 675 | return; |
675 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && | 676 | if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
676 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) | 677 | (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) |
@@ -696,7 +697,7 @@ void pci_disable_link_state(struct pci_dev *pdev, int state) | |||
696 | struct pci_dev *parent = pdev->bus->self; | 697 | struct pci_dev *parent = pdev->bus->self; |
697 | struct pcie_link_state *link; | 698 | struct pcie_link_state *link; |
698 | 699 | ||
699 | if (aspm_disabled || !pdev->is_pcie) | 700 | if (aspm_disabled || !pci_is_pcie(pdev)) |
700 | return; | 701 | return; |
701 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || | 702 | if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || |
702 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) | 703 | pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) |
@@ -841,8 +842,9 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) | |||
841 | { | 842 | { |
842 | struct pcie_link_state *link_state = pdev->link_state; | 843 | struct pcie_link_state *link_state = pdev->link_state; |
843 | 844 | ||
844 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 845 | if (!pci_is_pcie(pdev) || |
845 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | 846 | (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
847 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | ||
846 | return; | 848 | return; |
847 | 849 | ||
848 | if (link_state->aspm_support) | 850 | if (link_state->aspm_support) |
@@ -857,8 +859,9 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) | |||
857 | { | 859 | { |
858 | struct pcie_link_state *link_state = pdev->link_state; | 860 | struct pcie_link_state *link_state = pdev->link_state; |
859 | 861 | ||
860 | if (!pdev->is_pcie || (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && | 862 | if (!pci_is_pcie(pdev) || |
861 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | 863 | (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && |
864 | pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) | ||
862 | return; | 865 | return; |
863 | 866 | ||
864 | if (link_state->aspm_support) | 867 | if (link_state->aspm_support) |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 17ad53868f9f..aaeb9d21cba5 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -11,31 +11,16 @@ | |||
11 | 11 | ||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | 13 | ||
14 | #if !defined(PCI_CAP_ID_PME) | 14 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 |
15 | #define PCI_CAP_ID_PME 1 | ||
16 | #endif | ||
17 | |||
18 | #if !defined(PCI_CAP_ID_EXP) | ||
19 | #define PCI_CAP_ID_EXP 0x10 | ||
20 | #endif | ||
21 | |||
22 | #define PORT_TYPE_MASK 0xf | ||
23 | #define PORT_TO_SLOT_MASK 0x100 | ||
24 | #define SLOT_HP_CAPABLE_MASK 0x40 | ||
25 | #define PCIE_CAPABILITIES_REG 0x2 | ||
26 | #define PCIE_SLOT_CAPABILITIES_REG 0x14 | ||
27 | #define PCIE_PORT_DEVICE_MAXSERVICES 4 | ||
28 | #define PCIE_PORT_MSI_VECTOR_MASK 0x1f | ||
29 | /* | 15 | /* |
30 | * According to the PCI Express Base Specification 2.0, the indices of the MSI-X | 16 | * According to the PCI Express Base Specification 2.0, the indices of |
31 | * table entires used by port services must not exceed 31 | 17 | * the MSI-X table entires used by port services must not exceed 31 |
32 | */ | 18 | */ |
33 | #define PCIE_PORT_MAX_MSIX_ENTRIES 32 | 19 | #define PCIE_PORT_MAX_MSIX_ENTRIES 32 |
34 | 20 | ||
35 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) | 21 | #define get_descriptor_id(type, service) (((type - 4) << 4) | service) |
36 | 22 | ||
37 | extern struct bus_type pcie_port_bus_type; | 23 | extern struct bus_type pcie_port_bus_type; |
38 | extern int pcie_port_device_probe(struct pci_dev *dev); | ||
39 | extern int pcie_port_device_register(struct pci_dev *dev); | 24 | extern int pcie_port_device_register(struct pci_dev *dev); |
40 | #ifdef CONFIG_PM | 25 | #ifdef CONFIG_PM |
41 | extern int pcie_port_device_suspend(struct device *dev); | 26 | extern int pcie_port_device_suspend(struct device *dev); |
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c index ef3a4eeaebb4..18bf90f748f6 100644 --- a/drivers/pci/pcie/portdrv_bus.c +++ b/drivers/pci/pcie/portdrv_bus.c | |||
@@ -26,7 +26,6 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type); | |||
26 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | 26 | static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) |
27 | { | 27 | { |
28 | struct pcie_device *pciedev; | 28 | struct pcie_device *pciedev; |
29 | struct pcie_port_data *port_data; | ||
30 | struct pcie_port_service_driver *driver; | 29 | struct pcie_port_service_driver *driver; |
31 | 30 | ||
32 | if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) | 31 | if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type) |
@@ -38,10 +37,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | |||
38 | if (driver->service != pciedev->service) | 37 | if (driver->service != pciedev->service) |
39 | return 0; | 38 | return 0; |
40 | 39 | ||
41 | port_data = pci_get_drvdata(pciedev->port); | 40 | if ((driver->port_type != PCIE_ANY_PORT) && |
42 | 41 | (driver->port_type != pciedev->port->pcie_type)) | |
43 | if (driver->port_type != PCIE_ANY_PORT | ||
44 | && driver->port_type != port_data->port_type) | ||
45 | return 0; | 42 | return 0; |
46 | 43 | ||
47 | return 1; | 44 | return 1; |
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 52f84fca9f7d..413262eb95b7 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -108,9 +108,9 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
108 | * the value in this field indicates which MSI-X Table entry is | 108 | * the value in this field indicates which MSI-X Table entry is |
109 | * used to generate the interrupt message." | 109 | * used to generate the interrupt message." |
110 | */ | 110 | */ |
111 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 111 | pos = pci_pcie_cap(dev); |
112 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); | 112 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
113 | entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK; | 113 | entry = (reg16 & PCI_EXP_FLAGS_IRQ) >> 9; |
114 | if (entry >= nr_entries) | 114 | if (entry >= nr_entries) |
115 | goto Error; | 115 | goto Error; |
116 | 116 | ||
@@ -177,37 +177,40 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * assign_interrupt_mode - choose interrupt mode for PCI Express port services | 180 | * init_service_irqs - initialize irqs for PCI Express port services |
181 | * (INTx, MSI-X, MSI) and set up vectors | ||
182 | * @dev: PCI Express port to handle | 181 | * @dev: PCI Express port to handle |
183 | * @vectors: Array of interrupt vectors to populate | 182 | * @irqs: Array of irqs to populate |
184 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() | 183 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() |
185 | * | 184 | * |
186 | * Return value: Interrupt mode associated with the port | 185 | * Return value: Interrupt mode associated with the port |
187 | */ | 186 | */ |
188 | static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | 187 | static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) |
189 | { | 188 | { |
190 | int irq, interrupt_mode = PCIE_PORT_NO_IRQ; | 189 | int i, irq; |
191 | int i; | ||
192 | 190 | ||
193 | /* Try to use MSI-X if supported */ | 191 | /* Try to use MSI-X if supported */ |
194 | if (!pcie_port_enable_msix(dev, vectors, mask)) | 192 | if (!pcie_port_enable_msix(dev, irqs, mask)) |
195 | return PCIE_PORT_MSIX_MODE; | 193 | return 0; |
196 | |||
197 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ | 194 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ |
198 | if (!pci_enable_msi(dev)) | 195 | irq = -1; |
199 | interrupt_mode = PCIE_PORT_MSI_MODE; | 196 | if (!pci_enable_msi(dev) || dev->pin) |
200 | 197 | irq = dev->irq; | |
201 | if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin) | ||
202 | interrupt_mode = PCIE_PORT_INTx_MODE; | ||
203 | 198 | ||
204 | irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1; | ||
205 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) | 199 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) |
206 | vectors[i] = irq; | 200 | irqs[i] = irq; |
201 | irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | ||
207 | 202 | ||
208 | vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | 203 | if (irq < 0) |
204 | return -ENODEV; | ||
205 | return 0; | ||
206 | } | ||
209 | 207 | ||
210 | return interrupt_mode; | 208 | static void cleanup_service_irqs(struct pci_dev *dev) |
209 | { | ||
210 | if (dev->msix_enabled) | ||
211 | pci_disable_msix(dev); | ||
212 | else if (dev->msi_enabled) | ||
213 | pci_disable_msi(dev); | ||
211 | } | 214 | } |
212 | 215 | ||
213 | /** | 216 | /** |
@@ -226,13 +229,12 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
226 | u16 reg16; | 229 | u16 reg16; |
227 | u32 reg32; | 230 | u32 reg32; |
228 | 231 | ||
229 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 232 | pos = pci_pcie_cap(dev); |
230 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®16); | 233 | pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); |
231 | /* Hot-Plug Capable */ | 234 | /* Hot-Plug Capable */ |
232 | if (reg16 & PORT_TO_SLOT_MASK) { | 235 | if (reg16 & PCI_EXP_FLAGS_SLOT) { |
233 | pci_read_config_dword(dev, | 236 | pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); |
234 | pos + PCIE_SLOT_CAPABILITIES_REG, ®32); | 237 | if (reg32 & PCI_EXP_SLTCAP_HPC) |
235 | if (reg32 & SLOT_HP_CAPABLE_MASK) | ||
236 | services |= PCIE_PORT_SERVICE_HP; | 238 | services |= PCIE_PORT_SERVICE_HP; |
237 | } | 239 | } |
238 | /* AER capable */ | 240 | /* AER capable */ |
@@ -241,80 +243,47 @@ static int get_port_device_capability(struct pci_dev *dev) | |||
241 | /* VC support */ | 243 | /* VC support */ |
242 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) | 244 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) |
243 | services |= PCIE_PORT_SERVICE_VC; | 245 | services |= PCIE_PORT_SERVICE_VC; |
246 | /* Root ports are capable of generating PME too */ | ||
247 | if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) | ||
248 | services |= PCIE_PORT_SERVICE_PME; | ||
244 | 249 | ||
245 | return services; | 250 | return services; |
246 | } | 251 | } |
247 | 252 | ||
248 | /** | 253 | /** |
249 | * pcie_device_init - initialize PCI Express port service device | 254 | * pcie_device_init - allocate and initialize PCI Express port service device |
250 | * @dev: Port service device to initialize | 255 | * @pdev: PCI Express port to associate the service device with |
251 | * @parent: PCI Express port to associate the service device with | 256 | * @service: Type of service to associate with the service device |
252 | * @port_type: Type of the port | ||
253 | * @service_type: Type of service to associate with the service device | ||
254 | * @irq: Interrupt vector to associate with the service device | 257 | * @irq: Interrupt vector to associate with the service device |
255 | */ | 258 | */ |
256 | static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, | 259 | static int pcie_device_init(struct pci_dev *pdev, int service, int irq) |
257 | int service_type, int irq) | ||
258 | { | 260 | { |
259 | struct pcie_port_data *port_data = pci_get_drvdata(parent); | 261 | int retval; |
262 | struct pcie_device *pcie; | ||
260 | struct device *device; | 263 | struct device *device; |
261 | int port_type = port_data->port_type; | ||
262 | 264 | ||
263 | dev->port = parent; | 265 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); |
264 | dev->irq = irq; | 266 | if (!pcie) |
265 | dev->service = service_type; | 267 | return -ENOMEM; |
268 | pcie->port = pdev; | ||
269 | pcie->irq = irq; | ||
270 | pcie->service = service; | ||
266 | 271 | ||
267 | /* Initialize generic device interface */ | 272 | /* Initialize generic device interface */ |
268 | device = &dev->device; | 273 | device = &pcie->device; |
269 | memset(device, 0, sizeof(struct device)); | ||
270 | device->bus = &pcie_port_bus_type; | 274 | device->bus = &pcie_port_bus_type; |
271 | device->driver = NULL; | ||
272 | dev_set_drvdata(device, NULL); | ||
273 | device->release = release_pcie_device; /* callback to free pcie dev */ | 275 | device->release = release_pcie_device; /* callback to free pcie dev */ |
274 | dev_set_name(device, "%s:pcie%02x", | 276 | dev_set_name(device, "%s:pcie%02x", |
275 | pci_name(parent), get_descriptor_id(port_type, service_type)); | 277 | pci_name(pdev), |
276 | device->parent = &parent->dev; | 278 | get_descriptor_id(pdev->pcie_type, service)); |
277 | } | 279 | device->parent = &pdev->dev; |
278 | 280 | ||
279 | /** | 281 | retval = device_register(device); |
280 | * alloc_pcie_device - allocate PCI Express port service device structure | 282 | if (retval) |
281 | * @parent: PCI Express port to associate the service device with | 283 | kfree(pcie); |
282 | * @port_type: Type of the port | 284 | else |
283 | * @service_type: Type of service to associate with the service device | 285 | get_device(device); |
284 | * @irq: Interrupt vector to associate with the service device | 286 | return retval; |
285 | */ | ||
286 | static struct pcie_device* alloc_pcie_device(struct pci_dev *parent, | ||
287 | int service_type, int irq) | ||
288 | { | ||
289 | struct pcie_device *device; | ||
290 | |||
291 | device = kzalloc(sizeof(struct pcie_device), GFP_KERNEL); | ||
292 | if (!device) | ||
293 | return NULL; | ||
294 | |||
295 | pcie_device_init(parent, device, service_type, irq); | ||
296 | return device; | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * pcie_port_device_probe - check if device is a PCI Express port | ||
301 | * @dev: Device to check | ||
302 | */ | ||
303 | int pcie_port_device_probe(struct pci_dev *dev) | ||
304 | { | ||
305 | int pos, type; | ||
306 | u16 reg; | ||
307 | |||
308 | if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP))) | ||
309 | return -ENODEV; | ||
310 | |||
311 | pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, ®); | ||
312 | type = (reg >> 4) & PORT_TYPE_MASK; | ||
313 | if ( type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT || | ||
314 | type == PCIE_SW_DOWNSTREAM_PORT ) | ||
315 | return 0; | ||
316 | |||
317 | return -ENODEV; | ||
318 | } | 287 | } |
319 | 288 | ||
320 | /** | 289 | /** |
@@ -326,77 +295,49 @@ int pcie_port_device_probe(struct pci_dev *dev) | |||
326 | */ | 295 | */ |
327 | int pcie_port_device_register(struct pci_dev *dev) | 296 | int pcie_port_device_register(struct pci_dev *dev) |
328 | { | 297 | { |
329 | struct pcie_port_data *port_data; | 298 | int status, capabilities, i, nr_service; |
330 | int status, capabilities, irq_mode, i, nr_serv; | 299 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; |
331 | int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; | ||
332 | u16 reg16; | ||
333 | |||
334 | port_data = kzalloc(sizeof(*port_data), GFP_KERNEL); | ||
335 | if (!port_data) | ||
336 | return -ENOMEM; | ||
337 | pci_set_drvdata(dev, port_data); | ||
338 | |||
339 | /* Get port type */ | ||
340 | pci_read_config_word(dev, | ||
341 | pci_find_capability(dev, PCI_CAP_ID_EXP) + | ||
342 | PCIE_CAPABILITIES_REG, ®16); | ||
343 | port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK; | ||
344 | 300 | ||
301 | /* Get and check PCI Express port services */ | ||
345 | capabilities = get_port_device_capability(dev); | 302 | capabilities = get_port_device_capability(dev); |
346 | /* Root ports are capable of generating PME too */ | 303 | if (!capabilities) |
347 | if (port_data->port_type == PCIE_RC_PORT) | 304 | return -ENODEV; |
348 | capabilities |= PCIE_PORT_SERVICE_PME; | ||
349 | |||
350 | irq_mode = assign_interrupt_mode(dev, vectors, capabilities); | ||
351 | if (irq_mode == PCIE_PORT_NO_IRQ) { | ||
352 | /* | ||
353 | * Don't use service devices that require interrupts if there is | ||
354 | * no way to generate them. | ||
355 | */ | ||
356 | if (!(capabilities & PCIE_PORT_SERVICE_VC)) { | ||
357 | status = -ENODEV; | ||
358 | goto Error; | ||
359 | } | ||
360 | capabilities = PCIE_PORT_SERVICE_VC; | ||
361 | } | ||
362 | port_data->port_irq_mode = irq_mode; | ||
363 | 305 | ||
306 | /* Enable PCI Express port device */ | ||
364 | status = pci_enable_device(dev); | 307 | status = pci_enable_device(dev); |
365 | if (status) | 308 | if (status) |
366 | goto Error; | 309 | return status; |
367 | pci_set_master(dev); | 310 | pci_set_master(dev); |
311 | /* | ||
312 | * Initialize service irqs. Don't use service devices that | ||
313 | * require interrupts if there is no way to generate them. | ||
314 | */ | ||
315 | status = init_service_irqs(dev, irqs, capabilities); | ||
316 | if (status) { | ||
317 | capabilities &= PCIE_PORT_SERVICE_VC; | ||
318 | if (!capabilities) | ||
319 | goto error_disable; | ||
320 | } | ||
368 | 321 | ||
369 | /* Allocate child services if any */ | 322 | /* Allocate child services if any */ |
370 | for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { | 323 | status = -ENODEV; |
371 | struct pcie_device *child; | 324 | nr_service = 0; |
325 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { | ||
372 | int service = 1 << i; | 326 | int service = 1 << i; |
373 | |||
374 | if (!(capabilities & service)) | 327 | if (!(capabilities & service)) |
375 | continue; | 328 | continue; |
376 | 329 | if (!pcie_device_init(dev, service, irqs[i])) | |
377 | child = alloc_pcie_device(dev, service, vectors[i]); | 330 | nr_service++; |
378 | if (!child) | ||
379 | continue; | ||
380 | |||
381 | status = device_register(&child->device); | ||
382 | if (status) { | ||
383 | kfree(child); | ||
384 | continue; | ||
385 | } | ||
386 | |||
387 | get_device(&child->device); | ||
388 | nr_serv++; | ||
389 | } | ||
390 | if (!nr_serv) { | ||
391 | pci_disable_device(dev); | ||
392 | status = -ENODEV; | ||
393 | goto Error; | ||
394 | } | 331 | } |
332 | if (!nr_service) | ||
333 | goto error_cleanup_irqs; | ||
395 | 334 | ||
396 | return 0; | 335 | return 0; |
397 | 336 | ||
398 | Error: | 337 | error_cleanup_irqs: |
399 | kfree(port_data); | 338 | cleanup_service_irqs(dev); |
339 | error_disable: | ||
340 | pci_disable_device(dev); | ||
400 | return status; | 341 | return status; |
401 | } | 342 | } |
402 | 343 | ||
@@ -464,21 +405,9 @@ static int remove_iter(struct device *dev, void *data) | |||
464 | */ | 405 | */ |
465 | void pcie_port_device_remove(struct pci_dev *dev) | 406 | void pcie_port_device_remove(struct pci_dev *dev) |
466 | { | 407 | { |
467 | struct pcie_port_data *port_data = pci_get_drvdata(dev); | ||
468 | |||
469 | device_for_each_child(&dev->dev, NULL, remove_iter); | 408 | device_for_each_child(&dev->dev, NULL, remove_iter); |
409 | cleanup_service_irqs(dev); | ||
470 | pci_disable_device(dev); | 410 | pci_disable_device(dev); |
471 | |||
472 | switch (port_data->port_irq_mode) { | ||
473 | case PCIE_PORT_MSIX_MODE: | ||
474 | pci_disable_msix(dev); | ||
475 | break; | ||
476 | case PCIE_PORT_MSI_MODE: | ||
477 | pci_disable_msi(dev); | ||
478 | break; | ||
479 | } | ||
480 | |||
481 | kfree(port_data); | ||
482 | } | 411 | } |
483 | 412 | ||
484 | /** | 413 | /** |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f635e476d632..ce52ea34fee5 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -67,14 +67,16 @@ static struct dev_pm_ops pcie_portdrv_pm_ops = { | |||
67 | * this port device. | 67 | * this port device. |
68 | * | 68 | * |
69 | */ | 69 | */ |
70 | static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | 70 | static int __devinit pcie_portdrv_probe(struct pci_dev *dev, |
71 | const struct pci_device_id *id ) | 71 | const struct pci_device_id *id) |
72 | { | 72 | { |
73 | int status; | 73 | int status; |
74 | 74 | ||
75 | status = pcie_port_device_probe(dev); | 75 | if (!pci_is_pcie(dev) || |
76 | if (status) | 76 | ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && |
77 | return status; | 77 | (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) && |
78 | (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) | ||
79 | return -ENODEV; | ||
78 | 80 | ||
79 | if (!dev->irq && dev->pin) { | 81 | if (!dev->irq && dev->pin) { |
80 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " | 82 | dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; " |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8105e32117f6..98ffb2de22e9 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/cpumask.h> | 11 | #include <linux/cpumask.h> |
12 | #include <linux/pci-aspm.h> | 12 | #include <linux/pci-aspm.h> |
13 | #include <acpi/acpi_hest.h> | ||
13 | #include "pci.h" | 14 | #include "pci.h" |
14 | 15 | ||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 16 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
@@ -163,12 +164,12 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
163 | { | 164 | { |
164 | u32 l, sz, mask; | 165 | u32 l, sz, mask; |
165 | 166 | ||
166 | mask = type ? ~PCI_ROM_ADDRESS_ENABLE : ~0; | 167 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
167 | 168 | ||
168 | res->name = pci_name(dev); | 169 | res->name = pci_name(dev); |
169 | 170 | ||
170 | pci_read_config_dword(dev, pos, &l); | 171 | pci_read_config_dword(dev, pos, &l); |
171 | pci_write_config_dword(dev, pos, mask); | 172 | pci_write_config_dword(dev, pos, l | mask); |
172 | pci_read_config_dword(dev, pos, &sz); | 173 | pci_read_config_dword(dev, pos, &sz); |
173 | pci_write_config_dword(dev, pos, l); | 174 | pci_write_config_dword(dev, pos, l); |
174 | 175 | ||
@@ -223,9 +224,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
223 | goto fail; | 224 | goto fail; |
224 | 225 | ||
225 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { | 226 | if ((sizeof(resource_size_t) < 8) && (sz64 > 0x100000000ULL)) { |
226 | dev_err(&dev->dev, "can't handle 64-bit BAR\n"); | 227 | dev_err(&dev->dev, "reg %x: can't handle 64-bit BAR\n", |
228 | pos); | ||
227 | goto fail; | 229 | goto fail; |
228 | } else if ((sizeof(resource_size_t) < 8) && l) { | 230 | } |
231 | |||
232 | res->flags |= IORESOURCE_MEM_64; | ||
233 | if ((sizeof(resource_size_t) < 8) && l) { | ||
229 | /* Address above 32-bit boundary; disable the BAR */ | 234 | /* Address above 32-bit boundary; disable the BAR */ |
230 | pci_write_config_dword(dev, pos, 0); | 235 | pci_write_config_dword(dev, pos, 0); |
231 | pci_write_config_dword(dev, pos + 4, 0); | 236 | pci_write_config_dword(dev, pos + 4, 0); |
@@ -234,14 +239,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
234 | } else { | 239 | } else { |
235 | res->start = l64; | 240 | res->start = l64; |
236 | res->end = l64 + sz64; | 241 | res->end = l64 + sz64; |
237 | dev_printk(KERN_DEBUG, &dev->dev, | 242 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", |
238 | "reg %x %s: %pR\n", pos, | 243 | pos, res); |
239 | (res->flags & IORESOURCE_PREFETCH) ? | ||
240 | "64bit mmio pref" : "64bit mmio", | ||
241 | res); | ||
242 | } | 244 | } |
243 | |||
244 | res->flags |= IORESOURCE_MEM_64; | ||
245 | } else { | 245 | } else { |
246 | sz = pci_size(l, sz, mask); | 246 | sz = pci_size(l, sz, mask); |
247 | 247 | ||
@@ -251,11 +251,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
251 | res->start = l; | 251 | res->start = l; |
252 | res->end = l + sz; | 252 | res->end = l + sz; |
253 | 253 | ||
254 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos, | 254 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
255 | (res->flags & IORESOURCE_IO) ? "io port" : | ||
256 | ((res->flags & IORESOURCE_PREFETCH) ? | ||
257 | "32bit mmio pref" : "32bit mmio"), | ||
258 | res); | ||
259 | } | 255 | } |
260 | 256 | ||
261 | out: | 257 | out: |
@@ -297,8 +293,11 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
297 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ | 293 | if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */ |
298 | return; | 294 | return; |
299 | 295 | ||
296 | dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n", | ||
297 | child->secondary, child->subordinate, | ||
298 | dev->transparent ? " (subtractive decode)": ""); | ||
299 | |||
300 | if (dev->transparent) { | 300 | if (dev->transparent) { |
301 | dev_info(&dev->dev, "transparent bridge\n"); | ||
302 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | 301 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) |
303 | child->resource[i] = child->parent->resource[i - 3]; | 302 | child->resource[i] = child->parent->resource[i - 3]; |
304 | } | 303 | } |
@@ -323,7 +322,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
323 | res->start = base; | 322 | res->start = base; |
324 | if (!res->end) | 323 | if (!res->end) |
325 | res->end = limit + 0xfff; | 324 | res->end = limit + 0xfff; |
326 | dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res); | 325 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
327 | } | 326 | } |
328 | 327 | ||
329 | res = child->resource[1]; | 328 | res = child->resource[1]; |
@@ -335,8 +334,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
335 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 334 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
336 | res->start = base; | 335 | res->start = base; |
337 | res->end = limit + 0xfffff; | 336 | res->end = limit + 0xfffff; |
338 | dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n", | 337 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
339 | res); | ||
340 | } | 338 | } |
341 | 339 | ||
342 | res = child->resource[2]; | 340 | res = child->resource[2]; |
@@ -375,9 +373,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
375 | res->flags |= IORESOURCE_MEM_64; | 373 | res->flags |= IORESOURCE_MEM_64; |
376 | res->start = base; | 374 | res->start = base; |
377 | res->end = limit + 0xfffff; | 375 | res->end = limit + 0xfffff; |
378 | dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n", | 376 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
379 | (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", | ||
380 | res); | ||
381 | } | 377 | } |
382 | } | 378 | } |
383 | 379 | ||
@@ -651,13 +647,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, | |||
651 | (child->number > bus->subordinate) || | 647 | (child->number > bus->subordinate) || |
652 | (child->number < bus->number) || | 648 | (child->number < bus->number) || |
653 | (child->subordinate < bus->number)) { | 649 | (child->subordinate < bus->number)) { |
654 | pr_debug("PCI: Bus #%02x (-#%02x) is %s " | 650 | dev_info(&child->dev, "[bus %02x-%02x] %s " |
655 | "hidden behind%s bridge #%02x (-#%02x)\n", | 651 | "hidden behind%s bridge %s [bus %02x-%02x]\n", |
656 | child->number, child->subordinate, | 652 | child->number, child->subordinate, |
657 | (bus->number > child->subordinate && | 653 | (bus->number > child->subordinate && |
658 | bus->subordinate < child->number) ? | 654 | bus->subordinate < child->number) ? |
659 | "wholly" : "partially", | 655 | "wholly" : "partially", |
660 | bus->self->transparent ? " transparent" : "", | 656 | bus->self->transparent ? " transparent" : "", |
657 | dev_name(&bus->dev), | ||
661 | bus->number, bus->subordinate); | 658 | bus->number, bus->subordinate); |
662 | } | 659 | } |
663 | bus = bus->parent; | 660 | bus = bus->parent; |
@@ -693,6 +690,7 @@ static void set_pcie_port_type(struct pci_dev *pdev) | |||
693 | if (!pos) | 690 | if (!pos) |
694 | return; | 691 | return; |
695 | pdev->is_pcie = 1; | 692 | pdev->is_pcie = 1; |
693 | pdev->pcie_cap = pos; | ||
696 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 694 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
697 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | 695 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; |
698 | } | 696 | } |
@@ -703,7 +701,7 @@ static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
703 | u16 reg16; | 701 | u16 reg16; |
704 | u32 reg32; | 702 | u32 reg32; |
705 | 703 | ||
706 | pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); | 704 | pos = pci_pcie_cap(pdev); |
707 | if (!pos) | 705 | if (!pos) |
708 | return; | 706 | return; |
709 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 707 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
@@ -714,6 +712,12 @@ static void set_pcie_hotplug_bridge(struct pci_dev *pdev) | |||
714 | pdev->is_hotplug_bridge = 1; | 712 | pdev->is_hotplug_bridge = 1; |
715 | } | 713 | } |
716 | 714 | ||
715 | static void set_pci_aer_firmware_first(struct pci_dev *pdev) | ||
716 | { | ||
717 | if (acpi_hest_firmware_first_pci(pdev)) | ||
718 | pdev->aer_firmware_first = 1; | ||
719 | } | ||
720 | |||
717 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) | 721 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
718 | 722 | ||
719 | /** | 723 | /** |
@@ -731,6 +735,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
731 | u32 class; | 735 | u32 class; |
732 | u8 hdr_type; | 736 | u8 hdr_type; |
733 | struct pci_slot *slot; | 737 | struct pci_slot *slot; |
738 | int pos = 0; | ||
734 | 739 | ||
735 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) | 740 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) |
736 | return -EIO; | 741 | return -EIO; |
@@ -742,6 +747,7 @@ int pci_setup_device(struct pci_dev *dev) | |||
742 | dev->multifunction = !!(hdr_type & 0x80); | 747 | dev->multifunction = !!(hdr_type & 0x80); |
743 | dev->error_state = pci_channel_io_normal; | 748 | dev->error_state = pci_channel_io_normal; |
744 | set_pcie_port_type(dev); | 749 | set_pcie_port_type(dev); |
750 | set_pci_aer_firmware_first(dev); | ||
745 | 751 | ||
746 | list_for_each_entry(slot, &dev->bus->slots, list) | 752 | list_for_each_entry(slot, &dev->bus->slots, list) |
747 | if (PCI_SLOT(dev->devfn) == slot->number) | 753 | if (PCI_SLOT(dev->devfn) == slot->number) |
@@ -822,6 +828,11 @@ int pci_setup_device(struct pci_dev *dev) | |||
822 | dev->transparent = ((dev->class & 0xff) == 1); | 828 | dev->transparent = ((dev->class & 0xff) == 1); |
823 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); | 829 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); |
824 | set_pcie_hotplug_bridge(dev); | 830 | set_pcie_hotplug_bridge(dev); |
831 | pos = pci_find_capability(dev, PCI_CAP_ID_SSVID); | ||
832 | if (pos) { | ||
833 | pci_read_config_word(dev, pos + PCI_SSVID_VENDOR_ID, &dev->subsystem_vendor); | ||
834 | pci_read_config_word(dev, pos + PCI_SSVID_DEVICE_ID, &dev->subsystem_device); | ||
835 | } | ||
825 | break; | 836 | break; |
826 | 837 | ||
827 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ | 838 | case PCI_HEADER_TYPE_CARDBUS: /* CardBus bridge header */ |
@@ -907,7 +918,7 @@ int pci_cfg_space_size(struct pci_dev *dev) | |||
907 | if (class == PCI_CLASS_BRIDGE_HOST) | 918 | if (class == PCI_CLASS_BRIDGE_HOST) |
908 | return pci_cfg_space_size_ext(dev); | 919 | return pci_cfg_space_size_ext(dev); |
909 | 920 | ||
910 | pos = pci_find_capability(dev, PCI_CAP_ID_EXP); | 921 | pos = pci_pcie_cap(dev); |
911 | if (!pos) { | 922 | if (!pos) { |
912 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); | 923 | pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); |
913 | if (!pos) | 924 | if (!pos) |
@@ -1014,6 +1025,9 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1014 | 1025 | ||
1015 | /* Single Root I/O Virtualization */ | 1026 | /* Single Root I/O Virtualization */ |
1016 | pci_iov_init(dev); | 1027 | pci_iov_init(dev); |
1028 | |||
1029 | /* Enable ACS P2P upstream forwarding */ | ||
1030 | pci_enable_acs(dev); | ||
1017 | } | 1031 | } |
1018 | 1032 | ||
1019 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | 1033 | void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |
@@ -1110,7 +1124,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1110 | unsigned int devfn, pass, max = bus->secondary; | 1124 | unsigned int devfn, pass, max = bus->secondary; |
1111 | struct pci_dev *dev; | 1125 | struct pci_dev *dev; |
1112 | 1126 | ||
1113 | pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(bus), bus->number); | 1127 | dev_dbg(&bus->dev, "scanning bus\n"); |
1114 | 1128 | ||
1115 | /* Go find them, Rover! */ | 1129 | /* Go find them, Rover! */ |
1116 | for (devfn = 0; devfn < 0x100; devfn += 8) | 1130 | for (devfn = 0; devfn < 0x100; devfn += 8) |
@@ -1124,8 +1138,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1124 | * all PCI-to-PCI bridges on this bus. | 1138 | * all PCI-to-PCI bridges on this bus. |
1125 | */ | 1139 | */ |
1126 | if (!bus->is_added) { | 1140 | if (!bus->is_added) { |
1127 | pr_debug("PCI: Fixups for bus %04x:%02x\n", | 1141 | dev_dbg(&bus->dev, "fixups for bus\n"); |
1128 | pci_domain_nr(bus), bus->number); | ||
1129 | pcibios_fixup_bus(bus); | 1142 | pcibios_fixup_bus(bus); |
1130 | if (pci_is_root_bus(bus)) | 1143 | if (pci_is_root_bus(bus)) |
1131 | bus->is_added = 1; | 1144 | bus->is_added = 1; |
@@ -1145,8 +1158,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1145 | * | 1158 | * |
1146 | * Return how far we've got finding sub-buses. | 1159 | * Return how far we've got finding sub-buses. |
1147 | */ | 1160 | */ |
1148 | pr_debug("PCI: Bus scan for %04x:%02x returning with max=%02x\n", | 1161 | dev_dbg(&bus->dev, "bus scan returning with max=%02x\n", max); |
1149 | pci_domain_nr(bus), bus->number, max); | ||
1150 | return max; | 1162 | return max; |
1151 | } | 1163 | } |
1152 | 1164 | ||
@@ -1154,7 +1166,7 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1154 | int bus, struct pci_ops *ops, void *sysdata) | 1166 | int bus, struct pci_ops *ops, void *sysdata) |
1155 | { | 1167 | { |
1156 | int error; | 1168 | int error; |
1157 | struct pci_bus *b; | 1169 | struct pci_bus *b, *b2; |
1158 | struct device *dev; | 1170 | struct device *dev; |
1159 | 1171 | ||
1160 | b = pci_alloc_bus(); | 1172 | b = pci_alloc_bus(); |
@@ -1170,9 +1182,10 @@ struct pci_bus * pci_create_bus(struct device *parent, | |||
1170 | b->sysdata = sysdata; | 1182 | b->sysdata = sysdata; |
1171 | b->ops = ops; | 1183 | b->ops = ops; |
1172 | 1184 | ||
1173 | if (pci_find_bus(pci_domain_nr(b), bus)) { | 1185 | b2 = pci_find_bus(pci_domain_nr(b), bus); |
1186 | if (b2) { | ||
1174 | /* If we already got to this bus through a different bridge, ignore it */ | 1187 | /* If we already got to this bus through a different bridge, ignore it */ |
1175 | pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); | 1188 | dev_dbg(&b2->dev, "bus already known\n"); |
1176 | goto err_out; | 1189 | goto err_out; |
1177 | } | 1190 | } |
1178 | 1191 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 245d2cdb4765..7cfa7c38d318 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -357,7 +357,7 @@ static void __devinit quirk_io_region(struct pci_dev *dev, unsigned region, | |||
357 | pcibios_bus_to_resource(dev, res, &bus_region); | 357 | pcibios_bus_to_resource(dev, res, &bus_region); |
358 | 358 | ||
359 | pci_claim_resource(dev, nr); | 359 | pci_claim_resource(dev, nr); |
360 | dev_info(&dev->dev, "quirk: region %04x-%04x claimed by %s\n", region, region + size - 1, name); | 360 | dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name); |
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
@@ -1680,6 +1680,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_ | |||
1680 | */ | 1680 | */ |
1681 | #define AMD_813X_MISC 0x40 | 1681 | #define AMD_813X_MISC 0x40 |
1682 | #define AMD_813X_NOIOAMODE (1<<0) | 1682 | #define AMD_813X_NOIOAMODE (1<<0) |
1683 | #define AMD_813X_REV_B1 0x12 | ||
1683 | #define AMD_813X_REV_B2 0x13 | 1684 | #define AMD_813X_REV_B2 0x13 |
1684 | 1685 | ||
1685 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | 1686 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) |
@@ -1688,7 +1689,8 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1688 | 1689 | ||
1689 | if (noioapicquirk) | 1690 | if (noioapicquirk) |
1690 | return; | 1691 | return; |
1691 | if (dev->revision == AMD_813X_REV_B2) | 1692 | if ((dev->revision == AMD_813X_REV_B1) || |
1693 | (dev->revision == AMD_813X_REV_B2)) | ||
1692 | return; | 1694 | return; |
1693 | 1695 | ||
1694 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); | 1696 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); |
@@ -1698,8 +1700,10 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | |||
1698 | dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n", | 1700 | dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n", |
1699 | dev->vendor, dev->device); | 1701 | dev->vendor, dev->device); |
1700 | } | 1702 | } |
1701 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | 1703 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); |
1702 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | 1704 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); |
1705 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
1706 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
1703 | 1707 | ||
1704 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 | 1708 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 |
1705 | 1709 | ||
@@ -2595,9 +2599,37 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) | |||
2595 | static int __init pci_apply_final_quirks(void) | 2599 | static int __init pci_apply_final_quirks(void) |
2596 | { | 2600 | { |
2597 | struct pci_dev *dev = NULL; | 2601 | struct pci_dev *dev = NULL; |
2602 | u8 cls = 0; | ||
2603 | u8 tmp; | ||
2604 | |||
2605 | if (pci_cache_line_size) | ||
2606 | printk(KERN_DEBUG "PCI: CLS %u bytes\n", | ||
2607 | pci_cache_line_size << 2); | ||
2598 | 2608 | ||
2599 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 2609 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
2600 | pci_fixup_device(pci_fixup_final, dev); | 2610 | pci_fixup_device(pci_fixup_final, dev); |
2611 | /* | ||
2612 | * If arch hasn't set it explicitly yet, use the CLS | ||
2613 | * value shared by all PCI devices. If there's a | ||
2614 | * mismatch, fall back to the default value. | ||
2615 | */ | ||
2616 | if (!pci_cache_line_size) { | ||
2617 | pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp); | ||
2618 | if (!cls) | ||
2619 | cls = tmp; | ||
2620 | if (!tmp || cls == tmp) | ||
2621 | continue; | ||
2622 | |||
2623 | printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), " | ||
2624 | "using %u bytes\n", cls << 2, tmp << 2, | ||
2625 | pci_dfl_cache_line_size << 2); | ||
2626 | pci_cache_line_size = pci_dfl_cache_line_size; | ||
2627 | } | ||
2628 | } | ||
2629 | if (!pci_cache_line_size) { | ||
2630 | printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n", | ||
2631 | cls << 2, pci_dfl_cache_line_size << 2); | ||
2632 | pci_cache_line_size = cls; | ||
2601 | } | 2633 | } |
2602 | 2634 | ||
2603 | return 0; | 2635 | return 0; |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index ec415352d9ba..6dae87143258 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -26,14 +26,14 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) | |||
26 | { | 26 | { |
27 | struct pci_dev *tmp = NULL; | 27 | struct pci_dev *tmp = NULL; |
28 | 28 | ||
29 | if (pdev->is_pcie) | 29 | if (pci_is_pcie(pdev)) |
30 | return NULL; | 30 | return NULL; |
31 | while (1) { | 31 | while (1) { |
32 | if (pci_is_root_bus(pdev->bus)) | 32 | if (pci_is_root_bus(pdev->bus)) |
33 | break; | 33 | break; |
34 | pdev = pdev->bus->self; | 34 | pdev = pdev->bus->self; |
35 | /* a p2p bridge */ | 35 | /* a p2p bridge */ |
36 | if (!pdev->is_pcie) { | 36 | if (!pci_is_pcie(pdev)) { |
37 | tmp = pdev; | 37 | tmp = pdev; |
38 | continue; | 38 | continue; |
39 | } | 39 | } |
@@ -149,32 +149,33 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
149 | } | 149 | } |
150 | 150 | ||
151 | /** | 151 | /** |
152 | * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot | 152 | * pci_get_domain_bus_and_slot - locate PCI device for a given PCI domain (segment), bus, and slot |
153 | * @bus: number of PCI bus on which desired PCI device resides | 153 | * @domain: PCI domain/segment on which the PCI device resides. |
154 | * @devfn: encodes number of PCI slot in which the desired PCI | 154 | * @bus: PCI bus on which desired PCI device resides |
155 | * device resides and the logical device number within that slot | 155 | * @devfn: encodes number of PCI slot in which the desired PCI device |
156 | * in case of multi-function devices. | 156 | * resides and the logical device number within that slot in case of |
157 | * | 157 | * multi-function devices. |
158 | * Note: the bus/slot search is limited to PCI domain (segment) 0. | ||
159 | * | 158 | * |
160 | * Given a PCI bus and slot/function number, the desired PCI device | 159 | * Given a PCI domain, bus, and slot/function number, the desired PCI |
161 | * is located in system global list of PCI devices. If the device | 160 | * device is located in the list of PCI devices. If the device is |
162 | * is found, a pointer to its data structure is returned. If no | 161 | * found, its reference count is increased and this function returns a |
163 | * device is found, %NULL is returned. The returned device has its | 162 | * pointer to its data structure. The caller must decrement the |
164 | * reference count bumped by one. | 163 | * reference count by calling pci_dev_put(). If no device is found, |
164 | * %NULL is returned. | ||
165 | */ | 165 | */ |
166 | 166 | struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, | |
167 | struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | 167 | unsigned int devfn) |
168 | { | 168 | { |
169 | struct pci_dev *dev = NULL; | 169 | struct pci_dev *dev = NULL; |
170 | 170 | ||
171 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 171 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
172 | if (pci_domain_nr(dev->bus) == 0 && | 172 | if (pci_domain_nr(dev->bus) == domain && |
173 | (dev->bus->number == bus && dev->devfn == devfn)) | 173 | (dev->bus->number == bus && dev->devfn == devfn)) |
174 | return dev; | 174 | return dev; |
175 | } | 175 | } |
176 | return NULL; | 176 | return NULL; |
177 | } | 177 | } |
178 | EXPORT_SYMBOL(pci_get_domain_bus_and_slot); | ||
178 | 179 | ||
179 | static int match_pci_dev_by_id(struct device *dev, void *data) | 180 | static int match_pci_dev_by_id(struct device *dev, void *data) |
180 | { | 181 | { |
@@ -354,5 +355,4 @@ EXPORT_SYMBOL(pci_find_next_bus); | |||
354 | EXPORT_SYMBOL(pci_get_device); | 355 | EXPORT_SYMBOL(pci_get_device); |
355 | EXPORT_SYMBOL(pci_get_subsys); | 356 | EXPORT_SYMBOL(pci_get_subsys); |
356 | EXPORT_SYMBOL(pci_get_slot); | 357 | EXPORT_SYMBOL(pci_get_slot); |
357 | EXPORT_SYMBOL(pci_get_bus_and_slot); | ||
358 | EXPORT_SYMBOL(pci_get_class); | 358 | EXPORT_SYMBOL(pci_get_class); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index cb1a027eb552..c48cd377b3f5 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -71,53 +71,50 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus) | |||
71 | void pci_setup_cardbus(struct pci_bus *bus) | 71 | void pci_setup_cardbus(struct pci_bus *bus) |
72 | { | 72 | { |
73 | struct pci_dev *bridge = bus->self; | 73 | struct pci_dev *bridge = bus->self; |
74 | struct resource *res; | ||
74 | struct pci_bus_region region; | 75 | struct pci_bus_region region; |
75 | 76 | ||
76 | dev_info(&bridge->dev, "CardBus bridge, secondary bus %04x:%02x\n", | 77 | dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n", |
77 | pci_domain_nr(bus), bus->number); | 78 | bus->secondary, bus->subordinate); |
78 | 79 | ||
79 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | 80 | res = bus->resource[0]; |
80 | if (bus->resource[0]->flags & IORESOURCE_IO) { | 81 | pcibios_resource_to_bus(bridge, ®ion, res); |
82 | if (res->flags & IORESOURCE_IO) { | ||
81 | /* | 83 | /* |
82 | * The IO resource is allocated a range twice as large as it | 84 | * The IO resource is allocated a range twice as large as it |
83 | * would normally need. This allows us to set both IO regs. | 85 | * would normally need. This allows us to set both IO regs. |
84 | */ | 86 | */ |
85 | dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", | 87 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
86 | (unsigned long)region.start, | ||
87 | (unsigned long)region.end); | ||
88 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, | 88 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, |
89 | region.start); | 89 | region.start); |
90 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, | 90 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, |
91 | region.end); | 91 | region.end); |
92 | } | 92 | } |
93 | 93 | ||
94 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 94 | res = bus->resource[1]; |
95 | if (bus->resource[1]->flags & IORESOURCE_IO) { | 95 | pcibios_resource_to_bus(bridge, ®ion, res); |
96 | dev_info(&bridge->dev, " IO window: %#08lx-%#08lx\n", | 96 | if (res->flags & IORESOURCE_IO) { |
97 | (unsigned long)region.start, | 97 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
98 | (unsigned long)region.end); | ||
99 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, | 98 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, |
100 | region.start); | 99 | region.start); |
101 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, | 100 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, |
102 | region.end); | 101 | region.end); |
103 | } | 102 | } |
104 | 103 | ||
105 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 104 | res = bus->resource[2]; |
106 | if (bus->resource[2]->flags & IORESOURCE_MEM) { | 105 | pcibios_resource_to_bus(bridge, ®ion, res); |
107 | dev_info(&bridge->dev, " PREFETCH window: %#08lx-%#08lx\n", | 106 | if (res->flags & IORESOURCE_MEM) { |
108 | (unsigned long)region.start, | 107 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
109 | (unsigned long)region.end); | ||
110 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, | 108 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, |
111 | region.start); | 109 | region.start); |
112 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, | 110 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, |
113 | region.end); | 111 | region.end); |
114 | } | 112 | } |
115 | 113 | ||
116 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); | 114 | res = bus->resource[3]; |
117 | if (bus->resource[3]->flags & IORESOURCE_MEM) { | 115 | pcibios_resource_to_bus(bridge, ®ion, res); |
118 | dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", | 116 | if (res->flags & IORESOURCE_MEM) { |
119 | (unsigned long)region.start, | 117 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
120 | (unsigned long)region.end); | ||
121 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, | 118 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, |
122 | region.start); | 119 | region.start); |
123 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, | 120 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, |
@@ -140,34 +137,33 @@ EXPORT_SYMBOL(pci_setup_cardbus); | |||
140 | static void pci_setup_bridge(struct pci_bus *bus) | 137 | static void pci_setup_bridge(struct pci_bus *bus) |
141 | { | 138 | { |
142 | struct pci_dev *bridge = bus->self; | 139 | struct pci_dev *bridge = bus->self; |
140 | struct resource *res; | ||
143 | struct pci_bus_region region; | 141 | struct pci_bus_region region; |
144 | u32 l, bu, lu, io_upper16; | 142 | u32 l, bu, lu, io_upper16; |
145 | int pref_mem64; | ||
146 | 143 | ||
147 | if (pci_is_enabled(bridge)) | 144 | if (pci_is_enabled(bridge)) |
148 | return; | 145 | return; |
149 | 146 | ||
150 | dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n", | 147 | dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n", |
151 | pci_domain_nr(bus), bus->number); | 148 | bus->secondary, bus->subordinate); |
152 | 149 | ||
153 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | 150 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ |
154 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | 151 | res = bus->resource[0]; |
155 | if (bus->resource[0]->flags & IORESOURCE_IO) { | 152 | pcibios_resource_to_bus(bridge, ®ion, res); |
153 | if (res->flags & IORESOURCE_IO) { | ||
156 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | 154 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); |
157 | l &= 0xffff0000; | 155 | l &= 0xffff0000; |
158 | l |= (region.start >> 8) & 0x00f0; | 156 | l |= (region.start >> 8) & 0x00f0; |
159 | l |= region.end & 0xf000; | 157 | l |= region.end & 0xf000; |
160 | /* Set up upper 16 bits of I/O base/limit. */ | 158 | /* Set up upper 16 bits of I/O base/limit. */ |
161 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); | 159 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); |
162 | dev_info(&bridge->dev, " IO window: %#04lx-%#04lx\n", | 160 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
163 | (unsigned long)region.start, | ||
164 | (unsigned long)region.end); | ||
165 | } | 161 | } |
166 | else { | 162 | else { |
167 | /* Clear upper 16 bits of I/O base/limit. */ | 163 | /* Clear upper 16 bits of I/O base/limit. */ |
168 | io_upper16 = 0; | 164 | io_upper16 = 0; |
169 | l = 0x00f0; | 165 | l = 0x00f0; |
170 | dev_info(&bridge->dev, " IO window: disabled\n"); | 166 | dev_info(&bridge->dev, " bridge window [io disabled]\n"); |
171 | } | 167 | } |
172 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ | 168 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ |
173 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); | 169 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); |
@@ -178,17 +174,16 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
178 | 174 | ||
179 | /* Set up the top and bottom of the PCI Memory segment | 175 | /* Set up the top and bottom of the PCI Memory segment |
180 | for this bus. */ | 176 | for this bus. */ |
181 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | 177 | res = bus->resource[1]; |
182 | if (bus->resource[1]->flags & IORESOURCE_MEM) { | 178 | pcibios_resource_to_bus(bridge, ®ion, res); |
179 | if (res->flags & IORESOURCE_MEM) { | ||
183 | l = (region.start >> 16) & 0xfff0; | 180 | l = (region.start >> 16) & 0xfff0; |
184 | l |= region.end & 0xfff00000; | 181 | l |= region.end & 0xfff00000; |
185 | dev_info(&bridge->dev, " MEM window: %#08lx-%#08lx\n", | 182 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
186 | (unsigned long)region.start, | ||
187 | (unsigned long)region.end); | ||
188 | } | 183 | } |
189 | else { | 184 | else { |
190 | l = 0x0000fff0; | 185 | l = 0x0000fff0; |
191 | dev_info(&bridge->dev, " MEM window: disabled\n"); | 186 | dev_info(&bridge->dev, " bridge window [mem disabled]\n"); |
192 | } | 187 | } |
193 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | 188 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); |
194 | 189 | ||
@@ -198,34 +193,27 @@ static void pci_setup_bridge(struct pci_bus *bus) | |||
198 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); | 193 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); |
199 | 194 | ||
200 | /* Set up PREF base/limit. */ | 195 | /* Set up PREF base/limit. */ |
201 | pref_mem64 = 0; | ||
202 | bu = lu = 0; | 196 | bu = lu = 0; |
203 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | 197 | res = bus->resource[2]; |
204 | if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { | 198 | pcibios_resource_to_bus(bridge, ®ion, res); |
205 | int width = 8; | 199 | if (res->flags & IORESOURCE_PREFETCH) { |
206 | l = (region.start >> 16) & 0xfff0; | 200 | l = (region.start >> 16) & 0xfff0; |
207 | l |= region.end & 0xfff00000; | 201 | l |= region.end & 0xfff00000; |
208 | if (bus->resource[2]->flags & IORESOURCE_MEM_64) { | 202 | if (res->flags & IORESOURCE_MEM_64) { |
209 | pref_mem64 = 1; | ||
210 | bu = upper_32_bits(region.start); | 203 | bu = upper_32_bits(region.start); |
211 | lu = upper_32_bits(region.end); | 204 | lu = upper_32_bits(region.end); |
212 | width = 16; | ||
213 | } | 205 | } |
214 | dev_info(&bridge->dev, " PREFETCH window: %#0*llx-%#0*llx\n", | 206 | dev_info(&bridge->dev, " bridge window %pR\n", res); |
215 | width, (unsigned long long)region.start, | ||
216 | width, (unsigned long long)region.end); | ||
217 | } | 207 | } |
218 | else { | 208 | else { |
219 | l = 0x0000fff0; | 209 | l = 0x0000fff0; |
220 | dev_info(&bridge->dev, " PREFETCH window: disabled\n"); | 210 | dev_info(&bridge->dev, " bridge window [mem pref disabled]\n"); |
221 | } | 211 | } |
222 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); | 212 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); |
223 | 213 | ||
224 | if (pref_mem64) { | 214 | /* Set the upper 32 bits of PREF base & limit. */ |
225 | /* Set the upper 32 bits of PREF base & limit. */ | 215 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); |
226 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, bu); | 216 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); |
227 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, lu); | ||
228 | } | ||
229 | 217 | ||
230 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | 218 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); |
231 | } | 219 | } |
@@ -345,6 +333,10 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size) | |||
345 | #endif | 333 | #endif |
346 | size = ALIGN(size + size1, 4096); | 334 | size = ALIGN(size + size1, 4096); |
347 | if (!size) { | 335 | if (!size) { |
336 | if (b_res->start || b_res->end) | ||
337 | dev_info(&bus->self->dev, "disabling bridge window " | ||
338 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
339 | bus->secondary, bus->subordinate); | ||
348 | b_res->flags = 0; | 340 | b_res->flags = 0; |
349 | return; | 341 | return; |
350 | } | 342 | } |
@@ -390,8 +382,9 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
390 | align = pci_resource_alignment(dev, r); | 382 | align = pci_resource_alignment(dev, r); |
391 | order = __ffs(align) - 20; | 383 | order = __ffs(align) - 20; |
392 | if (order > 11) { | 384 | if (order > 11) { |
393 | dev_warn(&dev->dev, "BAR %d bad alignment %llx: " | 385 | dev_warn(&dev->dev, "disabling BAR %d: %pR " |
394 | "%pR\n", i, (unsigned long long)align, r); | 386 | "(bad alignment %#llx)\n", i, r, |
387 | (unsigned long long) align); | ||
395 | r->flags = 0; | 388 | r->flags = 0; |
396 | continue; | 389 | continue; |
397 | } | 390 | } |
@@ -425,6 +418,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
425 | } | 418 | } |
426 | size = ALIGN(size, min_align); | 419 | size = ALIGN(size, min_align); |
427 | if (!size) { | 420 | if (!size) { |
421 | if (b_res->start || b_res->end) | ||
422 | dev_info(&bus->self->dev, "disabling bridge window " | ||
423 | "%pR to [bus %02x-%02x] (unused)\n", b_res, | ||
424 | bus->secondary, bus->subordinate); | ||
428 | b_res->flags = 0; | 425 | b_res->flags = 0; |
429 | return 1; | 426 | return 1; |
430 | } | 427 | } |
@@ -582,10 +579,7 @@ static void pci_bus_dump_res(struct pci_bus *bus) | |||
582 | if (!res || !res->end) | 579 | if (!res || !res->end) |
583 | continue; | 580 | continue; |
584 | 581 | ||
585 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %s %pR\n", i, | 582 | dev_printk(KERN_DEBUG, &bus->dev, "resource %d %pR\n", i, res); |
586 | (res->flags & IORESOURCE_IO) ? "io: " : | ||
587 | ((res->flags & IORESOURCE_PREFETCH)? "pref mem":"mem:"), | ||
588 | res); | ||
589 | } | 583 | } |
590 | } | 584 | } |
591 | 585 | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index c54526b206b5..7d678bb15ffb 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -51,12 +51,6 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
51 | 51 | ||
52 | pcibios_resource_to_bus(dev, ®ion, res); | 52 | pcibios_resource_to_bus(dev, ®ion, res); |
53 | 53 | ||
54 | dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] " | ||
55 | "flags %#lx\n", resno, res, | ||
56 | (unsigned long long)region.start, | ||
57 | (unsigned long long)region.end, | ||
58 | (unsigned long)res->flags); | ||
59 | |||
60 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); | 54 | new = region.start | (res->flags & PCI_REGION_FLAG_MASK); |
61 | if (res->flags & IORESOURCE_IO) | 55 | if (res->flags & IORESOURCE_IO) |
62 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; | 56 | mask = (u32)PCI_BASE_ADDRESS_IO_MASK; |
@@ -91,9 +85,9 @@ void pci_update_resource(struct pci_dev *dev, int resno) | |||
91 | } | 85 | } |
92 | } | 86 | } |
93 | res->flags &= ~IORESOURCE_UNSET; | 87 | res->flags &= ~IORESOURCE_UNSET; |
94 | dev_dbg(&dev->dev, "BAR %d: moved to bus [%#llx-%#llx] flags %#lx\n", | 88 | dev_info(&dev->dev, "BAR %d: set to %pR (PCI address [%#llx-%#llx]\n", |
95 | resno, (unsigned long long)region.start, | 89 | resno, res, (unsigned long long)region.start, |
96 | (unsigned long long)region.end, res->flags); | 90 | (unsigned long long)region.end); |
97 | } | 91 | } |
98 | 92 | ||
99 | int pci_claim_resource(struct pci_dev *dev, int resource) | 93 | int pci_claim_resource(struct pci_dev *dev, int resource) |
@@ -103,20 +97,17 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
103 | int err; | 97 | int err; |
104 | 98 | ||
105 | root = pci_find_parent_resource(dev, res); | 99 | root = pci_find_parent_resource(dev, res); |
106 | 100 | if (!root) { | |
107 | err = -EINVAL; | 101 | dev_err(&dev->dev, "no compatible bridge window for %pR\n", |
108 | if (root != NULL) | 102 | res); |
109 | err = request_resource(root, res); | 103 | return -EINVAL; |
110 | |||
111 | if (err) { | ||
112 | const char *dtype = resource < PCI_BRIDGE_RESOURCES ? "device" : "bridge"; | ||
113 | dev_err(&dev->dev, "BAR %d: %s of %s %pR\n", | ||
114 | resource, | ||
115 | root ? "address space collision on" : | ||
116 | "no parent found for", | ||
117 | dtype, res); | ||
118 | } | 104 | } |
119 | 105 | ||
106 | err = request_resource(root, res); | ||
107 | if (err) | ||
108 | dev_err(&dev->dev, | ||
109 | "address space collision: %pR already in use\n", res); | ||
110 | |||
120 | return err; | 111 | return err; |
121 | } | 112 | } |
122 | EXPORT_SYMBOL(pci_claim_resource); | 113 | EXPORT_SYMBOL(pci_claim_resource); |
@@ -124,7 +115,7 @@ EXPORT_SYMBOL(pci_claim_resource); | |||
124 | #ifdef CONFIG_PCI_QUIRKS | 115 | #ifdef CONFIG_PCI_QUIRKS |
125 | void pci_disable_bridge_window(struct pci_dev *dev) | 116 | void pci_disable_bridge_window(struct pci_dev *dev) |
126 | { | 117 | { |
127 | dev_dbg(&dev->dev, "Disabling bridge window.\n"); | 118 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
128 | 119 | ||
129 | /* MMIO Base/Limit */ | 120 | /* MMIO Base/Limit */ |
130 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); | 121 | pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0); |
@@ -165,6 +156,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
165 | 156 | ||
166 | if (!ret) { | 157 | if (!ret) { |
167 | res->flags &= ~IORESOURCE_STARTALIGN; | 158 | res->flags &= ~IORESOURCE_STARTALIGN; |
159 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | ||
168 | if (resno < PCI_BRIDGE_RESOURCES) | 160 | if (resno < PCI_BRIDGE_RESOURCES) |
169 | pci_update_resource(dev, resno); | 161 | pci_update_resource(dev, resno); |
170 | } | 162 | } |
@@ -178,12 +170,12 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
178 | resource_size_t align; | 170 | resource_size_t align; |
179 | struct pci_bus *bus; | 171 | struct pci_bus *bus; |
180 | int ret; | 172 | int ret; |
173 | char *type; | ||
181 | 174 | ||
182 | align = pci_resource_alignment(dev, res); | 175 | align = pci_resource_alignment(dev, res); |
183 | if (!align) { | 176 | if (!align) { |
184 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | 177 | dev_info(&dev->dev, "BAR %d: can't assign %pR " |
185 | "alignment) %pR flags %#lx\n", | 178 | "(bogus alignment)\n", resno, res); |
186 | resno, res, res->flags); | ||
187 | return -EINVAL; | 179 | return -EINVAL; |
188 | } | 180 | } |
189 | 181 | ||
@@ -198,9 +190,20 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
198 | break; | 190 | break; |
199 | } | 191 | } |
200 | 192 | ||
201 | if (ret) | 193 | if (ret) { |
202 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | 194 | if (res->flags & IORESOURCE_MEM) |
203 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | 195 | if (res->flags & IORESOURCE_PREFETCH) |
196 | type = "mem pref"; | ||
197 | else | ||
198 | type = "mem"; | ||
199 | else if (res->flags & IORESOURCE_IO) | ||
200 | type = "io"; | ||
201 | else | ||
202 | type = "unknown"; | ||
203 | dev_info(&dev->dev, | ||
204 | "BAR %d: can't assign %s (size %#llx)\n", | ||
205 | resno, type, (unsigned long long) resource_size(res)); | ||
206 | } | ||
204 | 207 | ||
205 | return ret; | 208 | return ret; |
206 | } | 209 | } |
@@ -225,9 +228,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | |||
225 | 228 | ||
226 | r_align = pci_resource_alignment(dev, r); | 229 | r_align = pci_resource_alignment(dev, r); |
227 | if (!r_align) { | 230 | if (!r_align) { |
228 | dev_warn(&dev->dev, "BAR %d: bogus alignment " | 231 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", |
229 | "%pR flags %#lx\n", | 232 | i, r); |
230 | i, r, r->flags); | ||
231 | continue; | 233 | continue; |
232 | } | 234 | } |
233 | for (list = head; ; list = list->next) { | 235 | for (list = head; ; list = list->next) { |
@@ -274,8 +276,8 @@ int pci_enable_resources(struct pci_dev *dev, int mask) | |||
274 | continue; | 276 | continue; |
275 | 277 | ||
276 | if (!r->parent) { | 278 | if (!r->parent) { |
277 | dev_err(&dev->dev, "device not available because of " | 279 | dev_err(&dev->dev, "device not available " |
278 | "BAR %d %pR collisions\n", i, r); | 280 | "(can't reserve %pR)\n", r); |
279 | return -EINVAL; | 281 | return -EINVAL; |
280 | } | 282 | } |
281 | 283 | ||
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 4cd70d056810..a73b040ddbfb 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -184,26 +184,33 @@ fail: | |||
184 | 184 | ||
185 | =====================================================================*/ | 185 | =====================================================================*/ |
186 | 186 | ||
187 | /* | 187 | static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq) |
188 | * Since there is only one interrupt available to CardBus | ||
189 | * devices, all devices downstream of this device must | ||
190 | * be using this IRQ. | ||
191 | */ | ||
192 | static void cardbus_assign_irqs(struct pci_bus *bus, int irq) | ||
193 | { | 188 | { |
194 | struct pci_dev *dev; | 189 | struct pci_dev *dev; |
195 | 190 | ||
196 | list_for_each_entry(dev, &bus->devices, bus_list) { | 191 | list_for_each_entry(dev, &bus->devices, bus_list) { |
197 | u8 irq_pin; | 192 | u8 irq_pin; |
198 | 193 | ||
194 | /* | ||
195 | * Since there is only one interrupt available to | ||
196 | * CardBus devices, all devices downstream of this | ||
197 | * device must be using this IRQ. | ||
198 | */ | ||
199 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); | 199 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); |
200 | if (irq_pin) { | 200 | if (irq_pin) { |
201 | dev->irq = irq; | 201 | dev->irq = irq; |
202 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | 202 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); |
203 | } | 203 | } |
204 | 204 | ||
205 | /* | ||
206 | * Some controllers transfer very slowly with 0 CLS. | ||
207 | * Configure it. This may fail as CLS configuration | ||
208 | * is mandatory only for MWI. | ||
209 | */ | ||
210 | pci_set_cacheline_size(dev); | ||
211 | |||
205 | if (dev->subordinate) | 212 | if (dev->subordinate) |
206 | cardbus_assign_irqs(dev->subordinate, irq); | 213 | cardbus_config_irq_and_cls(dev->subordinate, irq); |
207 | } | 214 | } |
208 | } | 215 | } |
209 | 216 | ||
@@ -228,7 +235,7 @@ int __ref cb_alloc(struct pcmcia_socket * s) | |||
228 | */ | 235 | */ |
229 | pci_bus_size_bridges(bus); | 236 | pci_bus_size_bridges(bus); |
230 | pci_bus_assign_resources(bus); | 237 | pci_bus_assign_resources(bus); |
231 | cardbus_assign_irqs(bus, s->pci_irq); | 238 | cardbus_config_irq_and_cls(bus, s->pci_irq); |
232 | 239 | ||
233 | /* socket specific tune function */ | 240 | /* socket specific tune function */ |
234 | if (s->tune_bridge) | 241 | if (s->tune_bridge) |
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 8473fe5ed7ff..dfbd5a6cc58b 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -285,15 +285,10 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) | |||
285 | * the PCI region, and that might prevent a PCI | 285 | * the PCI region, and that might prevent a PCI |
286 | * driver from requesting its resources. | 286 | * driver from requesting its resources. |
287 | */ | 287 | */ |
288 | dev_warn(&dev->dev, "%s resource " | 288 | dev_warn(&dev->dev, |
289 | "(0x%llx-0x%llx) overlaps %s BAR %d " | 289 | "disabling %pR because it overlaps " |
290 | "(0x%llx-0x%llx), disabling\n", | 290 | "%s BAR %d %pR\n", res, |
291 | pnp_resource_type_name(res), | 291 | pci_name(pdev), i, &pdev->resource[i]); |
292 | (unsigned long long) pnp_start, | ||
293 | (unsigned long long) pnp_end, | ||
294 | pci_name(pdev), i, | ||
295 | (unsigned long long) pci_start, | ||
296 | (unsigned long long) pci_end); | ||
297 | res->flags |= IORESOURCE_DISABLED; | 292 | res->flags |= IORESOURCE_DISABLED; |
298 | } | 293 | } |
299 | } | 294 | } |
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index ba9765427886..64d0596bafb5 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c | |||
@@ -517,7 +517,7 @@ struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq, | |||
517 | res->start = irq; | 517 | res->start = irq; |
518 | res->end = irq; | 518 | res->end = irq; |
519 | 519 | ||
520 | pnp_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags); | 520 | pnp_dbg(&dev->dev, " add %pr\n", res); |
521 | return pnp_res; | 521 | return pnp_res; |
522 | } | 522 | } |
523 | 523 | ||
@@ -538,7 +538,7 @@ struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma, | |||
538 | res->start = dma; | 538 | res->start = dma; |
539 | res->end = dma; | 539 | res->end = dma; |
540 | 540 | ||
541 | pnp_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags); | 541 | pnp_dbg(&dev->dev, " add %pr\n", res); |
542 | return pnp_res; | 542 | return pnp_res; |
543 | } | 543 | } |
544 | 544 | ||
@@ -562,8 +562,7 @@ struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev, | |||
562 | res->start = start; | 562 | res->start = start; |
563 | res->end = end; | 563 | res->end = end; |
564 | 564 | ||
565 | pnp_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n", | 565 | pnp_dbg(&dev->dev, " add %pr\n", res); |
566 | (unsigned long long) start, (unsigned long long) end, flags); | ||
567 | return pnp_res; | 566 | return pnp_res; |
568 | } | 567 | } |
569 | 568 | ||
@@ -587,8 +586,7 @@ struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev, | |||
587 | res->start = start; | 586 | res->start = start; |
588 | res->end = end; | 587 | res->end = end; |
589 | 588 | ||
590 | pnp_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n", | 589 | pnp_dbg(&dev->dev, " add %pr\n", res); |
591 | (unsigned long long) start, (unsigned long long) end, flags); | ||
592 | return pnp_res; | 590 | return pnp_res; |
593 | } | 591 | } |
594 | 592 | ||
diff --git a/drivers/pnp/support.c b/drivers/pnp/support.c index 63087d5ce609..9585c1c1cc36 100644 --- a/drivers/pnp/support.c +++ b/drivers/pnp/support.c | |||
@@ -75,47 +75,14 @@ char *pnp_resource_type_name(struct resource *res) | |||
75 | 75 | ||
76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) | 76 | void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc) |
77 | { | 77 | { |
78 | char buf[128]; | ||
79 | int len; | ||
80 | struct pnp_resource *pnp_res; | 78 | struct pnp_resource *pnp_res; |
81 | struct resource *res; | ||
82 | 79 | ||
83 | if (list_empty(&dev->resources)) { | 80 | if (list_empty(&dev->resources)) |
84 | pnp_dbg(&dev->dev, "%s: no current resources\n", desc); | 81 | pnp_dbg(&dev->dev, "%s: no current resources\n", desc); |
85 | return; | 82 | else { |
86 | } | 83 | pnp_dbg(&dev->dev, "%s: current resources:\n", desc); |
87 | 84 | list_for_each_entry(pnp_res, &dev->resources, list) | |
88 | pnp_dbg(&dev->dev, "%s: current resources:\n", desc); | 85 | pnp_dbg(&dev->dev, "%pr\n", &pnp_res->res); |
89 | list_for_each_entry(pnp_res, &dev->resources, list) { | ||
90 | res = &pnp_res->res; | ||
91 | len = 0; | ||
92 | |||
93 | len += scnprintf(buf + len, sizeof(buf) - len, " %-3s ", | ||
94 | pnp_resource_type_name(res)); | ||
95 | |||
96 | if (res->flags & IORESOURCE_DISABLED) { | ||
97 | pnp_dbg(&dev->dev, "%sdisabled\n", buf); | ||
98 | continue; | ||
99 | } | ||
100 | |||
101 | switch (pnp_resource_type(res)) { | ||
102 | case IORESOURCE_IO: | ||
103 | case IORESOURCE_MEM: | ||
104 | len += scnprintf(buf + len, sizeof(buf) - len, | ||
105 | "%#llx-%#llx flags %#lx", | ||
106 | (unsigned long long) res->start, | ||
107 | (unsigned long long) res->end, | ||
108 | res->flags); | ||
109 | break; | ||
110 | case IORESOURCE_IRQ: | ||
111 | case IORESOURCE_DMA: | ||
112 | len += scnprintf(buf + len, sizeof(buf) - len, | ||
113 | "%lld flags %#lx", | ||
114 | (unsigned long long) res->start, | ||
115 | res->flags); | ||
116 | break; | ||
117 | } | ||
118 | pnp_dbg(&dev->dev, "%s\n", buf); | ||
119 | } | 86 | } |
120 | } | 87 | } |
121 | 88 | ||
diff --git a/drivers/pnp/system.c b/drivers/pnp/system.c index 59b90922da8c..49c1720df59a 100644 --- a/drivers/pnp/system.c +++ b/drivers/pnp/system.c | |||
@@ -22,11 +22,11 @@ static const struct pnp_device_id pnp_dev_table[] = { | |||
22 | {"", 0} | 22 | {"", 0} |
23 | }; | 23 | }; |
24 | 24 | ||
25 | static void reserve_range(struct pnp_dev *dev, resource_size_t start, | 25 | static void reserve_range(struct pnp_dev *dev, struct resource *r, int port) |
26 | resource_size_t end, int port) | ||
27 | { | 26 | { |
28 | char *regionid; | 27 | char *regionid; |
29 | const char *pnpid = dev_name(&dev->dev); | 28 | const char *pnpid = dev_name(&dev->dev); |
29 | resource_size_t start = r->start, end = r->end; | ||
30 | struct resource *res; | 30 | struct resource *res; |
31 | 31 | ||
32 | regionid = kmalloc(16, GFP_KERNEL); | 32 | regionid = kmalloc(16, GFP_KERNEL); |
@@ -48,10 +48,8 @@ static void reserve_range(struct pnp_dev *dev, resource_size_t start, | |||
48 | * example do reserve stuff they know about too, so we may well | 48 | * example do reserve stuff they know about too, so we may well |
49 | * have double reservations. | 49 | * have double reservations. |
50 | */ | 50 | */ |
51 | dev_info(&dev->dev, "%s range 0x%llx-0x%llx %s reserved\n", | 51 | dev_info(&dev->dev, "%pR %s reserved\n", r, |
52 | port ? "ioport" : "iomem", | 52 | res ? "has been" : "could not be"); |
53 | (unsigned long long) start, (unsigned long long) end, | ||
54 | res ? "has been" : "could not be"); | ||
55 | } | 53 | } |
56 | 54 | ||
57 | static void reserve_resources_of_dev(struct pnp_dev *dev) | 55 | static void reserve_resources_of_dev(struct pnp_dev *dev) |
@@ -77,14 +75,14 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) | |||
77 | if (res->end < res->start) | 75 | if (res->end < res->start) |
78 | continue; /* invalid */ | 76 | continue; /* invalid */ |
79 | 77 | ||
80 | reserve_range(dev, res->start, res->end, 1); | 78 | reserve_range(dev, res, 1); |
81 | } | 79 | } |
82 | 80 | ||
83 | for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { | 81 | for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { |
84 | if (res->flags & IORESOURCE_DISABLED) | 82 | if (res->flags & IORESOURCE_DISABLED) |
85 | continue; | 83 | continue; |
86 | 84 | ||
87 | reserve_range(dev, res->start, res->end, 0); | 85 | reserve_range(dev, res, 0); |
88 | } | 86 | } |
89 | } | 87 | } |
90 | 88 | ||
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index 91a68e9eb66d..603598f4dbb1 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c | |||
@@ -25,7 +25,10 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | |||
28 | #include <asm/xen/hypervisor.h> | 29 | #include <asm/xen/hypervisor.h> |
30 | |||
31 | #include <xen/xen.h> | ||
29 | #include <xen/events.h> | 32 | #include <xen/events.h> |
30 | #include <xen/page.h> | 33 | #include <xen/page.h> |
31 | #include <xen/interface/io/fbif.h> | 34 | #include <xen/interface/io/fbif.h> |
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 420433613584..f6738d8b02bc 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c | |||
@@ -52,6 +52,8 @@ | |||
52 | 52 | ||
53 | #include <asm/xen/hypervisor.h> | 53 | #include <asm/xen/hypervisor.h> |
54 | #include <asm/xen/hypercall.h> | 54 | #include <asm/xen/hypercall.h> |
55 | |||
56 | #include <xen/xen.h> | ||
55 | #include <xen/interface/xen.h> | 57 | #include <xen/interface/xen.h> |
56 | #include <xen/interface/memory.h> | 58 | #include <xen/interface/memory.h> |
57 | #include <xen/xenbus.h> | 59 | #include <xen/xenbus.h> |
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c index 0f765a920189..14e2d995e958 100644 --- a/drivers/xen/cpu_hotplug.c +++ b/drivers/xen/cpu_hotplug.c | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/notifier.h> | 1 | #include <linux/notifier.h> |
2 | 2 | ||
3 | #include <xen/xen.h> | ||
3 | #include <xen/xenbus.h> | 4 | #include <xen/xenbus.h> |
4 | 5 | ||
5 | #include <asm/xen/hypervisor.h> | 6 | #include <asm/xen/hypervisor.h> |
diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 79bedba44fee..f70a4f4698c5 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #include <linux/gfp.h> | 48 | #include <linux/gfp.h> |
49 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
50 | #include <linux/cpu.h> | 50 | #include <linux/cpu.h> |
51 | |||
52 | #include <xen/xen.h> | ||
51 | #include <xen/events.h> | 53 | #include <xen/events.h> |
52 | #include <xen/evtchn.h> | 54 | #include <xen/evtchn.h> |
53 | #include <asm/xen/hypervisor.h> | 55 | #include <asm/xen/hypervisor.h> |
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 7d8f531fb8e8..4c6c0bd636a8 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/vmalloc.h> | 37 | #include <linux/vmalloc.h> |
38 | #include <linux/uaccess.h> | 38 | #include <linux/uaccess.h> |
39 | 39 | ||
40 | #include <xen/xen.h> | ||
40 | #include <xen/interface/xen.h> | 41 | #include <xen/interface/xen.h> |
41 | #include <xen/page.h> | 42 | #include <xen/page.h> |
42 | #include <xen/grant_table.h> | 43 | #include <xen/grant_table.h> |
diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index 88a60e03ccf0..ae5cb05a1a1c 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/xen/hypervisor.h> | 14 | #include <asm/xen/hypervisor.h> |
15 | #include <asm/xen/hypercall.h> | 15 | #include <asm/xen/hypercall.h> |
16 | 16 | ||
17 | #include <xen/xen.h> | ||
17 | #include <xen/xenbus.h> | 18 | #include <xen/xenbus.h> |
18 | #include <xen/interface/xen.h> | 19 | #include <xen/interface/xen.h> |
19 | #include <xen/interface/version.h> | 20 | #include <xen/interface/version.h> |
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 649fcdf114b7..2f7aaa99dc47 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #include <asm/page.h> | 49 | #include <asm/page.h> |
50 | #include <asm/pgtable.h> | 50 | #include <asm/pgtable.h> |
51 | #include <asm/xen/hypervisor.h> | 51 | #include <asm/xen/hypervisor.h> |
52 | |||
53 | #include <xen/xen.h> | ||
52 | #include <xen/xenbus.h> | 54 | #include <xen/xenbus.h> |
53 | #include <xen/events.h> | 55 | #include <xen/events.h> |
54 | #include <xen/page.h> | 56 | #include <xen/page.h> |
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c index 6559e0c752ce..8924d93136f1 100644 --- a/drivers/xen/xenfs/super.c +++ b/drivers/xen/xenfs/super.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/magic.h> | 14 | #include <linux/magic.h> |
15 | 15 | ||
16 | #include <xen/xen.h> | ||
17 | |||
16 | #include "xenfs.h" | 18 | #include "xenfs.h" |
17 | 19 | ||
18 | #include <asm/xen/hypervisor.h> | 20 | #include <asm/xen/hypervisor.h> |
diff --git a/include/acpi/acpi_hest.h b/include/acpi/acpi_hest.h new file mode 100644 index 000000000000..63194d03cb2d --- /dev/null +++ b/include/acpi/acpi_hest.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef __ACPI_HEST_H | ||
2 | #define __ACPI_HEST_H | ||
3 | |||
4 | #include <linux/pci.h> | ||
5 | |||
6 | #ifdef CONFIG_ACPI | ||
7 | extern int acpi_hest_firmware_first_pci(struct pci_dev *pci); | ||
8 | #else | ||
9 | static inline int acpi_hest_firmware_first_pci(struct pci_dev *pci) { return 0; } | ||
10 | #endif | ||
11 | |||
12 | #endif | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index f5c7cd343e56..04771b9c3316 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -218,6 +218,7 @@ struct pci_dev { | |||
218 | unsigned int class; /* 3 bytes: (base,sub,prog-if) */ | 218 | unsigned int class; /* 3 bytes: (base,sub,prog-if) */ |
219 | u8 revision; /* PCI revision, low byte of class word */ | 219 | u8 revision; /* PCI revision, low byte of class word */ |
220 | u8 hdr_type; /* PCI header type (`multi' flag masked out) */ | 220 | u8 hdr_type; /* PCI header type (`multi' flag masked out) */ |
221 | u8 pcie_cap; /* PCI-E capability offset */ | ||
221 | u8 pcie_type; /* PCI-E device/port type */ | 222 | u8 pcie_type; /* PCI-E device/port type */ |
222 | u8 rom_base_reg; /* which config register controls the ROM */ | 223 | u8 rom_base_reg; /* which config register controls the ROM */ |
223 | u8 pin; /* which interrupt pin this device uses */ | 224 | u8 pin; /* which interrupt pin this device uses */ |
@@ -280,6 +281,7 @@ struct pci_dev { | |||
280 | unsigned int is_virtfn:1; | 281 | unsigned int is_virtfn:1; |
281 | unsigned int reset_fn:1; | 282 | unsigned int reset_fn:1; |
282 | unsigned int is_hotplug_bridge:1; | 283 | unsigned int is_hotplug_bridge:1; |
284 | unsigned int aer_firmware_first:1; | ||
283 | pci_dev_flags_t dev_flags; | 285 | pci_dev_flags_t dev_flags; |
284 | atomic_t enable_cnt; /* pci_enable_device has been called */ | 286 | atomic_t enable_cnt; /* pci_enable_device has been called */ |
285 | 287 | ||
@@ -635,7 +637,13 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, | |||
635 | unsigned int ss_vendor, unsigned int ss_device, | 637 | unsigned int ss_vendor, unsigned int ss_device, |
636 | struct pci_dev *from); | 638 | struct pci_dev *from); |
637 | struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn); | 639 | struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn); |
638 | struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn); | 640 | struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus, |
641 | unsigned int devfn); | ||
642 | static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus, | ||
643 | unsigned int devfn) | ||
644 | { | ||
645 | return pci_get_domain_bus_and_slot(0, bus, devfn); | ||
646 | } | ||
639 | struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from); | 647 | struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from); |
640 | int pci_dev_present(const struct pci_device_id *ids); | 648 | int pci_dev_present(const struct pci_device_id *ids); |
641 | 649 | ||
@@ -701,6 +709,7 @@ void pci_disable_device(struct pci_dev *dev); | |||
701 | void pci_set_master(struct pci_dev *dev); | 709 | void pci_set_master(struct pci_dev *dev); |
702 | void pci_clear_master(struct pci_dev *dev); | 710 | void pci_clear_master(struct pci_dev *dev); |
703 | int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); | 711 | int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); |
712 | int pci_set_cacheline_size(struct pci_dev *dev); | ||
704 | #define HAVE_PCI_SET_MWI | 713 | #define HAVE_PCI_SET_MWI |
705 | int __must_check pci_set_mwi(struct pci_dev *dev); | 714 | int __must_check pci_set_mwi(struct pci_dev *dev); |
706 | int pci_try_set_mwi(struct pci_dev *dev); | 715 | int pci_try_set_mwi(struct pci_dev *dev); |
@@ -1246,6 +1255,8 @@ extern int pci_pci_problems; | |||
1246 | 1255 | ||
1247 | extern unsigned long pci_cardbus_io_size; | 1256 | extern unsigned long pci_cardbus_io_size; |
1248 | extern unsigned long pci_cardbus_mem_size; | 1257 | extern unsigned long pci_cardbus_mem_size; |
1258 | extern u8 pci_dfl_cache_line_size; | ||
1259 | extern u8 pci_cache_line_size; | ||
1249 | 1260 | ||
1250 | extern unsigned long pci_hotplug_io_size; | 1261 | extern unsigned long pci_hotplug_io_size; |
1251 | extern unsigned long pci_hotplug_mem_size; | 1262 | extern unsigned long pci_hotplug_mem_size; |
@@ -1290,5 +1301,34 @@ extern void pci_hp_create_module_link(struct pci_slot *pci_slot); | |||
1290 | extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); | 1301 | extern void pci_hp_remove_module_link(struct pci_slot *pci_slot); |
1291 | #endif | 1302 | #endif |
1292 | 1303 | ||
1304 | /** | ||
1305 | * pci_pcie_cap - get the saved PCIe capability offset | ||
1306 | * @dev: PCI device | ||
1307 | * | ||
1308 | * PCIe capability offset is calculated at PCI device initialization | ||
1309 | * time and saved in the data structure. This function returns saved | ||
1310 | * PCIe capability offset. Using this instead of pci_find_capability() | ||
1311 | * reduces unnecessary search in the PCI configuration space. If you | ||
1312 | * need to calculate PCIe capability offset from raw device for some | ||
1313 | * reasons, please use pci_find_capability() instead. | ||
1314 | */ | ||
1315 | static inline int pci_pcie_cap(struct pci_dev *dev) | ||
1316 | { | ||
1317 | return dev->pcie_cap; | ||
1318 | } | ||
1319 | |||
1320 | /** | ||
1321 | * pci_is_pcie - check if the PCI device is PCI Express capable | ||
1322 | * @dev: PCI device | ||
1323 | * | ||
1324 | * Retrun true if the PCI device is PCI Express capable, false otherwise. | ||
1325 | */ | ||
1326 | static inline bool pci_is_pcie(struct pci_dev *dev) | ||
1327 | { | ||
1328 | return !!pci_pcie_cap(dev); | ||
1329 | } | ||
1330 | |||
1331 | void pci_request_acs(void); | ||
1332 | |||
1293 | #endif /* __KERNEL__ */ | 1333 | #endif /* __KERNEL__ */ |
1294 | #endif /* LINUX_PCI_H */ | 1334 | #endif /* LINUX_PCI_H */ |
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index dd0bed4f1cf0..9f2ad0aa3c39 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h | |||
@@ -365,6 +365,11 @@ | |||
365 | #define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ | 365 | #define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ |
366 | #define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ | 366 | #define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ |
367 | 367 | ||
368 | /* PCI Bridge Subsystem ID registers */ | ||
369 | |||
370 | #define PCI_SSVID_VENDOR_ID 4 /* PCI-Bridge subsystem vendor id register */ | ||
371 | #define PCI_SSVID_DEVICE_ID 6 /* PCI-Bridge subsystem device id register */ | ||
372 | |||
368 | /* PCI Express capability registers */ | 373 | /* PCI Express capability registers */ |
369 | 374 | ||
370 | #define PCI_EXP_FLAGS 2 /* Capabilities register */ | 375 | #define PCI_EXP_FLAGS 2 /* Capabilities register */ |
@@ -502,6 +507,7 @@ | |||
502 | #define PCI_EXT_CAP_ID_VC 2 | 507 | #define PCI_EXT_CAP_ID_VC 2 |
503 | #define PCI_EXT_CAP_ID_DSN 3 | 508 | #define PCI_EXT_CAP_ID_DSN 3 |
504 | #define PCI_EXT_CAP_ID_PWR 4 | 509 | #define PCI_EXT_CAP_ID_PWR 4 |
510 | #define PCI_EXT_CAP_ID_ACS 13 | ||
505 | #define PCI_EXT_CAP_ID_ARI 14 | 511 | #define PCI_EXT_CAP_ID_ARI 14 |
506 | #define PCI_EXT_CAP_ID_ATS 15 | 512 | #define PCI_EXT_CAP_ID_ATS 15 |
507 | #define PCI_EXT_CAP_ID_SRIOV 16 | 513 | #define PCI_EXT_CAP_ID_SRIOV 16 |
@@ -662,4 +668,16 @@ | |||
662 | #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ | 668 | #define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */ |
663 | #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ | 669 | #define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */ |
664 | 670 | ||
671 | /* Access Control Service */ | ||
672 | #define PCI_ACS_CAP 0x04 /* ACS Capability Register */ | ||
673 | #define PCI_ACS_SV 0x01 /* Source Validation */ | ||
674 | #define PCI_ACS_TB 0x02 /* Translation Blocking */ | ||
675 | #define PCI_ACS_RR 0x04 /* P2P Request Redirect */ | ||
676 | #define PCI_ACS_CR 0x08 /* P2P Completion Redirect */ | ||
677 | #define PCI_ACS_UF 0x10 /* Upstream Forwarding */ | ||
678 | #define PCI_ACS_EC 0x20 /* P2P Egress Control */ | ||
679 | #define PCI_ACS_DT 0x40 /* Direct Translated P2P */ | ||
680 | #define PCI_ACS_CTRL 0x06 /* ACS Control Register */ | ||
681 | #define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */ | ||
682 | |||
665 | #endif /* LINUX_PCI_REGS_H */ | 683 | #endif /* LINUX_PCI_REGS_H */ |
diff --git a/include/linux/pcieport_if.h b/include/linux/pcieport_if.h index b4c79545330b..6775532b92a9 100644 --- a/include/linux/pcieport_if.h +++ b/include/linux/pcieport_if.h | |||
@@ -10,10 +10,7 @@ | |||
10 | #define _PCIEPORT_IF_H_ | 10 | #define _PCIEPORT_IF_H_ |
11 | 11 | ||
12 | /* Port Type */ | 12 | /* Port Type */ |
13 | #define PCIE_RC_PORT 4 /* Root port of RC */ | 13 | #define PCIE_ANY_PORT (~0) |
14 | #define PCIE_SW_UPSTREAM_PORT 5 /* Upstream port of Switch */ | ||
15 | #define PCIE_SW_DOWNSTREAM_PORT 6 /* Downstream port of Switch */ | ||
16 | #define PCIE_ANY_PORT 7 | ||
17 | 14 | ||
18 | /* Service Type */ | 15 | /* Service Type */ |
19 | #define PCIE_PORT_SERVICE_PME_SHIFT 0 /* Power Management Event */ | 16 | #define PCIE_PORT_SERVICE_PME_SHIFT 0 /* Power Management Event */ |
@@ -25,17 +22,6 @@ | |||
25 | #define PCIE_PORT_SERVICE_VC_SHIFT 3 /* Virtual Channel */ | 22 | #define PCIE_PORT_SERVICE_VC_SHIFT 3 /* Virtual Channel */ |
26 | #define PCIE_PORT_SERVICE_VC (1 << PCIE_PORT_SERVICE_VC_SHIFT) | 23 | #define PCIE_PORT_SERVICE_VC (1 << PCIE_PORT_SERVICE_VC_SHIFT) |
27 | 24 | ||
28 | /* Root/Upstream/Downstream Port's Interrupt Mode */ | ||
29 | #define PCIE_PORT_NO_IRQ (-1) | ||
30 | #define PCIE_PORT_INTx_MODE 0 | ||
31 | #define PCIE_PORT_MSI_MODE 1 | ||
32 | #define PCIE_PORT_MSIX_MODE 2 | ||
33 | |||
34 | struct pcie_port_data { | ||
35 | int port_type; /* Type of the port */ | ||
36 | int port_irq_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ | ||
37 | }; | ||
38 | |||
39 | struct pcie_device { | 25 | struct pcie_device { |
40 | int irq; /* Service IRQ/MSI/MSI-X Vector */ | 26 | int irq; /* Service IRQ/MSI/MSI-X Vector */ |
41 | struct pci_dev *port; /* Root/Upstream/Downstream Port */ | 27 | struct pci_dev *port; /* Root/Upstream/Downstream Port */ |
diff --git a/include/xen/xen.h b/include/xen/xen.h new file mode 100644 index 000000000000..a16402418d31 --- /dev/null +++ b/include/xen/xen.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef _XEN_XEN_H | ||
2 | #define _XEN_XEN_H | ||
3 | |||
4 | enum xen_domain_type { | ||
5 | XEN_NATIVE, /* running on bare hardware */ | ||
6 | XEN_PV_DOMAIN, /* running in a PV domain */ | ||
7 | XEN_HVM_DOMAIN, /* running in a Xen hvm domain */ | ||
8 | }; | ||
9 | |||
10 | #ifdef CONFIG_XEN | ||
11 | extern enum xen_domain_type xen_domain_type; | ||
12 | #else | ||
13 | #define xen_domain_type XEN_NATIVE | ||
14 | #endif | ||
15 | |||
16 | #define xen_domain() (xen_domain_type != XEN_NATIVE) | ||
17 | #define xen_pv_domain() (xen_domain() && \ | ||
18 | xen_domain_type == XEN_PV_DOMAIN) | ||
19 | #define xen_hvm_domain() (xen_domain() && \ | ||
20 | xen_domain_type == XEN_HVM_DOMAIN) | ||
21 | |||
22 | #ifdef CONFIG_XEN_DOM0 | ||
23 | #include <xen/interface/xen.h> | ||
24 | #include <asm/xen/hypervisor.h> | ||
25 | |||
26 | #define xen_initial_domain() (xen_pv_domain() && \ | ||
27 | xen_start_info->flags & SIF_INITDOMAIN) | ||
28 | #else /* !CONFIG_XEN_DOM0 */ | ||
29 | #define xen_initial_domain() (0) | ||
30 | #endif /* CONFIG_XEN_DOM0 */ | ||
31 | |||
32 | #endif /* _XEN_XEN_H */ | ||
diff --git a/kernel/resource.c b/kernel/resource.c index fb11a58b9594..dc15686b7a77 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -308,35 +308,37 @@ static int find_resource(struct resource *root, struct resource *new, | |||
308 | void *alignf_data) | 308 | void *alignf_data) |
309 | { | 309 | { |
310 | struct resource *this = root->child; | 310 | struct resource *this = root->child; |
311 | resource_size_t start, end; | ||
311 | 312 | ||
312 | new->start = root->start; | 313 | start = root->start; |
313 | /* | 314 | /* |
314 | * Skip past an allocated resource that starts at 0, since the assignment | 315 | * Skip past an allocated resource that starts at 0, since the assignment |
315 | * of this->start - 1 to new->end below would cause an underflow. | 316 | * of this->start - 1 to new->end below would cause an underflow. |
316 | */ | 317 | */ |
317 | if (this && this->start == 0) { | 318 | if (this && this->start == 0) { |
318 | new->start = this->end + 1; | 319 | start = this->end + 1; |
319 | this = this->sibling; | 320 | this = this->sibling; |
320 | } | 321 | } |
321 | for(;;) { | 322 | for(;;) { |
322 | if (this) | 323 | if (this) |
323 | new->end = this->start - 1; | 324 | end = this->start - 1; |
324 | else | 325 | else |
325 | new->end = root->end; | 326 | end = root->end; |
326 | if (new->start < min) | 327 | if (start < min) |
327 | new->start = min; | 328 | start = min; |
328 | if (new->end > max) | 329 | if (end > max) |
329 | new->end = max; | 330 | end = max; |
330 | new->start = ALIGN(new->start, align); | 331 | start = ALIGN(start, align); |
331 | if (alignf) | 332 | if (alignf) |
332 | alignf(alignf_data, new, size, align); | 333 | alignf(alignf_data, new, size, align); |
333 | if (new->start < new->end && new->end - new->start >= size - 1) { | 334 | if (start < end && end - start >= size - 1) { |
334 | new->end = new->start + size - 1; | 335 | new->start = start; |
336 | new->end = start + size - 1; | ||
335 | return 0; | 337 | return 0; |
336 | } | 338 | } |
337 | if (!this) | 339 | if (!this) |
338 | break; | 340 | break; |
339 | new->start = this->end + 1; | 341 | start = this->end + 1; |
340 | this = this->sibling; | 342 | this = this->sibling; |
341 | } | 343 | } |
342 | return -EBUSY; | 344 | return -EBUSY; |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 33bed5e67a21..6438cd5599ee 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -595,37 +595,89 @@ static char *symbol_string(char *buf, char *end, void *ptr, | |||
595 | } | 595 | } |
596 | 596 | ||
597 | static char *resource_string(char *buf, char *end, struct resource *res, | 597 | static char *resource_string(char *buf, char *end, struct resource *res, |
598 | struct printf_spec spec) | 598 | struct printf_spec spec, const char *fmt) |
599 | { | 599 | { |
600 | #ifndef IO_RSRC_PRINTK_SIZE | 600 | #ifndef IO_RSRC_PRINTK_SIZE |
601 | #define IO_RSRC_PRINTK_SIZE 4 | 601 | #define IO_RSRC_PRINTK_SIZE 6 |
602 | #endif | 602 | #endif |
603 | 603 | ||
604 | #ifndef MEM_RSRC_PRINTK_SIZE | 604 | #ifndef MEM_RSRC_PRINTK_SIZE |
605 | #define MEM_RSRC_PRINTK_SIZE 8 | 605 | #define MEM_RSRC_PRINTK_SIZE 10 |
606 | #endif | 606 | #endif |
607 | struct printf_spec num_spec = { | 607 | struct printf_spec hex_spec = { |
608 | .base = 16, | 608 | .base = 16, |
609 | .precision = -1, | 609 | .precision = -1, |
610 | .flags = SPECIAL | SMALL | ZEROPAD, | 610 | .flags = SPECIAL | SMALL | ZEROPAD, |
611 | }; | 611 | }; |
612 | /* room for the actual numbers, the two "0x", -, [, ] and the final zero */ | 612 | struct printf_spec dec_spec = { |
613 | char sym[4*sizeof(resource_size_t) + 8]; | 613 | .base = 10, |
614 | .precision = -1, | ||
615 | .flags = 0, | ||
616 | }; | ||
617 | struct printf_spec str_spec = { | ||
618 | .field_width = -1, | ||
619 | .precision = 10, | ||
620 | .flags = LEFT, | ||
621 | }; | ||
622 | struct printf_spec flag_spec = { | ||
623 | .base = 16, | ||
624 | .precision = -1, | ||
625 | .flags = SPECIAL | SMALL, | ||
626 | }; | ||
627 | |||
628 | /* 32-bit res (sizeof==4): 10 chars in dec, 10 in hex ("0x" + 8) | ||
629 | * 64-bit res (sizeof==8): 20 chars in dec, 18 in hex ("0x" + 16) */ | ||
630 | #define RSRC_BUF_SIZE ((2 * sizeof(resource_size_t)) + 4) | ||
631 | #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) | ||
632 | #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref disabled]") | ||
633 | #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") | ||
634 | char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, | ||
635 | 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; | ||
636 | |||
614 | char *p = sym, *pend = sym + sizeof(sym); | 637 | char *p = sym, *pend = sym + sizeof(sym); |
615 | int size = -1; | 638 | int size = -1, addr = 0; |
639 | int decode = (fmt[0] == 'R') ? 1 : 0; | ||
616 | 640 | ||
617 | if (res->flags & IORESOURCE_IO) | 641 | if (res->flags & IORESOURCE_IO) { |
618 | size = IO_RSRC_PRINTK_SIZE; | 642 | size = IO_RSRC_PRINTK_SIZE; |
619 | else if (res->flags & IORESOURCE_MEM) | 643 | addr = 1; |
644 | } else if (res->flags & IORESOURCE_MEM) { | ||
620 | size = MEM_RSRC_PRINTK_SIZE; | 645 | size = MEM_RSRC_PRINTK_SIZE; |
646 | addr = 1; | ||
647 | } | ||
621 | 648 | ||
622 | *p++ = '['; | 649 | *p++ = '['; |
623 | num_spec.field_width = size; | 650 | if (res->flags & IORESOURCE_IO) |
624 | p = number(p, pend, res->start, num_spec); | 651 | p = string(p, pend, "io ", str_spec); |
625 | *p++ = '-'; | 652 | else if (res->flags & IORESOURCE_MEM) |
626 | p = number(p, pend, res->end, num_spec); | 653 | p = string(p, pend, "mem ", str_spec); |
654 | else if (res->flags & IORESOURCE_IRQ) | ||
655 | p = string(p, pend, "irq ", str_spec); | ||
656 | else if (res->flags & IORESOURCE_DMA) | ||
657 | p = string(p, pend, "dma ", str_spec); | ||
658 | else { | ||
659 | p = string(p, pend, "??? ", str_spec); | ||
660 | decode = 0; | ||
661 | } | ||
662 | hex_spec.field_width = size; | ||
663 | p = number(p, pend, res->start, addr ? hex_spec : dec_spec); | ||
664 | if (res->start != res->end) { | ||
665 | *p++ = '-'; | ||
666 | p = number(p, pend, res->end, addr ? hex_spec : dec_spec); | ||
667 | } | ||
668 | if (decode) { | ||
669 | if (res->flags & IORESOURCE_MEM_64) | ||
670 | p = string(p, pend, " 64bit", str_spec); | ||
671 | if (res->flags & IORESOURCE_PREFETCH) | ||
672 | p = string(p, pend, " pref", str_spec); | ||
673 | if (res->flags & IORESOURCE_DISABLED) | ||
674 | p = string(p, pend, " disabled", str_spec); | ||
675 | } else { | ||
676 | p = string(p, pend, " flags ", str_spec); | ||
677 | p = number(p, pend, res->flags, flag_spec); | ||
678 | } | ||
627 | *p++ = ']'; | 679 | *p++ = ']'; |
628 | *p = 0; | 680 | *p = '\0'; |
629 | 681 | ||
630 | return string(buf, end, sym, spec); | 682 | return string(buf, end, sym, spec); |
631 | } | 683 | } |
@@ -801,8 +853,8 @@ static char *ip4_addr_string(char *buf, char *end, const u8 *addr, | |||
801 | * - 'f' For simple symbolic function names without offset | 853 | * - 'f' For simple symbolic function names without offset |
802 | * - 'S' For symbolic direct pointers with offset | 854 | * - 'S' For symbolic direct pointers with offset |
803 | * - 's' For symbolic direct pointers without offset | 855 | * - 's' For symbolic direct pointers without offset |
804 | * - 'R' For a struct resource pointer, it prints the range of | 856 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
805 | * addresses (not the name nor the flags) | 857 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
806 | * - 'M' For a 6-byte MAC address, it prints the address in the | 858 | * - 'M' For a 6-byte MAC address, it prints the address in the |
807 | * usual colon-separated hex notation | 859 | * usual colon-separated hex notation |
808 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons | 860 | * - 'm' For a 6-byte MAC address, it prints the hex address without colons |
@@ -833,7 +885,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
833 | case 'S': | 885 | case 'S': |
834 | return symbol_string(buf, end, ptr, spec, *fmt); | 886 | return symbol_string(buf, end, ptr, spec, *fmt); |
835 | case 'R': | 887 | case 'R': |
836 | return resource_string(buf, end, ptr, spec); | 888 | case 'r': |
889 | return resource_string(buf, end, ptr, spec, fmt); | ||
837 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ | 890 | case 'M': /* Colon separated: 00:01:02:03:04:05 */ |
838 | case 'm': /* Contiguous: 000102030405 */ | 891 | case 'm': /* Contiguous: 000102030405 */ |
839 | return mac_address_string(buf, end, ptr, spec, fmt); | 892 | return mac_address_string(buf, end, ptr, spec, fmt); |