diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-09-07 02:19:51 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-09-07 02:19:51 -0400 |
commit | a1922ed661ab2c1637d0b10cde933bd9cd33d965 (patch) | |
tree | 0f1777542b385ebefd30b3586d830fd8ed6fda5b /arch/x86/pci/acpi.c | |
parent | 75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (diff) | |
parent | d28daf923ac5e4a0d7cecebae56f3e339189366b (diff) |
Merge branch 'tracing/core' into tracing/hw-breakpoints
Conflicts:
arch/Kconfig
kernel/trace/trace.h
Merge reason: resolve the conflicts, plus adopt to the new
ring-buffer APIs.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/pci/acpi.c')
-rw-r--r-- | arch/x86/pci/acpi.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index c0ecf250fe51..1014eb4bfc37 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -38,15 +38,26 @@ count_resource(struct acpi_resource *acpi_res, void *data) | |||
38 | struct acpi_resource_address64 addr; | 38 | struct acpi_resource_address64 addr; |
39 | acpi_status status; | 39 | acpi_status status; |
40 | 40 | ||
41 | if (info->res_num >= PCI_BUS_NUM_RESOURCES) | ||
42 | return AE_OK; | ||
43 | |||
44 | status = resource_to_addr(acpi_res, &addr); | 41 | status = resource_to_addr(acpi_res, &addr); |
45 | if (ACPI_SUCCESS(status)) | 42 | if (ACPI_SUCCESS(status)) |
46 | info->res_num++; | 43 | info->res_num++; |
47 | return AE_OK; | 44 | return AE_OK; |
48 | } | 45 | } |
49 | 46 | ||
47 | static int | ||
48 | bus_has_transparent_bridge(struct pci_bus *bus) | ||
49 | { | ||
50 | struct pci_dev *dev; | ||
51 | |||
52 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
53 | u16 class = dev->class >> 8; | ||
54 | |||
55 | if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) | ||
56 | return true; | ||
57 | } | ||
58 | return false; | ||
59 | } | ||
60 | |||
50 | static acpi_status | 61 | static acpi_status |
51 | setup_resource(struct acpi_resource *acpi_res, void *data) | 62 | setup_resource(struct acpi_resource *acpi_res, void *data) |
52 | { | 63 | { |
@@ -56,9 +67,11 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
56 | acpi_status status; | 67 | acpi_status status; |
57 | unsigned long flags; | 68 | unsigned long flags; |
58 | struct resource *root; | 69 | struct resource *root; |
70 | int max_root_bus_resources = PCI_BUS_NUM_RESOURCES; | ||
71 | u64 start, end; | ||
59 | 72 | ||
60 | if (info->res_num >= PCI_BUS_NUM_RESOURCES) | 73 | if (bus_has_transparent_bridge(info->bus)) |
61 | return AE_OK; | 74 | max_root_bus_resources -= 3; |
62 | 75 | ||
63 | status = resource_to_addr(acpi_res, &addr); | 76 | status = resource_to_addr(acpi_res, &addr); |
64 | if (!ACPI_SUCCESS(status)) | 77 | if (!ACPI_SUCCESS(status)) |
@@ -75,11 +88,22 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
75 | } else | 88 | } else |
76 | return AE_OK; | 89 | return AE_OK; |
77 | 90 | ||
91 | start = addr.minimum + addr.translation_offset; | ||
92 | end = start + addr.address_length - 1; | ||
93 | if (info->res_num >= max_root_bus_resources) { | ||
94 | printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx " | ||
95 | "from %s for %s due to _CRS returning more than " | ||
96 | "%d resource descriptors\n", (unsigned long) start, | ||
97 | (unsigned long) end, root->name, info->name, | ||
98 | max_root_bus_resources); | ||
99 | return AE_OK; | ||
100 | } | ||
101 | |||
78 | res = &info->res[info->res_num]; | 102 | res = &info->res[info->res_num]; |
79 | res->name = info->name; | 103 | res->name = info->name; |
80 | res->flags = flags; | 104 | res->flags = flags; |
81 | res->start = addr.minimum + addr.translation_offset; | 105 | res->start = start; |
82 | res->end = res->start + addr.address_length - 1; | 106 | res->end = end; |
83 | res->child = NULL; | 107 | res->child = NULL; |
84 | 108 | ||
85 | if (insert_resource(root, res)) { | 109 | if (insert_resource(root, res)) { |
@@ -94,23 +118,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data) | |||
94 | } | 118 | } |
95 | 119 | ||
96 | static void | 120 | static void |
97 | adjust_transparent_bridge_resources(struct pci_bus *bus) | ||
98 | { | ||
99 | struct pci_dev *dev; | ||
100 | |||
101 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
102 | int i; | ||
103 | u16 class = dev->class >> 8; | ||
104 | |||
105 | if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent) { | ||
106 | for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) | ||
107 | dev->subordinate->resource[i] = | ||
108 | dev->bus->resource[i - 3]; | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | static void | ||
114 | get_current_resources(struct acpi_device *device, int busnum, | 121 | get_current_resources(struct acpi_device *device, int busnum, |
115 | int domain, struct pci_bus *bus) | 122 | int domain, struct pci_bus *bus) |
116 | { | 123 | { |
@@ -137,8 +144,6 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
137 | info.res_num = 0; | 144 | info.res_num = 0; |
138 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | 145 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, |
139 | &info); | 146 | &info); |
140 | if (info.res_num) | ||
141 | adjust_transparent_bridge_resources(bus); | ||
142 | 147 | ||
143 | return; | 148 | return; |
144 | 149 | ||
@@ -201,8 +206,15 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
201 | */ | 206 | */ |
202 | memcpy(bus->sysdata, sd, sizeof(*sd)); | 207 | memcpy(bus->sysdata, sd, sizeof(*sd)); |
203 | kfree(sd); | 208 | kfree(sd); |
204 | } else | 209 | } else { |
205 | bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd); | 210 | bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); |
211 | if (bus) { | ||
212 | if (pci_probe & PCI_USE__CRS) | ||
213 | get_current_resources(device, busnum, domain, | ||
214 | bus); | ||
215 | bus->subordinate = pci_scan_child_bus(bus); | ||
216 | } | ||
217 | } | ||
206 | 218 | ||
207 | if (!bus) | 219 | if (!bus) |
208 | kfree(sd); | 220 | kfree(sd); |
@@ -217,8 +229,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
217 | #endif | 229 | #endif |
218 | } | 230 | } |
219 | 231 | ||
220 | if (bus && (pci_probe & PCI_USE__CRS)) | ||
221 | get_current_resources(device, busnum, domain, bus); | ||
222 | return bus; | 232 | return bus; |
223 | } | 233 | } |
224 | 234 | ||