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