]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/acpi_behave_uniquely_based_on_processor_declaration.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / acpi_behave_uniquely_based_on_processor_declaration.patch
1 From: Myron Stowe <myron.stowe@hp.com>
2 Subject: ACPI: Behave uniquely based on processor declaration definition type
3 References: bnc#440062
4 Patch-Mainline: yes
5 Commit-ID: b26e9286fb438eb78bcdb68b67a3dbb8bc539125
6
7 Signed-off-by: Thomas Renninger <trenn@suse.de>
8
9 Associating a Local SAPIC with a processor object is dependent upon the
10 processor object's definition type. CPUs declared as "Processor" should
11 use the Local SAPIC's 'processor_id', and CPUs declared as "Device"
12 should use the 'uid'. Note that for "Processor" declarations, even if a
13 '_UID' child object exists, it has no bearing with respect to mapping
14 Local SAPICs (see section 5.2.11.13 - Local SAPIC Structure; "Advanced
15 Configuration and Power Interface Specification", Revision 3.0b).
16
17 This patch changes the lsapic mapping logic to rely on the distinction of
18 how the processor object was declared - the mapping can't just try both
19 types of matches regardless of declaration type and rely on one failing
20 as is currently being done.
21
22 Signed-off-by: Myron Stowe <myron.stowe@hp.com>
23 Signed-off-by: Len Brown <len.brown@intel.com>
24
25 ---
26 drivers/acpi/processor_core.c | 78 +++++++++++++++++++++++-------------------
27 1 file changed, 44 insertions(+), 34 deletions(-)
28
29 Index: linux-2.6.27/drivers/acpi/processor_core.c
30 ===================================================================
31 --- linux-2.6.27.orig/drivers/acpi/processor_core.c
32 +++ linux-2.6.27/drivers/acpi/processor_core.c
33 @@ -410,7 +410,7 @@ static int acpi_processor_remove_fs(stru
34 /* Use the acpiid in MADT to map cpus in case of SMP */
35
36 #ifndef CONFIG_SMP
37 -static int get_cpu_id(acpi_handle handle, u32 acpi_id) {return -1;}
38 +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id) { return -1; }
39 #else
40
41 static struct acpi_table_madt *madt;
42 @@ -429,27 +429,35 @@ static int map_lapic_id(struct acpi_subt
43 }
44
45 static int map_lsapic_id(struct acpi_subtable_header *entry,
46 - u32 acpi_id, int *apic_id)
47 + int device_declaration, u32 acpi_id, int *apic_id)
48 {
49 struct acpi_madt_local_sapic *lsapic =
50 (struct acpi_madt_local_sapic *)entry;
51 + u32 tmp = (lsapic->id << 8) | lsapic->eid;
52 +
53 /* Only check enabled APICs*/
54 - if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
55 - /* First check against id */
56 - if (lsapic->processor_id == acpi_id) {
57 - *apic_id = (lsapic->id << 8) | lsapic->eid;
58 - return 1;
59 - /* Check against optional uid */
60 - } else if (entry->length >= 16 &&
61 - lsapic->uid == acpi_id) {
62 - *apic_id = lsapic->uid;
63 - return 1;
64 - }
65 - }
66 + if (!(lsapic->lapic_flags & ACPI_MADT_ENABLED))
67 + return 0;
68 +
69 + /* Device statement declaration type */
70 + if (device_declaration) {
71 + if (entry->length < 16)
72 + printk(KERN_ERR PREFIX
73 + "Invalid LSAPIC with Device type processor (SAPIC ID %#x)\n",
74 + tmp);
75 + else if (lsapic->uid == acpi_id)
76 + goto found;
77 + /* Processor statement declaration type */
78 + } else if (lsapic->processor_id == acpi_id)
79 + goto found;
80 +
81 return 0;
82 +found:
83 + *apic_id = tmp;
84 + return 1;
85 }
86
87 -static int map_madt_entry(u32 acpi_id)
88 +static int map_madt_entry(int type, u32 acpi_id)
89 {
90 unsigned long madt_end, entry;
91 int apic_id = -1;
92 @@ -470,7 +478,7 @@ static int map_madt_entry(u32 acpi_id)
93 if (map_lapic_id(header, acpi_id, &apic_id))
94 break;
95 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
96 - if (map_lsapic_id(header, acpi_id, &apic_id))
97 + if (map_lsapic_id(header, type, acpi_id, &apic_id))
98 break;
99 }
100 entry += header->length;
101 @@ -478,7 +486,7 @@ static int map_madt_entry(u32 acpi_id)
102 return apic_id;
103 }
104
105 -static int map_mat_entry(acpi_handle handle, u32 acpi_id)
106 +static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
107 {
108 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
109 union acpi_object *obj;
110 @@ -501,7 +509,7 @@ static int map_mat_entry(acpi_handle han
111 if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
112 map_lapic_id(header, acpi_id, &apic_id);
113 } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
114 - map_lsapic_id(header, acpi_id, &apic_id);
115 + map_lsapic_id(header, type, acpi_id, &apic_id);
116 }
117
118 exit:
119 @@ -510,14 +518,14 @@ exit:
120 return apic_id;
121 }
122
123 -static int get_cpu_id(acpi_handle handle, u32 acpi_id)
124 +static int get_cpu_id(acpi_handle handle, int type, u32 acpi_id)
125 {
126 int i;
127 int apic_id = -1;
128
129 - apic_id = map_mat_entry(handle, acpi_id);
130 + apic_id = map_mat_entry(handle, type, acpi_id);
131 if (apic_id == -1)
132 - apic_id = map_madt_entry(acpi_id);
133 + apic_id = map_madt_entry(type, acpi_id);
134 if (apic_id == -1)
135 return apic_id;
136
137 @@ -533,15 +541,16 @@ static int get_cpu_id(acpi_handle handle
138 Driver Interface
139 -------------------------------------------------------------------------- */
140
141 -static int acpi_processor_get_info(struct acpi_processor *pr, unsigned has_uid)
142 +static int acpi_processor_get_info(struct acpi_device *device)
143 {
144 acpi_status status = 0;
145 union acpi_object object = { 0 };
146 struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
147 - int cpu_index;
148 + struct acpi_processor *pr;
149 + int cpu_index, device_declaration = 0;
150 static int cpu0_initialized;
151
152 -
153 + pr = acpi_driver_data(device);
154 if (!pr)
155 return -EINVAL;
156
157 @@ -562,22 +571,23 @@ static int acpi_processor_get_info(struc
158 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
159 "No bus mastering arbitration control\n"));
160
161 - /* Check if it is a Device with HID and UID */
162 - if (has_uid) {
163 + if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_HID)) {
164 + /*
165 + * Declared with "Device" statement; match _UID.
166 + * Note that we don't handle string _UIDs yet.
167 + */
168 unsigned long long value;
169 status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
170 NULL, &value);
171 if (ACPI_FAILURE(status)) {
172 - printk(KERN_ERR PREFIX "Evaluating processor _UID\n");
173 + printk(KERN_ERR PREFIX
174 + "Evaluating processor _UID [%#x]\n", status);
175 return -ENODEV;
176 }
177 + device_declaration = 1;
178 pr->acpi_id = value;
179 } else {
180 - /*
181 - * Evalute the processor object. Note that it is common on SMP to
182 - * have the first (boot) processor with a valid PBLK address while
183 - * all others have a NULL address.
184 - */
185 + /* Declared with "Processor" statement; match ProcessorID */
186 status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
187 if (ACPI_FAILURE(status)) {
188 printk(KERN_ERR PREFIX "Evaluating processor object\n");
189 @@ -590,7 +600,7 @@ static int acpi_processor_get_info(struc
190 */
191 pr->acpi_id = object.processor.proc_id;
192 }
193 - cpu_index = get_cpu_id(pr->handle, pr->acpi_id);
194 + cpu_index = get_cpu_id(pr->handle, device_declaration, pr->acpi_id);
195
196 /* Handle UP system running SMP kernel, with no LAPIC in MADT */
197 if (!cpu0_initialized && (cpu_index == -1) &&
198 @@ -662,7 +672,7 @@ static int __cpuinit acpi_processor_star
199
200 pr = acpi_driver_data(device);
201
202 - result = acpi_processor_get_info(pr, device->flags.unique_id);
203 + result = acpi_processor_get_info(device);
204 if (result) {
205 /* Processor is physically not present */
206 return 0;