Print this page
acpica-unix2-20130823
PANKOVs restructure

@@ -3,11 +3,11 @@
  * Module Name: exfldio - Aml Field I/O
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:

@@ -96,10 +96,11 @@
     ACPI_OPERAND_OBJECT     *ObjDesc,
     UINT32                  FieldDatumByteOffset)
 {
     ACPI_STATUS             Status = AE_OK;
     ACPI_OPERAND_OBJECT     *RgnDesc;
+    UINT8                   SpaceId;
 
 
     ACPI_FUNCTION_TRACE_U32 (ExSetupRegion, FieldDatumByteOffset);
 
 

@@ -114,10 +115,20 @@
             AcpiUtGetObjectTypeName (RgnDesc)));
 
         return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
     }
 
+    SpaceId = RgnDesc->Region.SpaceId;
+
+    /* Validate the Space ID */
+
+    if (!AcpiIsValidSpaceId (SpaceId))
+    {
+        ACPI_ERROR ((AE_INFO, "Invalid/unknown Address Space ID: 0x%2.2X", SpaceId));
+        return_ACPI_STATUS (AE_AML_INVALID_SPACE_ID);
+    }
+
     /*
      * If the Region Address and Length have not been previously evaluated,
      * evaluate them now and save the results.
      */
     if (!(RgnDesc->Common.Flags & AOPOBJ_DATA_VALID))

@@ -128,15 +139,16 @@
             return_ACPI_STATUS (Status);
         }
     }
 
     /*
-     * Exit now for SMBus or IPMI address space, it has a non-linear
+     * Exit now for SMBus, GSBus or IPMI address space, it has a non-linear
      * address space and the request cannot be directly validated
      */
-    if (RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_SMBUS ||
-        RgnDesc->Region.SpaceId == ACPI_ADR_SPACE_IPMI)
+    if (SpaceId == ACPI_ADR_SPACE_SMBUS ||
+        SpaceId == ACPI_ADR_SPACE_GSBUS ||
+        SpaceId == ACPI_ADR_SPACE_IPMI)
     {
         /* SMBus or IPMI has a non-linear address space */
 
         return_ACPI_STATUS (AE_OK);
     }

@@ -288,11 +300,12 @@
         FieldDatumByteOffset,
         ACPI_CAST_PTR (void, (RgnDesc->Region.Address + RegionOffset))));
 
     /* Invoke the appropriate AddressSpace/OpRegion handler */
 
-    Status = AcpiEvAddressSpaceDispatch (RgnDesc, Function, RegionOffset,
+    Status = AcpiEvAddressSpaceDispatch (RgnDesc, ObjDesc,
+                Function, RegionOffset,
                 ACPI_MUL_8 (ObjDesc->CommonField.AccessByteWidth), Value);
 
     if (ACPI_FAILURE (Status))
     {
         if (Status == AE_NOT_IMPLEMENTED)

@@ -351,10 +364,15 @@
     {
         /*
          * The Value is larger than the maximum value that can fit into
          * the register.
          */
+        ACPI_ERROR ((AE_INFO,
+            "Index value 0x%8.8X%8.8X overflows field width 0x%X",
+            ACPI_FORMAT_UINT64 (Value),
+            ObjDesc->CommonField.BitLength));
+
         return (TRUE);
     }
 
     /* The Value will fit into the field with no truncation */
 

@@ -460,13 +478,11 @@
         }
 
         Status = AE_OK;
         break;
 
-
     case ACPI_TYPE_LOCAL_BANK_FIELD:
-
         /*
          * Ensure that the BankValue is not beyond the capacity of
          * the register
          */
         if (AcpiExRegisterOverflow (ObjDesc->BankField.BankObj,

@@ -492,24 +508,20 @@
          * RegionField case and write the datum to the Operation Region
          */
 
         /*lint -fallthrough */
 
-
     case ACPI_TYPE_LOCAL_REGION_FIELD:
         /*
          * For simple RegionFields, we just directly access the owning
          * Operation Region.
          */
         Status = AcpiExAccessRegion (ObjDesc, FieldDatumByteOffset, Value,
                     ReadWrite);
         break;
 
-
     case ACPI_TYPE_LOCAL_INDEX_FIELD:
-
-
         /*
          * Ensure that the IndexValue is not beyond the capacity of
          * the register
          */
         if (AcpiExRegisterOverflow (ObjDesc->IndexField.IndexObj,

@@ -555,11 +567,10 @@
             Status = AcpiExInsertIntoField (ObjDesc->IndexField.DataObj,
                         Value, sizeof (UINT64));
         }
         break;
 
-
     default:
 
         ACPI_ERROR ((AE_INFO, "Wrong object type in field I/O %u",
             ObjDesc->Common.Type));
         Status = AE_AML_INTERNAL;

@@ -746,11 +757,22 @@
     /* Handle the simple case here */
 
     if ((ObjDesc->CommonField.StartFieldBitOffset == 0) &&
         (ObjDesc->CommonField.BitLength == AccessBitWidth))
     {
+        if (BufferLength >= sizeof (UINT64))
+        {
         Status = AcpiExFieldDatumIo (ObjDesc, 0, Buffer, ACPI_READ);
+        }
+        else
+        {
+            /* Use RawDatum (UINT64) to handle buffers < 64 bits */
+
+            Status = AcpiExFieldDatumIo (ObjDesc, 0, &RawDatum, ACPI_READ);
+            ACPI_MEMCPY (Buffer, &RawDatum, BufferLength);
+        }
+
         return_ACPI_STATUS (Status);
     }
 
 /* TBD: Move to common setup code */
 

@@ -1031,7 +1053,5 @@
     {
         ACPI_FREE (NewBuffer);
     }
     return_ACPI_STATUS (Status);
 }
-
-