1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include <acpi/acpi.h>
45#include "accommon.h"
46#include "acdispat.h"
47#include "acnamesp.h"
48#include "acinterp.h"
49
50#define _COMPONENT ACPI_DISPATCHER
51ACPI_MODULE_NAME("dsmthdat")
52
53
54static void
55acpi_ds_method_data_delete_value(u8 type,
56 u32 index, struct acpi_walk_state *walk_state);
57
58static acpi_status
59acpi_ds_method_data_set_value(u8 type,
60 u32 index,
61 union acpi_operand_object *object,
62 struct acpi_walk_state *walk_state);
63
64#ifdef ACPI_OBSOLETE_FUNCTIONS
65acpi_object_type
66acpi_ds_method_data_get_type(u16 opcode,
67 u32 index, struct acpi_walk_state *walk_state);
68#endif
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91void acpi_ds_method_data_init(struct acpi_walk_state *walk_state)
92{
93 u32 i;
94
95 ACPI_FUNCTION_TRACE(ds_method_data_init);
96
97
98
99 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
100 ACPI_MOVE_32_TO_32(&walk_state->arguments[i].name,
101 NAMEOF_ARG_NTE);
102 walk_state->arguments[i].name.integer |= (i << 24);
103 walk_state->arguments[i].descriptor_type = ACPI_DESC_TYPE_NAMED;
104 walk_state->arguments[i].type = ACPI_TYPE_ANY;
105 walk_state->arguments[i].flags = ANOBJ_METHOD_ARG;
106 }
107
108
109
110 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
111 ACPI_MOVE_32_TO_32(&walk_state->local_variables[i].name,
112 NAMEOF_LOCAL_NTE);
113
114 walk_state->local_variables[i].name.integer |= (i << 24);
115 walk_state->local_variables[i].descriptor_type =
116 ACPI_DESC_TYPE_NAMED;
117 walk_state->local_variables[i].type = ACPI_TYPE_ANY;
118 walk_state->local_variables[i].flags = ANOBJ_METHOD_LOCAL;
119 }
120
121 return_VOID;
122}
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137void acpi_ds_method_data_delete_all(struct acpi_walk_state *walk_state)
138{
139 u32 index;
140
141 ACPI_FUNCTION_TRACE(ds_method_data_delete_all);
142
143
144
145 for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
146 if (walk_state->local_variables[index].object) {
147 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Local%u=%p\n",
148 index,
149 walk_state->local_variables[index].
150 object));
151
152
153
154 acpi_ns_detach_object(&walk_state->
155 local_variables[index]);
156 }
157 }
158
159
160
161 for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
162 if (walk_state->arguments[index].object) {
163 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Deleting Arg%u=%p\n",
164 index,
165 walk_state->arguments[index].object));
166
167
168
169 acpi_ns_detach_object(&walk_state->arguments[index]);
170 }
171 }
172
173 return_VOID;
174}
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192acpi_status
193acpi_ds_method_data_init_args(union acpi_operand_object **params,
194 u32 max_param_count,
195 struct acpi_walk_state *walk_state)
196{
197 acpi_status status;
198 u32 index = 0;
199
200 ACPI_FUNCTION_TRACE_PTR(ds_method_data_init_args, params);
201
202 if (!params) {
203 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
204 "No param list passed to method\n"));
205 return_ACPI_STATUS(AE_OK);
206 }
207
208
209
210 while ((index < ACPI_METHOD_NUM_ARGS) &&
211 (index < max_param_count) && params[index]) {
212
213
214
215
216
217 status = acpi_ds_method_data_set_value(ACPI_REFCLASS_ARG, index,
218 params[index],
219 walk_state);
220 if (ACPI_FAILURE(status)) {
221 return_ACPI_STATUS(status);
222 }
223
224 index++;
225 }
226
227 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%u args passed to method\n", index));
228 return_ACPI_STATUS(AE_OK);
229}
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247acpi_status
248acpi_ds_method_data_get_node(u8 type,
249 u32 index,
250 struct acpi_walk_state *walk_state,
251 struct acpi_namespace_node **node)
252{
253 ACPI_FUNCTION_TRACE(ds_method_data_get_node);
254
255
256
257
258 switch (type) {
259 case ACPI_REFCLASS_LOCAL:
260
261 if (index > ACPI_METHOD_MAX_LOCAL) {
262 ACPI_ERROR((AE_INFO,
263 "Local index %u is invalid (max %u)",
264 index, ACPI_METHOD_MAX_LOCAL));
265 return_ACPI_STATUS(AE_AML_INVALID_INDEX);
266 }
267
268
269
270 *node = &walk_state->local_variables[index];
271 break;
272
273 case ACPI_REFCLASS_ARG:
274
275 if (index > ACPI_METHOD_MAX_ARG) {
276 ACPI_ERROR((AE_INFO,
277 "Arg index %u is invalid (max %u)",
278 index, ACPI_METHOD_MAX_ARG));
279 return_ACPI_STATUS(AE_AML_INVALID_INDEX);
280 }
281
282
283
284 *node = &walk_state->arguments[index];
285 break;
286
287 default:
288
289 ACPI_ERROR((AE_INFO, "Type %u is invalid", type));
290 return_ACPI_STATUS(AE_TYPE);
291 }
292
293 return_ACPI_STATUS(AE_OK);
294}
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313static acpi_status
314acpi_ds_method_data_set_value(u8 type,
315 u32 index,
316 union acpi_operand_object *object,
317 struct acpi_walk_state *walk_state)
318{
319 acpi_status status;
320 struct acpi_namespace_node *node;
321
322 ACPI_FUNCTION_TRACE(ds_method_data_set_value);
323
324 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
325 "NewObj %p Type %2.2X, Refs=%u [%s]\n", object,
326 type, object->common.reference_count,
327 acpi_ut_get_type_name(object->common.type)));
328
329
330
331 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
332 if (ACPI_FAILURE(status)) {
333 return_ACPI_STATUS(status);
334 }
335
336
337
338
339
340
341
342 acpi_ut_add_reference(object);
343
344
345
346 node->object = object;
347 return_ACPI_STATUS(status);
348}
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367acpi_status
368acpi_ds_method_data_get_value(u8 type,
369 u32 index,
370 struct acpi_walk_state *walk_state,
371 union acpi_operand_object **dest_desc)
372{
373 acpi_status status;
374 struct acpi_namespace_node *node;
375 union acpi_operand_object *object;
376
377 ACPI_FUNCTION_TRACE(ds_method_data_get_value);
378
379
380
381 if (!dest_desc) {
382 ACPI_ERROR((AE_INFO, "Null object descriptor pointer"));
383 return_ACPI_STATUS(AE_BAD_PARAMETER);
384 }
385
386
387
388 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
389 if (ACPI_FAILURE(status)) {
390 return_ACPI_STATUS(status);
391 }
392
393
394
395 object = node->object;
396
397
398
399 if (!object) {
400
401
402
403
404
405
406
407
408
409
410 if (acpi_gbl_enable_interpreter_slack) {
411 object = acpi_ut_create_integer_object((u64) 0);
412 if (!object) {
413 return_ACPI_STATUS(AE_NO_MEMORY);
414 }
415
416 node->object = object;
417 }
418
419
420
421 else
422 switch (type) {
423 case ACPI_REFCLASS_ARG:
424
425 ACPI_ERROR((AE_INFO,
426 "Uninitialized Arg[%u] at node %p",
427 index, node));
428
429 return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
430
431 case ACPI_REFCLASS_LOCAL:
432
433
434
435
436 return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL);
437
438 default:
439
440 ACPI_ERROR((AE_INFO,
441 "Not a Arg/Local opcode: 0x%X",
442 type));
443 return_ACPI_STATUS(AE_AML_INTERNAL);
444 }
445 }
446
447
448
449
450
451 *dest_desc = object;
452 acpi_ut_add_reference(object);
453
454 return_ACPI_STATUS(AE_OK);
455}
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473static void
474acpi_ds_method_data_delete_value(u8 type,
475 u32 index, struct acpi_walk_state *walk_state)
476{
477 acpi_status status;
478 struct acpi_namespace_node *node;
479 union acpi_operand_object *object;
480
481 ACPI_FUNCTION_TRACE(ds_method_data_delete_value);
482
483
484
485 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
486 if (ACPI_FAILURE(status)) {
487 return_VOID;
488 }
489
490
491
492 object = acpi_ns_get_attached_object(node);
493
494
495
496
497
498
499 node->object = NULL;
500
501 if ((object) &&
502 (ACPI_GET_DESCRIPTOR_TYPE(object) == ACPI_DESC_TYPE_OPERAND)) {
503
504
505
506
507
508 acpi_ut_remove_reference(object);
509 }
510
511 return_VOID;
512}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532acpi_status
533acpi_ds_store_object_to_local(u8 type,
534 u32 index,
535 union acpi_operand_object *obj_desc,
536 struct acpi_walk_state *walk_state)
537{
538 acpi_status status;
539 struct acpi_namespace_node *node;
540 union acpi_operand_object *current_obj_desc;
541 union acpi_operand_object *new_obj_desc;
542
543 ACPI_FUNCTION_TRACE(ds_store_object_to_local);
544 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Type=%2.2X Index=%u Obj=%p\n",
545 type, index, obj_desc));
546
547
548
549 if (!obj_desc) {
550 return_ACPI_STATUS(AE_BAD_PARAMETER);
551 }
552
553
554
555 status = acpi_ds_method_data_get_node(type, index, walk_state, &node);
556 if (ACPI_FAILURE(status)) {
557 return_ACPI_STATUS(status);
558 }
559
560 current_obj_desc = acpi_ns_get_attached_object(node);
561 if (current_obj_desc == obj_desc) {
562 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Obj=%p already installed!\n",
563 obj_desc));
564 return_ACPI_STATUS(status);
565 }
566
567
568
569
570
571
572
573
574 new_obj_desc = obj_desc;
575 if (obj_desc->common.reference_count > 1) {
576 status =
577 acpi_ut_copy_iobject_to_iobject(obj_desc, &new_obj_desc,
578 walk_state);
579 if (ACPI_FAILURE(status)) {
580 return_ACPI_STATUS(status);
581 }
582 }
583
584
585
586
587
588
589
590 if (current_obj_desc) {
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607 if (type == ACPI_REFCLASS_ARG) {
608
609
610
611
612 if ((ACPI_GET_DESCRIPTOR_TYPE(current_obj_desc) ==
613 ACPI_DESC_TYPE_OPERAND)
614 && (current_obj_desc->common.type ==
615 ACPI_TYPE_LOCAL_REFERENCE)
616 && (current_obj_desc->reference.class ==
617 ACPI_REFCLASS_REFOF)) {
618 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
619 "Arg (%p) is an ObjRef(Node), storing in node %p\n",
620 new_obj_desc,
621 current_obj_desc));
622
623
624
625
626
627
628 status =
629 acpi_ex_store_object_to_node(new_obj_desc,
630 current_obj_desc->
631 reference.
632 object,
633 walk_state,
634 ACPI_NO_IMPLICIT_CONVERSION);
635
636
637
638 if (new_obj_desc != obj_desc) {
639 acpi_ut_remove_reference(new_obj_desc);
640 }
641 return_ACPI_STATUS(status);
642 }
643 }
644
645
646
647 acpi_ds_method_data_delete_value(type, index, walk_state);
648 }
649
650
651
652
653
654
655 status =
656 acpi_ds_method_data_set_value(type, index, new_obj_desc,
657 walk_state);
658
659
660
661 if (new_obj_desc != obj_desc) {
662 acpi_ut_remove_reference(new_obj_desc);
663 }
664
665 return_ACPI_STATUS(status);
666}
667
668#ifdef ACPI_OBSOLETE_FUNCTIONS
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683acpi_object_type
684acpi_ds_method_data_get_type(u16 opcode,
685 u32 index, struct acpi_walk_state *walk_state)
686{
687 acpi_status status;
688 struct acpi_namespace_node *node;
689 union acpi_operand_object *object;
690
691 ACPI_FUNCTION_TRACE(ds_method_data_get_type);
692
693
694
695 status = acpi_ds_method_data_get_node(opcode, index, walk_state, &node);
696 if (ACPI_FAILURE(status)) {
697 return_VALUE((ACPI_TYPE_NOT_FOUND));
698 }
699
700
701
702 object = acpi_ns_get_attached_object(node);
703 if (!object) {
704
705
706
707 return_VALUE(ACPI_TYPE_ANY);
708 }
709
710
711
712 return_VALUE(object->type);
713}
714#endif
715