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