Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[pandora-kernel.git] / drivers / acpi / acpica / exfldio.c
index 0472173..38293fd 100644 (file)
@@ -119,8 +119,8 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
        }
 
        /*
-        * Exit now for SMBus or IPMI address space, it has a non-linear address space
-        * and the request cannot be directly validated
+        * Exit now for SMBus or IPMI 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 ||
            rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) {
@@ -147,8 +147,7 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
         * (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.base_byte_offset + field_datum_byte_offset +
             obj_desc->common_field.access_byte_width)) {
                if (acpi_gbl_enable_interpreter_slack) {
                        /*
@@ -680,6 +679,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
        u32 buffer_tail_bits;
        u32 datum_count;
        u32 field_datum_count;
+       u32 access_bit_width;
        u32 i;
 
        ACPI_FUNCTION_TRACE(ex_extract_from_field);
@@ -694,16 +694,36 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
 
                return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
        }
+
        ACPI_MEMSET(buffer, 0, buffer_length);
+       access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
+
+       /* Handle the simple case here */
+
+       if ((obj_desc->common_field.start_field_bit_offset == 0) &&
+           (obj_desc->common_field.bit_length == access_bit_width)) {
+               status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ);
+               return_ACPI_STATUS(status);
+       }
+
+/* TBD: Move to common setup code */
+
+       /* Field algorithm is limited to sizeof(u64), truncate if needed */
+
+       if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
+               obj_desc->common_field.access_byte_width = sizeof(u64);
+               access_bit_width = sizeof(u64) * 8;
+       }
 
        /* 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);
+       datum_count =
+           ACPI_ROUND_UP_TO(obj_desc->common_field.bit_length,
+                            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);
 
        /* Priming read from the field */
@@ -738,12 +758,11 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
                 * 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) <
+               if (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 -
+                           raw_datum << (access_bit_width -
                                          obj_desc->common_field.
                                          start_field_bit_offset);
                }
@@ -765,8 +784,7 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc,
 
        /* Mask off any extra bits in the last datum */
 
-       buffer_tail_bits = obj_desc->common_field.bit_length %
-           obj_desc->common_field.access_bit_width;
+       buffer_tail_bits = obj_desc->common_field.bit_length % access_bit_width;
        if (buffer_tail_bits) {
                merged_datum &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
        }
@@ -798,6 +816,7 @@ acpi_status
 acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                          void *buffer, u32 buffer_length)
 {
+       void *new_buffer;
        acpi_status status;
        u64 mask;
        u64 width_mask;
@@ -808,9 +827,9 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
        u32 buffer_tail_bits;
        u32 datum_count;
        u32 field_datum_count;
-       u32 i;
+       u32 access_bit_width;
        u32 required_length;
-       void *new_buffer;
+       u32 i;
 
        ACPI_FUNCTION_TRACE(ex_insert_into_field);
 
@@ -844,17 +863,24 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                buffer_length = required_length;
        }
 
+/* TBD: Move to common setup code */
+
+       /* Algo is limited to sizeof(u64), so cut the access_byte_width */
+       if (obj_desc->common_field.access_byte_width > sizeof(u64)) {
+               obj_desc->common_field.access_byte_width = sizeof(u64);
+       }
+
+       access_bit_width = ACPI_MUL_8(obj_desc->common_field.access_byte_width);
+
        /*
         * 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) {
+       if (access_bit_width == ACPI_INTEGER_BIT_SIZE) {
                width_mask = ACPI_UINT64_MAX;
        } else {
-               width_mask =
-                   ACPI_MASK_BITS_ABOVE(obj_desc->common_field.
-                                        access_bit_width);
+               width_mask = ACPI_MASK_BITS_ABOVE(access_bit_width);
        }
 
        mask = width_mask &
@@ -863,12 +889,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
        /* 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);
+                                      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 */
@@ -905,12 +930,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                 * 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 -
+               if ((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 -
+                           raw_datum >> (access_bit_width -
                                          obj_desc->common_field.
                                          start_field_bit_offset);
                } else {
@@ -929,6 +953,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
                ACPI_MEMCPY(&raw_datum, ((char *)buffer) + buffer_offset,
                            ACPI_MIN(obj_desc->common_field.access_byte_width,
                                     buffer_length - buffer_offset));
+
                merged_datum |=
                    raw_datum << obj_desc->common_field.start_field_bit_offset;
        }
@@ -937,7 +962,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc,
 
        buffer_tail_bits = (obj_desc->common_field.bit_length +
                            obj_desc->common_field.start_field_bit_offset) %
-           obj_desc->common_field.access_bit_width;
+           access_bit_width;
        if (buffer_tail_bits) {
                mask &= ACPI_MASK_BITS_ABOVE(buffer_tail_bits);
        }