1
2
3
4
5
6
7
8
9
10#include <acpi/acpi.h>
11#include "accommon.h"
12#include "acnamesp.h"
13#include "acpredef.h"
14
15#define _COMPONENT ACPI_NAMESPACE
16ACPI_MODULE_NAME("nsprepkg")
17
18
19static acpi_status
20acpi_ns_check_package_list(struct acpi_evaluate_info *info,
21 const union acpi_predefined_info *package,
22 union acpi_operand_object **elements, u32 count);
23
24static acpi_status
25acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
26 union acpi_operand_object **elements,
27 u8 type1,
28 u32 count1,
29 u8 type2, u32 count2, u32 start_index);
30
31static acpi_status
32acpi_ns_custom_package(struct acpi_evaluate_info *info,
33 union acpi_operand_object **elements, u32 count);
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50acpi_status
51acpi_ns_check_package(struct acpi_evaluate_info *info,
52 union acpi_operand_object **return_object_ptr)
53{
54 union acpi_operand_object *return_object = *return_object_ptr;
55 const union acpi_predefined_info *package;
56 union acpi_operand_object **elements;
57 acpi_status status = AE_OK;
58 u32 expected_count;
59 u32 count;
60 u32 i;
61
62 ACPI_FUNCTION_TRACE(ns_check_package);
63
64
65
66 package = info->predefined + 1;
67
68 ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
69 "%s Validating return Package of Type %X, Count %X\n",
70 info->full_pathname, package->ret_info.type,
71 return_object->package.count));
72
73
74
75
76
77 acpi_ns_remove_null_elements(info, package->ret_info.type,
78 return_object);
79
80
81
82 elements = return_object->package.elements;
83 count = return_object->package.count;
84
85
86
87
88
89 if (!count) {
90 if (package->ret_info.type == ACPI_PTYPE1_VAR) {
91 return_ACPI_STATUS(AE_OK);
92 }
93
94 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
95 info->node_flags,
96 "Return Package has no elements (empty)"));
97
98 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
99 }
100
101
102
103
104
105
106
107 switch (package->ret_info.type) {
108 case ACPI_PTYPE_CUSTOM:
109
110 status = acpi_ns_custom_package(info, elements, count);
111 break;
112
113 case ACPI_PTYPE1_FIXED:
114
115
116
117
118
119
120 expected_count =
121 package->ret_info.count1 + package->ret_info.count2;
122 if (count < expected_count) {
123 goto package_too_small;
124 } else if (count > expected_count) {
125 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
126 "%s: Return Package is larger than needed - "
127 "found %u, expected %u\n",
128 info->full_pathname, count,
129 expected_count));
130 }
131
132
133
134 status = acpi_ns_check_package_elements(info, elements,
135 package->ret_info.
136 object_type1,
137 package->ret_info.
138 count1,
139 package->ret_info.
140 object_type2,
141 package->ret_info.
142 count2, 0);
143 break;
144
145 case ACPI_PTYPE1_VAR:
146
147
148
149
150 for (i = 0; i < count; i++) {
151 status = acpi_ns_check_object_type(info, elements,
152 package->ret_info.
153 object_type1, i);
154 if (ACPI_FAILURE(status)) {
155 return_ACPI_STATUS(status);
156 }
157
158 elements++;
159 }
160 break;
161
162 case ACPI_PTYPE1_OPTION:
163
164
165
166
167
168
169
170 expected_count = package->ret_info3.count;
171 if (count < expected_count) {
172 goto package_too_small;
173 }
174
175
176
177 for (i = 0; i < count; i++) {
178 if (i < package->ret_info3.count) {
179
180
181
182 status =
183 acpi_ns_check_object_type(info, elements,
184 package->
185 ret_info3.
186 object_type[i],
187 i);
188 if (ACPI_FAILURE(status)) {
189 return_ACPI_STATUS(status);
190 }
191 } else {
192
193
194 status =
195 acpi_ns_check_object_type(info, elements,
196 package->
197 ret_info3.
198 tail_object_type,
199 i);
200 if (ACPI_FAILURE(status)) {
201 return_ACPI_STATUS(status);
202 }
203 }
204
205 elements++;
206 }
207 break;
208
209 case ACPI_PTYPE2_REV_FIXED:
210
211
212
213 status =
214 acpi_ns_check_object_type(info, elements,
215 ACPI_RTYPE_INTEGER, 0);
216 if (ACPI_FAILURE(status)) {
217 return_ACPI_STATUS(status);
218 }
219
220 elements++;
221 count--;
222
223
224
225 status =
226 acpi_ns_check_package_list(info, package, elements, count);
227 break;
228
229 case ACPI_PTYPE2_PKG_COUNT:
230
231
232
233 status =
234 acpi_ns_check_object_type(info, elements,
235 ACPI_RTYPE_INTEGER, 0);
236 if (ACPI_FAILURE(status)) {
237 return_ACPI_STATUS(status);
238 }
239
240
241
242
243
244 expected_count = (u32)(*elements)->integer.value;
245 if (expected_count >= count) {
246 goto package_too_small;
247 }
248
249 count = expected_count;
250 elements++;
251
252
253
254 status =
255 acpi_ns_check_package_list(info, package, elements, count);
256 break;
257
258 case ACPI_PTYPE2:
259 case ACPI_PTYPE2_FIXED:
260 case ACPI_PTYPE2_MIN:
261 case ACPI_PTYPE2_COUNT:
262 case ACPI_PTYPE2_FIX_VAR:
263
264
265
266
267
268
269
270
271
272
273 if (*elements
274 && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
275
276
277
278 status =
279 acpi_ns_wrap_with_package(info, return_object,
280 return_object_ptr);
281 if (ACPI_FAILURE(status)) {
282 return_ACPI_STATUS(status);
283 }
284
285
286
287 return_object = *return_object_ptr;
288 elements = return_object->package.elements;
289 count = 1;
290 }
291
292
293
294 status =
295 acpi_ns_check_package_list(info, package, elements, count);
296 break;
297
298 case ACPI_PTYPE2_VAR_VAR:
299
300
301
302
303 break;
304
305 case ACPI_PTYPE2_UUID_PAIR:
306
307
308
309 if (count & 1) {
310 expected_count = count + 1;
311 goto package_too_small;
312 }
313
314 while (count > 0) {
315 status = acpi_ns_check_object_type(info, elements,
316 package->ret_info.
317 object_type1, 0);
318 if (ACPI_FAILURE(status)) {
319 return_ACPI_STATUS(status);
320 }
321
322
323
324 if ((*elements)->buffer.length != 16) {
325 ACPI_WARN_PREDEFINED((AE_INFO,
326 info->full_pathname,
327 info->node_flags,
328 "Invalid length for UUID Buffer"));
329 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
330 }
331
332 status = acpi_ns_check_object_type(info, elements + 1,
333 package->ret_info.
334 object_type2, 0);
335 if (ACPI_FAILURE(status)) {
336 return_ACPI_STATUS(status);
337 }
338
339 elements += 2;
340 count -= 2;
341 }
342 break;
343
344 default:
345
346
347
348 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
349 info->node_flags,
350 "Invalid internal return type in table entry: %X",
351 package->ret_info.type));
352
353 return_ACPI_STATUS(AE_AML_INTERNAL);
354 }
355
356 return_ACPI_STATUS(status);
357
358package_too_small:
359
360
361
362 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
363 "Return Package is too small - found %u elements, expected %u",
364 count, expected_count));
365
366 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
367}
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385static acpi_status
386acpi_ns_check_package_list(struct acpi_evaluate_info *info,
387 const union acpi_predefined_info *package,
388 union acpi_operand_object **elements, u32 count)
389{
390 union acpi_operand_object *sub_package;
391 union acpi_operand_object **sub_elements;
392 acpi_status status;
393 u32 expected_count;
394 u32 i;
395 u32 j;
396
397
398
399
400
401
402
403
404 for (i = 0; i < count; i++) {
405 sub_package = *elements;
406 sub_elements = sub_package->package.elements;
407 info->parent_package = sub_package;
408
409
410
411 status = acpi_ns_check_object_type(info, &sub_package,
412 ACPI_RTYPE_PACKAGE, i);
413 if (ACPI_FAILURE(status)) {
414 return (status);
415 }
416
417
418
419 info->parent_package = sub_package;
420 switch (package->ret_info.type) {
421 case ACPI_PTYPE2:
422 case ACPI_PTYPE2_PKG_COUNT:
423 case ACPI_PTYPE2_REV_FIXED:
424
425
426
427 expected_count =
428 package->ret_info.count1 + package->ret_info.count2;
429 if (sub_package->package.count < expected_count) {
430 goto package_too_small;
431 }
432
433 status =
434 acpi_ns_check_package_elements(info, sub_elements,
435 package->ret_info.
436 object_type1,
437 package->ret_info.
438 count1,
439 package->ret_info.
440 object_type2,
441 package->ret_info.
442 count2, 0);
443 if (ACPI_FAILURE(status)) {
444 return (status);
445 }
446 break;
447
448 case ACPI_PTYPE2_FIX_VAR:
449
450
451
452
453 expected_count =
454 package->ret_info.count1 + package->ret_info.count2;
455 if (sub_package->package.count < expected_count) {
456 goto package_too_small;
457 }
458
459 status =
460 acpi_ns_check_package_elements(info, sub_elements,
461 package->ret_info.
462 object_type1,
463 package->ret_info.
464 count1,
465 package->ret_info.
466 object_type2,
467 sub_package->package.
468 count -
469 package->ret_info.
470 count1, 0);
471 if (ACPI_FAILURE(status)) {
472 return (status);
473 }
474 break;
475
476 case ACPI_PTYPE2_VAR_VAR:
477
478
479
480 break;
481
482 case ACPI_PTYPE2_FIXED:
483
484
485
486 expected_count = package->ret_info2.count;
487 if (sub_package->package.count < expected_count) {
488 goto package_too_small;
489 }
490
491
492
493 for (j = 0; j < expected_count; j++) {
494 status =
495 acpi_ns_check_object_type(info,
496 &sub_elements[j],
497 package->
498 ret_info2.
499 object_type[j],
500 j);
501 if (ACPI_FAILURE(status)) {
502 return (status);
503 }
504 }
505 break;
506
507 case ACPI_PTYPE2_MIN:
508
509
510
511 expected_count = package->ret_info.count1;
512 if (sub_package->package.count < expected_count) {
513 goto package_too_small;
514 }
515
516
517
518 status =
519 acpi_ns_check_package_elements(info, sub_elements,
520 package->ret_info.
521 object_type1,
522 sub_package->package.
523 count, 0, 0, 0);
524 if (ACPI_FAILURE(status)) {
525 return (status);
526 }
527 break;
528
529 case ACPI_PTYPE2_COUNT:
530
531
532
533
534 status = acpi_ns_check_object_type(info, sub_elements,
535 ACPI_RTYPE_INTEGER,
536 0);
537 if (ACPI_FAILURE(status)) {
538 return (status);
539 }
540
541
542
543
544
545 expected_count = (u32)(*sub_elements)->integer.value;
546 if (sub_package->package.count < expected_count) {
547 goto package_too_small;
548 }
549
550 if (sub_package->package.count <
551 package->ret_info.count1) {
552 expected_count = package->ret_info.count1;
553 goto package_too_small;
554 }
555
556 if (expected_count == 0) {
557
558
559
560
561
562
563 expected_count = sub_package->package.count;
564 (*sub_elements)->integer.value = expected_count;
565 }
566
567
568
569 status =
570 acpi_ns_check_package_elements(info,
571 (sub_elements + 1),
572 package->ret_info.
573 object_type1,
574 (expected_count - 1),
575 0, 0, 1);
576 if (ACPI_FAILURE(status)) {
577 return (status);
578 }
579 break;
580
581 default:
582
583 ACPI_ERROR((AE_INFO, "Invalid Package type: %X",
584 package->ret_info.type));
585 return (AE_AML_INTERNAL);
586 }
587
588 elements++;
589 }
590
591 return (AE_OK);
592
593package_too_small:
594
595
596
597 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
598 "Return SubPackage[%u] is too small - found %u elements, expected %u",
599 i, sub_package->package.count, expected_count));
600
601 return (AE_AML_OPERAND_VALUE);
602}
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622static acpi_status
623acpi_ns_custom_package(struct acpi_evaluate_info *info,
624 union acpi_operand_object **elements, u32 count)
625{
626 u32 expected_count;
627 u32 version;
628 acpi_status status = AE_OK;
629
630 ACPI_FUNCTION_NAME(ns_custom_package);
631
632
633
634 if ((*elements)->common.type != ACPI_TYPE_INTEGER) {
635 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
636 info->node_flags,
637 "Return Package has invalid object type for version number"));
638 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
639 }
640
641 version = (u32)(*elements)->integer.value;
642 expected_count = 21;
643
644 if (version == 0) {
645 expected_count = 20;
646 }
647
648 if (count < expected_count) {
649 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
650 info->node_flags,
651 "Return Package is too small - found %u elements, expected %u",
652 count, expected_count));
653 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
654 } else if (count > expected_count) {
655 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
656 "%s: Return Package is larger than needed - "
657 "found %u, expected %u\n",
658 info->full_pathname, count, expected_count));
659 }
660
661
662
663 status = acpi_ns_check_package_elements(info, elements,
664 ACPI_RTYPE_INTEGER, 16,
665 ACPI_RTYPE_STRING, 4, 0);
666 if (ACPI_FAILURE(status)) {
667 return_ACPI_STATUS(status);
668 }
669
670
671
672 if (version > 0) {
673 status = acpi_ns_check_package_elements(info, elements + 20,
674 ACPI_RTYPE_INTEGER, 1,
675 0, 0, 20);
676 }
677
678 return_ACPI_STATUS(status);
679}
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700static acpi_status
701acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
702 union acpi_operand_object **elements,
703 u8 type1,
704 u32 count1,
705 u8 type2, u32 count2, u32 start_index)
706{
707 union acpi_operand_object **this_element = elements;
708 acpi_status status;
709 u32 i;
710
711 ACPI_FUNCTION_TRACE(ns_check_package_elements);
712
713
714
715
716
717
718 for (i = 0; i < count1; i++) {
719 status = acpi_ns_check_object_type(info, this_element,
720 type1, i + start_index);
721 if (ACPI_FAILURE(status)) {
722 return_ACPI_STATUS(status);
723 }
724
725 this_element++;
726 }
727
728 for (i = 0; i < count2; i++) {
729 status = acpi_ns_check_object_type(info, this_element,
730 type2,
731 (i + count1 + start_index));
732 if (ACPI_FAILURE(status)) {
733 return_ACPI_STATUS(status);
734 }
735
736 this_element++;
737 }
738
739 return_ACPI_STATUS(AE_OK);
740}
741