]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/acpi/acpica/utresrc.c
ACPICA: ACPI 6.2: Add support for PinGroupConfig() resource
[karo-tx-linux.git] / drivers / acpi / acpica / utresrc.c
1 /*******************************************************************************
2  *
3  * Module Name: utresrc - Resource management utilities
4  *
5  ******************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2017, 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_UTILITIES
49 ACPI_MODULE_NAME("utresrc")
50
51 #if defined(ACPI_DEBUG_OUTPUT) || defined (ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
52 /*
53  * Strings used to decode resource descriptors.
54  * Used by both the disassembler and the debugger resource dump routines
55  */
56 const char *acpi_gbl_bm_decode[] = {
57         "NotBusMaster",
58         "BusMaster"
59 };
60
61 const char *acpi_gbl_config_decode[] = {
62         "0 - Good Configuration",
63         "1 - Acceptable Configuration",
64         "2 - Suboptimal Configuration",
65         "3 - ***Invalid Configuration***",
66 };
67
68 const char *acpi_gbl_consume_decode[] = {
69         "ResourceProducer",
70         "ResourceConsumer"
71 };
72
73 const char *acpi_gbl_dec_decode[] = {
74         "PosDecode",
75         "SubDecode"
76 };
77
78 const char *acpi_gbl_he_decode[] = {
79         "Level",
80         "Edge"
81 };
82
83 const char *acpi_gbl_io_decode[] = {
84         "Decode10",
85         "Decode16"
86 };
87
88 const char *acpi_gbl_ll_decode[] = {
89         "ActiveHigh",
90         "ActiveLow",
91         "ActiveBoth",
92         "Reserved"
93 };
94
95 const char *acpi_gbl_max_decode[] = {
96         "MaxNotFixed",
97         "MaxFixed"
98 };
99
100 const char *acpi_gbl_mem_decode[] = {
101         "NonCacheable",
102         "Cacheable",
103         "WriteCombining",
104         "Prefetchable"
105 };
106
107 const char *acpi_gbl_min_decode[] = {
108         "MinNotFixed",
109         "MinFixed"
110 };
111
112 const char *acpi_gbl_mtp_decode[] = {
113         "AddressRangeMemory",
114         "AddressRangeReserved",
115         "AddressRangeACPI",
116         "AddressRangeNVS"
117 };
118
119 const char *acpi_gbl_rng_decode[] = {
120         "InvalidRanges",
121         "NonISAOnlyRanges",
122         "ISAOnlyRanges",
123         "EntireRange"
124 };
125
126 const char *acpi_gbl_rw_decode[] = {
127         "ReadOnly",
128         "ReadWrite"
129 };
130
131 const char *acpi_gbl_shr_decode[] = {
132         "Exclusive",
133         "Shared",
134         "ExclusiveAndWake",     /* ACPI 5.0 */
135         "SharedAndWake"         /* ACPI 5.0 */
136 };
137
138 const char *acpi_gbl_siz_decode[] = {
139         "Transfer8",
140         "Transfer8_16",
141         "Transfer16",
142         "InvalidSize"
143 };
144
145 const char *acpi_gbl_trs_decode[] = {
146         "DenseTranslation",
147         "SparseTranslation"
148 };
149
150 const char *acpi_gbl_ttp_decode[] = {
151         "TypeStatic",
152         "TypeTranslation"
153 };
154
155 const char *acpi_gbl_typ_decode[] = {
156         "Compatibility",
157         "TypeA",
158         "TypeB",
159         "TypeF"
160 };
161
162 const char *acpi_gbl_ppc_decode[] = {
163         "PullDefault",
164         "PullUp",
165         "PullDown",
166         "PullNone"
167 };
168
169 const char *acpi_gbl_ior_decode[] = {
170         "IoRestrictionNone",
171         "IoRestrictionInputOnly",
172         "IoRestrictionOutputOnly",
173         "IoRestrictionNoneAndPreserve"
174 };
175
176 const char *acpi_gbl_dts_decode[] = {
177         "Width8bit",
178         "Width16bit",
179         "Width32bit",
180         "Width64bit",
181         "Width128bit",
182         "Width256bit",
183 };
184
185 /* GPIO connection type */
186
187 const char *acpi_gbl_ct_decode[] = {
188         "Interrupt",
189         "I/O"
190 };
191
192 /* Serial bus type */
193
194 const char *acpi_gbl_sbt_decode[] = {
195         "/* UNKNOWN serial bus type */",
196         "I2C",
197         "SPI",
198         "UART"
199 };
200
201 /* I2C serial bus access mode */
202
203 const char *acpi_gbl_am_decode[] = {
204         "AddressingMode7Bit",
205         "AddressingMode10Bit"
206 };
207
208 /* I2C serial bus slave mode */
209
210 const char *acpi_gbl_sm_decode[] = {
211         "ControllerInitiated",
212         "DeviceInitiated"
213 };
214
215 /* SPI serial bus wire mode */
216
217 const char *acpi_gbl_wm_decode[] = {
218         "FourWireMode",
219         "ThreeWireMode"
220 };
221
222 /* SPI serial clock phase */
223
224 const char *acpi_gbl_cph_decode[] = {
225         "ClockPhaseFirst",
226         "ClockPhaseSecond"
227 };
228
229 /* SPI serial bus clock polarity */
230
231 const char *acpi_gbl_cpo_decode[] = {
232         "ClockPolarityLow",
233         "ClockPolarityHigh"
234 };
235
236 /* SPI serial bus device polarity */
237
238 const char *acpi_gbl_dp_decode[] = {
239         "PolarityLow",
240         "PolarityHigh"
241 };
242
243 /* UART serial bus endian */
244
245 const char *acpi_gbl_ed_decode[] = {
246         "LittleEndian",
247         "BigEndian"
248 };
249
250 /* UART serial bus bits per byte */
251
252 const char *acpi_gbl_bpb_decode[] = {
253         "DataBitsFive",
254         "DataBitsSix",
255         "DataBitsSeven",
256         "DataBitsEight",
257         "DataBitsNine",
258         "/* UNKNOWN Bits per byte */",
259         "/* UNKNOWN Bits per byte */",
260         "/* UNKNOWN Bits per byte */"
261 };
262
263 /* UART serial bus stop bits */
264
265 const char *acpi_gbl_sb_decode[] = {
266         "StopBitsZero",
267         "StopBitsOne",
268         "StopBitsOnePlusHalf",
269         "StopBitsTwo"
270 };
271
272 /* UART serial bus flow control */
273
274 const char *acpi_gbl_fc_decode[] = {
275         "FlowControlNone",
276         "FlowControlHardware",
277         "FlowControlXON",
278         "/* UNKNOWN flow control keyword */"
279 };
280
281 /* UART serial bus parity type */
282
283 const char *acpi_gbl_pt_decode[] = {
284         "ParityTypeNone",
285         "ParityTypeEven",
286         "ParityTypeOdd",
287         "ParityTypeMark",
288         "ParityTypeSpace",
289         "/* UNKNOWN parity keyword */",
290         "/* UNKNOWN parity keyword */",
291         "/* UNKNOWN parity keyword */"
292 };
293
294 /* pin_config type */
295
296 const char *acpi_gbl_ptyp_decode[] = {
297         "Default",
298         "Bias Pull-up",
299         "Bias Pull-down",
300         "Bias Default",
301         "Bias Disable",
302         "Bias High Impedance",
303         "Bias Bus Hold",
304         "Drive Open Drain",
305         "Drive Open Source",
306         "Drive Push Pull",
307         "Drive Strength",
308         "Slew Rate",
309         "Input Debounce",
310         "Input Schmitt Trigger",
311 };
312
313 #endif
314
315 /*
316  * Base sizes of the raw AML resource descriptors, indexed by resource type.
317  * Zero indicates a reserved (and therefore invalid) resource type.
318  */
319 const u8 acpi_gbl_resource_aml_sizes[] = {
320         /* Small descriptors */
321
322         0,
323         0,
324         0,
325         0,
326         ACPI_AML_SIZE_SMALL(struct aml_resource_irq),
327         ACPI_AML_SIZE_SMALL(struct aml_resource_dma),
328         ACPI_AML_SIZE_SMALL(struct aml_resource_start_dependent),
329         ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
330         ACPI_AML_SIZE_SMALL(struct aml_resource_io),
331         ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
332         ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma),
333         0,
334         0,
335         0,
336         ACPI_AML_SIZE_SMALL(struct aml_resource_vendor_small),
337         ACPI_AML_SIZE_SMALL(struct aml_resource_end_tag),
338
339         /* Large descriptors */
340
341         0,
342         ACPI_AML_SIZE_LARGE(struct aml_resource_memory24),
343         ACPI_AML_SIZE_LARGE(struct aml_resource_generic_register),
344         0,
345         ACPI_AML_SIZE_LARGE(struct aml_resource_vendor_large),
346         ACPI_AML_SIZE_LARGE(struct aml_resource_memory32),
347         ACPI_AML_SIZE_LARGE(struct aml_resource_fixed_memory32),
348         ACPI_AML_SIZE_LARGE(struct aml_resource_address32),
349         ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
350         ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
351         ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
352         ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64),
353         ACPI_AML_SIZE_LARGE(struct aml_resource_gpio),
354         ACPI_AML_SIZE_LARGE(struct aml_resource_pin_function),
355         ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus),
356         ACPI_AML_SIZE_LARGE(struct aml_resource_pin_config),
357         ACPI_AML_SIZE_LARGE(struct aml_resource_pin_group),
358         ACPI_AML_SIZE_LARGE(struct aml_resource_pin_group_function),
359         ACPI_AML_SIZE_LARGE(struct aml_resource_pin_group_config),
360 };
361
362 const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = {
363         0,
364         ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus),
365         ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus),
366         ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus),
367 };
368
369 /*
370  * Resource types, used to validate the resource length field.
371  * The length of fixed-length types must match exactly, variable
372  * lengths must meet the minimum required length, etc.
373  * Zero indicates a reserved (and therefore invalid) resource type.
374  */
375 static const u8 acpi_gbl_resource_types[] = {
376         /* Small descriptors */
377
378         0,
379         0,
380         0,
381         0,
382         ACPI_SMALL_VARIABLE_LENGTH,     /* 04 IRQ */
383         ACPI_FIXED_LENGTH,      /* 05 DMA */
384         ACPI_SMALL_VARIABLE_LENGTH,     /* 06 start_dependent_functions */
385         ACPI_FIXED_LENGTH,      /* 07 end_dependent_functions */
386         ACPI_FIXED_LENGTH,      /* 08 IO */
387         ACPI_FIXED_LENGTH,      /* 09 fixed_IO */
388         ACPI_FIXED_LENGTH,      /* 0A fixed_DMA */
389         0,
390         0,
391         0,
392         ACPI_VARIABLE_LENGTH,   /* 0E vendor_short */
393         ACPI_FIXED_LENGTH,      /* 0F end_tag */
394
395         /* Large descriptors */
396
397         0,
398         ACPI_FIXED_LENGTH,      /* 01 Memory24 */
399         ACPI_FIXED_LENGTH,      /* 02 generic_register */
400         0,
401         ACPI_VARIABLE_LENGTH,   /* 04 vendor_long */
402         ACPI_FIXED_LENGTH,      /* 05 Memory32 */
403         ACPI_FIXED_LENGTH,      /* 06 memory32_fixed */
404         ACPI_VARIABLE_LENGTH,   /* 07 Dword* address */
405         ACPI_VARIABLE_LENGTH,   /* 08 Word* address */
406         ACPI_VARIABLE_LENGTH,   /* 09 extended_IRQ */
407         ACPI_VARIABLE_LENGTH,   /* 0A Qword* address */
408         ACPI_FIXED_LENGTH,      /* 0B Extended* address */
409         ACPI_VARIABLE_LENGTH,   /* 0C Gpio* */
410         ACPI_VARIABLE_LENGTH,   /* 0D pin_function */
411         ACPI_VARIABLE_LENGTH,   /* 0E *serial_bus */
412         ACPI_VARIABLE_LENGTH,   /* 0F pin_config */
413         ACPI_VARIABLE_LENGTH,   /* 10 pin_group */
414         ACPI_VARIABLE_LENGTH,   /* 11 pin_group_function */
415         ACPI_VARIABLE_LENGTH,   /* 12 pin_group_config */
416 };
417
418 /*******************************************************************************
419  *
420  * FUNCTION:    acpi_ut_walk_aml_resources
421  *
422  * PARAMETERS:  walk_state          - Current walk info
423  * PARAMETERS:  aml                 - Pointer to the raw AML resource template
424  *              aml_length          - Length of the entire template
425  *              user_function       - Called once for each descriptor found. If
426  *                                    NULL, a pointer to the end_tag is returned
427  *              context             - Passed to user_function
428  *
429  * RETURN:      Status
430  *
431  * DESCRIPTION: Walk a raw AML resource list(buffer). User function called
432  *              once for each resource found.
433  *
434  ******************************************************************************/
435
436 acpi_status
437 acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
438                            u8 *aml,
439                            acpi_size aml_length,
440                            acpi_walk_aml_callback user_function, void **context)
441 {
442         acpi_status status;
443         u8 *end_aml;
444         u8 resource_index;
445         u32 length;
446         u32 offset = 0;
447         u8 end_tag[2] = { 0x79, 0x00 };
448
449         ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
450
451         /* The absolute minimum resource template is one end_tag descriptor */
452
453         if (aml_length < sizeof(struct aml_resource_end_tag)) {
454                 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
455         }
456
457         /* Point to the end of the resource template buffer */
458
459         end_aml = aml + aml_length;
460
461         /* Walk the byte list, abort on any invalid descriptor type or length */
462
463         while (aml < end_aml) {
464
465                 /* Validate the Resource Type and Resource Length */
466
467                 status =
468                     acpi_ut_validate_resource(walk_state, aml, &resource_index);
469                 if (ACPI_FAILURE(status)) {
470                         /*
471                          * Exit on failure. Cannot continue because the descriptor
472                          * length may be bogus also.
473                          */
474                         return_ACPI_STATUS(status);
475                 }
476
477                 /* Get the length of this descriptor */
478
479                 length = acpi_ut_get_descriptor_length(aml);
480
481                 /* Invoke the user function */
482
483                 if (user_function) {
484                         status =
485                             user_function(aml, length, offset, resource_index,
486                                           context);
487                         if (ACPI_FAILURE(status)) {
488                                 return_ACPI_STATUS(status);
489                         }
490                 }
491
492                 /* An end_tag descriptor terminates this resource template */
493
494                 if (acpi_ut_get_resource_type(aml) ==
495                     ACPI_RESOURCE_NAME_END_TAG) {
496                         /*
497                          * There must be at least one more byte in the buffer for
498                          * the 2nd byte of the end_tag
499                          */
500                         if ((aml + 1) >= end_aml) {
501                                 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
502                         }
503
504                         /*
505                          * The end_tag opcode must be followed by a zero byte.
506                          * Although this byte is technically defined to be a checksum,
507                          * in practice, all ASL compilers set this byte to zero.
508                          */
509                         if (*(aml + 1) != 0) {
510                                 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
511                         }
512
513                         /* Return the pointer to the end_tag if requested */
514
515                         if (!user_function) {
516                                 *context = aml;
517                         }
518
519                         /* Normal exit */
520
521                         return_ACPI_STATUS(AE_OK);
522                 }
523
524                 aml += length;
525                 offset += length;
526         }
527
528         /* Did not find an end_tag descriptor */
529
530         if (user_function) {
531
532                 /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */
533
534                 (void)acpi_ut_validate_resource(walk_state, end_tag,
535                                                 &resource_index);
536                 status =
537                     user_function(end_tag, 2, offset, resource_index, context);
538                 if (ACPI_FAILURE(status)) {
539                         return_ACPI_STATUS(status);
540                 }
541         }
542
543         return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
544 }
545
546 /*******************************************************************************
547  *
548  * FUNCTION:    acpi_ut_validate_resource
549  *
550  * PARAMETERS:  walk_state          - Current walk info
551  *              aml                 - Pointer to the raw AML resource descriptor
552  *              return_index        - Where the resource index is returned. NULL
553  *                                    if the index is not required.
554  *
555  * RETURN:      Status, and optionally the Index into the global resource tables
556  *
557  * DESCRIPTION: Validate an AML resource descriptor by checking the Resource
558  *              Type and Resource Length. Returns an index into the global
559  *              resource information/dispatch tables for later use.
560  *
561  ******************************************************************************/
562
563 acpi_status
564 acpi_ut_validate_resource(struct acpi_walk_state *walk_state,
565                           void *aml, u8 *return_index)
566 {
567         union aml_resource *aml_resource;
568         u8 resource_type;
569         u8 resource_index;
570         acpi_rs_length resource_length;
571         acpi_rs_length minimum_resource_length;
572
573         ACPI_FUNCTION_ENTRY();
574
575         /*
576          * 1) Validate the resource_type field (Byte 0)
577          */
578         resource_type = ACPI_GET8(aml);
579
580         /*
581          * Byte 0 contains the descriptor name (Resource Type)
582          * Examine the large/small bit in the resource header
583          */
584         if (resource_type & ACPI_RESOURCE_NAME_LARGE) {
585
586                 /* Verify the large resource type (name) against the max */
587
588                 if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
589                         goto invalid_resource;
590                 }
591
592                 /*
593                  * Large Resource Type -- bits 6:0 contain the name
594                  * Translate range 0x80-0x8B to index range 0x10-0x1B
595                  */
596                 resource_index = (u8) (resource_type - 0x70);
597         } else {
598                 /*
599                  * Small Resource Type -- bits 6:3 contain the name
600                  * Shift range to index range 0x00-0x0F
601                  */
602                 resource_index = (u8)
603                     ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
604         }
605
606         /*
607          * Check validity of the resource type, via acpi_gbl_resource_types.
608          * Zero indicates an invalid resource.
609          */
610         if (!acpi_gbl_resource_types[resource_index]) {
611                 goto invalid_resource;
612         }
613
614         /*
615          * Validate the resource_length field. This ensures that the length
616          * is at least reasonable, and guarantees that it is non-zero.
617          */
618         resource_length = acpi_ut_get_resource_length(aml);
619         minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
620
621         /* Validate based upon the type of resource - fixed length or variable */
622
623         switch (acpi_gbl_resource_types[resource_index]) {
624         case ACPI_FIXED_LENGTH:
625
626                 /* Fixed length resource, length must match exactly */
627
628                 if (resource_length != minimum_resource_length) {
629                         goto bad_resource_length;
630                 }
631                 break;
632
633         case ACPI_VARIABLE_LENGTH:
634
635                 /* Variable length resource, length must be at least the minimum */
636
637                 if (resource_length < minimum_resource_length) {
638                         goto bad_resource_length;
639                 }
640                 break;
641
642         case ACPI_SMALL_VARIABLE_LENGTH:
643
644                 /* Small variable length resource, length can be (Min) or (Min-1) */
645
646                 if ((resource_length > minimum_resource_length) ||
647                     (resource_length < (minimum_resource_length - 1))) {
648                         goto bad_resource_length;
649                 }
650                 break;
651
652         default:
653
654                 /* Shouldn't happen (because of validation earlier), but be sure */
655
656                 goto invalid_resource;
657         }
658
659         aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
660         if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) {
661
662                 /* Validate the bus_type field */
663
664                 if ((aml_resource->common_serial_bus.type == 0) ||
665                     (aml_resource->common_serial_bus.type >
666                      AML_RESOURCE_MAX_SERIALBUSTYPE)) {
667                         if (walk_state) {
668                                 ACPI_ERROR((AE_INFO,
669                                             "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
670                                             aml_resource->common_serial_bus.
671                                             type));
672                         }
673                         return (AE_AML_INVALID_RESOURCE_TYPE);
674                 }
675         }
676
677         /* Optionally return the resource table index */
678
679         if (return_index) {
680                 *return_index = resource_index;
681         }
682
683         return (AE_OK);
684
685 invalid_resource:
686
687         if (walk_state) {
688                 ACPI_ERROR((AE_INFO,
689                             "Invalid/unsupported resource descriptor: Type 0x%2.2X",
690                             resource_type));
691         }
692         return (AE_AML_INVALID_RESOURCE_TYPE);
693
694 bad_resource_length:
695
696         if (walk_state) {
697                 ACPI_ERROR((AE_INFO,
698                             "Invalid resource descriptor length: Type "
699                             "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
700                             resource_type, resource_length,
701                             minimum_resource_length));
702         }
703         return (AE_AML_BAD_RESOURCE_LENGTH);
704 }
705
706 /*******************************************************************************
707  *
708  * FUNCTION:    acpi_ut_get_resource_type
709  *
710  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
711  *
712  * RETURN:      The Resource Type with no extraneous bits (except the
713  *              Large/Small descriptor bit -- this is left alone)
714  *
715  * DESCRIPTION: Extract the Resource Type/Name from the first byte of
716  *              a resource descriptor.
717  *
718  ******************************************************************************/
719
720 u8 acpi_ut_get_resource_type(void *aml)
721 {
722         ACPI_FUNCTION_ENTRY();
723
724         /*
725          * Byte 0 contains the descriptor name (Resource Type)
726          * Examine the large/small bit in the resource header
727          */
728         if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
729
730                 /* Large Resource Type -- bits 6:0 contain the name */
731
732                 return (ACPI_GET8(aml));
733         } else {
734                 /* Small Resource Type -- bits 6:3 contain the name */
735
736                 return ((u8) (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_SMALL_MASK));
737         }
738 }
739
740 /*******************************************************************************
741  *
742  * FUNCTION:    acpi_ut_get_resource_length
743  *
744  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
745  *
746  * RETURN:      Byte Length
747  *
748  * DESCRIPTION: Get the "Resource Length" of a raw AML descriptor. By
749  *              definition, this does not include the size of the descriptor
750  *              header or the length field itself.
751  *
752  ******************************************************************************/
753
754 u16 acpi_ut_get_resource_length(void *aml)
755 {
756         acpi_rs_length resource_length;
757
758         ACPI_FUNCTION_ENTRY();
759
760         /*
761          * Byte 0 contains the descriptor name (Resource Type)
762          * Examine the large/small bit in the resource header
763          */
764         if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
765
766                 /* Large Resource type -- bytes 1-2 contain the 16-bit length */
767
768                 ACPI_MOVE_16_TO_16(&resource_length, ACPI_ADD_PTR(u8, aml, 1));
769
770         } else {
771                 /* Small Resource type -- bits 2:0 of byte 0 contain the length */
772
773                 resource_length = (u16) (ACPI_GET8(aml) &
774                                          ACPI_RESOURCE_NAME_SMALL_LENGTH_MASK);
775         }
776
777         return (resource_length);
778 }
779
780 /*******************************************************************************
781  *
782  * FUNCTION:    acpi_ut_get_resource_header_length
783  *
784  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
785  *
786  * RETURN:      Length of the AML header (depends on large/small descriptor)
787  *
788  * DESCRIPTION: Get the length of the header for this resource.
789  *
790  ******************************************************************************/
791
792 u8 acpi_ut_get_resource_header_length(void *aml)
793 {
794         ACPI_FUNCTION_ENTRY();
795
796         /* Examine the large/small bit in the resource header */
797
798         if (ACPI_GET8(aml) & ACPI_RESOURCE_NAME_LARGE) {
799                 return (sizeof(struct aml_resource_large_header));
800         } else {
801                 return (sizeof(struct aml_resource_small_header));
802         }
803 }
804
805 /*******************************************************************************
806  *
807  * FUNCTION:    acpi_ut_get_descriptor_length
808  *
809  * PARAMETERS:  aml             - Pointer to the raw AML resource descriptor
810  *
811  * RETURN:      Byte length
812  *
813  * DESCRIPTION: Get the total byte length of a raw AML descriptor, including the
814  *              length of the descriptor header and the length field itself.
815  *              Used to walk descriptor lists.
816  *
817  ******************************************************************************/
818
819 u32 acpi_ut_get_descriptor_length(void *aml)
820 {
821         ACPI_FUNCTION_ENTRY();
822
823         /*
824          * Get the Resource Length (does not include header length) and add
825          * the header length (depends on if this is a small or large resource)
826          */
827         return (acpi_ut_get_resource_length(aml) +
828                 acpi_ut_get_resource_header_length(aml));
829 }
830
831 /*******************************************************************************
832  *
833  * FUNCTION:    acpi_ut_get_resource_end_tag
834  *
835  * PARAMETERS:  obj_desc        - The resource template buffer object
836  *              end_tag         - Where the pointer to the end_tag is returned
837  *
838  * RETURN:      Status, pointer to the end tag
839  *
840  * DESCRIPTION: Find the end_tag resource descriptor in an AML resource template
841  *              Note: allows a buffer length of zero.
842  *
843  ******************************************************************************/
844
845 acpi_status
846 acpi_ut_get_resource_end_tag(union acpi_operand_object *obj_desc, u8 **end_tag)
847 {
848         acpi_status status;
849
850         ACPI_FUNCTION_TRACE(ut_get_resource_end_tag);
851
852         /* Allow a buffer length of zero */
853
854         if (!obj_desc->buffer.length) {
855                 *end_tag = obj_desc->buffer.pointer;
856                 return_ACPI_STATUS(AE_OK);
857         }
858
859         /* Validate the template and get a pointer to the end_tag */
860
861         status = acpi_ut_walk_aml_resources(NULL, obj_desc->buffer.pointer,
862                                             obj_desc->buffer.length, NULL,
863                                             (void **)end_tag);
864
865         return_ACPI_STATUS(status);
866 }