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);
}
-
-