aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/dsfield.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2011-11-16 00:39:07 -0500
committerLen Brown <len.brown@intel.com>2012-01-17 03:36:29 -0500
commit9ce81784c9c0396a6a6be05248928a71134fe60b (patch)
treecccb8fc3a3514276ed0b1801f7bb26ba2319d62d /drivers/acpi/acpica/dsfield.c
parentffef68273b6278e98a99dd4051671d4854b20fe0 (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.c81
1 files changed, 66 insertions, 15 deletions
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index 34be60c0e44..aa880d99298 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}