ACPICA: Fix for resource descriptor optimization issues for _CRS/_SRC
authorBob Moore <robert.moore@intel.com>
Thu, 10 Apr 2008 15:06:43 +0000 (19:06 +0400)
committerLen Brown <len.brown@intel.com>
Tue, 22 Apr 2008 18:29:31 +0000 (14:29 -0400)
Fixed a problem where resource descriptor size optimization
could cause a problem when a _CRS resource template is passed
to a _SRS method. The _SRS resource template must use the same
descriptors (with the same size) as returned from _CRS. This
change affects the following resource descriptors: IRQ/IRQNoFlags
and StartDependendentFn/StartDependentFnNoPri.

http://bugzilla.kernel.org/show_bug.cgi?id=9487

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/resources/rscalc.c
drivers/acpi/resources/rsdump.c
drivers/acpi/resources/rsio.c
drivers/acpi/resources/rsirq.c
drivers/acpi/resources/rsmisc.c
include/acpi/acresrc.h
include/acpi/actypes.h

index dcc51e92ac92c418f66d8a31e0a8d6da211d1edc..db0a835e3317ec1b408e78203146400d718e36e3 100644 (file)
@@ -211,6 +211,13 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
                 * variable-length fields
                 */
                switch (resource->type) {
+               case ACPI_RESOURCE_TYPE_IRQ:
+
+                       if (resource->data.irq.descriptor_length == 2) {
+                               total_size--;
+                       }
+                       break;
+
                case ACPI_RESOURCE_TYPE_VENDOR:
                        /*
                         * Vendor Defined Resource:
index 46da116a4030eacb57756273641f4395b3f002b7..ed6447dcea78dcde44cb7881b3308723ddce8569 100644 (file)
@@ -87,8 +87,10 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table);
  *
  ******************************************************************************/
 
-struct acpi_rsdump_info acpi_rs_dump_irq[6] = {
+struct acpi_rsdump_info acpi_rs_dump_irq[7] = {
        {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length),
+        "Descriptor Length", NULL},
        {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering",
         acpi_gbl_he_decode},
        {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity",
@@ -115,9 +117,11 @@ struct acpi_rsdump_info acpi_rs_dump_dma[6] = {
         NULL}
 };
 
-struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = {
+struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = {
        {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf),
         "Start-Dependent-Functions", NULL},
+       {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length),
+        "Descriptor Length", NULL},
        {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority),
         "Compatibility Priority", acpi_gbl_config_decode},
        {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness),
index b297bc3e441942b4b993faca1e0133b846e85e83..50f3acdd9c8e0c1b93833b9fd8109c4826e96ee6 100644 (file)
@@ -185,7 +185,7 @@ struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = {
  *
  ******************************************************************************/
 
-struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = {
+struct acpi_rsconvert_info acpi_rs_get_start_dpf[6] = {
        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT,
         ACPI_RS_SIZE(struct acpi_resource_start_dependent),
         ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)},
@@ -196,6 +196,12 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = {
         ACPI_ACCEPTABLE_CONFIGURATION,
         2},
 
+       /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */
+
+       {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
+        AML_OFFSET(start_dpf.descriptor_type),
+        0},
+
        /* All done if there is no flag byte present in the descriptor */
 
        {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1},
@@ -219,7 +225,9 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = {
  *
  ******************************************************************************/
 
-struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = {
+struct acpi_rsconvert_info acpi_rs_set_start_dpf[10] = {
+       /* Start with a default descriptor of length 1 */
+
        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT,
         sizeof(struct aml_resource_start_dependent),
         ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)},
@@ -235,6 +243,33 @@ struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = {
         ACPI_RS_OFFSET(data.start_dpf.performance_robustness),
         AML_OFFSET(start_dpf.flags),
         2},
+       /*
+        * All done if the output descriptor length is required to be 1
+        * (i.e., optimization to 0 bytes cannot be attempted)
+        */
+       {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+        ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
+        1},
+
+       /* Set length to 0 bytes (no flags byte) */
+
+       {ACPI_RSC_LENGTH, 0, 0,
+        sizeof(struct aml_resource_start_dependent_noprio)},
+
+       /*
+        * All done if the output descriptor length is required to be 0.
+        *
+        * TBD: Perhaps we should check for error if input flags are not
+        * compatible with a 0-byte descriptor.
+        */
+       {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+        ACPI_RS_OFFSET(data.start_dpf.descriptor_length),
+        0},
+
+       /* Reset length to 1 byte (descriptor with flags byte) */
+
+       {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)},
+
        /*
         * All done if flags byte is necessary -- if either priority value
         * is not ACPI_ACCEPTABLE_CONFIGURATION
index 5657f7b950399f619023edced4baec792876bc74..382a77b8400d4c01459bab78b22f1561a48d70d2 100644 (file)
@@ -52,7 +52,7 @@ ACPI_MODULE_NAME("rsirq")
  * acpi_rs_get_irq
  *
  ******************************************************************************/
-struct acpi_rsconvert_info acpi_rs_get_irq[7] = {
+struct acpi_rsconvert_info acpi_rs_get_irq[8] = {
        {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ,
         ACPI_RS_SIZE(struct acpi_resource_irq),
         ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)},
@@ -69,6 +69,12 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = {
         ACPI_EDGE_SENSITIVE,
         1},
 
+       /* Get the descriptor length (2 or 3 for IRQ descriptor) */
+
+       {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length),
+        AML_OFFSET(irq.descriptor_type),
+        0},
+
        /* All done if no flag byte present in descriptor */
 
        {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3},
@@ -94,7 +100,9 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = {
  *
  ******************************************************************************/
 
-struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
+struct acpi_rsconvert_info acpi_rs_set_irq[13] = {
+       /* Start with a default descriptor of length 3 */
+
        {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ,
         sizeof(struct aml_resource_irq),
         ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)},
@@ -105,7 +113,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
         AML_OFFSET(irq.irq_mask),
         ACPI_RS_OFFSET(data.irq.interrupt_count)},
 
-       /* Set the flags byte by default */
+       /* Set the flags byte */
 
        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering),
         AML_OFFSET(irq.flags),
@@ -118,6 +126,33 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
        {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable),
         AML_OFFSET(irq.flags),
         4},
