Revert "ARM: tegra: tegratab: dummy change"
[linux-2.6.git] / drivers / acpi / acpica / utresrc.c
index 91b7c00..9d441ea 100644 (file)
@@ -5,7 +5,7 @@
  ******************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2012, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "amlresrc.h"
+#include "acresrc.h"
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utresrc")
 #if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
 /*
  * Strings used to decode resource descriptors.
- * Used by both the disasssembler and the debugger resource dump routines
+ * Used by both the disassembler and the debugger resource dump routines
  */
 const char *acpi_gbl_bm_decode[] = {
        "NotBusMaster",
@@ -154,6 +154,138 @@ const char *acpi_gbl_typ_decode[] = {
        "TypeF"
 };
 
+const char *acpi_gbl_ppc_decode[] = {
+       "PullDefault",
+       "PullUp",
+       "PullDown",
+       "PullNone"
+};
+
+const char *acpi_gbl_ior_decode[] = {
+       "IoRestrictionNone",
+       "IoRestrictionInputOnly",
+       "IoRestrictionOutputOnly",
+       "IoRestrictionNoneAndPreserve"
+};
+
+const char *acpi_gbl_dts_decode[] = {
+       "Width8bit",
+       "Width16bit",
+       "Width32bit",
+       "Width64bit",
+       "Width128bit",
+       "Width256bit",
+};
+
+/* GPIO connection type */
+
+const char *acpi_gbl_ct_decode[] = {
+       "Interrupt",
+       "I/O"
+};
+
+/* Serial bus type */
+
+const char *acpi_gbl_sbt_decode[] = {
+       "/* UNKNOWN serial bus type */",
+       "I2C",
+       "SPI",
+       "UART"
+};
+
+/* I2C serial bus access mode */
+
+const char *acpi_gbl_am_decode[] = {
+       "AddressingMode7Bit",
+       "AddressingMode10Bit"
+};
+
+/* I2C serial bus slave mode */
+
+const char *acpi_gbl_sm_decode[] = {
+       "ControllerInitiated",
+       "DeviceInitiated"
+};
+
+/* SPI serial bus wire mode */
+
+const char *acpi_gbl_wm_decode[] = {
+       "FourWireMode",
+       "ThreeWireMode"
+};
+
+/* SPI serial clock phase */
+
+const char *acpi_gbl_cph_decode[] = {
+       "ClockPhaseFirst",
+       "ClockPhaseSecond"
+};
+
+/* SPI serial bus clock polarity */
+
+const char *acpi_gbl_cpo_decode[] = {
+       "ClockPolarityLow",
+       "ClockPolarityHigh"
+};
+
+/* SPI serial bus device polarity */
+
+const char *acpi_gbl_dp_decode[] = {
+       "PolarityLow",
+       "PolarityHigh"
+};
+
+/* UART serial bus endian */
+
+const char *acpi_gbl_ed_decode[] = {
+       "LittleEndian",
+       "BigEndian"
+};
+
+/* UART serial bus bits per byte */
+
+const char *acpi_gbl_bpb_decode[] = {
+       "DataBitsFive",
+       "DataBitsSix",
+       "DataBitsSeven",
+       "DataBitsEight",
+       "DataBitsNine",
+       "/* UNKNOWN Bits per byte */",
+       "/* UNKNOWN Bits per byte */",
+       "/* UNKNOWN Bits per byte */"
+};
+
+/* UART serial bus stop bits */
+
+const char *acpi_gbl_sb_decode[] = {
+       "StopBitsNone",
+       "StopBitsOne",
+       "StopBitsOnePlusHalf",
+       "StopBitsTwo"
+};
+
+/* UART serial bus flow control */
+
+const char *acpi_gbl_fc_decode[] = {
+       "FlowControlNone",
+       "FlowControlHardware",
+       "FlowControlXON",
+       "/* UNKNOWN flow control keyword */"
+};
+
+/* UART serial bus parity type */
+
+const char *acpi_gbl_pt_decode[] = {
+       "ParityTypeNone",
+       "ParityTypeEven",
+       "ParityTypeOdd",
+       "ParityTypeMark",
+       "ParityTypeSpace",
+       "/* UNKNOWN parity keyword */",
+       "/* UNKNOWN parity keyword */",
+       "/* UNKNOWN parity keyword */"
+};
+
 #endif
 
 /*
@@ -173,7 +305,7 @@ const u8 acpi_gbl_resource_aml_sizes[] = {
        ACPI_AML_SIZE_SMALL(struct aml_resource_end_dependent),
        ACPI_AML_SIZE_SMALL(struct aml_resource_io),
        ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_io),
-       0,
+       ACPI_AML_SIZE_SMALL(struct aml_resource_fixed_dma),
        0,
        0,
        0,
@@ -193,7 +325,17 @@ const u8 acpi_gbl_resource_aml_sizes[] = {
        ACPI_AML_SIZE_LARGE(struct aml_resource_address16),
        ACPI_AML_SIZE_LARGE(struct aml_resource_extended_irq),
        ACPI_AML_SIZE_LARGE(struct aml_resource_address64),
-       ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64)
+       ACPI_AML_SIZE_LARGE(struct aml_resource_extended_address64),
+       ACPI_AML_SIZE_LARGE(struct aml_resource_gpio),
+       0,
+       ACPI_AML_SIZE_LARGE(struct aml_resource_common_serialbus),
+};
+
+const u8 acpi_gbl_resource_aml_serial_bus_sizes[] = {
+       0,
+       ACPI_AML_SIZE_LARGE(struct aml_resource_i2c_serialbus),
+       ACPI_AML_SIZE_LARGE(struct aml_resource_spi_serialbus),
+       ACPI_AML_SIZE_LARGE(struct aml_resource_uart_serialbus),
 };
 
 /*
@@ -209,35 +351,49 @@ static const u8 acpi_gbl_resource_types[] = {
        0,
        0,
        0,
-       ACPI_SMALL_VARIABLE_LENGTH,
-       ACPI_FIXED_LENGTH,
-       ACPI_SMALL_VARIABLE_LENGTH,
-       ACPI_FIXED_LENGTH,
-       ACPI_FIXED_LENGTH,
-       ACPI_FIXED_LENGTH,
-       0,
+       ACPI_SMALL_VARIABLE_LENGTH,     /* 04 IRQ */
+       ACPI_FIXED_LENGTH,      /* 05 DMA */
+       ACPI_SMALL_VARIABLE_LENGTH,     /* 06 start_dependent_functions */
+       ACPI_FIXED_LENGTH,      /* 07 end_dependent_functions */
+       ACPI_FIXED_LENGTH,      /* 08 IO */
+       ACPI_FIXED_LENGTH,      /* 09 fixed_iO */
+       ACPI_FIXED_LENGTH,      /* 0_a fixed_dMA */
        0,
        0,
        0,
-       ACPI_VARIABLE_LENGTH,
-       ACPI_FIXED_LENGTH,
+       ACPI_VARIABLE_LENGTH,   /* 0_e vendor_short */
+       ACPI_FIXED_LENGTH,      /* 0_f end_tag */
 
        /* Large descriptors */
 
        0,
-       ACPI_FIXED_LENGTH,
-       ACPI_FIXED_LENGTH,
+       ACPI_FIXED_LENGTH,      /* 01 Memory24 */
+       ACPI_FIXED_LENGTH,      /* 02 generic_register */
        0,
-       ACPI_VARIABLE_LENGTH,
-       ACPI_FIXED_LENGTH,
-       ACPI_FIXED_LENGTH,
-       ACPI_VARIABLE_LENGTH,
-       ACPI_VARIABLE_LENGTH,
-       ACPI_VARIABLE_LENGTH,
-       ACPI_VARIABLE_LENGTH,
-       ACPI_FIXED_LENGTH
+       ACPI_VARIABLE_LENGTH,   /* 04 vendor_long */
+       ACPI_FIXED_LENGTH,      /* 05 Memory32 */
+       ACPI_FIXED_LENGTH,      /* 06 memory32_fixed */
+       ACPI_VARIABLE_LENGTH,   /* 07 Dword* address */
+       ACPI_VARIABLE_LENGTH,   /* 08 Word* address */
+       ACPI_VARIABLE_LENGTH,   /* 09 extended_iRQ */
+       ACPI_VARIABLE_LENGTH,   /* 0_a Qword* address */
+       ACPI_FIXED_LENGTH,      /* 0_b Extended* address */
+       ACPI_VARIABLE_LENGTH,   /* 0_c Gpio* */
+       0,
+       ACPI_VARIABLE_LENGTH    /* 0_e *serial_bus */
 };
 
