Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/acpi/acpica/dsfield.c
26285 views
1
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2
/******************************************************************************
3
*
4
* Module Name: dsfield - Dispatcher field routines
5
*
6
* Copyright (C) 2000 - 2025, Intel Corp.
7
*
8
*****************************************************************************/
9
10
#include <acpi/acpi.h>
11
#include "accommon.h"
12
#include "amlcode.h"
13
#include "acdispat.h"
14
#include "acinterp.h"
15
#include "acnamesp.h"
16
#include "acparser.h"
17
18
#ifdef ACPI_EXEC_APP
19
#include "aecommon.h"
20
#endif
21
22
#define _COMPONENT ACPI_DISPATCHER
23
ACPI_MODULE_NAME("dsfield")
24
25
/* Local prototypes */
26
#ifdef ACPI_ASL_COMPILER
27
#include "acdisasm.h"
28
static acpi_status
29
acpi_ds_create_external_region(acpi_status lookup_status,
30
union acpi_parse_object *op,
31
char *path,
32
struct acpi_walk_state *walk_state,
33
struct acpi_namespace_node **node);
34
#endif
35
36
static acpi_status
37
acpi_ds_get_field_names(struct acpi_create_field_info *info,
38
struct acpi_walk_state *walk_state,
39
union acpi_parse_object *arg);
40
41
#ifdef ACPI_ASL_COMPILER
42
/*******************************************************************************
43
*
44
* FUNCTION: acpi_ds_create_external_region (iASL Disassembler only)
45
*
46
* PARAMETERS: lookup_status - Status from ns_lookup operation
47
* op - Op containing the Field definition and args
48
* path - Pathname of the region
49
* ` walk_state - Current method state
50
* node - Where the new region node is returned
51
*
52
* RETURN: Status
53
*
54
* DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
55
* region node/object.
56
*
57
******************************************************************************/
58
59
static acpi_status
60
acpi_ds_create_external_region(acpi_status lookup_status,
61
union acpi_parse_object *op,
62
char *path,
63
struct acpi_walk_state *walk_state,
64
struct acpi_namespace_node **node)
65
{
66
acpi_status status;
67
union acpi_operand_object *obj_desc;
68
69
if (lookup_status != AE_NOT_FOUND) {
70
return (lookup_status);
71
}
72
73
/*
74
* Table disassembly:
75
* operation_region not found. Generate an External for it, and
76
* insert the name into the namespace.
77
*/
78
acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
79
80
status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
81
ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
82
walk_state, node);
83
if (ACPI_FAILURE(status)) {
84
return (status);
85
}
86
87
/* Must create and install a region object for the new node */
88
89
obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
90
if (!obj_desc) {
91
return (AE_NO_MEMORY);
92
}
93
94
obj_desc->region.node = *node;
95
status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
96
return (status);
97
}
98
#endif
99
100
/*******************************************************************************
101
*
102
* FUNCTION: acpi_ds_create_buffer_field
103
*
104
* PARAMETERS: op - Current parse op (create_XXField)
105
* walk_state - Current state
106
*
107
* RETURN: Status
108
*
109
* DESCRIPTION: Execute the create_field operators:
110
* create_bit_field_op,
111
* create_byte_field_op,
112
* create_word_field_op,
113
* create_dword_field_op,
114
* create_qword_field_op,
115
* create_field_op (all of which define a field in a buffer)
116
*
117
******************************************************************************/
118
119
acpi_status
120
acpi_ds_create_buffer_field(union acpi_parse_object *op,
121
struct acpi_walk_state *walk_state)
122
{
123
union acpi_parse_object *arg;
124
struct acpi_namespace_node *node;
125
acpi_status status;
126
union acpi_operand_object *obj_desc;
127
union acpi_operand_object *second_desc = NULL;
128
u32 flags;
129
130
ACPI_FUNCTION_TRACE(ds_create_buffer_field);
131
132
/*
133
* Get the name_string argument (name of the new buffer_field)
134
*/
135
if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
136
137
/* For create_field, name is the 4th argument */
138
139
arg = acpi_ps_get_arg(op, 3);
140
} else {
141
/* For all other create_XXXField operators, name is the 3rd argument */
142
143
arg = acpi_ps_get_arg(op, 2);
144
}
145
146
if (!arg) {
147
return_ACPI_STATUS(AE_AML_NO_OPERAND);
148
}
149
150
if (walk_state->deferred_node) {
151
node = walk_state->deferred_node;
152
} else {
153
/* Execute flag should always be set when this function is entered */
154
155
if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
156
ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
157
return_ACPI_STATUS(AE_AML_INTERNAL);
158
}
159
160
/* Creating new namespace node, should not already exist */
161
162
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
163
ACPI_NS_ERROR_IF_FOUND;
164
165
/*
166
* Mark node temporary if we are executing a normal control
167
* method. (Don't mark if this is a module-level code method)
168
*/
169
if (walk_state->method_node &&
170
!(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
171
flags |= ACPI_NS_TEMPORARY;
172
}
173
174
/* Enter the name_string into the namespace */
175
176
status = acpi_ns_lookup(walk_state->scope_info,
177
arg->common.value.string, ACPI_TYPE_ANY,
178
ACPI_IMODE_LOAD_PASS1, flags,
179
walk_state, &node);
180
if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE)
181
&& status == AE_ALREADY_EXISTS) {
182
status = AE_OK;
183
} else if (ACPI_FAILURE(status)) {
184
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
185
arg->common.value.string, status);
186
return_ACPI_STATUS(status);
187
}
188
}
189
190
/*
191
* We could put the returned object (Node) on the object stack for later,
192
* but for now, we will put it in the "op" object that the parser uses,
193
* so we can get it again at the end of this scope.
194
*/
195
op->common.node = node;
196
197
/*
198
* If there is no object attached to the node, this node was just created
199
* and we need to create the field object. Otherwise, this was a lookup
200
* of an existing node and we don't want to create the field object again.
201
*/
202
obj_desc = acpi_ns_get_attached_object(node);
203
if (obj_desc) {
204
return_ACPI_STATUS(AE_OK);
205
}
206
207
/*
208
* The Field definition is not fully parsed at this time.
209
* (We must save the address of the AML for the buffer and index operands)
210
*/
211
212
/* Create the buffer field object */
213
214
obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
215
if (!obj_desc) {
216
status = AE_NO_MEMORY;
217
goto cleanup;
218
}
219
220
/*
221
* Remember location in AML stream of the field unit opcode and operands
222
* -- since the buffer and index operands must be evaluated.
223
*/
224
second_desc = obj_desc->common.next_object;
225
second_desc->extra.aml_start = op->named.data;
226
second_desc->extra.aml_length = op->named.length;
227
obj_desc->buffer_field.node = node;
228
229
/* Attach constructed field descriptors to parent node */
230
231
status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
232
if (ACPI_FAILURE(status)) {
233
goto cleanup;
234
}
235
236
cleanup:
237
238
/* Remove local reference to the object */
239
240
acpi_ut_remove_reference(obj_desc);
241
return_ACPI_STATUS(status);
242
}
243
244
/*******************************************************************************
245
*
246
* FUNCTION: acpi_ds_get_field_names
247
*
248
* PARAMETERS: info - create_field info structure
249
* walk_state - Current method state
250
* arg - First parser arg for the field name list
251
*
252
* RETURN: Status
253
*
254
* DESCRIPTION: Process all named fields in a field declaration. Names are
255
* entered into the namespace.
256
*
257
******************************************************************************/
258
259
static acpi_status
260
acpi_ds_get_field_names(struct acpi_create_field_info *info,
261
struct acpi_walk_state *walk_state,
262
union acpi_parse_object *arg)
263
{
264
acpi_status status;
265
u64 position;
266
union acpi_parse_object *child;
267
268
#ifdef ACPI_EXEC_APP
269
union acpi_operand_object *result_desc;
270
union acpi_operand_object *obj_desc;
271
char *name_path;
272
#endif
273
274
ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
275
276
/* First field starts at bit zero */
277
278
info->field_bit_position = 0;
279
280
/* Process all elements in the field list (of parse nodes) */
281
282
while (arg) {
283
/*
284
* Four types of field elements are handled:
285
* 1) name - Enters a new named field into the namespace
286
* 2) offset - specifies a bit offset
287
* 3) access_as - changes the access mode/attributes
288
* 4) connection - Associate a resource template with the field
289
*/
290
switch (arg->common.aml_opcode) {
291
case AML_INT_RESERVEDFIELD_OP:
292
293
position = (u64)info->field_bit_position +
294
(u64)arg->common.value.size;
295
296
if (position > ACPI_UINT32_MAX) {
297
ACPI_ERROR((AE_INFO,
298
"Bit offset within field too large (> 0xFFFFFFFF)"));
299
return_ACPI_STATUS(AE_SUPPORT);
300
}
301
302
info->field_bit_position = (u32) position;
303
break;
304
305
case AML_INT_ACCESSFIELD_OP:
306
case AML_INT_EXTACCESSFIELD_OP:
307
/*
308
* Get new access_type, access_attribute, and access_length fields
309
* -- to be used for all field units that follow, until the
310
* end-of-field or another access_as keyword is encountered.
311
* NOTE. These three bytes are encoded in the integer value
312
* of the parseop for convenience.
313
*
314
* In field_flags, preserve the flag bits other than the
315
* ACCESS_TYPE bits.
316
*/
317
318
/* access_type (byte_acc, word_acc, etc.) */
319
320
info->field_flags = (u8)
321
((info->
322
field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
323
((u8)((u32)(arg->common.value.integer & 0x07))));
324
325
/* access_attribute (attrib_quick, attrib_byte, etc.) */
326
327
info->attribute = (u8)
328
((arg->common.value.integer >> 8) & 0xFF);
329
330
/* access_length (for serial/buffer protocols) */
331
332
info->access_length = (u8)
333
((arg->common.value.integer >> 16) & 0xFF);
334
break;
335
336
case AML_INT_CONNECTION_OP:
337
/*
338
* Clear any previous connection. New connection is used for all
339
* fields that follow, similar to access_as
340
*/
341
info->resource_buffer = NULL;
342
info->connection_node = NULL;
343
info->pin_number_index = 0;
344
345
/*
346
* A Connection() is either an actual resource descriptor (buffer)
347
* or a named reference to a resource template
348
*/
349
child = arg->common.value.arg;
350
if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
351
info->resource_buffer = child->named.data;
352
info->resource_length =
353
(u16)child->named.value.integer;
354
} else {
355
/* Lookup the Connection() namepath, it should already exist */
356
357
status = acpi_ns_lookup(walk_state->scope_info,
358
child->common.value.
359
name, ACPI_TYPE_ANY,
360
ACPI_IMODE_EXECUTE,
361
ACPI_NS_DONT_OPEN_SCOPE,
362
walk_state,
363
&info->connection_node);
364
if (ACPI_FAILURE(status)) {
365
ACPI_ERROR_NAMESPACE(walk_state->
366
scope_info,
367
child->common.
368
value.name,
369
status);
370
return_ACPI_STATUS(status);
371
}
372
}
373
break;
374
375
case AML_INT_NAMEDFIELD_OP:
376
377
/* Lookup the name, it should already exist */
378
379
status = acpi_ns_lookup(walk_state->scope_info,
380
(char *)&arg->named.name,
381
info->field_type,
382
ACPI_IMODE_EXECUTE,
383
ACPI_NS_DONT_OPEN_SCOPE,
384
walk_state, &info->field_node);
385
if (ACPI_FAILURE(status)) {
386
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
387
(char *)&arg->named.name,
388
status);
389
return_ACPI_STATUS(status);
390
} else {
391
arg->common.node = info->field_node;
392
info->field_bit_length = arg->common.value.size;
393
394
/*
395
* If there is no object attached to the node, this node was
396
* just created and we need to create the field object.
397
* Otherwise, this was a lookup of an existing node and we
398
* don't want to create the field object again.
399
*/
400
if (!acpi_ns_get_attached_object
401
(info->field_node)) {
402
status = acpi_ex_prep_field_value(info);
403
if (ACPI_FAILURE(status)) {
404
return_ACPI_STATUS(status);
405
}
406
#ifdef ACPI_EXEC_APP
407
name_path =
408
acpi_ns_get_external_pathname(info->
409
field_node);
410
if (ACPI_SUCCESS
411
(ae_lookup_init_file_entry
412
(name_path, &obj_desc))) {
413
acpi_ex_write_data_to_field
414
(obj_desc,
415
acpi_ns_get_attached_object
416
(info->field_node),
417
&result_desc);
418
acpi_ut_remove_reference
419
(obj_desc);
420
}
421
ACPI_FREE(name_path);
422
#endif
423
}
424
}
425
426
/* Keep track of bit position for the next field */
427
428
position = (u64)info->field_bit_position +
429
(u64)arg->common.value.size;
430
431
if (position > ACPI_UINT32_MAX) {
432
ACPI_ERROR((AE_INFO,
433
"Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
434
ACPI_CAST_PTR(char,
435
&info->field_node->
436
name)));
437
return_ACPI_STATUS(AE_SUPPORT);
438
}
439
440
info->field_bit_position += info->field_bit_length;
441
info->pin_number_index++; /* Index relative to previous Connection() */
442
break;
443
444
default:
445
446
ACPI_ERROR((AE_INFO,
447
"Invalid opcode in field list: 0x%X",
448
arg->common.aml_opcode));
449
return_ACPI_STATUS(AE_AML_BAD_OPCODE);
450
}
451
452
arg = arg->common.next;
453
}
454
455
return_ACPI_STATUS(AE_OK);
456
}
457
458
/*******************************************************************************
459
*
460
* FUNCTION: acpi_ds_create_field
461
*
462
* PARAMETERS: op - Op containing the Field definition and args
463
* region_node - Object for the containing Operation Region
464
* ` walk_state - Current method state
465
*
466
* RETURN: Status
467
*
468
* DESCRIPTION: Create a new field in the specified operation region
469
*
470
******************************************************************************/
471
472
acpi_status
473
acpi_ds_create_field(union acpi_parse_object *op,
474
struct acpi_namespace_node *region_node,
475
struct acpi_walk_state *walk_state)
476
{
477
acpi_status status;
478
union acpi_parse_object *arg;
479
struct acpi_create_field_info info;
480
481
ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
482
483
/* First arg is the name of the parent op_region (must already exist) */
484
485
arg = op->common.value.arg;
486
487
if (!region_node) {
488
status =
489
acpi_ns_lookup(walk_state->scope_info,
490
arg->common.value.name, ACPI_TYPE_REGION,
491
ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
492
walk_state, &region_node);
493
#ifdef ACPI_ASL_COMPILER
494
status = acpi_ds_create_external_region(status, arg,
495
arg->common.value.name,
496
walk_state,
497
&region_node);
498
#endif
499
if (ACPI_FAILURE(status)) {
500
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
501
arg->common.value.name, status);
502
return_ACPI_STATUS(status);
503
}
504
}
505
506
memset(&info, 0, sizeof(struct acpi_create_field_info));
507
508
/* Second arg is the field flags */
509
510
arg = arg->common.next;
511
info.field_flags = (u8) arg->common.value.integer;
512
info.attribute = 0;
513
514
/* Each remaining arg is a Named Field */
515
516
info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
517
info.region_node = region_node;
518
519
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
520
if (ACPI_FAILURE(status)) {
521
return_ACPI_STATUS(status);
522
}
523
524
if (info.region_node->object->region.space_id ==
525
ACPI_ADR_SPACE_PLATFORM_COMM) {
526
region_node->object->field.internal_pcc_buffer =
527
ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
528
length);
529
if (!region_node->object->field.internal_pcc_buffer) {
530
return_ACPI_STATUS(AE_NO_MEMORY);
531
}
532
}
533
534
return_ACPI_STATUS(status);
535
}
536
537
/*******************************************************************************
538
*
539
* FUNCTION: acpi_ds_init_field_objects
540
*
541
* PARAMETERS: op - Op containing the Field definition and args
542
* ` walk_state - Current method state
543
*
544
* RETURN: Status
545
*
546
* DESCRIPTION: For each "Field Unit" name in the argument list that is
547
* part of the field declaration, enter the name into the
548
* namespace.
549
*
550
******************************************************************************/
551
552
acpi_status
553
acpi_ds_init_field_objects(union acpi_parse_object *op,
554
struct acpi_walk_state *walk_state)
555
{
556
acpi_status status;
557
union acpi_parse_object *arg = NULL;
558
struct acpi_namespace_node *node;
559
u8 type = 0;
560
u32 flags;
561
562
ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
563
564
/* Execute flag should always be set when this function is entered */
565
566
if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
567
if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
568
569
/* bank_field Op is deferred, just return OK */
570
571
return_ACPI_STATUS(AE_OK);
572
}
573
574
ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
575
return_ACPI_STATUS(AE_AML_INTERNAL);
576
}
577
578
/*
579
* Get the field_list argument for this opcode. This is the start of the
580
* list of field elements.
581
*/
582
switch (walk_state->opcode) {
583
case AML_FIELD_OP:
584
585
arg = acpi_ps_get_arg(op, 2);
586
type = ACPI_TYPE_LOCAL_REGION_FIELD;
587
break;
588
589
case AML_BANK_FIELD_OP:
590
591
arg = acpi_ps_get_arg(op, 4);
592
type = ACPI_TYPE_LOCAL_BANK_FIELD;
593
break;
594
595
case AML_INDEX_FIELD_OP:
596
597
arg = acpi_ps_get_arg(op, 3);
598
type = ACPI_TYPE_LOCAL_INDEX_FIELD;
599
break;
600
601
default:
602
603
return_ACPI_STATUS(AE_BAD_PARAMETER);
604
}
605
606
/* Creating new namespace node(s), should not already exist */
607
608
flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
609
ACPI_NS_ERROR_IF_FOUND;
610
611
/*
612
* Mark node(s) temporary if we are executing a normal control
613
* method. (Don't mark if this is a module-level code method)
614
*/
615
if (walk_state->method_node &&
616
!(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
617
flags |= ACPI_NS_TEMPORARY;
618
}
619
#ifdef ACPI_EXEC_APP
620
flags |= ACPI_NS_OVERRIDE_IF_FOUND;
621
#endif
622
/*
623
* Walk the list of entries in the field_list
624
* Note: field_list can be of zero length. In this case, Arg will be NULL.
625
*/
626
while (arg) {
627
/*
628
* Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
629
* in the field names in order to enter them into the namespace.
630
*/
631
if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
632
status = acpi_ns_lookup(walk_state->scope_info,
633
(char *)&arg->named.name, type,
634
ACPI_IMODE_LOAD_PASS1, flags,
635
walk_state, &node);
636
if (ACPI_FAILURE(status)) {
637
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
638
(char *)&arg->named.name,
639
status);
640
if (status != AE_ALREADY_EXISTS) {
641
return_ACPI_STATUS(status);
642
}
643
644
/* Name already exists, just ignore this error */
645
}
646
647
arg->common.node = node;
648
}
649
650
/* Get the next field element in the list */
651
652
arg = arg->common.next;
653
}
654
655
return_ACPI_STATUS(AE_OK);
656
}
657
658
/*******************************************************************************
659
*
660
* FUNCTION: acpi_ds_create_bank_field
661
*
662
* PARAMETERS: op - Op containing the Field definition and args
663
* region_node - Object for the containing Operation Region
664
* walk_state - Current method state
665
*
666
* RETURN: Status
667
*
668
* DESCRIPTION: Create a new bank field in the specified operation region
669
*
670
******************************************************************************/
671
672
acpi_status
673
acpi_ds_create_bank_field(union acpi_parse_object *op,
674
struct acpi_namespace_node *region_node,
675
struct acpi_walk_state *walk_state)
676
{
677
acpi_status status;
678
union acpi_parse_object *arg;
679
struct acpi_create_field_info info;
680
681
ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
682
683
/* First arg is the name of the parent op_region (must already exist) */
684
685
arg = op->common.value.arg;
686
if (!region_node) {
687
status =
688
acpi_ns_lookup(walk_state->scope_info,
689
arg->common.value.name, ACPI_TYPE_REGION,
690
ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
691
walk_state, &region_node);
692
#ifdef ACPI_ASL_COMPILER
693
status = acpi_ds_create_external_region(status, arg,
694
arg->common.value.name,
695
walk_state,
696
&region_node);
697
#endif
698
if (ACPI_FAILURE(status)) {
699
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
700
arg->common.value.name, status);
701
return_ACPI_STATUS(status);
702
}
703
}
704
705
/* Second arg is the Bank Register (Field) (must already exist) */
706
707
arg = arg->common.next;
708
status =
709
acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
710
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
711
ACPI_NS_SEARCH_PARENT, walk_state,
712
&info.register_node);
713
if (ACPI_FAILURE(status)) {
714
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
715
arg->common.value.string, status);
716
return_ACPI_STATUS(status);
717
}
718
719
/*
720
* Third arg is the bank_value
721
* This arg is a term_arg, not a constant
722
* It will be evaluated later, by acpi_ds_eval_bank_field_operands
723
*/
724
arg = arg->common.next;
725
726
/* Fourth arg is the field flags */
727
728
arg = arg->common.next;
729
info.field_flags = (u8) arg->common.value.integer;
730
731
/* Each remaining arg is a Named Field */
732
733
info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
734
info.region_node = region_node;
735
736
/*
737
* Use Info.data_register_node to store bank_field Op
738
* It's safe because data_register_node will never be used when create
739
* bank field \we store aml_start and aml_length in the bank_field Op for
740
* late evaluation. Used in acpi_ex_prep_field_value(Info)
741
*
742
* TBD: Or, should we add a field in struct acpi_create_field_info, like
743
* "void *ParentOp"?
744
*/
745
info.data_register_node = (struct acpi_namespace_node *)op;
746
747
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
748
return_ACPI_STATUS(status);
749
}
750
751
/*******************************************************************************
752
*
753
* FUNCTION: acpi_ds_create_index_field
754
*
755
* PARAMETERS: op - Op containing the Field definition and args
756
* region_node - Object for the containing Operation Region
757
* ` walk_state - Current method state
758
*
759
* RETURN: Status
760
*
761
* DESCRIPTION: Create a new index field in the specified operation region
762
*
763
******************************************************************************/
764
765
acpi_status
766
acpi_ds_create_index_field(union acpi_parse_object *op,
767
struct acpi_namespace_node *region_node,
768
struct acpi_walk_state *walk_state)
769
{
770
acpi_status status;
771
union acpi_parse_object *arg;
772
struct acpi_create_field_info info;
773
774
ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
775
776
/* First arg is the name of the Index register (must already exist) */
777
778
arg = op->common.value.arg;
779
status =
780
acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
781
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
782
ACPI_NS_SEARCH_PARENT, walk_state,
783
&info.register_node);
784
if (ACPI_FAILURE(status)) {
785
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
786
arg->common.value.string, status);
787
return_ACPI_STATUS(status);
788
}
789
790
/* Second arg is the data register (must already exist) */
791
792
arg = arg->common.next;
793
status =
794
acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
795
ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
796
ACPI_NS_SEARCH_PARENT, walk_state,
797
&info.data_register_node);
798
if (ACPI_FAILURE(status)) {
799
ACPI_ERROR_NAMESPACE(walk_state->scope_info,
800
arg->common.value.string, status);
801
return_ACPI_STATUS(status);
802
}
803
804
/* Next arg is the field flags */
805
806
arg = arg->common.next;
807
info.field_flags = (u8) arg->common.value.integer;
808
809
/* Each remaining arg is a Named Field */
810
811
info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
812
info.region_node = region_node;
813
814
status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
815
return_ACPI_STATUS(status);
816
}
817
818