aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher/dsfield.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 14:52:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 14:52:52 -0400
commit08acd4f8af42affd8cbed81cc1b69fa12ddb213f (patch)
tree988d15db6233b20db6a500cd5f590c6d2041462d /drivers/acpi/dispatcher/dsfield.c
parentccf2779544eecfcc5447e2028d1029b6d4ff7bb6 (diff)
parent008238b54ac2350babf195084ecedbcf7851a202 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (179 commits) ACPI: Fix acpi_processor_idle and idle= boot parameters interaction acpi: fix section mismatch warning in pnpacpi intel_menlo: fix build warning ACPI: Cleanup: Remove unneeded, multiple local dummy variables ACPI: video - fix permissions on some proc entries ACPI: video - properly handle errors when registering proc elements ACPI: video - do not store invalid entries in attached_array list ACPI: re-name acpi_pm_ops to acpi_suspend_ops ACER_WMI/ASUS_LAPTOP: fix build bug thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed ACPI: check a return value correctly in acpi_power_get_context() #if 0 acpi/bay.c:eject_removable_drive() eeepc-laptop: add hwmon fan control eeepc-laptop: add backlight eeepc-laptop: add base driver ACPI: thinkpad-acpi: bump up version to 0.20 ACPI: thinkpad-acpi: fix selects in Kconfig ACPI: thinkpad-acpi: use a private workqueue ACPI: thinkpad-acpi: fluff really minor fix ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation ... Fixed conflicts in drivers/acpi/video.c and drivers/misc/intel_menlow.c manually.
Diffstat (limited to 'drivers/acpi/dispatcher/dsfield.c')
-rw-r--r--drivers/acpi/dispatcher/dsfield.c173
1 files changed, 100 insertions, 73 deletions
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
index f049639bac35..c78078315be9 100644
--- a/drivers/acpi/dispatcher/dsfield.c
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -5,7 +5,7 @@
5 *****************************************************************************/ 5 *****************************************************************************/
6 6
7/* 7/*
8 * Copyright (C) 2000 - 2007, R. Byron Moore 8 * Copyright (C) 2000 - 2008, Intel Corp.
9 * All rights reserved. 9 * All rights reserved.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
@@ -89,12 +89,16 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
89 89
90 ACPI_FUNCTION_TRACE(ds_create_buffer_field); 90 ACPI_FUNCTION_TRACE(ds_create_buffer_field);
91 91
92 /* Get the name_string argument */ 92 /*
93 93 * Get the name_string argument (name of the new buffer_field)
94 */
94 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 95 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
96
97 /* For create_field, name is the 4th argument */
98
95 arg = acpi_ps_get_arg(op, 3); 99 arg = acpi_ps_get_arg(op, 3);
96 } else { 100 } else {
97 /* Create Bit/Byte/Word/Dword field */ 101 /* For all other create_xXXField operators, name is the 3rd argument */
98 102
99 arg = acpi_ps_get_arg(op, 2); 103 arg = acpi_ps_get_arg(op, 2);
100 } 104 }
@@ -107,26 +111,30 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
107 node = walk_state->deferred_node; 111 node = walk_state->deferred_node;
108 status = AE_OK; 112 status = AE_OK;
109 } else { 113 } else {
110 /* 114 /* Execute flag should always be set when this function is entered */
111 * During the load phase, we want to enter the name of the field into 115
112 * the namespace. During the execute phase (when we evaluate the size 116 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
113 * operand), we want to lookup the name 117 return_ACPI_STATUS(AE_AML_INTERNAL);
114 */
115 if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
116 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
117 } else {
118 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
119 ACPI_NS_ERROR_IF_FOUND;
120 } 118 }
121 119
122 /* 120 /* Creating new namespace node, should not already exist */
123 * Enter the name_string into the namespace 121
124 */ 122 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
123 ACPI_NS_ERROR_IF_FOUND;
124
125 /* Mark node temporary if we are executing a method */
126
127 if (walk_state->method_node) {
128 flags |= ACPI_NS_TEMPORARY;
129 }
130
131 /* Enter the name_string into the namespace */
132
125 status = 133 status =
126 acpi_ns_lookup(walk_state->scope_info, 134 acpi_ns_lookup(walk_state->scope_info,
127 arg->common.value.string, ACPI_TYPE_ANY, 135 arg->common.value.string, ACPI_TYPE_ANY,
128 ACPI_IMODE_LOAD_PASS1, flags, walk_state, 136 ACPI_IMODE_LOAD_PASS1, flags, walk_state,
129 &(node)); 137 &node);
130 if (ACPI_FAILURE(status)) { 138 if (ACPI_FAILURE(status)) {
131 ACPI_ERROR_NAMESPACE(arg->common.value.string, status); 139 ACPI_ERROR_NAMESPACE(arg->common.value.string, status);
132 return_ACPI_STATUS(status); 140 return_ACPI_STATUS(status);
@@ -136,13 +144,13 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
136 /* 144 /*
137 * We could put the returned object (Node) on the object stack for later, 145 * We could put the returned object (Node) on the object stack for later,
138 * but for now, we will put it in the "op" object that the parser uses, 146 * but for now, we will put it in the "op" object that the parser uses,
139 * so we can get it again at the end of this scope 147 * so we can get it again at the end of this scope.
140 */ 148 */
141 op->common.node = node; 149 op->common.node = node;
142 150
143 /* 151 /*
144 * If there is no object attached to the node, this node was just created 152 * If there is no object attached to the node, this node was just created
145 * and we need to create the field object. Otherwise, this was a lookup 153 * and we need to create the field object. Otherwise, this was a lookup
146 * of an existing node and we don't want to create the field object again. 154 * of an existing node and we don't want to create the field object again.
147 */ 155 */
148 obj_desc = acpi_ns_get_attached_object(node); 156 obj_desc = acpi_ns_get_attached_object(node);
@@ -164,9 +172,8 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,
164 } 172 }
165 173
166 /* 174 /*
167 * Remember location in AML stream of the field unit 175 * Remember location in AML stream of the field unit opcode and operands --
168 * opcode and operands -- since the buffer and index 176 * since the buffer and index operands must be evaluated.
169 * operands must be evaluated.
170 */ 177 */
171 second_desc = obj_desc->common.next_object; 178 second_desc = obj_desc->common.next_object;
172 second_desc->extra.aml_start = op->named.data; 179 second_desc->extra.aml_start = op->named.data;
@@ -261,7 +268,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
261 268
262 case AML_INT_NAMEDFIELD_OP: 269 case AML_INT_NAMEDFIELD_OP:
263 270
264 /* Lookup the name */ 271 /* Lookup the name, it should already exist */
265 272
266 status = acpi_ns_lookup(walk_state->scope_info, 273 status = acpi_ns_lookup(walk_state->scope_info,
267 (char *)&arg->named.name, 274 (char *)&arg->named.name,
@@ -272,20 +279,23 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
272 if (ACPI_FAILURE(status)) { 279 if (ACPI_FAILURE(status)) {
273 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 280 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
274 status); 281 status);
275 if (status != AE_ALREADY_EXISTS) { 282 return_ACPI_STATUS(status);
276 return_ACPI_STATUS(status);
277 }
278
279 /* Already exists, ignore error */
280 } else { 283 } else {
281 arg->common.node = info->field_node; 284 arg->common.node = info->field_node;
282 info->field_bit_length = arg->common.value.size; 285 info->field_bit_length = arg->common.value.size;
283 286
284 /* Create and initialize an object for the new Field Node */ 287 /*
285 288 * If there is no object attached to the node, this node was
286 status = acpi_ex_prep_field_value(info); 289 * just created and we need to create the field object.
287 if (ACPI_FAILURE(status)) { 290 * Otherwise, this was a lookup of an existing node and we
288 return_ACPI_STATUS(status); 291 * don't want to create the field object again.
292 */
293 if (!acpi_ns_get_attached_object
294 (info->field_node)) {
295 status = acpi_ex_prep_field_value(info);
296 if (ACPI_FAILURE(status)) {
297 return_ACPI_STATUS(status);
298 }
289 } 299 }
290 } 300 }
291 301
@@ -399,9 +409,27 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
399 union acpi_parse_object *arg = NULL; 409 union acpi_parse_object *arg = NULL;
400 struct acpi_namespace_node *node; 410 struct acpi_namespace_node *node;
401 u8 type = 0; 411 u8 type = 0;
412 u32 flags;
402 413
403 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op); 414 ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
404 415
416 /* Execute flag should always be set when this function is entered */
417
418 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
419 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
420
421 /* bank_field Op is deferred, just return OK */
422
423 return_ACPI_STATUS(AE_OK);
424 }
425
426 return_ACPI_STATUS(AE_AML_INTERNAL);
427 }
428
429 /*
430 * Get the field_list argument for this opcode. This is the start of the
431 * list of field elements.
432 */
405 switch (walk_state->opcode) { 433 switch (walk_state->opcode) {
406 case AML_FIELD_OP: 434 case AML_FIELD_OP:
407 arg = acpi_ps_get_arg(op, 2); 435 arg = acpi_ps_get_arg(op, 2);
@@ -422,20 +450,33 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
422 return_ACPI_STATUS(AE_BAD_PARAMETER); 450 return_ACPI_STATUS(AE_BAD_PARAMETER);
423 } 451 }
424 452
453 if (!arg) {
454 return_ACPI_STATUS(AE_AML_NO_OPERAND);
455 }
456
457 /* Creating new namespace node(s), should not already exist */
458
459 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
460 ACPI_NS_ERROR_IF_FOUND;
461
462 /* Mark node(s) temporary if we are executing a method */
463
464 if (walk_state->method_node) {
465 flags |= ACPI_NS_TEMPORARY;
466 }
467
425 /* 468 /*
426 * Walk the list of entries in the field_list 469 * Walk the list of entries in the field_list
427 */ 470 */
428 while (arg) { 471 while (arg) {
429 472 /*
430 /* Ignore OFFSET and ACCESSAS terms here */ 473 * Ignore OFFSET and ACCESSAS terms here; we are only interested in the
431 474 * field names in order to enter them into the namespace.
475 */
432 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 476 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
433 status = acpi_ns_lookup(walk_state->scope_info, 477 status = acpi_ns_lookup(walk_state->scope_info,
434 (char *)&arg->named.name, 478 (char *)&arg->named.name, type,
435 type, ACPI_IMODE_LOAD_PASS1, 479 ACPI_IMODE_LOAD_PASS1, flags,
436 ACPI_NS_NO_UPSEARCH |
437 ACPI_NS_DONT_OPEN_SCOPE |
438 ACPI_NS_ERROR_IF_FOUND,
439 walk_state, &node); 480 walk_state, &node);
440 if (ACPI_FAILURE(status)) { 481 if (ACPI_FAILURE(status)) {
441 ACPI_ERROR_NAMESPACE((char *)&arg->named.name, 482 ACPI_ERROR_NAMESPACE((char *)&arg->named.name,
@@ -452,7 +493,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
452 arg->common.node = node; 493 arg->common.node = node;
453 } 494 }
454 495
455 /* Move to next field in the list */ 496 /* Get the next field element in the list */
456 497
457 arg = arg->common.next; 498 arg = arg->common.next;
458 } 499 }
@@ -466,7 +507,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
466 * 507 *
467 * PARAMETERS: Op - Op containing the Field definition and args 508 * PARAMETERS: Op - Op containing the Field definition and args
468 * region_node - Object for the containing Operation Region 509 * region_node - Object for the containing Operation Region
469 * ` walk_state - Current method state 510 * walk_state - Current method state
470 * 511 *
471 * RETURN: Status 512 * RETURN: Status
472 * 513 *
@@ -513,36 +554,13 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
513 return_ACPI_STATUS(status); 554 return_ACPI_STATUS(status);
514 } 555 }
515 556
516 /* Third arg is the bank_value */ 557 /*
517 558 * Third arg is the bank_value
518 /* TBD: This arg is a term_arg, not a constant, and must be evaluated */ 559 * This arg is a term_arg, not a constant
519 560 * It will be evaluated later, by acpi_ds_eval_bank_field_operands
561 */
520 arg = arg->common.next; 562 arg = arg->common.next;
521 563
522 /* Currently, only the following constants are supported */
523
524 switch (arg->common.aml_opcode) {
525 case AML_ZERO_OP:
526 info.bank_value = 0;
527 break;
528
529 case AML_ONE_OP:
530 info.bank_value = 1;
531 break;
532
533 case AML_BYTE_OP:
534 case AML_WORD_OP:
535 case AML_DWORD_OP:
536 case AML_QWORD_OP:
537 info.bank_value = (u32) arg->common.value.integer;
538 break;
539
540 default:
541 info.bank_value = 0;
542 ACPI_ERROR((AE_INFO,
543 "Non-constant BankValue for BankField is not implemented"));
544 }
545
546 /* Fourth arg is the field flags */ 564 /* Fourth arg is the field flags */
547 565
548 arg = arg->common.next; 566 arg = arg->common.next;
@@ -553,8 +571,17 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,
553 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD; 571 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
554 info.region_node = region_node; 572 info.region_node = region_node;
555 573
556 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 574 /*
575 * Use Info.data_register_node to store bank_field Op
576 * It's safe because data_register_node will never be used when create bank field
577 * We store aml_start and aml_length in the bank_field Op for late evaluation
578 * Used in acpi_ex_prep_field_value(Info)
579 *
580 * TBD: Or, should we add a field in struct acpi_create_field_info, like "void *ParentOp"?
581 */
582 info.data_register_node = (struct acpi_namespace_node *)op;
557 583
584 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
558 return_ACPI_STATUS(status); 585 return_ACPI_STATUS(status);
559} 586}
560 587