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