aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exfldio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/executer/exfldio.c')
-rw-r--r--drivers/acpi/executer/exfldio.c67
1 files changed, 44 insertions, 23 deletions
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c
index bd1af35f7fcf..051053f7cccb 100644
--- a/drivers/acpi/executer/exfldio.c
+++ b/drivers/acpi/executer/exfldio.c
@@ -87,7 +87,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
87 acpi_status status = AE_OK; 87 acpi_status status = AE_OK;
88 union acpi_operand_object *rgn_desc; 88 union acpi_operand_object *rgn_desc;
89 89
90 ACPI_FUNCTION_TRACE_U32("ex_setup_region", field_datum_byte_offset); 90 ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);
91 91
92 rgn_desc = obj_desc->common_field.region_obj; 92 rgn_desc = obj_desc->common_field.region_obj;
93 93
@@ -112,7 +112,18 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
112 } 112 }
113 } 113 }
114 114
115 /* Exit if Address/Length have been disallowed by the host OS */
116
117 if (rgn_desc->common.flags & AOPOBJ_INVALID) {
118 return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
119 }
120
121 /*
122 * Exit now for SMBus address space, it has a non-linear address space
123 * and the request cannot be directly validated
124 */
115 if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { 125 if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
126
116 /* SMBus has a non-linear address space */ 127 /* SMBus has a non-linear address space */
117 128
118 return_ACPI_STATUS(AE_OK); 129 return_ACPI_STATUS(AE_OK);
@@ -134,10 +145,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
134 * length of one field datum (access width) must fit within the region. 145 * length of one field datum (access width) must fit within the region.
135 * (Region length is specified in bytes) 146 * (Region length is specified in bytes)
136 */ 147 */
137 if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset + 148 if (rgn_desc->region.length <
138 field_datum_byte_offset + 149 (obj_desc->common_field.base_byte_offset +
139 obj_desc->common_field. 150 field_datum_byte_offset +
140 access_byte_width)) { 151 obj_desc->common_field.access_byte_width)) {
141 if (acpi_gbl_enable_interpreter_slack) { 152 if (acpi_gbl_enable_interpreter_slack) {
142 /* 153 /*
143 * Slack mode only: We will go ahead and allow access to this 154 * Slack mode only: We will go ahead and allow access to this
@@ -217,7 +228,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
217 union acpi_operand_object *rgn_desc; 228 union acpi_operand_object *rgn_desc;
218 acpi_physical_address address; 229 acpi_physical_address address;
219 230
220 ACPI_FUNCTION_TRACE("ex_access_region"); 231 ACPI_FUNCTION_TRACE(ex_access_region);
221 232
222 /* 233 /*
223 * Ensure that the region operands are fully evaluated and verify 234 * Ensure that the region operands are fully evaluated and verify
@@ -246,7 +257,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
246 } 257 }
247 258
248 ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD, 259 ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
249 " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n", 260 " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
250 acpi_ut_get_region_name(rgn_desc->region. 261 acpi_ut_get_region_name(rgn_desc->region.
251 space_id), 262 space_id),
252 rgn_desc->region.space_id, 263 rgn_desc->region.space_id,
@@ -352,7 +363,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
352 acpi_status status; 363 acpi_status status;
353 acpi_integer local_value; 364 acpi_integer local_value;
354 365
355 ACPI_FUNCTION_TRACE_U32("ex_field_datum_io", field_datum_byte_offset); 366 ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
356 367
357 if (read_write == ACPI_READ) { 368 if (read_write == ACPI_READ) {
358 if (!value) { 369 if (!value) {
@@ -487,10 +498,11 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
487 } 498 }
488 499
489 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 500 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
490 "I/O to Data Register: value_ptr %p\n", 501 "I/O to Data Register: ValuePtr %p\n",
491 value)); 502 value));
492 503
493 if (read_write == ACPI_READ) { 504 if (read_write == ACPI_READ) {
505
494 /* Read the datum from the data_register */ 506 /* Read the datum from the data_register */
495 507
496 status = 508 status =
@@ -559,7 +571,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
559 acpi_integer merged_value; 571 acpi_integer merged_value;
560 acpi_integer current_value; 572 acpi_integer current_value;
561 573
562 ACPI_FUNCTION_TRACE_U32("ex_write_with_update_rule", mask); 574 ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
563 575
564 /* Start with the new bits */ 576 /* Start with the new bits */
565 577
@@ -568,6 +580,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
568 /* If the mask is all ones, we don't need to worry about the update rule */ 580 /* If the mask is all ones, we don't need to worry about the update rule */
569 581
570 if (mask != ACPI_INTEGER_MAX) { 582 if (mask != ACPI_INTEGER_MAX) {
583
571 /* Decode the update rule */ 584 /* Decode the update rule */
572 585
573 switch (obj_desc->common_field. 586 switch (obj_desc->common_field.
@@ -614,7 +627,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
614 default: 627 default:
615 628
616 ACPI_ERROR((AE_INFO, 629 ACPI_ERROR((AE_INFO,
617 "Unknown update_rule value: %X", 630 "Unknown UpdateRule value: %X",
618 (obj_desc->common_field. 631 (obj_desc->common_field.
619 field_flags & 632 field_flags &
620 AML_FIELD_UPDATE_RULE_MASK))); 633 AML_FIELD_UPDATE_RULE_MASK)));
@@ -623,7 +636,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
623 } 636 }
624 637
625 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, 638 ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
626 "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n", 639 "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
627 ACPI_FORMAT_UINT64(mask), 640 ACPI_FORMAT_UINT64(mask),
628 field_datum_byte_offset, 641 field_datum_byte_offset,
629 obj_desc->common_field.access_byte_width, 642 obj_desc->common_field.access_byte_width,
@@ -666,7 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
666 u32 field_datum_count; 679 u32 field_datum_count;
667 u32 i; 680 u32 i;
668 681
669 ACPI_FUNCTION_TRACE("ex_extract_from_field"); 682 ACPI_FUNCTION_TRACE(ex_extract_from_field);
670 683
671 /* Validate target buffer and clear it */ 684 /* Validate target buffer and clear it */
672 685
@@ -704,6 +717,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
704 /* Read the rest of the field */ 717 /* Read the rest of the field */
705 718
706 for (i = 1; i < field_datum_count; i++) { 719 for (i = 1; i < field_datum_count; i++) {
720
707 /* Get next input datum from the field */ 721 /* Get next input datum from the field */
708 722
709 field_offset += obj_desc->common_field.access_byte_width; 723 field_offset += obj_desc->common_field.access_byte_width;
@@ -771,6 +785,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
771{ 785{
772 acpi_status status; 786 acpi_status status;
773 acpi_integer mask; 787 acpi_integer mask;
788 acpi_integer width_mask;
774 acpi_integer merged_datum; 789 acpi_integer merged_datum;
775 acpi_integer raw_datum = 0; 790 acpi_integer raw_datum = 0;
776 u32 field_offset = 0; 791 u32 field_offset = 0;
@@ -780,7 +795,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
780 u32 field_datum_count; 795 u32 field_datum_count;
781 u32 i; 796 u32 i;
782 797
783 ACPI_FUNCTION_TRACE("ex_insert_into_field"); 798 ACPI_FUNCTION_TRACE(ex_insert_into_field);
784 799
785 /* Validate input buffer */ 800 /* Validate input buffer */
786 801
@@ -795,15 +810,20 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
795 810
796 /* Compute the number of datums (access width data items) */ 811 /* Compute the number of datums (access width data items) */
797 812
813 width_mask =
814 ACPI_MASK_BITS_ABOVE(obj_desc->common_field.access_bit_width);
798 mask = 815 mask =
799 ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset); 816 width_mask & ACPI_MASK_BITS_BELOW(obj_desc->common_field.
800 datum_count = 817 start_field_bit_offset);
801 ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length, 818
802 obj_desc->common_field.access_bit_width); 819 datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
803 field_datum_count = 820 obj_desc->common_field.access_bit_width);
804 ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length + 821
805 obj_desc->common_field.start_field_bit_offset, 822 field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
806 obj_desc->common_field.access_bit_width); 823 obj_desc->common_field.
824 start_field_bit_offset,
825 obj_desc->common_field.
826 access_bit_width);
807 827
808 /* Get initial Datum from the input buffer */ 828 /* Get initial Datum from the input buffer */
809 829
@@ -817,6 +837,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
817 /* Write the entire field */ 837 /* Write the entire field */
818 838
819 for (i = 1; i < field_datum_count; i++) { 839 for (i = 1; i < field_datum_count; i++) {
840
820 /* Write merged datum to the target field */ 841 /* Write merged datum to the target field */
821 842
822 merged_datum &= mask; 843 merged_datum &= mask;
@@ -833,7 +854,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
833 merged_datum = raw_datum >> 854 merged_datum = raw_datum >>
834 (obj_desc->common_field.access_bit_width - 855 (obj_desc->common_field.access_bit_width -
835 obj_desc->common_field.start_field_bit_offset); 856 obj_desc->common_field.start_field_bit_offset);
836 mask = ACPI_INTEGER_MAX; 857 mask = width_mask;
837 858
838 if (i == datum_count) { 859 if (i == datum_count) {
839 break; 860 break;