]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/acpi/executer/exfldio.c
Merge branch 'linus'
[linux-2.6-omap-h63xx.git] / drivers / acpi / executer / exfldio.c
index ca9925c0d0115d825df34a7b509f605efa775956..65a48b6170ee3c9803771cad7a58c2caecc04b77 100644 (file)
@@ -5,7 +5,7 @@
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2006, R. Byron Moore
+ * Copyright (C) 2000 - 2007, R. Byron Moore
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -145,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
@@ -257,14 +257,13 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
        }
 
        ACPI_DEBUG_PRINT_RAW((ACPI_DB_BFIELD,
-                             " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %8.8X%8.8X\n",
+                             " Region [%s:%X], Width %X, ByteBase %X, Offset %X at %p\n",
                              acpi_ut_get_region_name(rgn_desc->region.
                                                      space_id),
                              rgn_desc->region.space_id,
                              obj_desc->common_field.access_byte_width,
                              obj_desc->common_field.base_byte_offset,
-                             field_datum_byte_offset,
-                             ACPI_FORMAT_UINT64(address)));
+                             field_datum_byte_offset, (void *)address));
 
        /* Invoke the appropriate address_space/op_region handler */
 
@@ -727,11 +726,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;
@@ -785,6 +796,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;
@@ -807,17 +819,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 */
 
@@ -842,13 +869,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;