treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / acpi / acpica / nsprepkg.c
blob237b3ddeb075705968331b400d025538c023dd44
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
4 * Module Name: nsprepkg - Validation of package objects for predefined names
6 * Copyright (C) 2000 - 2020, Intel Corp.
8 *****************************************************************************/
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acnamesp.h"
13 #include "acpredef.h"
15 #define _COMPONENT ACPI_NAMESPACE
16 ACPI_MODULE_NAME("nsprepkg")
18 /* Local prototypes */
19 static acpi_status
20 acpi_ns_check_package_list(struct acpi_evaluate_info *info,
21 const union acpi_predefined_info *package,
22 union acpi_operand_object **elements, u32 count);
24 static acpi_status
25 acpi_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);
31 static acpi_status
32 acpi_ns_custom_package(struct acpi_evaluate_info *info,
33 union acpi_operand_object **elements, u32 count);
35 /*******************************************************************************
37 * FUNCTION: acpi_ns_check_package
39 * PARAMETERS: info - Method execution information block
40 * return_object_ptr - Pointer to the object returned from the
41 * evaluation of a method or object
43 * RETURN: Status
45 * DESCRIPTION: Check a returned package object for the correct count and
46 * correct type of all sub-objects.
48 ******************************************************************************/
50 acpi_status
51 acpi_ns_check_package(struct acpi_evaluate_info *info,
52 union acpi_operand_object **return_object_ptr)
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;
62 ACPI_FUNCTION_NAME(ns_check_package);
64 /* The package info for this name is in the next table entry */
66 package = info->predefined + 1;
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));
74 * For variable-length Packages, we can safely remove all embedded
75 * and trailing NULL package elements
77 acpi_ns_remove_null_elements(info, package->ret_info.type,
78 return_object);
80 /* Extract package count and elements array */
82 elements = return_object->package.elements;
83 count = return_object->package.count;
86 * Most packages must have at least one element. The only exception
87 * is the variable-length package (ACPI_PTYPE1_VAR).
89 if (!count) {
90 if (package->ret_info.type == ACPI_PTYPE1_VAR) {
91 return (AE_OK);
94 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
95 info->node_flags,
96 "Return Package has no elements (empty)"));
98 return (AE_AML_OPERAND_VALUE);
102 * Decode the type of the expected package contents
104 * PTYPE1 packages contain no subpackages
105 * PTYPE2 packages contain subpackages
107 switch (package->ret_info.type) {
108 case ACPI_PTYPE_CUSTOM:
110 status = acpi_ns_custom_package(info, elements, count);
111 break;
113 case ACPI_PTYPE1_FIXED:
115 * The package count is fixed and there are no subpackages
117 * If package is too small, exit.
118 * If package is larger than expected, issue warning but continue
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));
132 /* Validate all elements of the returned package */
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;
145 case ACPI_PTYPE1_VAR:
147 * The package count is variable, there are no subpackages, and all
148 * elements must be of the same type
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 (status);
158 elements++;
160 break;
162 case ACPI_PTYPE1_OPTION:
164 * The package count is variable, there are no subpackages. There are
165 * a fixed number of required elements, and a variable number of
166 * optional elements.
168 * Check if package is at least as large as the minimum required
170 expected_count = package->ret_info3.count;
171 if (count < expected_count) {
172 goto package_too_small;
175 /* Variable number of sub-objects */
177 for (i = 0; i < count; i++) {
178 if (i < package->ret_info3.count) {
180 /* These are the required package elements (0, 1, or 2) */
182 status =
183 acpi_ns_check_object_type(info, elements,
184 package->
185 ret_info3.
186 object_type[i],
188 if (ACPI_FAILURE(status)) {
189 return (status);
191 } else {
192 /* These are the optional package elements */
194 status =
195 acpi_ns_check_object_type(info, elements,
196 package->
197 ret_info3.
198 tail_object_type,
200 if (ACPI_FAILURE(status)) {
201 return (status);
205 elements++;
207 break;
209 case ACPI_PTYPE2_REV_FIXED:
211 /* First element is the (Integer) revision */
213 status =
214 acpi_ns_check_object_type(info, elements,
215 ACPI_RTYPE_INTEGER, 0);
216 if (ACPI_FAILURE(status)) {
217 return (status);
220 elements++;
221 count--;
223 /* Examine the subpackages */
225 status =
226 acpi_ns_check_package_list(info, package, elements, count);
227 break;
229 case ACPI_PTYPE2_PKG_COUNT:
231 /* First element is the (Integer) count of subpackages to follow */
233 status =
234 acpi_ns_check_object_type(info, elements,
235 ACPI_RTYPE_INTEGER, 0);
236 if (ACPI_FAILURE(status)) {
237 return (status);
241 * Count cannot be larger than the parent package length, but allow it
242 * to be smaller. The >= accounts for the Integer above.
244 expected_count = (u32)(*elements)->integer.value;
245 if (expected_count >= count) {
246 goto package_too_small;
249 count = expected_count;
250 elements++;
252 /* Examine the subpackages */
254 status =
255 acpi_ns_check_package_list(info, package, elements, count);
256 break;
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:
264 * These types all return a single Package that consists of a
265 * variable number of subpackages.
267 * First, ensure that the first element is a subpackage. If not,
268 * the BIOS may have incorrectly returned the object as a single
269 * package instead of a Package of Packages (a common error if
270 * there is only one entry). We may be able to repair this by
271 * wrapping the returned Package with a new outer Package.
273 if (*elements
274 && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
276 /* Create the new outer package and populate it */
278 status =
279 acpi_ns_wrap_with_package(info, return_object,
280 return_object_ptr);
281 if (ACPI_FAILURE(status)) {
282 return (status);
285 /* Update locals to point to the new package (of 1 element) */
287 return_object = *return_object_ptr;
288 elements = return_object->package.elements;
289 count = 1;
292 /* Examine the subpackages */
294 status =
295 acpi_ns_check_package_list(info, package, elements, count);
296 break;
298 case ACPI_PTYPE2_VAR_VAR:
300 * Returns a variable list of packages, each with a variable list
301 * of objects.
303 break;
305 case ACPI_PTYPE2_UUID_PAIR:
307 /* The package must contain pairs of (UUID + type) */
309 if (count & 1) {
310 expected_count = count + 1;
311 goto package_too_small;
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 (status);
322 /* Validate length of the UUID buffer */
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 (AE_AML_OPERAND_VALUE);
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 (status);
339 elements += 2;
340 count -= 2;
342 break;
344 default:
346 /* Should not get here if predefined info table is correct */
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));
353 return (AE_AML_INTERNAL);
356 return (status);
358 package_too_small:
360 /* Error exit for the case with an incorrect package count */
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));
366 return (AE_AML_OPERAND_VALUE);
369 /*******************************************************************************
371 * FUNCTION: acpi_ns_check_package_list
373 * PARAMETERS: info - Method execution information block
374 * package - Pointer to package-specific info for method
375 * elements - Element list of parent package. All elements
376 * of this list should be of type Package.
377 * count - Count of subpackages
379 * RETURN: Status
381 * DESCRIPTION: Examine a list of subpackages
383 ******************************************************************************/
385 static acpi_status
386 acpi_ns_check_package_list(struct acpi_evaluate_info *info,
387 const union acpi_predefined_info *package,
388 union acpi_operand_object **elements, u32 count)
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;
398 * Validate each subpackage in the parent Package
400 * NOTE: assumes list of subpackages contains no NULL elements.
401 * Any NULL elements should have been removed by earlier call
402 * to acpi_ns_remove_null_elements.
404 for (i = 0; i < count; i++) {
405 sub_package = *elements;
406 sub_elements = sub_package->package.elements;
407 info->parent_package = sub_package;
409 /* Each sub-object must be of type Package */
411 status = acpi_ns_check_object_type(info, &sub_package,
412 ACPI_RTYPE_PACKAGE, i);
413 if (ACPI_FAILURE(status)) {
414 return (status);
417 /* Examine the different types of expected subpackages */
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:
425 /* Each subpackage has a fixed number of elements */
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;
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);
446 break;
448 case ACPI_PTYPE2_FIX_VAR:
450 * Each subpackage has a fixed number of elements and an
451 * optional element
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;
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);
474 break;
476 case ACPI_PTYPE2_VAR_VAR:
478 * Each subpackage has a fixed or variable number of elements
480 break;
482 case ACPI_PTYPE2_FIXED:
484 /* Each subpackage has a fixed length */
486 expected_count = package->ret_info2.count;
487 if (sub_package->package.count < expected_count) {
488 goto package_too_small;
491 /* Check the type of each subpackage element */
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],
501 if (ACPI_FAILURE(status)) {
502 return (status);
505 break;
507 case ACPI_PTYPE2_MIN:
509 /* Each subpackage has a variable but minimum length */
511 expected_count = package->ret_info.count1;
512 if (sub_package->package.count < expected_count) {
513 goto package_too_small;
516 /* Check the type of each subpackage element */
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);
527 break;
529 case ACPI_PTYPE2_COUNT:
531 * First element is the (Integer) count of elements, including
532 * the count field (the ACPI name is num_elements)
534 status = acpi_ns_check_object_type(info, sub_elements,
535 ACPI_RTYPE_INTEGER,
537 if (ACPI_FAILURE(status)) {
538 return (status);
542 * Make sure package is large enough for the Count and is
543 * is as large as the minimum size
545 expected_count = (u32)(*sub_elements)->integer.value;
546 if (sub_package->package.count < expected_count) {
547 goto package_too_small;
550 if (sub_package->package.count <
551 package->ret_info.count1) {
552 expected_count = package->ret_info.count1;
553 goto package_too_small;
556 if (expected_count == 0) {
558 * Either the num_entries element was originally zero or it was
559 * a NULL element and repaired to an Integer of value zero.
560 * In either case, repair it by setting num_entries to be the
561 * actual size of the subpackage.
563 expected_count = sub_package->package.count;
564 (*sub_elements)->integer.value = expected_count;
567 /* Check the type of each subpackage element */
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);
579 break;
581 default: /* Should not get here, type was validated by caller */
583 ACPI_ERROR((AE_INFO, "Invalid Package type: %X",
584 package->ret_info.type));
585 return (AE_AML_INTERNAL);
588 elements++;
591 return (AE_OK);
593 package_too_small:
595 /* The subpackage count was smaller than required */
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));
601 return (AE_AML_OPERAND_VALUE);
604 /*******************************************************************************
606 * FUNCTION: acpi_ns_custom_package
608 * PARAMETERS: info - Method execution information block
609 * elements - Pointer to the package elements array
610 * count - Element count for the package
612 * RETURN: Status
614 * DESCRIPTION: Check a returned package object for the correct count and
615 * correct type of all sub-objects.
617 * NOTE: Currently used for the _BIX method only. When needed for two or more
618 * methods, probably a detect/dispatch mechanism will be required.
620 ******************************************************************************/
622 static acpi_status
623 acpi_ns_custom_package(struct acpi_evaluate_info *info,
624 union acpi_operand_object **elements, u32 count)
626 u32 expected_count;
627 u32 version;
628 acpi_status status = AE_OK;
630 ACPI_FUNCTION_NAME(ns_custom_package);
632 /* Get version number, must be Integer */
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);
641 version = (u32)(*elements)->integer.value;
642 expected_count = 21; /* Version 1 */
644 if (version == 0) {
645 expected_count = 20; /* Version 0 */
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));
661 /* Validate all elements of the returned package */
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);
670 /* Version 1 has a single trailing integer */
672 if (version > 0) {
673 status = acpi_ns_check_package_elements(info, elements + 20,
674 ACPI_RTYPE_INTEGER, 1,
675 0, 0, 20);
678 return_ACPI_STATUS(status);
681 /*******************************************************************************
683 * FUNCTION: acpi_ns_check_package_elements
685 * PARAMETERS: info - Method execution information block
686 * elements - Pointer to the package elements array
687 * type1 - Object type for first group
688 * count1 - Count for first group
689 * type2 - Object type for second group
690 * count2 - Count for second group
691 * start_index - Start of the first group of elements
693 * RETURN: Status
695 * DESCRIPTION: Check that all elements of a package are of the correct object
696 * type. Supports up to two groups of different object types.
698 ******************************************************************************/
700 static acpi_status
701 acpi_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)
707 union acpi_operand_object **this_element = elements;
708 acpi_status status;
709 u32 i;
712 * Up to two groups of package elements are supported by the data
713 * structure. All elements in each group must be of the same type.
714 * The second group can have a count of zero.
716 for (i = 0; i < count1; i++) {
717 status = acpi_ns_check_object_type(info, this_element,
718 type1, i + start_index);
719 if (ACPI_FAILURE(status)) {
720 return (status);
723 this_element++;
726 for (i = 0; i < count2; i++) {
727 status = acpi_ns_check_object_type(info, this_element,
728 type2,
729 (i + count1 + start_index));
730 if (ACPI_FAILURE(status)) {
731 return (status);
734 this_element++;
737 return (AE_OK);