]> Pileus Git - ~andy/linux/blob - drivers/acpi/acpica/rsmisc.c
tools/power: turbostat: fix large c1% issue
[~andy/linux] / drivers / acpi / acpica / rsmisc.c
1 /*******************************************************************************
2  *
3  * Module Name: rsmisc - Miscellaneous resource descriptors
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2012, 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 "acresrc.h"
47
48 #define _COMPONENT          ACPI_RESOURCES
49 ACPI_MODULE_NAME("rsmisc")
50 #define INIT_RESOURCE_TYPE(i)       i->resource_offset
51 #define INIT_RESOURCE_LENGTH(i)     i->aml_offset
52 #define INIT_TABLE_LENGTH(i)        i->value
53 #define COMPARE_OPCODE(i)           i->resource_offset
54 #define COMPARE_TARGET(i)           i->aml_offset
55 #define COMPARE_VALUE(i)            i->value
56 /*******************************************************************************
57  *
58  * FUNCTION:    acpi_rs_convert_aml_to_resource
59  *
60  * PARAMETERS:  Resource            - Pointer to the resource descriptor
61  *              Aml                 - Where the AML descriptor is returned
62  *              Info                - Pointer to appropriate conversion table
63  *
64  * RETURN:      Status
65  *
66  * DESCRIPTION: Convert an external AML resource descriptor to the corresponding
67  *              internal resource descriptor
68  *
69  ******************************************************************************/
70 acpi_status
71 acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
72                                 union aml_resource *aml,
73                                 struct acpi_rsconvert_info *info)
74 {
75         acpi_rs_length aml_resource_length;
76         void *source;
77         void *destination;
78         char *target;
79         u8 count;
80         u8 flags_mode = FALSE;
81         u16 item_count = 0;
82         u16 temp16 = 0;
83
84         ACPI_FUNCTION_TRACE(rs_convert_aml_to_resource);
85
86         if (!info) {
87                 return_ACPI_STATUS(AE_BAD_PARAMETER);
88         }
89
90         if (((acpi_size) resource) & 0x3) {
91
92                 /* Each internal resource struct is expected to be 32-bit aligned */
93
94                 ACPI_WARNING((AE_INFO,
95                               "Misaligned resource pointer (get): %p Type 0x%2.2X Length %u",
96                               resource, resource->type, resource->length));
97         }
98
99         /* Extract the resource Length field (does not include header length) */
100
101         aml_resource_length = acpi_ut_get_resource_length(aml);
102
103         /*
104          * First table entry must be ACPI_RSC_INITxxx and must contain the
105          * table length (# of table entries)
106          */
107         count = INIT_TABLE_LENGTH(info);
108         while (count) {
109                 /*
110                  * Source is the external AML byte stream buffer,
111                  * destination is the internal resource descriptor
112                  */
113                 source = ACPI_ADD_PTR(void, aml, info->aml_offset);
114                 destination =
115                     ACPI_ADD_PTR(void, resource, info->resource_offset);
116
117                 switch (info->opcode) {
118                 case ACPI_RSC_INITGET:
119                         /*
120                          * Get the resource type and the initial (minimum) length
121                          */
122                         ACPI_MEMSET(resource, 0, INIT_RESOURCE_LENGTH(info));
123                         resource->type = INIT_RESOURCE_TYPE(info);
124                         resource->length = INIT_RESOURCE_LENGTH(info);
125                         break;
126
127                 case ACPI_RSC_INITSET:
128                         break;
129
130                 case ACPI_RSC_FLAGINIT:
131
132                         flags_mode = TRUE;
133                         break;
134
135                 case ACPI_RSC_1BITFLAG:
136                         /*
137                          * Mask and shift the flag bit
138                          */
139                         ACPI_SET8(destination) = (u8)
140                             ((ACPI_GET8(source) >> info->value) & 0x01);
141                         break;
142
143                 case ACPI_RSC_2BITFLAG:
144                         /*
145                          * Mask and shift the flag bits
146                          */
147                         ACPI_SET8(destination) = (u8)
148                             ((ACPI_GET8(source) >> info->value) & 0x03);
149                         break;
150
151                 case ACPI_RSC_3BITFLAG:
152                         /*
153                          * Mask and shift the flag bits
154                          */
155                         ACPI_SET8(destination) = (u8)
156                             ((ACPI_GET8(source) >> info->value) & 0x07);
157                         break;
158
159                 case ACPI_RSC_COUNT:
160
161                         item_count = ACPI_GET8(source);
162                         ACPI_SET8(destination) = (u8) item_count;
163
164                         resource->length = resource->length +
165                             (info->value * (item_count - 1));
166                         break;
167
168                 case ACPI_RSC_COUNT16:
169
170                         item_count = aml_resource_length;
171                         ACPI_SET16(destination) = item_count;
172
173                         resource->length = resource->length +
174                             (info->value * (item_count - 1));
175                         break;
176
177                 case ACPI_RSC_COUNT_GPIO_PIN:
178
179                         target = ACPI_ADD_PTR(void, aml, info->value);
180                         item_count = ACPI_GET16(target) - ACPI_GET16(source);
181
182                         resource->length = resource->length + item_count;
183                         item_count = item_count / 2;
184                         ACPI_SET16(destination) = item_count;
185                         break;
186
187                 case ACPI_RSC_COUNT_GPIO_VEN:
188
189                         item_count = ACPI_GET8(source);
190                         ACPI_SET8(destination) = (u8)item_count;
191
192                         resource->length = resource->length +
193                             (info->value * item_count);
194                         break;
195
196                 case ACPI_RSC_COUNT_GPIO_RES:
197
198                         /*
199                          * Vendor data is optional (length/offset may both be zero)
200                          * Examine vendor data length field first
201                          */
202                         target = ACPI_ADD_PTR(void, aml, (info->value + 2));
203                         if (ACPI_GET16(target)) {
204
205                                 /* Use vendor offset to get resource source length */
206
207                                 target = ACPI_ADD_PTR(void, aml, info->value);
208                                 item_count =
209                                     ACPI_GET16(target) - ACPI_GET16(source);
210                         } else {
211                                 /* No vendor data to worry about */
212
213                                 item_count = aml->large_header.resource_length +
214                                     sizeof(struct aml_resource_large_header) -
215                                     ACPI_GET16(source);
216                         }
217
218                         resource->length = resource->length + item_count;
219                         ACPI_SET16(destination) = item_count;
220                         break;
221
222                 case ACPI_RSC_COUNT_SERIAL_VEN:
223
224                         item_count = ACPI_GET16(source) - info->value;
225
226                         resource->length = resource->length + item_count;
227                         ACPI_SET16(destination) = item_count;
228                         break;
229
230                 case ACPI_RSC_COUNT_SERIAL_RES:
231
232                         item_count = (aml_resource_length +
233                                       sizeof(struct aml_resource_large_header))
234                             - ACPI_GET16(source) - info->value;
235
236                         resource->length = resource->length + item_count;
237                         ACPI_SET16(destination) = item_count;
238                         break;
239
240                 case ACPI_RSC_LENGTH:
241
242                         resource->length = resource->length + info->value;
243                         break;
244
245                 case ACPI_RSC_MOVE8:
246                 case ACPI_RSC_MOVE16:
247                 case ACPI_RSC_MOVE32:
248                 case ACPI_RSC_MOVE64:
249                         /*
250                          * Raw data move. Use the Info value field unless item_count has
251                          * been previously initialized via a COUNT opcode
252                          */
253                         if (info->value) {
254                                 item_count = info->value;
255                         }
256                         acpi_rs_move_data(destination, source, item_count,
257                                           info->opcode);
258                         break;
259
260                 case ACPI_RSC_MOVE_GPIO_PIN:
261
262                         /* Generate and set the PIN data pointer */
263
264                         target = (char *)ACPI_ADD_PTR(void, resource,
265                                                       (resource->length -
266                                                        item_count * 2));
267                         *(u16 **)destination = ACPI_CAST_PTR(u16, target);
268
269                         /* Copy the PIN data */
270
271                         source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source));
272                         acpi_rs_move_data(target, source, item_count,
273                                           info->opcode);
274                         break;
275
276                 case ACPI_RSC_MOVE_GPIO_RES:
277
278                         /* Generate and set the resource_source string pointer */
279
280                         target = (char *)ACPI_ADD_PTR(void, resource,
281                                                       (resource->length -
282                                                        item_count));
283                         *(u8 **)destination = ACPI_CAST_PTR(u8, target);
284
285                         /* Copy the resource_source string */
286
287                         source = ACPI_ADD_PTR(void, aml, ACPI_GET16(source));
288                         acpi_rs_move_data(target, source, item_count,
289                                           info->opcode);
290                         break;
291
292                 case ACPI_RSC_MOVE_SERIAL_VEN:
293
294                         /* Generate and set the Vendor Data pointer */
295
296                         target = (char *)ACPI_ADD_PTR(void, resource,
297                                                       (resource->length -
298                                                        item_count));
299                         *(u8 **)destination = ACPI_CAST_PTR(u8, target);
300
301                         /* Copy the Vendor Data */
302
303                         source = ACPI_ADD_PTR(void, aml, info->value);
304                         acpi_rs_move_data(target, source, item_count,
305                                           info->opcode);
306                         break;
307
308                 case ACPI_RSC_MOVE_SERIAL_RES:
309
310                         /* Generate and set the resource_source string pointer */
311
312                         target = (char *)ACPI_ADD_PTR(void, resource,
313                                                       (resource->length -
314                                                        item_count));
315                         *(u8 **)destination = ACPI_CAST_PTR(u8, target);
316
317                         /* Copy the resource_source string */
318
319                         source =
320                             ACPI_ADD_PTR(void, aml,
321                                          (ACPI_GET16(source) + info->value));
322                         acpi_rs_move_data(target, source, item_count,
323                                           info->opcode);
324                         break;
325
326                 case ACPI_RSC_SET8:
327
328                         ACPI_MEMSET(destination, info->aml_offset, info->value);
329                         break;
330
331                 case ACPI_RSC_DATA8:
332
333                         target = ACPI_ADD_PTR(char, resource, info->value);
334                         ACPI_MEMCPY(destination, source, ACPI_GET16(target));
335                         break;
336
337                 case ACPI_RSC_ADDRESS:
338                         /*
339                          * Common handler for address descriptor flags
340                          */
341                         if (!acpi_rs_get_address_common(resource, aml)) {
342                                 return_ACPI_STATUS
343                                     (AE_AML_INVALID_RESOURCE_TYPE);
344                         }
345                         break;
346
347                 case ACPI_RSC_SOURCE:
348                         /*
349                          * Optional resource_source (Index and String)
350                          */
351                         resource->length +=
352                             acpi_rs_get_resource_source(aml_resource_length,
353                                                         info->value,
354                                                         destination, aml, NULL);
355                         break;
356
357                 case ACPI_RSC_SOURCEX:
358                         /*
359                          * Optional resource_source (Index and String). This is the more
360                          * complicated case used by the Interrupt() macro
361                          */
362                         target = ACPI_ADD_PTR(char, resource,
363                                               info->aml_offset +
364                                               (item_count * 4));
365
366                         resource->length +=
367                             acpi_rs_get_resource_source(aml_resource_length,
368                                                         (acpi_rs_length)
369                                                         (((item_count -
370                                                            1) * sizeof(u32)) +
371                                                          info->value),
372                                                         destination, aml,
373                                                         target);
374                         break;
375
376                 case ACPI_RSC_BITMASK:
377                         /*
378                          * 8-bit encoded bitmask (DMA macro)
379                          */
380                         item_count =
381                             acpi_rs_decode_bitmask(ACPI_GET8(source),
382                                                    destination);
383                         if (item_count) {
384                                 resource->length += (item_count - 1);
385                         }
386
387                         target = ACPI_ADD_PTR(char, resource, info->value);
388                         ACPI_SET8(target) = (u8) item_count;
389                         break;
390
391                 case ACPI_RSC_BITMASK16:
392                         /*
393                          * 16-bit encoded bitmask (IRQ macro)
394                          */
395                         ACPI_MOVE_16_TO_16(&temp16, source);
396
397                         item_count =
398                             acpi_rs_decode_bitmask(temp16, destination);
399                         if (item_count) {
400                                 resource->length += (item_count - 1);
401                         }
402
403                         target = ACPI_ADD_PTR(char, resource, info->value);
404                         ACPI_SET8(target) = (u8) item_count;
405                         break;
406
407                 case ACPI_RSC_EXIT_NE:
408                         /*
409                          * Control - Exit conversion if not equal
410                          */
411                         switch (info->resource_offset) {
412                         case ACPI_RSC_COMPARE_AML_LENGTH:
413                                 if (aml_resource_length != info->value) {
414                                         goto exit;
415                                 }
416                                 break;
417
418                         case ACPI_RSC_COMPARE_VALUE:
419                                 if (ACPI_GET8(source) != info->value) {
420                                         goto exit;
421                                 }
422                                 break;
423
424                         default:
425
426                                 ACPI_ERROR((AE_INFO,
427                                             "Invalid conversion sub-opcode"));
428                                 return_ACPI_STATUS(AE_BAD_PARAMETER);
429                         }
430                         break;
431
432                 default:
433
434                         ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
435                         return_ACPI_STATUS(AE_BAD_PARAMETER);
436                 }
437
438                 count--;
439                 info++;
440         }
441
442       exit:
443         if (!flags_mode) {
444
445                 /* Round the resource struct length up to the next boundary (32 or 64) */
446
447                 resource->length =
448                     (u32) ACPI_ROUND_UP_TO_NATIVE_WORD(resource->length);
449         }
450         return_ACPI_STATUS(AE_OK);
451 }
452
453 /*******************************************************************************
454  *
455  * FUNCTION:    acpi_rs_convert_resource_to_aml
456  *
457  * PARAMETERS:  Resource            - Pointer to the resource descriptor
458  *              Aml                 - Where the AML descriptor is returned
459  *              Info                - Pointer to appropriate conversion table
460  *
461  * RETURN:      Status
462  *
463  * DESCRIPTION: Convert an internal resource descriptor to the corresponding
464  *              external AML resource descriptor.
465  *
466  ******************************************************************************/
467
468 acpi_status
469 acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
470                                 union aml_resource *aml,
471                                 struct acpi_rsconvert_info *info)
472 {
473         void *source = NULL;
474         void *destination;
475         char *target;
476         acpi_rsdesc_size aml_length = 0;
477         u8 count;
478         u16 temp16 = 0;
479         u16 item_count = 0;
480
481         ACPI_FUNCTION_TRACE(rs_convert_resource_to_aml);
482
483         if (!info) {
484                 return_ACPI_STATUS(AE_BAD_PARAMETER);
485         }
486
487         /*
488          * First table entry must be ACPI_RSC_INITxxx and must contain the
489          * table length (# of table entries)
490          */
491         count = INIT_TABLE_LENGTH(info);
492
493         while (count) {
494                 /*
495                  * Source is the internal resource descriptor,
496                  * destination is the external AML byte stream buffer
497                  */
498                 source = ACPI_ADD_PTR(void, resource, info->resource_offset);
499                 destination = ACPI_ADD_PTR(void, aml, info->aml_offset);
500
501                 switch (info->opcode) {
502                 case ACPI_RSC_INITSET:
503
504                         ACPI_MEMSET(aml, 0, INIT_RESOURCE_LENGTH(info));
505                         aml_length = INIT_RESOURCE_LENGTH(info);
506                         acpi_rs_set_resource_header(INIT_RESOURCE_TYPE(info),
507                                                     aml_length, aml);
508                         break;
509
510                 case ACPI_RSC_INITGET:
511                         break;
512
513                 case ACPI_RSC_FLAGINIT:
514                         /*
515                          * Clear the flag byte
516                          */
517                         ACPI_SET8(destination) = 0;
518                         break;
519
520                 case ACPI_RSC_1BITFLAG:
521                         /*
522                          * Mask and shift the flag bit
523                          */
524                         ACPI_SET8(destination) |= (u8)
525                             ((ACPI_GET8(source) & 0x01) << info->value);
526                         break;
527
528                 case ACPI_RSC_2BITFLAG:
529                         /*
530                          * Mask and shift the flag bits
531                          */
532                         ACPI_SET8(destination) |= (u8)
533                             ((ACPI_GET8(source) & 0x03) << info->value);
534                         break;
535
536                 case ACPI_RSC_3BITFLAG:
537                         /*
538                          * Mask and shift the flag bits
539                          */
540                         ACPI_SET8(destination) |= (u8)
541                             ((ACPI_GET8(source) & 0x07) << info->value);
542                         break;
543
544                 case ACPI_RSC_COUNT:
545
546                         item_count = ACPI_GET8(source);
547                         ACPI_SET8(destination) = (u8) item_count;
548
549                         aml_length =
550                             (u16) (aml_length +
551                                    (info->value * (item_count - 1)));
552                         break;
553
554                 case ACPI_RSC_COUNT16:
555
556                         item_count = ACPI_GET16(source);
557                         aml_length = (u16) (aml_length + item_count);
558                         acpi_rs_set_resource_length(aml_length, aml);
559                         break;
560
561                 case ACPI_RSC_COUNT_GPIO_PIN:
562
563                         item_count = ACPI_GET16(source);
564                         ACPI_SET16(destination) = (u16)aml_length;
565
566                         aml_length = (u16)(aml_length + item_count * 2);
567                         target = ACPI_ADD_PTR(void, aml, info->value);
568                         ACPI_SET16(target) = (u16)aml_length;
569                         acpi_rs_set_resource_length(aml_length, aml);
570                         break;
571
572                 case ACPI_RSC_COUNT_GPIO_VEN:
573
574                         item_count = ACPI_GET16(source);
575                         ACPI_SET16(destination) = (u16)item_count;
576
577                         aml_length =
578                             (u16)(aml_length + (info->value * item_count));
579                         acpi_rs_set_resource_length(aml_length, aml);
580                         break;
581
582                 case ACPI_RSC_COUNT_GPIO_RES:
583
584                         /* Set resource source string length */
585
586                         item_count = ACPI_GET16(source);
587                         ACPI_SET16(destination) = (u16)aml_length;
588
589                         /* Compute offset for the Vendor Data */
590
591                         aml_length = (u16)(aml_length + item_count);
592                         target = ACPI_ADD_PTR(void, aml, info->value);
593
594                         /* Set vendor offset only if there is vendor data */
595
596                         if (resource->data.gpio.vendor_length) {
597                                 ACPI_SET16(target) = (u16)aml_length;
598                         }
599
600                         acpi_rs_set_resource_length(aml_length, aml);
601                         break;
602
603                 case ACPI_RSC_COUNT_SERIAL_VEN:
604
605                         item_count = ACPI_GET16(source);
606                         ACPI_SET16(destination) = item_count + info->value;
607                         aml_length = (u16)(aml_length + item_count);
608                         acpi_rs_set_resource_length(aml_length, aml);
609                         break;
610
611                 case ACPI_RSC_COUNT_SERIAL_RES:
612
613                         item_count = ACPI_GET16(source);
614                         aml_length = (u16)(aml_length + item_count);
615                         acpi_rs_set_resource_length(aml_length, aml);
616                         break;
617
618                 case ACPI_RSC_LENGTH:
619
620                         acpi_rs_set_resource_length(info->value, aml);
621                         break;
622
623                 case ACPI_RSC_MOVE8:
624                 case ACPI_RSC_MOVE16:
625                 case ACPI_RSC_MOVE32:
626                 case ACPI_RSC_MOVE64:
627
628                         if (info->value) {
629                                 item_count = info->value;
630                         }
631                         acpi_rs_move_data(destination, source, item_count,
632                                           info->opcode);
633                         break;
634
635                 case ACPI_RSC_MOVE_GPIO_PIN:
636
637                         destination = (char *)ACPI_ADD_PTR(void, aml,
638                                                            ACPI_GET16
639                                                            (destination));
640                         source = *(u16 **)source;
641                         acpi_rs_move_data(destination, source, item_count,
642                                           info->opcode);
643                         break;
644
645                 case ACPI_RSC_MOVE_GPIO_RES:
646
647                         /* Used for both resource_source string and vendor_data */
648
649                         destination = (char *)ACPI_ADD_PTR(void, aml,
650                                                            ACPI_GET16
651                                                            (destination));
652                         source = *(u8 **)source;
653                         acpi_rs_move_data(destination, source, item_count,
654                                           info->opcode);
655                         break;
656
657                 case ACPI_RSC_MOVE_SERIAL_VEN:
658
659                         destination = (char *)ACPI_ADD_PTR(void, aml,
660                                                            (aml_length -
661                                                             item_count));
662                         source = *(u8 **)source;
663                         acpi_rs_move_data(destination, source, item_count,
664                                           info->opcode);
665                         break;
666
667                 case ACPI_RSC_MOVE_SERIAL_RES:
668
669                         destination = (char *)ACPI_ADD_PTR(void, aml,
670                                                            (aml_length -
671                                                             item_count));
672                         source = *(u8 **)source;
673                         acpi_rs_move_data(destination, source, item_count,
674                                           info->opcode);
675                         break;
676
677                 case ACPI_RSC_ADDRESS:
678
679                         /* Set the Resource Type, General Flags, and Type-Specific Flags */
680
681                         acpi_rs_set_address_common(aml, resource);
682                         break;
683
684                 case ACPI_RSC_SOURCEX:
685                         /*
686                          * Optional resource_source (Index and String)
687                          */
688                         aml_length =
689                             acpi_rs_set_resource_source(aml, (acpi_rs_length)
690                                                         aml_length, source);
691                         acpi_rs_set_resource_length(aml_length, aml);
692                         break;
693
694                 case ACPI_RSC_SOURCE:
695                         /*
696                          * Optional resource_source (Index and String). This is the more
697                          * complicated case used by the Interrupt() macro
698                          */
699                         aml_length =
700                             acpi_rs_set_resource_source(aml, info->value,
701                                                         source);
702                         acpi_rs_set_resource_length(aml_length, aml);
703                         break;
704
705                 case ACPI_RSC_BITMASK:
706                         /*
707                          * 8-bit encoded bitmask (DMA macro)
708                          */
709                         ACPI_SET8(destination) = (u8)
710                             acpi_rs_encode_bitmask(source,
711                                                    *ACPI_ADD_PTR(u8, resource,
712                                                                  info->value));
713                         break;
714
715                 case ACPI_RSC_BITMASK16:
716                         /*
717                          * 16-bit encoded bitmask (IRQ macro)
718                          */
719                         temp16 = acpi_rs_encode_bitmask(source,
720                                                         *ACPI_ADD_PTR(u8,
721                                                                       resource,
722                                                                       info->
723                                                                       value));
724                         ACPI_MOVE_16_TO_16(destination, &temp16);
725                         break;
726
727                 case ACPI_RSC_EXIT_LE:
728                         /*
729                          * Control - Exit conversion if less than or equal
730                          */
731                         if (item_count <= info->value) {
732                                 goto exit;
733                         }
734                         break;
735
736                 case ACPI_RSC_EXIT_NE:
737                         /*
738                          * Control - Exit conversion if not equal
739                          */
740                         switch (COMPARE_OPCODE(info)) {
741                         case ACPI_RSC_COMPARE_VALUE:
742
743                                 if (*ACPI_ADD_PTR(u8, resource,
744                                                   COMPARE_TARGET(info)) !=
745                                     COMPARE_VALUE(info)) {
746                                         goto exit;
747                                 }
748                                 break;
749
750                         default:
751
752                                 ACPI_ERROR((AE_INFO,
753                                             "Invalid conversion sub-opcode"));
754                                 return_ACPI_STATUS(AE_BAD_PARAMETER);
755                         }
756                         break;
757
758                 case ACPI_RSC_EXIT_EQ:
759                         /*
760                          * Control - Exit conversion if equal
761                          */
762                         if (*ACPI_ADD_PTR(u8, resource,
763                                           COMPARE_TARGET(info)) ==
764                             COMPARE_VALUE(info)) {
765                                 goto exit;
766                         }
767                         break;
768
769                 default:
770
771                         ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
772                         return_ACPI_STATUS(AE_BAD_PARAMETER);
773                 }
774
775                 count--;
776                 info++;
777         }
778
779       exit:
780         return_ACPI_STATUS(AE_OK);
781 }
782
783 #if 0
784 /* Previous resource validations */
785
786 if (aml->ext_address64.revision_iD != AML_RESOURCE_EXTENDED_ADDRESS_REVISION) {
787         return_ACPI_STATUS(AE_SUPPORT);
788 }
789
790 if (resource->data.start_dpf.performance_robustness >= 3) {
791         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_VALUE);
792 }
793
794 if (((aml->irq.flags & 0x09) == 0x00) || ((aml->irq.flags & 0x09) == 0x09)) {
795         /*
796          * Only [active_high, edge_sensitive] or [active_low, level_sensitive]
797          * polarity/trigger interrupts are allowed (ACPI spec, section
798          * "IRQ Format"), so 0x00 and 0x09 are illegal.
799          */
800         ACPI_ERROR((AE_INFO,
801                     "Invalid interrupt polarity/trigger in resource list, 0x%X",
802                     aml->irq.flags));
803         return_ACPI_STATUS(AE_BAD_DATA);
804 }
805
806 resource->data.extended_irq.interrupt_count = temp8;
807 if (temp8 < 1) {
808
809         /* Must have at least one IRQ */
810
811         return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
812 }
813
814 if (resource->data.dma.transfer == 0x03) {
815         ACPI_ERROR((AE_INFO, "Invalid DMA.Transfer preference (3)"));
816         return_ACPI_STATUS(AE_BAD_DATA);
817 }
818 #endif