]> Pileus Git - ~andy/linux/blob - drivers/acpi/acpica/nsprepkg.c
Merge tag 'for-linus-20130301' of git://git.infradead.org/linux-mtd
[~andy/linux] / drivers / acpi / acpica / nsprepkg.c
1 /******************************************************************************
2  *
3  * Module Name: nsprepkg - Validation of package objects for predefined names
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2013, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
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
50 ACPI_MODULE_NAME("nsprepkg")
51
52 /* Local prototypes */
53 static acpi_status
54 acpi_ns_check_package_list(struct acpi_predefined_data *data,
55                            const union acpi_predefined_info *package,
56                            union acpi_operand_object **elements, u32 count);
57
58 static acpi_status
59 acpi_ns_check_package_elements(struct acpi_predefined_data *data,
60                                union acpi_operand_object **elements,
61                                u8 type1,
62                                u32 count1,
63                                u8 type2, u32 count2, u32 start_index);
64
65 /*******************************************************************************
66  *
67  * FUNCTION:    acpi_ns_check_package
68  *
69  * PARAMETERS:  data                - Pointer to validation data structure
70  *              return_object_ptr   - Pointer to the object returned from the
71  *                                    evaluation of a method or object
72  *
73  * RETURN:      Status
74  *
75  * DESCRIPTION: Check a returned package object for the correct count and
76  *              correct type of all sub-objects.
77  *
78  ******************************************************************************/
79
80 acpi_status
81 acpi_ns_check_package(struct acpi_predefined_data *data,
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         /* The package info for this name is in the next table entry */
95
96         package = data->predefined + 1;
97
98         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
99                           "%s Validating return Package of Type %X, Count %X\n",
100                           data->pathname, package->ret_info.type,
101                           return_object->package.count));
102
103         /*
104          * For variable-length Packages, we can safely remove all embedded
105          * and trailing NULL package elements
106          */
107         acpi_ns_remove_null_elements(data, package->ret_info.type,
108                                      return_object);
109
110         /* Extract package count and elements array */
111
112         elements = return_object->package.elements;
113         count = return_object->package.count;
114
115         /* The package must have at least one element, else invalid */
116
117         if (!count) {
118                 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
119                                       "Return Package has no elements (empty)"));
120
121                 return (AE_AML_OPERAND_VALUE);
122         }
123
124         /*
125          * Decode the type of the expected package contents
126          *
127          * PTYPE1 packages contain no subpackages
128          * PTYPE2 packages contain sub-packages
129          */
130         switch (package->ret_info.type) {
131         case ACPI_PTYPE1_FIXED:
132
133                 /*
134                  * The package count is fixed and there are no sub-packages
135                  *
136                  * If package is too small, exit.
137                  * If package is larger than expected, issue warning but continue
138                  */
139                 expected_count =
140                     package->ret_info.count1 + package->ret_info.count2;
141                 if (count < expected_count) {
142                         goto package_too_small;
143                 } else if (count > expected_count) {
144                         ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
145                                           "%s: Return Package is larger than needed - "
146                                           "found %u, expected %u\n",
147                                           data->pathname, count,
148                                           expected_count));
149                 }
150
151                 /* Validate all elements of the returned package */
152
153                 status = acpi_ns_check_package_elements(data, elements,
154                                                         package->ret_info.
155                                                         object_type1,
156                                                         package->ret_info.
157                                                         count1,
158                                                         package->ret_info.
159                                                         object_type2,
160                                                         package->ret_info.
161                                                         count2, 0);
162                 break;
163
164         case ACPI_PTYPE1_VAR:
165
166                 /*
167                  * The package count is variable, there are no sub-packages, and all
168                  * elements must be of the same type
169                  */
170                 for (i = 0; i < count; i++) {
171                         status = acpi_ns_check_object_type(data, elements,
172                                                            package->ret_info.
173                                                            object_type1, i);
174                         if (ACPI_FAILURE(status)) {
175                                 return (status);
176                         }
177                         elements++;
178                 }
179                 break;
180
181         case ACPI_PTYPE1_OPTION:
182
183                 /*
184                  * The package count is variable, there are no sub-packages. There are
185                  * a fixed number of required elements, and a variable number of
186                  * optional elements.
187                  *
188                  * Check if package is at least as large as the minimum required
189                  */
190                 expected_count = package->ret_info3.count;
191                 if (count < expected_count) {
192                         goto package_too_small;
193                 }
194
195                 /* Variable number of sub-objects */
196
197                 for (i = 0; i < count; i++) {
198                         if (i < package->ret_info3.count) {
199
200                                 /* These are the required package elements (0, 1, or 2) */
201
202                                 status =
203                                     acpi_ns_check_object_type(data, elements,
204                                                               package->
205                                                               ret_info3.
206                                                               object_type[i],
207                                                               i);
208                                 if (ACPI_FAILURE(status)) {
209                                         return (status);
210                                 }
211                         } else {
212                                 /* These are the optional package elements */
213
214                                 status =
215                                     acpi_ns_check_object_type(data, elements,
216                                                               package->
217                                                               ret_info3.
218                                                               tail_object_type,
219                                                               i);
220                                 if (ACPI_FAILURE(status)) {
221                                         return (status);
222                                 }
223                         }
224                         elements++;
225                 }
226                 break;
227
228         case ACPI_PTYPE2_REV_FIXED:
229
230                 /* First element is the (Integer) revision */
231
232                 status = acpi_ns_check_object_type(data, elements,
233                                                    ACPI_RTYPE_INTEGER, 0);
234                 if (ACPI_FAILURE(status)) {
235                         return (status);
236                 }
237
238                 elements++;
239                 count--;
240
241                 /* Examine the sub-packages */
242
243                 status =
244                     acpi_ns_check_package_list(data, package, elements, count);
245                 break;
246
247         case ACPI_PTYPE2_PKG_COUNT:
248
249                 /* First element is the (Integer) count of sub-packages to follow */
250
251                 status = acpi_ns_check_object_type(data, elements,
252                                                    ACPI_RTYPE_INTEGER, 0);
253                 if (ACPI_FAILURE(status)) {
254                         return (status);
255                 }
256
257                 /*
258                  * Count cannot be larger than the parent package length, but allow it
259                  * to be smaller. The >= accounts for the Integer above.
260                  */
261                 expected_count = (u32)(*elements)->integer.value;
262                 if (expected_count >= count) {
263                         goto package_too_small;
264                 }
265
266                 count = expected_count;
267                 elements++;
268
269                 /* Examine the sub-packages */
270
271                 status =
272                     acpi_ns_check_package_list(data, package, elements, count);
273                 break;
274
275         case ACPI_PTYPE2:
276         case ACPI_PTYPE2_FIXED:
277         case ACPI_PTYPE2_MIN:
278         case ACPI_PTYPE2_COUNT:
279         case ACPI_PTYPE2_FIX_VAR:
280
281                 /*
282                  * These types all return a single Package that consists of a
283                  * variable number of sub-Packages.
284                  *
285                  * First, ensure that the first element is a sub-Package. If not,
286                  * the BIOS may have incorrectly returned the object as a single
287                  * package instead of a Package of Packages (a common error if
288                  * there is only one entry). We may be able to repair this by
289                  * wrapping the returned Package with a new outer Package.
290                  */
291                 if (*elements
292                     && ((*elements)->common.type != ACPI_TYPE_PACKAGE)) {
293
294                         /* Create the new outer package and populate it */
295
296                         status =
297                             acpi_ns_wrap_with_package(data, return_object,
298                                                       return_object_ptr);
299                         if (ACPI_FAILURE(status)) {
300                                 return (status);
301                         }
302
303                         /* Update locals to point to the new package (of 1 element) */
304
305                         return_object = *return_object_ptr;
306                         elements = return_object->package.elements;
307                         count = 1;
308                 }
309
310                 /* Examine the sub-packages */
311
312                 status =
313                     acpi_ns_check_package_list(data, package, elements, count);
314                 break;
315
316         default:
317
318                 /* Should not get here if predefined info table is correct */
319
320                 ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
321                                       "Invalid internal return type in table entry: %X",
322                                       package->ret_info.type));
323
324                 return (AE_AML_INTERNAL);
325         }
326
327         return (status);
328
329       package_too_small:
330
331         /* Error exit for the case with an incorrect package count */
332
333         ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
334                               "Return Package is too small - found %u elements, expected %u",
335                               count, expected_count));
336
337         return (AE_AML_OPERAND_VALUE);
338 }
339
340 /*******************************************************************************
341  *
342  * FUNCTION:    acpi_ns_check_package_list
343  *
344  * PARAMETERS:  data            - Pointer to validation data structure
345  *              package         - Pointer to package-specific info for method
346  *              elements        - Element list of parent package. All elements
347  *                                of this list should be of type Package.
348  *              count           - Count of subpackages
349  *
350  * RETURN:      Status
351  *
352  * DESCRIPTION: Examine a list of subpackages
353  *
354  ******************************************************************************/
355
356 static acpi_status
357 acpi_ns_check_package_list(struct acpi_predefined_data *data,
358                            const union acpi_predefined_info *package,
359                            union acpi_operand_object **elements, u32 count)
360 {
361         union acpi_operand_object *sub_package;
362         union acpi_operand_object **sub_elements;
363         acpi_status status;
364         u32 expected_count;
365         u32 i;
366         u32 j;
367
368         /*
369          * Validate each sub-Package in the parent Package
370          *
371          * NOTE: assumes list of sub-packages contains no NULL elements.
372          * Any NULL elements should have been removed by earlier call
373          * to acpi_ns_remove_null_elements.
374          */
375         for (i = 0; i < count; i++) {
376                 sub_package = *elements;
377                 sub_elements = sub_package->package.elements;
378                 data->parent_package = sub_package;
379
380                 /* Each sub-object must be of type Package */
381
382                 status = acpi_ns_check_object_type(data, &sub_package,
383                                                    ACPI_RTYPE_PACKAGE, i);
384                 if (ACPI_FAILURE(status)) {
385                         return (status);
386                 }
387
388                 /* Examine the different types of expected sub-packages */
389
390                 data->parent_package = sub_package;
391                 switch (package->ret_info.type) {
392                 case ACPI_PTYPE2:
393                 case ACPI_PTYPE2_PKG_COUNT:
394                 case ACPI_PTYPE2_REV_FIXED:
395
396                         /* Each subpackage has a fixed number of elements */
397
398                         expected_count =
399                             package->ret_info.count1 + package->ret_info.count2;
400                         if (sub_package->package.count < expected_count) {
401                                 goto package_too_small;
402                         }
403
404                         status =
405                             acpi_ns_check_package_elements(data, sub_elements,
406                                                            package->ret_info.
407                                                            object_type1,
408                                                            package->ret_info.
409                                                            count1,
410                                                            package->ret_info.
411                                                            object_type2,
412                                                            package->ret_info.
413                                                            count2, 0);
414                         if (ACPI_FAILURE(status)) {
415                                 return (status);
416                         }
417                         break;
418
419                 case ACPI_PTYPE2_FIX_VAR:
420                         /*
421                          * Each subpackage has a fixed number of elements and an
422                          * optional element
423                          */
424                         expected_count =
425                             package->ret_info.count1 + package->ret_info.count2;
426                         if (sub_package->package.count < expected_count) {
427                                 goto package_too_small;
428                         }
429
430                         status =
431                             acpi_ns_check_package_elements(data, sub_elements,
432                                                            package->ret_info.
433                                                            object_type1,
434                                                            package->ret_info.
435                                                            count1,
436                                                            package->ret_info.
437                                                            object_type2,
438                                                            sub_package->package.
439                                                            count -
440                                                            package->ret_info.
441                                                            count1, 0);
442                         if (ACPI_FAILURE(status)) {
443                                 return (status);
444                         }
445                         break;
446
447                 case ACPI_PTYPE2_FIXED:
448
449                         /* Each sub-package has a fixed length */
450
451                         expected_count = package->ret_info2.count;
452                         if (sub_package->package.count < expected_count) {
453                                 goto package_too_small;
454                         }
455
456                         /* Check the type of each sub-package element */
457
458                         for (j = 0; j < expected_count; j++) {
459                                 status =
460                                     acpi_ns_check_object_type(data,
461                                                               &sub_elements[j],
462                                                               package->
463                                                               ret_info2.
464                                                               object_type[j],
465                                                               j);
466                                 if (ACPI_FAILURE(status)) {
467                                         return (status);
468                                 }
469                         }
470                         break;
471
472                 case ACPI_PTYPE2_MIN:
473
474                         /* Each sub-package has a variable but minimum length */
475
476                         expected_count = package->ret_info.count1;
477                         if (sub_package->package.count < expected_count) {
478                                 goto package_too_small;
479                         }
480
481                         /* Check the type of each sub-package element */
482
483                         status =
484                             acpi_ns_check_package_elements(data, sub_elements,
485                                                            package->ret_info.
486                                                            object_type1,
487                                                            sub_package->package.
488                                                            count, 0, 0, 0);
489                         if (ACPI_FAILURE(status)) {
490                                 return (status);
491                         }
492                         break;
493
494                 case ACPI_PTYPE2_COUNT:
495
496                         /*
497                          * First element is the (Integer) count of elements, including
498                          * the count field (the ACPI name is num_elements)
499                          */
500                         status = acpi_ns_check_object_type(data, sub_elements,
501                                                            ACPI_RTYPE_INTEGER,
502                                                            0);
503                         if (ACPI_FAILURE(status)) {
504                                 return (status);
505                         }
506
507                         /*
508                          * Make sure package is large enough for the Count and is
509                          * is as large as the minimum size
510                          */
511                         expected_count = (u32)(*sub_elements)->integer.value;
512                         if (sub_package->package.count < expected_count) {
513                                 goto package_too_small;
514                         }
515                         if (sub_package->package.count <
516                             package->ret_info.count1) {
517                                 expected_count = package->ret_info.count1;
518                                 goto package_too_small;
519                         }
520                         if (expected_count == 0) {
521                                 /*
522                                  * Either the num_entries element was originally zero or it was
523                                  * a NULL element and repaired to an Integer of value zero.
524                                  * In either case, repair it by setting num_entries to be the
525                                  * actual size of the subpackage.
526                                  */
527                                 expected_count = sub_package->package.count;
528                                 (*sub_elements)->integer.value = expected_count;
529                         }
530
531                         /* Check the type of each sub-package element */
532
533                         status =
534                             acpi_ns_check_package_elements(data,
535                                                            (sub_elements + 1),
536                                                            package->ret_info.
537                                                            object_type1,
538                                                            (expected_count - 1),
539                                                            0, 0, 1);
540                         if (ACPI_FAILURE(status)) {
541                                 return (status);
542                         }
543                         break;
544
545                 default:        /* Should not get here, type was validated by caller */
546
547                         return (AE_AML_INTERNAL);
548                 }
549
550                 elements++;
551         }
552
553         return (AE_OK);
554
555       package_too_small:
556
557         /* The sub-package count was smaller than required */
558
559         ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
560                               "Return Sub-Package[%u] is too small - found %u elements, expected %u",
561                               i, sub_package->package.count, expected_count));
562
563         return (AE_AML_OPERAND_VALUE);
564 }
565
566 /*******************************************************************************
567  *
568  * FUNCTION:    acpi_ns_check_package_elements
569  *
570  * PARAMETERS:  data            - Pointer to validation data structure
571  *              elements        - Pointer to the package elements array
572  *              type1           - Object type for first group
573  *              count1          - Count for first group
574  *              type2           - Object type for second group
575  *              count2          - Count for second group
576  *              start_index     - Start of the first group of elements
577  *
578  * RETURN:      Status
579  *
580  * DESCRIPTION: Check that all elements of a package are of the correct object
581  *              type. Supports up to two groups of different object types.
582  *
583  ******************************************************************************/
584
585 static acpi_status
586 acpi_ns_check_package_elements(struct acpi_predefined_data *data,
587                                union acpi_operand_object **elements,
588                                u8 type1,
589                                u32 count1,
590                                u8 type2, u32 count2, u32 start_index)
591 {
592         union acpi_operand_object **this_element = elements;
593         acpi_status status;
594         u32 i;
595
596         /*
597          * Up to two groups of package elements are supported by the data
598          * structure. All elements in each group must be of the same type.
599          * The second group can have a count of zero.
600          */
601         for (i = 0; i < count1; i++) {
602                 status = acpi_ns_check_object_type(data, this_element,
603                                                    type1, i + start_index);
604                 if (ACPI_FAILURE(status)) {
605                         return (status);
606                 }
607                 this_element++;
608         }
609
610         for (i = 0; i < count2; i++) {
611                 status = acpi_ns_check_object_type(data, this_element,
612                                                    type2,
613                                                    (i + count1 + start_index));
614                 if (ACPI_FAILURE(status)) {
615                         return (status);
616                 }
617                 this_element++;
618         }
619
620         return (AE_OK);
621 }