exfldio.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,154 行 · 第 1/3 页
C
1,154 行
*/ ACPI_MEMCPY (value, (obj_desc->buffer_field.buffer_obj)->buffer.pointer + obj_desc->buffer_field.base_byte_offset + field_datum_byte_offset, obj_desc->common_field.access_byte_width); } else { /* * Copy the data to the target buffer. * Length is the field width in bytes. */ ACPI_MEMCPY ((obj_desc->buffer_field.buffer_obj)->buffer.pointer + obj_desc->buffer_field.base_byte_offset + field_datum_byte_offset, value, obj_desc->common_field.access_byte_width); } status = AE_OK; break; case ACPI_TYPE_LOCAL_BANK_FIELD: /* Ensure that the bank_value is not beyond the capacity of the register */ if (acpi_ex_register_overflow (obj_desc->bank_field.bank_obj, (acpi_integer) obj_desc->bank_field.value)) { return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); } /* * For bank_fields, we must write the bank_value to the bank_register * (itself a region_field) before we can access the data. */ status = acpi_ex_insert_into_field (obj_desc->bank_field.bank_obj, &obj_desc->bank_field.value, sizeof (obj_desc->bank_field.value)); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } /* * Now that the Bank has been selected, fall through to the * region_field case and write the datum to the Operation Region */ /*lint -fallthrough */ case ACPI_TYPE_LOCAL_REGION_FIELD: /* * For simple region_fields, we just directly access the owning * Operation Region. */ status = acpi_ex_access_region (obj_desc, field_datum_byte_offset, value, read_write); break; case ACPI_TYPE_LOCAL_INDEX_FIELD: /* Ensure that the index_value is not beyond the capacity of the register */ if (acpi_ex_register_overflow (obj_desc->index_field.index_obj, (acpi_integer) obj_desc->index_field.value)) { return_ACPI_STATUS (AE_AML_REGISTER_LIMIT); } /* Write the index value to the index_register (itself a region_field) */ field_datum_byte_offset += obj_desc->index_field.value; ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Write to Index Register: Value %8.8X\n", field_datum_byte_offset)); status = acpi_ex_insert_into_field (obj_desc->index_field.index_obj, &field_datum_byte_offset, sizeof (field_datum_byte_offset)); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "I/O to Data Register: value_ptr %p\n", value)); if (read_write == ACPI_READ) { /* Read the datum from the data_register */ status = acpi_ex_extract_from_field (obj_desc->index_field.data_obj, value, sizeof (acpi_integer)); } else { /* Write the datum to the data_register */ status = acpi_ex_insert_into_field (obj_desc->index_field.data_obj, value, sizeof (acpi_integer)); } break; default: ACPI_REPORT_ERROR (("Wrong object type in field I/O %X\n", ACPI_GET_OBJECT_TYPE (obj_desc))); status = AE_AML_INTERNAL; break; } if (ACPI_SUCCESS (status)) { if (read_write == ACPI_READ) { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Read %8.8X%8.8X, Width %d\n", ACPI_FORMAT_UINT64 (*value), obj_desc->common_field.access_byte_width)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD, "Value Written %8.8X%8.8X, Width %d\n", ACPI_FORMAT_UINT64 (*value), obj_desc->common_field.access_byte_width)); } } return_ACPI_STATUS (status);}/******************************************************************************* * * FUNCTION: acpi_ex_write_with_update_rule * * PARAMETERS: *obj_desc - Field to be set * Value - Value to store * * RETURN: Status * * DESCRIPTION: Apply the field update rule to a field write * ******************************************************************************/acpi_statusacpi_ex_write_with_update_rule ( union acpi_operand_object *obj_desc, acpi_integer mask, acpi_integer field_value, u32 field_datum_byte_offset){ acpi_status status = AE_OK; acpi_integer merged_value; acpi_integer current_value; ACPI_FUNCTION_TRACE_U32 ("ex_write_with_update_rule", mask); /* Start with the new bits */ merged_value = field_value; /* 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.field_flags & AML_FIELD_UPDATE_RULE_MASK) { case AML_FIELD_UPDATE_PRESERVE: /* * Check if update rule needs to be applied (not if mask is all * ones) The left shift drops the bits we want to ignore. */ if ((~mask << (ACPI_MUL_8 (sizeof (mask)) - ACPI_MUL_8 (obj_desc->common_field.access_byte_width))) != 0) { /* * Read the current contents of the byte/word/dword containing * the field, and merge with the new field value. */ status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, ¤t_value, ACPI_READ); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } merged_value |= (current_value & ~mask); } break; case AML_FIELD_UPDATE_WRITE_AS_ONES: /* Set positions outside the field to all ones */ merged_value |= ~mask; break; case AML_FIELD_UPDATE_WRITE_AS_ZEROS: /* Set positions outside the field to all zeros */ merged_value &= mask; break; default: ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "write_with_update_rule: Unknown update_rule setting: %X\n", (obj_desc->common_field.field_flags & AML_FIELD_UPDATE_RULE_MASK))); return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } } 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", ACPI_FORMAT_UINT64 (mask), field_datum_byte_offset, obj_desc->common_field.access_byte_width, ACPI_FORMAT_UINT64 (field_value), ACPI_FORMAT_UINT64 (merged_value))); /* Write the merged value */ status = acpi_ex_field_datum_io (obj_desc, field_datum_byte_offset, &merged_value, ACPI_WRITE); return_ACPI_STATUS (status);}/******************************************************************************* * * FUNCTION: acpi_ex_get_buffer_datum * * PARAMETERS: Datum - Where the Datum is returned * Buffer - Raw field buffer * buffer_length - Entire length (used for big-endian only) * byte_granularity - 1/2/4/8 Granularity of the field * (aka Datum Size) * buffer_offset - Datum offset into the buffer * * RETURN: none * * DESCRIPTION: Get a datum from the buffer according to the buffer field * byte granularity * ******************************************************************************/voidacpi_ex_get_buffer_datum ( acpi_integer *datum, void *buffer, u32 buffer_length, u32 byte_granularity, u32 buffer_offset){ u32 index; ACPI_FUNCTION_TRACE_U32 ("ex_get_buffer_datum", byte_granularity); /* Get proper index into buffer (handles big/little endian) */ index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity); /* Move the requested number of bytes */ switch (byte_granularity) { case ACPI_FIELD_BYTE_GRANULARITY: *datum = ((u8 *) buffer) [index]; break; case ACPI_FIELD_WORD_GRANULARITY: ACPI_MOVE_16_TO_64 (datum, &(((u16 *) buffer) [index])); break; case ACPI_FIELD_DWORD_GRANULARITY: ACPI_MOVE_32_TO_64 (datum, &(((u32 *) buffer) [index])); break; case ACPI_FIELD_QWORD_GRANULARITY: ACPI_MOVE_64_TO_64 (datum, &(((u64 *) buffer) [index])); break; default: /* Should not get here */ break; } return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ex_set_buffer_datum * * PARAMETERS: merged_datum - Value to store * Buffer - Receiving buffer * buffer_length - Entire length (used for big-endian only) * byte_granularity - 1/2/4/8 Granularity of the field * (aka Datum Size) * buffer_offset - Datum offset into the buffer * * RETURN: none * * DESCRIPTION: Store the merged datum to the buffer according to the * byte granularity * ******************************************************************************/voidacpi_ex_set_buffer_datum ( acpi_integer merged_datum, void *buffer, u32 buffer_length, u32 byte_granularity, u32 buffer_offset){ u32 index; ACPI_FUNCTION_TRACE_U32 ("ex_set_buffer_datum", byte_granularity); /* Get proper index into buffer (handles big/little endian) */ index = ACPI_BUFFER_INDEX (buffer_length, buffer_offset, byte_granularity); /* Move the requested number of bytes */ switch (byte_granularity) { case ACPI_FIELD_BYTE_GRANULARITY: ((u8 *) buffer) [index] = (u8) merged_datum; break; case ACPI_FIELD_WORD_GRANULARITY: ACPI_MOVE_64_TO_16 (&(((u16 *) buffer)[index]), &merged_datum); break; case ACPI_FIELD_DWORD_GRANULARITY: ACPI_MOVE_64_TO_32 (&(((u32 *) buffer)[index]), &merged_datum); break; case ACPI_FIELD_QWORD_GRANULARITY: ACPI_MOVE_64_TO_64 (&(((u64 *) buffer)[index]), &merged_datum); break; default: /* Should not get here */ break; } return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ex_common_buffer_setup * * PARAMETERS: obj_desc - Field object * buffer_length - Length of caller's buffer * datum_count - Where the datum_count is returned * * RETURN: Status, datum_count * * DESCRIPTION: Common code to validate the incoming buffer size and compute * the number of field "datums" that must be read or written. * A "datum" is the smallest unit that can be read or written * to the field, it is either 1,2,4, or 8 bytes. * ******************************************************************************/acpi_statusacpi_ex_common_buffer_setup ( union acpi_operand_object *obj_desc, u32 buffer_length, u32 *datum_count)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?