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