+
+       /*
+        * All done if the output descriptor length is required to be 3
+        * (i.e., optimization to 2 bytes cannot be attempted)
+        */
+       {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+        ACPI_RS_OFFSET(data.irq.descriptor_length),
+        3},
+
+       /* Set length to 2 bytes (no flags byte) */
+
+       {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)},
+
+       /*
+        * All done if the output descriptor length is required to be 2.
+        *
+        * TBD: Perhaps we should check for error if input flags are not
+        * compatible with a 2-byte descriptor.
+        */
+       {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE,
+        ACPI_RS_OFFSET(data.irq.descriptor_length),
+        2},
+
+       /* Reset length to 3 bytes (descriptor with flags byte) */
+
+       {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)},
+
        /*
         * Check if the flags byte is necessary. Not needed if the flags are:
         * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE
@@ -134,7 +169,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = {
         ACPI_RS_OFFSET(data.irq.sharable),
         ACPI_EXCLUSIVE},
 
-       /* irq_no_flags() descriptor can be used */
+       /* We can optimize to a 2-byte irq_no_flags() descriptor */
 
        {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}
 };
index c7081afa893aeb22529ee2a8ea89bc39261b7eb9..3e69eff303fb561f2e8836358a12e0b2406bc6c7 100644 (file)
@@ -497,6 +497,17 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource,
                        }
                        break;
 
+               case ACPI_RSC_EXIT_EQ:
+                       /*
+                        * Control - Exit conversion if equal
+                        */
+                       if (*ACPI_ADD_PTR(u8, resource,
+                                         COMPARE_TARGET(info)) ==
+                           COMPARE_VALUE(info)) {
+                               goto exit;
+                       }
+                       break;
+
                default:
 
                        ACPI_ERROR((AE_INFO, "Invalid conversion opcode"));
index 9486ab266a5e24b898e427d90f289b2988595b87..33e9f3813220fed61bfce91c8c95b224c29cfa30 100644 (file)
@@ -94,6 +94,7 @@ typedef const struct acpi_rsconvert_info {
 #define ACPI_RSC_BITMASK16              18
 #define ACPI_RSC_EXIT_NE                19
 #define ACPI_RSC_EXIT_LE                20
+#define ACPI_RSC_EXIT_EQ                21
 
 /* Resource Conversion sub-opcodes */
 
index bb44700680a34354ac41c3c3dd8dd26a9a02f4bf..599657eac2d46566bf275a74d15647565cc49640 100644 (file)
@@ -986,6 +986,7 @@ struct acpi_vendor_uuid {
  *  Structures used to describe device resources
  */
 struct acpi_resource_irq {
+       u8 descriptor_length;
        u8 triggering;
        u8 polarity;
        u8 sharable;
@@ -1002,6 +1003,7 @@ struct acpi_resource_dma {
 };
 
 struct acpi_resource_start_dependent {
+       u8 descriptor_length;
        u8 compatibility_priority;
        u8 performance_robustness;
 };