fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / acpi / executer / exfldio.c
index bd1af35..40f0bee 100644 (file)
@@ -87,7 +87,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
        acpi_status status = AE_OK;
        union acpi_operand_object *rgn_desc;
 
-       ACPI_FUNCTION_TRACE_U32("ex_setup_region", field_datum_byte_offset);
+       ACPI_FUNCTION_TRACE_U32(ex_setup_region, field_datum_byte_offset);
 
        rgn_desc = obj_desc->common_field.region_obj;
 
@@ -112,7 +112,18 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
                }
        }
 
+       /* Exit if Address/Length have been disallowed by the host OS */
+
+       if (rgn_desc->common.flags & AOPOBJ_INVALID) {
+               return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+       }
+
+       /*
+        * Exit now for SMBus address space, it has a non-linear address space
+        * and the request cannot be directly validated
+        */
        if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) {
+
                /* SMBus has a non-linear address space */
 
                return_ACPI_STATUS(AE_OK);
@@ -134,10 +145,10 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
         * length of one field datum (access width) must fit within the region.
         * (Region length is specified in bytes)
         */
-       if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset +
-                                      field_datum_byte_offset +
-                                      obj_desc->common_field.
-                                      access_byte_width)) {
+       if (rgn_desc->region.length <
+           (obj_desc->common_field.base_byte_offset +
+            field_datum_byte_offset +
+            obj_desc->common_field.access_byte_width)) {
                if (acpi_gbl_enable_interpreter_slack) {
                        /*
                         * 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,
        union acpi_operand_object *rgn_desc;
        acpi_physical_address address;
 
-       ACPI_FUNCTION_TRACE("ex_access_region");
+       ACPI_FUNCTION_TRACE(ex_access_region);
 
        /*
         * Ensure that the region operands are fully evaluated and verify
@@ -246,7 +257,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
        }
 
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
-                             " Region [%s:%X], Width %X, byte_base %X, Offset %X at %8.8X%8.8X\n",
+                             " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
                              acpi_ut_get_region_name(rgn_desc->region.
                                                      space_id),
                              rgn_desc->region.space_id,
@@ -352,7 +363,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
        acpi_status status;
        acpi_integer local_value;
 
-       ACPI_FUNCTION_TRACE_U32("ex_field_datum_io", field_datum_byte_offset);
+       ACPI_FUNCTION_TRACE_U32(ex_field_datum_io, field_datum_byte_offset);
 
        if (read_write == ACPI_READ) {
                if (!value) {
@@ -487,10 +498,11 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
                }
 
                ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-                                 "I/O to Data Register: value_ptr %p\n",
+                                 "I/O to Data Register: ValuePtr %p\n",
                                  value));
 
                if (read_write == ACPI_READ) {
+
                        /* Read the datum from the data_register */
 
                        status =
@@ -559,7 +571,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
        acpi_integer merged_value;
        acpi_integer current_value;
 
-       ACPI_FUNCTION_TRACE_U32("ex_write_with_update_rule", mask);
+       ACPI_FUNCTION_TRACE_U32(ex_write_with_update_rule, mask);
 
        /* Start with the new bits  */
 
@@ -568,6 +580,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
        /* If the mask is all ones, we don't need to worry about the update rule */
 
        if (mask != ACPI_INTEGER_MAX) {
+
                /* Decode the update rule */
 
                switch (obj_desc->common_field.
@@ -614,7 +627,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
                default:
 
                        ACPI_ERROR((AE_INFO,
-                                   "Unknown update_rule value: %X",
+                                   "Unknown UpdateRule value: %X",
                                    (obj_desc->common_field.
                                     field_flags &
                                     AML_FIELD_UPDATE_RULE_MASK)));
@@ -623,7 +636,7 @@ acpi_ex_write_with_update_rule(union acpi_operand_object *obj_desc,
        }
 
        ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
-                         "Mask %8.8X%8.8X, datum_offset %X, Width %X, Value %8.8X%8.8X, merged_value %8.8X%8.8X\n",
+                         "Mask %8.8X%8.8X, DatumOffset %X, Width %X, Value %8.8X%8.8X, MergedValue %8.8X%8.8X\n",
                          ACPI_FORMAT_UINT64(mask),
                          field_datum_byte_offset,
                          obj_desc->common_field.access_byte_width,
@@ -666,7 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
        u32 field_datum_count;
        u32 i;
 
-       ACPI_FUNCTION_TRACE("ex_extract_from_field");
+       ACPI_FUNCTION_TRACE(ex_extract_from_field);
 
        /* Validate target buffer and clear it */
 
@@ -704,6 +717,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
        /* Read the rest of the field */
 
        for (i = 1; i < field_datum_count; i++) {
+
                /* Get next input datum from the field */
 
                field_offset += obj_desc->common_field.access_byte_width;
@@ -713,11 +727,23 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
                        return_ACPI_STATUS(status);
                }
 
-               /* Merge with previous datum if necessary */
-
-               merged_datum |= raw_datum <<
-                   (obj_desc->common_field.access_bit_width -
-                    obj_desc->common_field.start_field_bit_offset);
+               /*
+                * Merge with previous datum if necessary.
+                *
+                * Note: Before the shift, check if the shift value will be larger than
+                * the integer size. If so, there is no need to perform the operation.
+                * This avoids the differences in behavior between different compilers
+                * concerning shift values larger than the target data width.
+                */
+               if ((obj_desc->common_field.access_bit_width -
+                    obj_desc->common_field.start_field_bit_offset) <
+                   ACPI_INTEGER_BIT_SIZE) {
+                       merged_datum |=
+                           raw_datum << (obj_desc->common_field.
+                                         access_bit_width -
+                                         obj_desc->common_field.
+                                         start_field_bit_offset);
+               }
 
                if (i == datum_count) {
                        break;
@@ -771,6 +797,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
 {
        acpi_status status;
        acpi_integer mask;
+       acpi_integer width_mask;
        acpi_integer merged_datum;
        acpi_integer raw_datum = 0;
        u32 field_offset = 0;
@@ -780,7 +807,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
        u32 field_datum_count;
        u32 i;
 
-       ACPI_FUNCTION_TRACE("ex_insert_into_field");
+       ACPI_FUNCTION_TRACE(ex_insert_into_field);
 
        /* Validate input buffer */
 
@@ -793,17 +820,32 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
        }
 
-       /* Compute the number of datums (access width data items) */
+       /*
+        * Create the bitmasks used for bit insertion.
+        * Note: This if/else is used to bypass compiler differences with the
+        * shift operator
+        */
+       if (obj_desc->common_field.access_bit_width == ACPI_INTEGER_BIT_SIZE) {
+               width_mask = ACPI_INTEGER_MAX;
+       } else {
+               width_mask =
+                   ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
+                                        access_bit_width);
+       }
 
-       mask =
+       mask = width_mask &
            ACPI_MASK_BITS_BELOW(obj_desc->common_field.start_field_bit_offset);
-       datum_count =
-           ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
-                            obj_desc->common_field.access_bit_width);
-       field_datum_count =
-           ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
-                            obj_desc->common_field.start_field_bit_offset,
-                            obj_desc->common_field.access_bit_width);
+
+       /* Compute the number of datums (access width data items) */
+
+       datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
+                                      obj_desc->common_field.access_bit_width);
+
+       field_datum_count = ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length +
+                                            obj_desc->common_field.
+                                            start_field_bit_offset,
+                                            obj_desc->common_field.
+                                            access_bit_width);
 
        /* Get initial Datum from the input buffer */
 
@@ -817,6 +859,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
        /* Write the entire field */
 
        for (i = 1; i < field_datum_count; i++) {
+
                /* Write merged datum to the target field */
 
                merged_datum &= mask;
@@ -827,13 +870,30 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                        return_ACPI_STATUS(status);
                }
 
-               /* Start new output datum by merging with previous input datum */
-
                field_offset += obj_desc->common_field.access_byte_width;
-               merged_datum = raw_datum >>
-                   (obj_desc->common_field.access_bit_width -
-                    obj_desc->common_field.start_field_bit_offset);
-               mask = ACPI_INTEGER_MAX;
+
+               /*
+                * Start new output datum by merging with previous input datum
+                * if necessary.
+                *
+                * Note: Before the shift, check if the shift value will be larger than
+                * the integer size. If so, there is no need to perform the operation.
+                * This avoids the differences in behavior between different compilers
+                * concerning shift values larger than the target data width.
+                */
+               if ((obj_desc->common_field.access_bit_width -
+                    obj_desc->common_field.start_field_bit_offset) <
+                   ACPI_INTEGER_BIT_SIZE) {
+                       merged_datum =
+                           raw_datum >> (obj_desc->common_field.
+                                         access_bit_width -
+                                         obj_desc->common_field.
+                                         start_field_bit_offset);
+               } else {
+                       merged_datum = 0;
+               }
+
+               mask = width_mask;
 
                if (i == datum_count) {
                        break;