aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/utresrc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/acpica/utresrc.c')
-rw-r--r--drivers/acpi/acpica/utresrc.c276
1 files changed, 242 insertions, 34 deletions
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
index 6ffd3a8bdaa5..cd7fbbf57f30 100644
--- a/drivers/acpi/acpica/utresrc.c
+++ b/drivers/acpi/acpica/utresrc.c
@@ -43,7 +43,7 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include "accommon.h" 45#include "accommon.h"
46#include "amlresrc.h" 46#include "acresrc.h"
47 47
48#define _COMPONENT ACPI_UTILITIES 48#define _COMPONENT ACPI_UTILITIES
49ACPI_MODULE_NAME("utresrc") 49ACPI_MODULE_NAME("utresrc")
@@ -154,6 +154,138 @@ const char *acpi_gbl_typ_decode[] = {
154 "TypeF" 154 "TypeF"
155}; 155};
156 156
157const char *acpi_gbl_ppc_decode[] = {
158 "PullDefault",
159 "PullUp",
160 "PullDown",
161 "PullNone"
162};
163
164const char *acpi_gbl_ior_decode[] = {
165 "IoRestrictionNone",
166 "IoRestrictionInputOnly",
167 "IoRestrictionOutputOnly",
168 "IoRestrictionNoneAndPreserve"
169};
170
171const char *acpi_gbl_dts_decode[] = {
172 "Width8bit",
173 "Width16bit",
174 "Width32bit",
175 "Width64bit",
176 "Width128bit",
177 "Width256bit",
178};
179
180/* GPIO connection type */
181
182const char *acpi_gbl_ct_decode[] = {
183 "Interrupt",
184 "I/O"
185};
186
187/* Serial bus type */
188
189const char *acpi_gbl_sbt_decode[] = {
190 "/* UNKNOWN serial bus type */",
191 "I2C",
192 "SPI",
193 "UART"
194};
195
196/* I2C serial bus access mode */
197
198const char *acpi_gbl_am_decode[] = {
199 "AddressingMode7Bit",
200 "AddressingMode10Bit"
201};
202
203/* I2C serial bus slave mode */
204
205const char *acpi_gbl_sm_decode[] = {
206 "ControllerInitiated",
207 "DeviceInitiated"
208};
209
210/* SPI serial bus wire mode */
211
212const char *acpi_gbl_wm_decode[] = {
213 "FourWireMode",
214 "ThreeWireMode"
215};
216
217/* SPI serial clock phase */
218
219const char *acpi_gbl_cph_decode[] = {
220 "ClockPhaseFirst",
221 "ClockPhaseSecond"
222};
223
224/* SPI serial bus clock polarity */
225
226const char *acpi_gbl_cpo_decode[] = {
227 "ClockPolarityLow",
228 "ClockPolarityHigh"
229};
230
231/* SPI serial bus device polarity */
232
233const char *acpi_gbl_dp_decode[] = {
234 "PolarityLow",
235 "PolarityHigh"
236};
237
238/* UART serial bus endian */
239
240const char *acpi_gbl_ed_decode[] = {
241 "LittleEndian",
242 "BigEndian"
243};
244
245/* UART serial bus bits per byte */
246
247const char *acpi_gbl_bpb_decode[] = {
248 "DataBitsFive",
249 "DataBitsSix",
250 "DataBitsSeven",
251 "DataBitsEight",
252 "DataBitsNine",
253 "/* UNKNOWN Bits per byte */",
254 "/* UNKNOWN Bits per byte */",
255 "/* UNKNOWN Bits per byte */"
256};
257
258/* UART serial bus stop bits */
259
260const char *acpi_gbl_sb_decode[] = {
261 "StopBitsNone",
262 "StopBitsOne",
263 "StopBitsOnePlusHalf",
264 "StopBitsTwo"
265};
266
267/* UART serial bus flow control */
268
269const char *acpi_gbl_fc_decode[] = {
270 "FlowControlNone",
271 "FlowControlHardware",
272 "FlowControlXON",
273 "/* UNKNOWN flow control keyword */"
274};
275
276/* UART serial bus parity type */
277
278const char *acpi_gbl_pt_decode[] = {
279 "ParityTypeNone",
280 "ParityTypeEven",
281 "ParityTypeOdd",
282 "ParityTypeMark",
283 "ParityTypeSpace",
284 "/* UNKNOWN parity keyword */",
285 "/* UNKNOWN parity keyword */",
286 "/* UNKNOWN parity keyword */"
287};
288
157#endif 289#endif
158 290
159/* 291/*
@@ -173,7 +305,7 @@ const u8 acpi_gbl_resource_aml_sizes[] = {
173 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent), 305 ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
174 ACPI_AML_SIZE_SMALL(struct aml_resource_io), 306 ACPI_AML_SIZE_SMALL(struct aml_resource_io),
175 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io), 307 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
176 0, 308 ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma),
177 0, 309 0,
178 0, 310 0,
179 0, 311 0,
@@ -193,7 +325,17 @@ const u8 acpi_gbl_resource_aml_sizes[] = {
193 ACPI_AML_SIZE_LARGE(struct aml_resource_address16), 325 ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
194 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq), 326 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
195 ACPI_AML_SIZE_LARGE(struct aml_resource_address64), 327 ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
196 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64) 328 ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64),
329 ACPI_AML_SIZE_LARGE(struct aml_resource_gpio),
330 0,
331 ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus),
332};
333
334const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = {
335 0,
336 ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus),
337 ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus),
338 ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus),
197}; 339};
198 340
199/* 341/*
@@ -209,35 +351,49 @@ static const u8 acpi_gbl_resource_types[] = {
209 0, 351 0,
210 0, 352 0,
211 0, 353 0,
212 ACPI_SMALL_VARIABLE_LENGTH, 354 ACPI_SMALL_VARIABLE_LENGTH, /* 04 IRQ */
213 ACPI_FIXED_LENGTH, 355 ACPI_FIXED_LENGTH, /* 05 DMA */
214 ACPI_SMALL_VARIABLE_LENGTH, 356 ACPI_SMALL_VARIABLE_LENGTH, /* 06 start_dependent_functions */
215 ACPI_FIXED_LENGTH, 357 ACPI_FIXED_LENGTH, /* 07 end_dependent_functions */
216 ACPI_FIXED_LENGTH, 358 ACPI_FIXED_LENGTH, /* 08 IO */
217 ACPI_FIXED_LENGTH, 359 ACPI_FIXED_LENGTH, /* 09 fixed_iO */
218 0, 360 ACPI_FIXED_LENGTH, /* 0_a fixed_dMA */
219 0, 361 0,
220 0, 362 0,
221 0, 363 0,
222 ACPI_VARIABLE_LENGTH, 364 ACPI_VARIABLE_LENGTH, /* 0_e vendor_short */
223 ACPI_FIXED_LENGTH, 365 ACPI_FIXED_LENGTH, /* 0_f end_tag */
224 366
225 /* Large descriptors */ 367 /* Large descriptors */
226 368
227 0, 369 0,
228 ACPI_FIXED_LENGTH, 370 ACPI_FIXED_LENGTH, /* 01 Memory24 */
229 ACPI_FIXED_LENGTH, 371 ACPI_FIXED_LENGTH, /* 02 generic_register */
230 0, 372 0,
231 ACPI_VARIABLE_LENGTH, 373 ACPI_VARIABLE_LENGTH, /* 04 vendor_long */
232 ACPI_FIXED_LENGTH, 374 ACPI_FIXED_LENGTH, /* 05 Memory32 */
233 ACPI_FIXED_LENGTH, 375 ACPI_FIXED_LENGTH, /* 06 memory32_fixed */
234 ACPI_VARIABLE_LENGTH, 376 ACPI_VARIABLE_LENGTH, /* 07 Dword* address */
235 ACPI_VARIABLE_LENGTH, 377 ACPI_VARIABLE_LENGTH, /* 08 Word* address */
236 ACPI_VARIABLE_LENGTH, 378 ACPI_VARIABLE_LENGTH, /* 09 extended_iRQ */
237 ACPI_VARIABLE_LENGTH, 379 ACPI_VARIABLE_LENGTH, /* 0_a Qword* address */
238 ACPI_FIXED_LENGTH 380 ACPI_FIXED_LENGTH, /* 0_b Extended* address */
381 ACPI_VARIABLE_LENGTH, /* 0_c Gpio* */
382 0,
383 ACPI_VARIABLE_LENGTH /* 0_e *serial_bus */
239}; 384};
240 385
386/*
387 * For the i_aSL compiler/disassembler, we don't want any error messages
388 * because the disassembler uses the resource validation code to determine
389 * if Buffer objects are actually Resource Templates.
390 */
391#ifdef ACPI_ASL_COMPILER
392#define ACPI_RESOURCE_ERROR(plist)
393#else
394#define ACPI_RESOURCE_ERROR(plist) ACPI_ERROR(plist)
395#endif
396
241/******************************************************************************* 397/*******************************************************************************
242 * 398 *
243 * FUNCTION: acpi_ut_walk_aml_resources 399 * FUNCTION: acpi_ut_walk_aml_resources
@@ -265,6 +421,7 @@ acpi_ut_walk_aml_resources(u8 * aml,
265 u8 resource_index; 421 u8 resource_index;
266 u32 length; 422 u32 length;
267 u32 offset = 0; 423 u32 offset = 0;
424 u8 end_tag[2] = { 0x79, 0x00 };
268 425
269 ACPI_FUNCTION_TRACE(ut_walk_aml_resources); 426 ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
270 427
@@ -286,6 +443,10 @@ acpi_ut_walk_aml_resources(u8 * aml,
286 443
287 status = acpi_ut_validate_resource(aml, &resource_index); 444 status = acpi_ut_validate_resource(aml, &resource_index);
288 if (ACPI_FAILURE(status)) { 445 if (ACPI_FAILURE(status)) {
446 /*
447 * Exit on failure. Cannot continue because the descriptor length
448 * may be bogus also.
449 */
289 return_ACPI_STATUS(status); 450 return_ACPI_STATUS(status);
290 } 451 }
291 452
@@ -300,7 +461,7 @@ acpi_ut_walk_aml_resources(u8 * aml,
300 user_function(aml, length, offset, resource_index, 461 user_function(aml, length, offset, resource_index,
301 context); 462 context);
302 if (ACPI_FAILURE(status)) { 463 if (ACPI_FAILURE(status)) {
303 return (status); 464 return_ACPI_STATUS(status);
304 } 465 }
305 } 466 }
306 467
@@ -333,7 +494,19 @@ acpi_ut_walk_aml_resources(u8 * aml,
333 494
334 /* Did not find an end_tag descriptor */ 495 /* Did not find an end_tag descriptor */
335 496
336 return (AE_AML_NO_RESOURCE_END_TAG); 497 if (user_function) {
498
499 /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */
500
501 (void)acpi_ut_validate_resource(end_tag, &resource_index);
502 status =
503 user_function(end_tag, 2, offset, resource_index, context);
504 if (ACPI_FAILURE(status)) {
505 return_ACPI_STATUS(status);
506 }
507 }
508
509 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
337} 510}
338 511
339/******************************************************************************* 512/*******************************************************************************
@@ -354,6 +527,7 @@ acpi_ut_walk_aml_resources(u8 * aml,
354 527
355acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index) 528acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
356{ 529{
530 union aml_resource *aml_resource;
357 u8 resource_type; 531 u8 resource_type;
358 u8 resource_index; 532 u8 resource_index;
359 acpi_rs_length resource_length; 533 acpi_rs_length resource_length;
@@ -375,7 +549,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
375 /* Verify the large resource type (name) against the max */ 549 /* Verify the large resource type (name) against the max */
376 550
377 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) { 551 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
378 return (AE_AML_INVALID_RESOURCE_TYPE); 552 goto invalid_resource;
379 } 553 }
380 554
381 /* 555 /*
@@ -392,15 +566,17 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
392 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3); 566 ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
393 } 567 }
394 568
395 /* Check validity of the resource type, zero indicates name is invalid */ 569 /*
396 570 * Check validity of the resource type, via acpi_gbl_resource_types. Zero
571 * indicates an invalid resource.
572 */
397 if (!acpi_gbl_resource_types[resource_index]) { 573 if (!acpi_gbl_resource_types[resource_index]) {
398 return (AE_AML_INVALID_RESOURCE_TYPE); 574 goto invalid_resource;
399 } 575 }
400 576
401 /* 577 /*
402 * 2) Validate the resource_length field. This ensures that the length 578 * Validate the resource_length field. This ensures that the length
403 * is at least reasonable, and guarantees that it is non-zero. 579 * is at least reasonable, and guarantees that it is non-zero.
404 */ 580 */
405 resource_length = acpi_ut_get_resource_length(aml); 581 resource_length = acpi_ut_get_resource_length(aml);
406 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index]; 582 minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
@@ -413,7 +589,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
413 /* Fixed length resource, length must match exactly */ 589 /* Fixed length resource, length must match exactly */
414 590
415 if (resource_length != minimum_resource_length) { 591 if (resource_length != minimum_resource_length) {
416 return (AE_AML_BAD_RESOURCE_LENGTH); 592 goto bad_resource_length;
417 } 593 }
418 break; 594 break;
419 595
@@ -422,7 +598,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
422 /* Variable length resource, length must be at least the minimum */ 598 /* Variable length resource, length must be at least the minimum */
423 599
424 if (resource_length < minimum_resource_length) { 600 if (resource_length < minimum_resource_length) {
425 return (AE_AML_BAD_RESOURCE_LENGTH); 601 goto bad_resource_length;
426 } 602 }
427 break; 603 break;
428 604
@@ -432,7 +608,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
432 608
433 if ((resource_length > minimum_resource_length) || 609 if ((resource_length > minimum_resource_length) ||
434 (resource_length < (minimum_resource_length - 1))) { 610 (resource_length < (minimum_resource_length - 1))) {
435 return (AE_AML_BAD_RESOURCE_LENGTH); 611 goto bad_resource_length;
436 } 612 }
437 break; 613 break;
438 614
@@ -440,7 +616,23 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
440 616
441 /* Shouldn't happen (because of validation earlier), but be sure */ 617 /* Shouldn't happen (because of validation earlier), but be sure */
442 618
443 return (AE_AML_INVALID_RESOURCE_TYPE); 619 goto invalid_resource;
620 }
621
622 aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
623 if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) {
624
625 /* Validate the bus_type field */
626
627 if ((aml_resource->common_serial_bus.type == 0) ||
628 (aml_resource->common_serial_bus.type >
629 AML_RESOURCE_MAX_SERIALBUSTYPE)) {
630 ACPI_RESOURCE_ERROR((AE_INFO,
631 "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
632 aml_resource->common_serial_bus.
633 type));
634 return (AE_AML_INVALID_RESOURCE_TYPE);
635 }
444 } 636 }
445 637
446 /* Optionally return the resource table index */ 638 /* Optionally return the resource table index */
@@ -450,6 +642,22 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
450 } 642 }
451 643
452 return (AE_OK); 644 return (AE_OK);
645
646 invalid_resource:
647
648 ACPI_RESOURCE_ERROR((AE_INFO,
649 "Invalid/unsupported resource descriptor: Type 0x%2.2X",
650 resource_type));
651 return (AE_AML_INVALID_RESOURCE_TYPE);
652
653 bad_resource_length:
654
655 ACPI_RESOURCE_ERROR((AE_INFO,
656 "Invalid resource descriptor length: Type "
657 "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
658 resource_type, resource_length,
659 minimum_resource_length));
660 return (AE_AML_BAD_RESOURCE_LENGTH);
453} 661}
454 662
455/******************************************************************************* 663/*******************************************************************************