+/*
+ * For the i_aSL compiler/disassembler, we don't want any error messages
+ * because the disassembler uses the resource validation code to determine
+ * if Buffer objects are actually Resource Templates.
+ */
+#ifdef ACPI_ASL_COMPILER
+#define ACPI_RESOURCE_ERROR(plist)
+#else
+#define ACPI_RESOURCE_ERROR(plist)  ACPI_ERROR(plist)
+#endif
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ut_walk_aml_resources
@@ -265,6 +421,7 @@ acpi_ut_walk_aml_resources(u8 * aml,
        u8 resource_index;
        u32 length;
        u32 offset = 0;
+       u8 end_tag[2] = { 0x79, 0x00 };
 
        ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
 
@@ -286,6 +443,10 @@ acpi_ut_walk_aml_resources(u8 * aml,
 
                status = acpi_ut_validate_resource(aml, &resource_index);
                if (ACPI_FAILURE(status)) {
+                       /*
+                        * Exit on failure. Cannot continue because the descriptor length
+                        * may be bogus also.
+                        */
                        return_ACPI_STATUS(status);
                }
 
@@ -300,7 +461,7 @@ acpi_ut_walk_aml_resources(u8 * aml,
                            user_function(aml, length, offset, resource_index,
                                          context);
                        if (ACPI_FAILURE(status)) {
-                               return (status);
+                               return_ACPI_STATUS(status);
                        }
                }
 
@@ -333,7 +494,19 @@ acpi_ut_walk_aml_resources(u8 * aml,
 
        /* Did not find an end_tag descriptor */
 
-       return (AE_AML_NO_RESOURCE_END_TAG);
+       if (user_function) {
+
+               /* Insert an end_tag anyway. acpi_rs_get_list_length always leaves room */
+
+               (void)acpi_ut_validate_resource(end_tag, &resource_index);
+               status =
+                   user_function(end_tag, 2, offset, resource_index, context);
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
+       }
+
+       return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
 }
 
 /*******************************************************************************
@@ -354,6 +527,7 @@ acpi_ut_walk_aml_resources(u8 * aml,
 
 acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
 {
+       union aml_resource *aml_resource;
        u8 resource_type;
        u8 resource_index;
        acpi_rs_length resource_length;
@@ -375,7 +549,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
                /* Verify the large resource type (name) against the max */
 
                if (resource_type > ACPI_RESOURCE_NAME_LARGE_MAX) {
-                       return (AE_AML_INVALID_RESOURCE_TYPE);
+                       goto invalid_resource;
                }
 
                /*
@@ -392,15 +566,17 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
                    ((resource_type & ACPI_RESOURCE_NAME_SMALL_MASK) >> 3);
        }
 
-       /* Check validity of the resource type, zero indicates name is invalid */
-
+       /*
+        * Check validity of the resource type, via acpi_gbl_resource_types. Zero
+        * indicates an invalid resource.
+        */
        if (!acpi_gbl_resource_types[resource_index]) {
-               return (AE_AML_INVALID_RESOURCE_TYPE);
+               goto invalid_resource;
        }
 
        /*
-        * 2) Validate the resource_length field. This ensures that the length
-        *    is at least reasonable, and guarantees that it is non-zero.
+        * Validate the resource_length field. This ensures that the length
+        * is at least reasonable, and guarantees that it is non-zero.
         */
        resource_length = acpi_ut_get_resource_length(aml);
        minimum_resource_length = acpi_gbl_resource_aml_sizes[resource_index];
@@ -413,7 +589,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
                /* Fixed length resource, length must match exactly */
 
                if (resource_length != minimum_resource_length) {
-                       return (AE_AML_BAD_RESOURCE_LENGTH);
+                       goto bad_resource_length;
                }
                break;
 
@@ -422,7 +598,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
                /* Variable length resource, length must be at least the minimum */
 
                if (resource_length < minimum_resource_length) {
-                       return (AE_AML_BAD_RESOURCE_LENGTH);
+                       goto bad_resource_length;
                }
                break;
 
@@ -432,7 +608,7 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
 
                if ((resource_length > minimum_resource_length) ||
                    (resource_length < (minimum_resource_length - 1))) {
-                       return (AE_AML_BAD_RESOURCE_LENGTH);
+                       goto bad_resource_length;
                }
                break;
 
@@ -440,7 +616,23 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
 
                /* Shouldn't happen (because of validation earlier), but be sure */
 
-               return (AE_AML_INVALID_RESOURCE_TYPE);
+               goto invalid_resource;
+       }
+
+       aml_resource = ACPI_CAST_PTR(union aml_resource, aml);
+       if (resource_type == ACPI_RESOURCE_NAME_SERIAL_BUS) {
+
+               /* Validate the bus_type field */
+
+               if ((aml_resource->common_serial_bus.type == 0) ||
+                   (aml_resource->common_serial_bus.type >
+                    AML_RESOURCE_MAX_SERIALBUSTYPE)) {
+                       ACPI_RESOURCE_ERROR((AE_INFO,
+                                            "Invalid/unsupported SerialBus resource descriptor: BusType 0x%2.2X",
+                                            aml_resource->common_serial_bus.
+                                            type));
+                       return (AE_AML_INVALID_RESOURCE_TYPE);
+               }
        }
 
        /* Optionally return the resource table index */
@@ -450,6 +642,22 @@ acpi_status acpi_ut_validate_resource(void *aml, u8 * return_index)
        }
 
        return (AE_OK);
+
+      invalid_resource:
+
+       ACPI_RESOURCE_ERROR((AE_INFO,
+                            "Invalid/unsupported resource descriptor: Type 0x%2.2X",
+                            resource_type));
+       return (AE_AML_INVALID_RESOURCE_TYPE);
+
+      bad_resource_length:
+
+       ACPI_RESOURCE_ERROR((AE_INFO,
+                            "Invalid resource descriptor length: Type "
+                            "0x%2.2X, Length 0x%4.4X, MinLength 0x%4.4X",
+                            resource_type, resource_length,
+                            minimum_resource_length));
+       return (AE_AML_BAD_RESOURCE_LENGTH);
 }
 
 /*******************************************************************************