diff options
author | Bob Moore <robert.moore@intel.com> | 2011-11-16 00:39:07 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-01-17 03:36:29 -0500 |
commit | 9ce81784c9c0396a6a6be05248928a71134fe60b (patch) | |
tree | cccb8fc3a3514276ed0b1801f7bb26ba2319d62d /drivers/acpi/acpica/dsfield.c | |
parent | ffef68273b6278e98a99dd4051671d4854b20fe0 (diff) |
ACPI 5.0: Implement Connection() and AccessAs() changes
Support within the interpreter and operation region dispatch.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/dsfield.c')
-rw-r--r-- | drivers/acpi/acpica/dsfield.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 34be60c0e448..aa880d992984 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c | |||
@@ -221,6 +221,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
221 | { | 221 | { |
222 | acpi_status status; | 222 | acpi_status status; |
223 | u64 position; | 223 | u64 position; |
224 | union acpi_parse_object *child; | ||
224 | 225 | ||
225 | ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); | 226 | ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); |
226 | 227 | ||
@@ -232,10 +233,11 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
232 | 233 | ||
233 | while (arg) { | 234 | while (arg) { |
234 | /* | 235 | /* |
235 | * Three types of field elements are handled: | 236 | * Four types of field elements are handled: |
236 | * 1) Offset - specifies a bit offset | 237 | * 1) Name - Enters a new named field into the namespace |
237 | * 2) access_as - changes the access mode | 238 | * 2) Offset - specifies a bit offset |
238 | * 3) Name - Enters a new named field into the namespace | 239 | * 3) access_as - changes the access mode/attributes |
240 | * 4) Connection - Associate a resource template with the field | ||
239 | */ | 241 | */ |
240 | switch (arg->common.aml_opcode) { | 242 | switch (arg->common.aml_opcode) { |
241 | case AML_INT_RESERVEDFIELD_OP: | 243 | case AML_INT_RESERVEDFIELD_OP: |
@@ -253,21 +255,70 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info, | |||
253 | break; | 255 | break; |
254 | 256 | ||
255 | case AML_INT_ACCESSFIELD_OP: | 257 | case AML_INT_ACCESSFIELD_OP: |
256 | 258 | case AML_INT_EXTACCESSFIELD_OP: | |
257 | /* | 259 | /* |
258 | * Get a new access_type and access_attribute -- to be used for all | 260 | * Get new access_type, access_attribute, and access_length fields |
259 | * field units that follow, until field end or another access_as | 261 | * -- to be used for all field units that follow, until the |
260 | * keyword. | 262 | * end-of-field or another access_as keyword is encountered. |
263 | * NOTE. These three bytes are encoded in the integer value | ||
264 | * of the parseop for convenience. | ||
261 | * | 265 | * |
262 | * In field_flags, preserve the flag bits other than the | 266 | * In field_flags, preserve the flag bits other than the |
263 | * ACCESS_TYPE bits | 267 | * ACCESS_TYPE bits. |
264 | */ | 268 | */ |
269 | |||
270 | /* access_type (byte_acc, word_acc, etc.) */ | ||
271 | |||
265 | info->field_flags = (u8) | 272 | info->field_flags = (u8) |
266 | ((info-> | 273 | ((info-> |
267 | field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | | 274 | field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | |
268 | ((u8) ((u32) arg->common.value.integer >> 8))); | 275 | ((u8)((u32)(arg->common.value.integer & 0x07)))); |
276 | |||
277 | /* access_attribute (attrib_quick, attrib_byte, etc.) */ | ||
278 | |||
279 | info->attribute = | ||
280 | (u8)((arg->common.value.integer >> 8) & 0xFF); | ||
281 | |||
282 | /* access_length (for serial/buffer protocols) */ | ||
283 | |||
284 | info->access_length = | ||
285 | (u8)((arg->common.value.integer >> 16) & 0xFF); | ||
286 | break; | ||
287 | |||
288 | case AML_INT_CONNECTION_OP: | ||
289 | /* | ||
290 | * Clear any previous connection. New connection is used for all | ||
291 | * fields that follow, similar to access_as | ||
292 | */ | ||
293 | info->resource_buffer = NULL; | ||
294 | info->connection_node = NULL; | ||
269 | 295 | ||
270 | info->attribute = (u8) (arg->common.value.integer); | 296 | /* |
297 | * A Connection() is either an actual resource descriptor (buffer) | ||
298 | * or a named reference to a resource template | ||
299 | */ | ||
300 | child = arg->common.value.arg; | ||
301 | if (child->common.aml_opcode == AML_INT_BYTELIST_OP) { | ||
302 | info->resource_buffer = child->named.data; | ||
303 | info->resource_length = | ||
304 | (u16)child->named.value.integer; | ||
305 | } else { | ||
306 | /* Lookup the Connection() namepath, it should already exist */ | ||
307 | |||
308 | status = acpi_ns_lookup(walk_state->scope_info, | ||
309 | child->common.value. | ||
310 | name, ACPI_TYPE_ANY, | ||
311 | ACPI_IMODE_EXECUTE, | ||
312 | ACPI_NS_DONT_OPEN_SCOPE, | ||
313 | walk_state, | ||
314 | &info->connection_node); | ||
315 | if (ACPI_FAILURE(status)) { | ||
316 | ACPI_ERROR_NAMESPACE(child->common. | ||
317 | value.name, | ||
318 | status); | ||
319 | return_ACPI_STATUS(status); | ||
320 | } | ||
321 | } | ||
271 | break; | 322 | break; |
272 | 323 | ||
273 | case AML_INT_NAMEDFIELD_OP: | 324 | case AML_INT_NAMEDFIELD_OP: |
@@ -374,6 +425,8 @@ acpi_ds_create_field(union acpi_parse_object *op, | |||
374 | } | 425 | } |
375 | } | 426 | } |
376 | 427 | ||
428 | ACPI_MEMSET(&info, 0, sizeof(struct acpi_create_field_info)); | ||
429 | |||
377 | /* Second arg is the field flags */ | 430 | /* Second arg is the field flags */ |
378 | 431 | ||
379 | arg = arg->common.next; | 432 | arg = arg->common.next; |
@@ -386,7 +439,6 @@ acpi_ds_create_field(union acpi_parse_object *op, | |||
386 | info.region_node = region_node; | 439 | info.region_node = region_node; |
387 | 440 | ||
388 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | 441 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); |
389 | |||
390 | return_ACPI_STATUS(status); | 442 | return_ACPI_STATUS(status); |
391 | } | 443 | } |
392 | 444 | ||
@@ -474,8 +526,8 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, | |||
474 | */ | 526 | */ |
475 | while (arg) { | 527 | while (arg) { |
476 | /* | 528 | /* |
477 | * Ignore OFFSET and ACCESSAS terms here; we are only interested in the | 529 | * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested |
478 | * field names in order to enter them into the namespace. | 530 | * in the field names in order to enter them into the namespace. |
479 | */ | 531 | */ |
480 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { | 532 | if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { |
481 | status = acpi_ns_lookup(walk_state->scope_info, | 533 | status = acpi_ns_lookup(walk_state->scope_info, |
@@ -651,6 +703,5 @@ acpi_ds_create_index_field(union acpi_parse_object *op, | |||
651 | info.region_node = region_node; | 703 | info.region_node = region_node; |
652 | 704 | ||
653 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); | 705 | status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); |
654 | |||
655 | return_ACPI_STATUS(status); | 706 | return_ACPI_STATUS(status); |
656 | } | 707 | } |