aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/resources
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2005-11-17 13:07:00 -0500
committerLen Brown <len.brown@intel.com>2005-12-10 00:27:56 -0500
commitc51a4de85de720670f2fbc592a6f8040af72ad87 (patch)
treeccaa60c483fcc904abd63d936ff7dc380bf28e7b /drivers/acpi/resources
parent96db255c8f014ae3497507104e8df809785a619f (diff)
[ACPI] ACPICA 20051117
Fixed a problem in the AML parser where the method thread count could be decremented below zero if any errors occurred during the method parse phase. This should eliminate AE_AML_METHOD_LIMIT exceptions seen on some machines. This also fixed a related regression with the mechanism that detects and corrects methods that cannot properly handle reentrancy (related to the deployment of the new OwnerId mechanism.) Eliminated the pre-parsing of control methods (to detect errors) during table load. Related to the problem above, this was causing unwind issues if any errors occurred during the parse, and it seemed to be overkill. A table load should not be aborted if there are problems with any single control method, thus rendering this feature rather pointless. Fixed a problem with the new table-driven resource manager where an internal buffer overflow could occur for small resource templates. Implemented a new external interface, acpi_get_vendor_resource() This interface will find and return a vendor-defined resource descriptor within a _CRS or _PRS method via an ACPI 3.0 UUID match. (from Bjorn Helgaas) Removed the length limit (200) on string objects as per the upcoming ACPI 3.0A specification. This affects the following areas of the interpreter: 1) any implicit conversion of a Buffer to a String, 2) a String object result of the ASL Concatentate operator, 3) the String object result of the ASL ToString operator. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/resources')
-rw-r--r--drivers/acpi/resources/rscalc.c14
-rw-r--r--drivers/acpi/resources/rsdump.c24
-rw-r--r--drivers/acpi/resources/rslist.c4
-rw-r--r--drivers/acpi/resources/rsmisc.c92
-rw-r--r--drivers/acpi/resources/rsutils.c22
-rw-r--r--drivers/acpi/resources/rsxface.c208
6 files changed, 237 insertions, 127 deletions
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c
index eca7439ee9da..c2c4d9079c6c 100644
--- a/drivers/acpi/resources/rscalc.c
+++ b/drivers/acpi/resources/rscalc.c
@@ -300,7 +300,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
300 /* Point to the next object */ 300 /* Point to the next object */
301 301
302 resource = 302 resource =
303 ACPI_PTR_ADD(struct acpi_resource, resource, 303 ACPI_ADD_PTR(struct acpi_resource, resource,
304 resource->length); 304 resource->length);
305 } 305 }
306 306
@@ -374,8 +374,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
374 * Get the number of bits set in the 16-bit IRQ mask 374 * Get the number of bits set in the 16-bit IRQ mask
375 */ 375 */
376 ACPI_MOVE_16_TO_16(&temp16, buffer); 376 ACPI_MOVE_16_TO_16(&temp16, buffer);
377 extra_struct_bytes = 377 extra_struct_bytes = acpi_rs_count_set_bits(temp16);
378 acpi_rs_count_set_bits(temp16) * sizeof(u32);
379 break; 378 break;
380 379
381 case ACPI_RESOURCE_NAME_DMA: 380 case ACPI_RESOURCE_NAME_DMA:
@@ -383,8 +382,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
383 * DMA Resource: 382 * DMA Resource:
384 * Get the number of bits set in the 8-bit DMA mask 383 * Get the number of bits set in the 8-bit DMA mask
385 */ 384 */
386 extra_struct_bytes = 385 extra_struct_bytes = acpi_rs_count_set_bits(*buffer);
387 acpi_rs_count_set_bits(*buffer) * sizeof(u32);
388 break; 386 break;
389 387
390 case ACPI_RESOURCE_NAME_VENDOR_SMALL: 388 case ACPI_RESOURCE_NAME_VENDOR_SMALL:
@@ -399,9 +397,9 @@ acpi_rs_get_list_length(u8 * aml_buffer,
399 397
400 case ACPI_RESOURCE_NAME_END_TAG: 398 case ACPI_RESOURCE_NAME_END_TAG:
401 /* 399 /*
402 * End Tag: This is the normal exit 400 * End Tag: This is the normal exit, add size of end_tag
403 */ 401 */
404 *size_needed = buffer_size; 402 *size_needed = buffer_size + ACPI_RS_SIZE_MIN;
405 return_ACPI_STATUS(AE_OK); 403 return_ACPI_STATUS(AE_OK);
406 404
407 case ACPI_RESOURCE_NAME_VENDOR_LARGE: 405 case ACPI_RESOURCE_NAME_VENDOR_LARGE:
@@ -466,7 +464,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
466 464
467 temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] + 465 temp16 = (u16) (acpi_gbl_resource_struct_sizes[resource_index] +
468 extra_struct_bytes); 466 extra_struct_bytes);
469 buffer_size += (u32) ACPI_ALIGN_RESOURCE_SIZE(temp16); 467 buffer_size += (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(temp16);
470 468
471 /* 469 /*
472 * Point to the next resource within the stream 470 * Point to the next resource within the stream
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c
index f617ca80c5a6..cebd890d3db5 100644
--- a/drivers/acpi/resources/rsdump.c
+++ b/drivers/acpi/resources/rsdump.c
@@ -383,7 +383,7 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
383 383
384 while (count) { 384 while (count) {
385 previous_target = target; 385 previous_target = target;
386 target = ((u8 *) resource) + table->offset; 386 target = ACPI_ADD_PTR(u8, resource, table->offset);
387 name = table->name; 387 name = table->name;
388 388
389 switch (table->opcode) { 389 switch (table->opcode) {
@@ -410,22 +410,19 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
410 /* Data items, 8/16/32/64 bit */ 410 /* Data items, 8/16/32/64 bit */
411 411
412 case ACPI_RSD_UINT8: 412 case ACPI_RSD_UINT8:
413 acpi_rs_out_integer8(name, *ACPI_CAST_PTR(u8, target)); 413 acpi_rs_out_integer8(name, ACPI_GET8(target));
414 break; 414 break;
415 415
416 case ACPI_RSD_UINT16: 416 case ACPI_RSD_UINT16:
417 acpi_rs_out_integer16(name, 417 acpi_rs_out_integer16(name, ACPI_GET16(target));
418 *ACPI_CAST_PTR(u16, target));
419 break; 418 break;
420 419
421 case ACPI_RSD_UINT32: 420 case ACPI_RSD_UINT32:
422 acpi_rs_out_integer32(name, 421 acpi_rs_out_integer32(name, ACPI_GET32(target));
423 *ACPI_CAST_PTR(u32, target));
424 break; 422 break;
425 423
426 case ACPI_RSD_UINT64: 424 case ACPI_RSD_UINT64:
427 acpi_rs_out_integer64(name, 425 acpi_rs_out_integer64(name, ACPI_GET64(target));
428 *ACPI_CAST_PTR(u64, target));
429 break; 426 break;
430 427
431 /* Flags: 1-bit and 2-bit flags supported */ 428 /* Flags: 1-bit and 2-bit flags supported */
@@ -462,8 +459,8 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
462 * Note: The list length is obtained from the previous table entry 459 * Note: The list length is obtained from the previous table entry
463 */ 460 */
464 if (previous_target) { 461 if (previous_target) {
465 acpi_rs_dump_byte_list(*ACPI_CAST_PTR 462 acpi_rs_dump_byte_list(ACPI_GET16
466 (u16, previous_target), 463 (previous_target),
467 target); 464 target);
468 } 465 }
469 break; 466 break;
@@ -634,7 +631,7 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list)
634 /* Point to the next resource structure */ 631 /* Point to the next resource structure */
635 632
636 resource_list = 633 resource_list =
637 ACPI_PTR_ADD(struct acpi_resource, resource_list, 634 ACPI_ADD_PTR(struct acpi_resource, resource_list,
638 resource_list->length); 635 resource_list->length);
639 636
640 /* Exit when END_TAG descriptor is reached */ 637 /* Exit when END_TAG descriptor is reached */
@@ -675,9 +672,8 @@ void acpi_rs_dump_irq_list(u8 * route_table)
675 count); 672 count);
676 acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt); 673 acpi_rs_dump_descriptor(prt_element, acpi_rs_dump_prt);
677 674
678 prt_element = ACPI_CAST_PTR(struct acpi_pci_routing_table, 675 prt_element = ACPI_ADD_PTR(struct acpi_pci_routing_table,
679 ((u8 *) prt_element) + 676 prt_element, prt_element->length);
680 prt_element->length);
681 } 677 }
682} 678}
683 679
diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c
index b83996233c1d..573c06705641 100644
--- a/drivers/acpi/resources/rslist.c
+++ b/drivers/acpi/resources/rslist.c
@@ -112,7 +112,7 @@ acpi_rs_convert_aml_to_resources(u8 * aml, u32 aml_length, u8 * output_buffer)
112 /* Point to the next structure in the output buffer */ 112 /* Point to the next structure in the output buffer */
113 113
114 resource = 114 resource =
115 ACPI_PTR_ADD(struct acpi_resource, resource, 115 ACPI_ADD_PTR(struct acpi_resource, resource,
116 resource->length); 116 resource->length);
117 } 117 }
118 118
@@ -201,7 +201,7 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource,
201 /* Point to the next input resource descriptor */ 201 /* Point to the next input resource descriptor */
202 202
203 resource = 203 resource =
204 ACPI_PTR_ADD(struct acpi_resource, resource, 204 ACPI_ADD_PTR(struct acpi_resource, resource,
205 resource->length); 205 resource->length);
206 } 206 }
207 207
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c
index 16ad3bfbee2a..e1b5aa2af9a5 100644
--- a/drivers/acpi/resources/rsmisc.c
+++ b/drivers/acpi/resources/rsmisc.c
@@ -104,8 +104,9 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
104 * Source is the external AML byte stream buffer, 104 * Source is the external AML byte stream buffer,
105 * destination is the internal resource descriptor 105 * destination is the internal resource descriptor
106 */ 106 */
107 source = ((u8 *) aml) + info->aml_offset; 107 source = ACPI_ADD_PTR(void, aml, info->aml_offset);
108 destination = ((u8 *) resource) + info->resource_offset; 108 destination =
109 ACPI_ADD_PTR(void, resource, info->resource_offset);
109 110
110 switch (info->opcode) { 111 switch (info->opcode) {
111 case ACPI_RSC_INITGET: 112 case ACPI_RSC_INITGET:
@@ -129,22 +130,22 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
129 /* 130 /*
130 * Mask and shift the flag bit 131 * Mask and shift the flag bit
131 */ 132 */
132 *((u8 *) destination) = (u8) 133 ACPI_SET8(destination) = (u8)
133 ((*((u8 *) source) >> info->value) & 0x01); 134 ((ACPI_GET8(source) >> info->value) & 0x01);
134 break; 135 break;
135 136
136 case ACPI_RSC_2BITFLAG: 137 case ACPI_RSC_2BITFLAG:
137 /* 138 /*
138 * Mask and shift the flag bits 139 * Mask and shift the flag bits
139 */ 140 */
140 *((u8 *) destination) = (u8) 141 ACPI_SET8(destination) = (u8)
141 ((*((u8 *) source) >> info->value) & 0x03); 142 ((ACPI_GET8(source) >> info->value) & 0x03);
142 break; 143 break;
143 144
144 case ACPI_RSC_COUNT: 145 case ACPI_RSC_COUNT:
145 146
146 item_count = *((u8 *) source); 147 item_count = ACPI_GET8(source);
147 *((u8 *) destination) = (u8) item_count; 148 ACPI_SET8(destination) = (u8) item_count;
148 149
149 resource->length = resource->length + 150 resource->length = resource->length +
150 (info->value * (item_count - 1)); 151 (info->value * (item_count - 1));
@@ -153,7 +154,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
153 case ACPI_RSC_COUNT16: 154 case ACPI_RSC_COUNT16:
154 155
155 item_count = aml_resource_length; 156 item_count = aml_resource_length;
156 *((u16 *) destination) = item_count; 157 ACPI_SET16(destination) = item_count;
157 158
158 resource->length = resource->length + 159 resource->length = resource->length +
159 (info->value * (item_count - 1)); 160 (info->value * (item_count - 1));
@@ -186,9 +187,8 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
186 187
187 case ACPI_RSC_DATA8: 188 case ACPI_RSC_DATA8:
188 189
189 target = ((char *)resource) + info->value; 190 target = ACPI_ADD_PTR(char, resource, info->value);
190 ACPI_MEMCPY(destination, source, 191 ACPI_MEMCPY(destination, source, ACPI_GET16(target));
191 *(ACPI_CAST_PTR(u16, target)));
192 break; 192 break;
193 193
194 case ACPI_RSC_ADDRESS: 194 case ACPI_RSC_ADDRESS:
@@ -217,8 +217,8 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
217 * complicated case used by the Interrupt() macro 217 * complicated case used by the Interrupt() macro
218 */ 218 */
219 target = 219 target =
220 ((char *)resource) + info->aml_offset + 220 ACPI_ADD_PTR(char, resource,
221 (item_count * 4); 221 info->aml_offset + (item_count * 4));
222 222
223 resource->length += 223 resource->length +=
224 acpi_rs_get_resource_source(aml_resource_length, 224 acpi_rs_get_resource_source(aml_resource_length,
@@ -230,15 +230,14 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
230 * 8-bit encoded bitmask (DMA macro) 230 * 8-bit encoded bitmask (DMA macro)
231 */ 231 */
232 item_count = 232 item_count =
233 acpi_rs_decode_bitmask(*((u8 *) source), 233 acpi_rs_decode_bitmask(ACPI_GET8(source),
234 destination); 234 destination);
235 if (item_count) { 235 if (item_count) {
236 resource->length += 236 resource->length += (item_count - 1);
237 resource->length + (item_count - 1);
238 } 237 }
239 238
240 target = ((char *)resource) + info->value; 239 target = ACPI_ADD_PTR(char, resource, info->value);
241 *((u8 *) target) = (u8) item_count; 240 ACPI_SET8(target) = (u8) item_count;
242 break; 241 break;
243 242
244 case ACPI_RSC_BITMASK16: 243 case ACPI_RSC_BITMASK16:
@@ -250,12 +249,11 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
250 item_count = 249 item_count =
251 acpi_rs_decode_bitmask(temp16, destination); 250 acpi_rs_decode_bitmask(temp16, destination);
252 if (item_count) { 251 if (item_count) {
253 resource->length = 252 resource->length += (item_count - 1);
254 resource->length + (item_count - 1);
255 } 253 }
256 254
257 target = ((char *)resource) + info->value; 255 target = ACPI_ADD_PTR(char, resource, info->value);
258 *((u8 *) target) = (u8) item_count; 256 ACPI_SET8(target) = (u8) item_count;
259 break; 257 break;
260 258
261 case ACPI_RSC_EXIT_NE: 259 case ACPI_RSC_EXIT_NE:
@@ -270,7 +268,7 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
270 break; 268 break;
271 269
272 case ACPI_RSC_COMPARE_VALUE: 270 case ACPI_RSC_COMPARE_VALUE:
273 if (*((u8 *) source) != info->value) { 271 if (ACPI_GET8(source) != info->value) {
274 goto exit; 272 goto exit;
275 } 273 }
276 break; 274 break;
@@ -349,8 +347,8 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
349 * Source is the internal resource descriptor, 347 * Source is the internal resource descriptor,
350 * destination is the external AML byte stream buffer 348 * destination is the external AML byte stream buffer
351 */ 349 */
352 source = ((u8 *) resource) + info->resource_offset; 350 source = ACPI_ADD_PTR(void, resource, info->resource_offset);
353 destination = ((u8 *) aml) + info->aml_offset; 351 destination = ACPI_ADD_PTR(void, aml, info->aml_offset);
354 352
355 switch (info->opcode) { 353 switch (info->opcode) {
356 case ACPI_RSC_INITSET: 354 case ACPI_RSC_INITSET:
@@ -368,37 +366,38 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
368 /* 366 /*
369 * Clear the flag byte 367 * Clear the flag byte
370 */ 368 */
371 *((u8 *) destination) = 0; 369 ACPI_SET8(destination) = 0;
372 break; 370 break;
373 371
374 case ACPI_RSC_1BITFLAG: 372 case ACPI_RSC_1BITFLAG:
375 /* 373 /*
376 * Mask and shift the flag bit 374 * Mask and shift the flag bit
377 */ 375 */
378 *((u8 *) destination) |= (u8) 376 ACPI_SET8(destination) |= (u8)
379 ((*((u8 *) source) & 0x01) << info->value); 377 ((ACPI_GET8(source) & 0x01) << info->value);
380 break; 378 break;
381 379
382 case ACPI_RSC_2BITFLAG: 380 case ACPI_RSC_2BITFLAG:
383 /* 381 /*
384 * Mask and shift the flag bits 382 * Mask and shift the flag bits
385 */ 383 */
386 *((u8 *) destination) |= (u8) 384 ACPI_SET8(destination) |= (u8)
387 ((*((u8 *) source) & 0x03) << info->value); 385 ((ACPI_GET8(source) & 0x03) << info->value);
388 break; 386 break;
389 387
390 case ACPI_RSC_COUNT: 388 case ACPI_RSC_COUNT:
391 389
392 item_count = *((u8 *) source); 390 item_count = ACPI_GET8(source);
393 *((u8 *) destination) = (u8) item_count; 391 ACPI_SET8(destination) = (u8) item_count;
394 392
395 aml_length = (u16) (aml_length + 393 aml_length =
396 (info->value * (item_count - 1))); 394 (u16) (aml_length +
395 (info->value * (item_count - 1)));
397 break; 396 break;
398 397
399 case ACPI_RSC_COUNT16: 398 case ACPI_RSC_COUNT16:
400 399
401 item_count = *((u16 *) source); 400 item_count = ACPI_GET16(source);
402 aml_length = (u16) (aml_length + item_count); 401 aml_length = (u16) (aml_length + item_count);
403 acpi_rs_set_resource_length(aml_length, aml); 402 acpi_rs_set_resource_length(aml_length, aml);
404 break; 403 break;
@@ -453,20 +452,21 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
453 /* 452 /*
454 * 8-bit encoded bitmask (DMA macro) 453 * 8-bit encoded bitmask (DMA macro)
455 */ 454 */
456 *((u8 *) destination) = (u8) 455 ACPI_SET8(destination) = (u8)
457 acpi_rs_encode_bitmask(source, 456 acpi_rs_encode_bitmask(source,
458 *(((u8 *) resource) + 457 *ACPI_ADD_PTR(u8, resource,
459 info->value)); 458 info->value));
460 break; 459 break;
461 460
462 case ACPI_RSC_BITMASK16: 461 case ACPI_RSC_BITMASK16:
463 /* 462 /*
464 * 16-bit encoded bitmask (IRQ macro) 463 * 16-bit encoded bitmask (IRQ macro)
465 */ 464 */
466 temp16 = 465 temp16 = acpi_rs_encode_bitmask(source,
467 acpi_rs_encode_bitmask(source, 466 *ACPI_ADD_PTR(u8,
468 *(((u8 *) resource) + 467 resource,
469 info->value)); 468 info->
469 value));
470 ACPI_MOVE_16_TO_16(destination, &temp16); 470 ACPI_MOVE_16_TO_16(destination, &temp16);
471 break; 471 break;
472 472
@@ -485,9 +485,9 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
485 */ 485 */
486 switch (COMPARE_OPCODE(info)) { 486 switch (COMPARE_OPCODE(info)) {
487 case ACPI_RSC_COMPARE_VALUE: 487 case ACPI_RSC_COMPARE_VALUE:
488 if (* 488
489 ((u8 *) (((u8 *) resource) + 489 if (*ACPI_ADD_PTR(u8, resource,
490 COMPARE_TARGET(info))) != 490 COMPARE_TARGET(info)) !=
491 COMPARE_VALUE(info)) { 491 COMPARE_VALUE(info)) {
492 goto exit; 492 goto exit;
493 } 493 }
diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c
index a1eac0f1df54..2236a0c90daa 100644
--- a/drivers/acpi/resources/rsutils.c
+++ b/drivers/acpi/resources/rsutils.c
@@ -152,18 +152,18 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
152 * misaligned memory transfers 152 * misaligned memory transfers
153 */ 153 */
154 case ACPI_RSC_MOVE16: 154 case ACPI_RSC_MOVE16:
155 ACPI_MOVE_16_TO_16(&((u16 *) destination)[i], 155 ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
156 &((u16 *) source)[i]); 156 &ACPI_CAST_PTR(u16, source)[i]);
157 break; 157 break;
158 158
159 case ACPI_RSC_MOVE32: 159 case ACPI_RSC_MOVE32:
160 ACPI_MOVE_32_TO_32(&((u32 *) destination)[i], 160 ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
161 &((u32 *) source)[i]); 161 &ACPI_CAST_PTR(u32, source)[i]);
162 break; 162 break;
163 163
164 case ACPI_RSC_MOVE64: 164 case ACPI_RSC_MOVE64:
165 ACPI_MOVE_64_TO_64(&((u64 *) destination)[i], 165 ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
166 &((u64 *) source)[i]); 166 &ACPI_CAST_PTR(u64, source)[i]);
167 break; 167 break;
168 168
169 default: 169 default:
@@ -318,7 +318,7 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length,
318 318
319 total_length = 319 total_length =
320 resource_length + sizeof(struct aml_resource_large_header); 320 resource_length + sizeof(struct aml_resource_large_header);
321 aml_resource_source = ((u8 *) aml) + minimum_length; 321 aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
322 322
323 /* 323 /*
324 * resource_source is present if the length of the descriptor is longer than 324 * resource_source is present if the length of the descriptor is longer than
@@ -338,9 +338,9 @@ acpi_rs_get_resource_source(acpi_rs_length resource_length,
338 * String destination pointer is not specified; Set the String 338 * String destination pointer is not specified; Set the String
339 * pointer to the end of the current resource_source structure. 339 * pointer to the end of the current resource_source structure.
340 */ 340 */
341 resource_source->string_ptr = (char *) 341 resource_source->string_ptr =
342 ((u8 *) resource_source) + 342 ACPI_ADD_PTR(char, resource_source,
343 sizeof(struct acpi_resource_source); 343 sizeof(struct acpi_resource_source));
344 } 344 }
345 345
346 /* 346 /*
@@ -407,7 +407,7 @@ acpi_rs_set_resource_source(union aml_resource * aml,
407 if (resource_source->string_length) { 407 if (resource_source->string_length) {
408 /* Point to the end of the AML descriptor */ 408 /* Point to the end of the AML descriptor */
409 409
410 aml_resource_source = ((u8 *) aml) + minimum_length; 410 aml_resource_source = ACPI_ADD_PTR(u8, aml, minimum_length);
411 411
412 /* Copy the resource_source_index */ 412 /* Copy the resource_source_index */
413 413
diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c
index 09d250ab9872..50a956b705b0 100644
--- a/drivers/acpi/resources/rsxface.c
+++ b/drivers/acpi/resources/rsxface.c
@@ -64,6 +64,10 @@ ACPI_MODULE_NAME("rsxface")
64 ACPI_COPY_FIELD(out, in, translation_offset); \ 64 ACPI_COPY_FIELD(out, in, translation_offset); \
65 ACPI_COPY_FIELD(out, in, address_length); \ 65 ACPI_COPY_FIELD(out, in, address_length); \
66 ACPI_COPY_FIELD(out, in, resource_source); 66 ACPI_COPY_FIELD(out, in, resource_source);
67/* Local prototypes */
68static acpi_status
69acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context);
70
67/******************************************************************************* 71/*******************************************************************************
68 * 72 *
69 * FUNCTION: acpi_get_irq_routing_table 73 * FUNCTION: acpi_get_irq_routing_table
@@ -86,6 +90,7 @@ ACPI_MODULE_NAME("rsxface")
86 * the object indicated by the passed device_handle. 90 * the object indicated by the passed device_handle.
87 * 91 *
88 ******************************************************************************/ 92 ******************************************************************************/
93
89acpi_status 94acpi_status
90acpi_get_irq_routing_table(acpi_handle device_handle, 95acpi_get_irq_routing_table(acpi_handle device_handle,
91 struct acpi_buffer *ret_buffer) 96 struct acpi_buffer *ret_buffer)
@@ -222,12 +227,12 @@ EXPORT_SYMBOL(acpi_get_possible_resources);
222 * 227 *
223 * FUNCTION: acpi_walk_resources 228 * FUNCTION: acpi_walk_resources
224 * 229 *
225 * PARAMETERS: device_handle - a handle to the device object for the 230 * PARAMETERS: device_handle - Handle to the device object for the
226 * device we are querying 231 * device we are querying
227 * Path - method name of the resources we want 232 * Name - Method name of the resources we want
228 * (METHOD_NAME__CRS or METHOD_NAME__PRS) 233 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
229 * user_function - called for each resource 234 * user_function - Called for each resource
230 * Context - passed to user_function 235 * Context - Passed to user_function
231 * 236 *
232 * RETURN: Status 237 * RETURN: Status
233 * 238 *
@@ -239,79 +244,74 @@ EXPORT_SYMBOL(acpi_get_possible_resources);
239 244
240acpi_status 245acpi_status
241acpi_walk_resources(acpi_handle device_handle, 246acpi_walk_resources(acpi_handle device_handle,
242 char *path, 247 char *name,
243 ACPI_WALK_RESOURCE_CALLBACK user_function, void *context) 248 ACPI_WALK_RESOURCE_CALLBACK user_function, void *context)
244{ 249{
245 acpi_status status; 250 acpi_status status;
246 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 251 struct acpi_buffer buffer;
247 struct acpi_resource *resource; 252 struct acpi_resource *resource;
248 struct acpi_resource *buffer_end; 253 struct acpi_resource *resource_end;
249 254
250 ACPI_FUNCTION_TRACE("acpi_walk_resources"); 255 ACPI_FUNCTION_TRACE("acpi_walk_resources");
251 256
252 if (!device_handle || 257 /* Parameter validation */
253 (ACPI_STRNCMP(path, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) && 258
254 ACPI_STRNCMP(path, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) { 259 if (!device_handle || !user_function || !name ||
260 (ACPI_STRNCMP(name, METHOD_NAME__CRS, sizeof(METHOD_NAME__CRS)) &&
261 ACPI_STRNCMP(name, METHOD_NAME__PRS, sizeof(METHOD_NAME__PRS)))) {
255 return_ACPI_STATUS(AE_BAD_PARAMETER); 262 return_ACPI_STATUS(AE_BAD_PARAMETER);
256 } 263 }
257 264
258 status = acpi_rs_get_method_data(device_handle, path, &buffer); 265 /* Get the _CRS or _PRS resource list */
266
267 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
268 status = acpi_rs_get_method_data(device_handle, name, &buffer);
259 if (ACPI_FAILURE(status)) { 269 if (ACPI_FAILURE(status)) {
260 return_ACPI_STATUS(status); 270 return_ACPI_STATUS(status);
261 } 271 }
262 272
263 /* Setup pointers */ 273 /* Buffer now contains the resource list */
264 274
265 resource = (struct acpi_resource *)buffer.pointer; 275 resource = ACPI_CAST_PTR(struct acpi_resource, buffer.pointer);
266 buffer_end = ACPI_CAST_PTR(struct acpi_resource, 276 resource_end =
267 ((u8 *) buffer.pointer + buffer.length)); 277 ACPI_ADD_PTR(struct acpi_resource, buffer.pointer, buffer.length);
268 278
269 /* Walk the resource list */ 279 /* Walk the resource list until the end_tag is found (or buffer end) */
270 280
271 for (;;) { 281 while (resource < resource_end) {
272 if (!resource || resource->type == ACPI_RESOURCE_TYPE_END_TAG) { 282 /* Sanity check the resource */
283
284 if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
285 status = AE_AML_INVALID_RESOURCE_TYPE;
273 break; 286 break;
274 } 287 }
275 288
276 status = user_function(resource, context); 289 /* Invoke the user function, abort on any error returned */
277
278 switch (status) {
279 case AE_OK:
280 case AE_CTRL_DEPTH:
281 290
282 /* Just keep going */ 291 status = user_function(resource, context);
292 if (ACPI_FAILURE(status)) {
293 if (status == AE_CTRL_TERMINATE) {
294 /* This is an OK termination by the user function */
283 295
284 status = AE_OK; 296 status = AE_OK;
297 }
285 break; 298 break;
299 }
286 300
287 case AE_CTRL_TERMINATE: 301 /* end_tag indicates end-of-list */
288
289 /* Exit now, with OK stats */
290
291 status = AE_OK;
292 goto cleanup;
293
294 default:
295
296 /* All others are valid exceptions */
297 302
298 goto cleanup; 303 if (resource->type == ACPI_RESOURCE_TYPE_END_TAG) {
304 break;
299 } 305 }
300 306
301 /* Get the next resource descriptor */ 307 /* Get the next resource descriptor */
302 308
303 resource = ACPI_NEXT_RESOURCE(resource); 309 resource =
304 310 ACPI_ADD_PTR(struct acpi_resource, resource,
305 /* Check for end-of-buffer */ 311 resource->length);
306
307 if (resource >= buffer_end) {
308 goto cleanup;
309 }
310 } 312 }
311 313
312 cleanup: 314 ACPI_MEM_FREE(buffer.pointer);
313
314 acpi_os_free(buffer.pointer);
315 return_ACPI_STATUS(status); 315 return_ACPI_STATUS(status);
316} 316}
317 317
@@ -381,6 +381,12 @@ acpi_resource_to_address64(struct acpi_resource *resource,
381 struct acpi_resource_address16 *address16; 381 struct acpi_resource_address16 *address16;
382 struct acpi_resource_address32 *address32; 382 struct acpi_resource_address32 *address32;
383 383
384 if (!resource || !out) {
385 return (AE_BAD_PARAMETER);
386 }
387
388 /* Convert 16 or 32 address descriptor to 64 */
389
384 switch (resource->type) { 390 switch (resource->type) {
385 case ACPI_RESOURCE_TYPE_ADDRESS16: 391 case ACPI_RESOURCE_TYPE_ADDRESS16:
386 392
@@ -410,3 +416,113 @@ acpi_resource_to_address64(struct acpi_resource *resource,
410} 416}
411 417
412EXPORT_SYMBOL(acpi_resource_to_address64); 418EXPORT_SYMBOL(acpi_resource_to_address64);
419
420/*******************************************************************************
421 *
422 * FUNCTION: acpi_get_vendor_resource
423 *
424 * PARAMETERS: device_handle - Handle for the parent device object
425 * Name - Method name for the parent resource
426 * (METHOD_NAME__CRS or METHOD_NAME__PRS)
427 * Uuid - Pointer to the UUID to be matched.
428 * includes both subtype and 16-byte UUID
429 * ret_buffer - Where the vendor resource is returned
430 *
431 * RETURN: Status
432 *
433 * DESCRIPTION: Walk a resource template for the specified evice to find a
434 * vendor-defined resource that matches the supplied UUID and
435 * UUID subtype. Returns a struct acpi_resource of type Vendor.
436 *
437 ******************************************************************************/
438
439acpi_status
440acpi_get_vendor_resource(acpi_handle device_handle,
441 char *name,
442 struct acpi_vendor_uuid * uuid,
443 struct acpi_buffer * ret_buffer)
444{
445 struct acpi_vendor_walk_info info;
446 acpi_status status;
447
448 /* Other parameters are validated by acpi_walk_resources */
449
450 if (!uuid || !ret_buffer) {
451 return (AE_BAD_PARAMETER);
452 }
453
454 info.uuid = uuid;
455 info.buffer = ret_buffer;
456 info.status = AE_NOT_EXIST;
457
458 /* Walk the _CRS or _PRS resource list for this device */
459
460 status =
461 acpi_walk_resources(device_handle, name,
462 acpi_rs_match_vendor_resource, &info);
463 if (ACPI_FAILURE(status)) {
464 return (status);
465 }
466
467 return (info.status);
468}
469
470/*******************************************************************************
471 *
472 * FUNCTION: acpi_rs_match_vendor_resource
473 *
474 * PARAMETERS: ACPI_WALK_RESOURCE_CALLBACK
475 *
476 * RETURN: Status
477 *
478 * DESCRIPTION: Match a vendor resource via the ACPI 3.0 UUID
479 *
480 ******************************************************************************/
481
482static acpi_status
483acpi_rs_match_vendor_resource(struct acpi_resource *resource, void *context)
484{
485 struct acpi_vendor_walk_info *info = context;
486 struct acpi_resource_vendor_typed *vendor;
487 struct acpi_buffer *buffer;
488 acpi_status status;
489
490 /* Ignore all descriptors except Vendor */
491
492 if (resource->type != ACPI_RESOURCE_TYPE_VENDOR) {
493 return (AE_OK);
494 }
495
496 vendor = &resource->data.vendor_typed;
497
498 /*
499 * For a valid match, these conditions must hold:
500 *
501 * 1) Length of descriptor data must be at least as long as a UUID struct
502 * 2) The UUID subtypes must match
503 * 3) The UUID data must match
504 */
505 if ((vendor->byte_length < (ACPI_UUID_LENGTH + 1)) ||
506 (vendor->uuid_subtype != info->uuid->subtype) ||
507 (ACPI_MEMCMP(vendor->uuid, info->uuid->data, ACPI_UUID_LENGTH))) {
508 return (AE_OK);
509 }
510
511 /* Validate/Allocate/Clear caller buffer */
512
513 buffer = info->buffer;
514 status = acpi_ut_initialize_buffer(buffer, resource->length);
515 if (ACPI_FAILURE(status)) {
516 return (status);
517 }
518
519 /* Found the correct resource, copy and return it */
520
521 ACPI_MEMCPY(buffer->pointer, resource, resource->length);
522 buffer->length = resource->length;
523
524 /* Found the desired descriptor, terminate resource walk */
525
526 info->status = AE_OK;
527 return (AE_CTRL_TERMINATE);
528}