summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/exfield.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/exfield.c')
-rw-r--r--sys/contrib/dev/acpica/exfield.c423
1 files changed, 95 insertions, 328 deletions
diff --git a/sys/contrib/dev/acpica/exfield.c b/sys/contrib/dev/acpica/exfield.c
index 49f3062..d6a75a5 100644
--- a/sys/contrib/dev/acpica/exfield.c
+++ b/sys/contrib/dev/acpica/exfield.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: exfield - ACPI AML (p-code) execution - field manipulation
- * $Revision: 95 $
+ * $Revision: 101 $
*
*****************************************************************************/
@@ -134,14 +134,13 @@
*
* FUNCTION: AcpiExReadDataFromField
*
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Number of bytes to transfer
+ * PARAMETERS: ObjDesc - The named field
+ * RetBufferDesc - Where the return data object is stored
*
- * RETURN: Status3
+ * RETURN: Status
*
- * DESCRIPTION: Read or write a named field
+ * DESCRIPTION: Read from a named field. Returns either an Integer or a
+ * Buffer, depending on the size of the field.
*
******************************************************************************/
@@ -154,6 +153,7 @@ AcpiExReadDataFromField (
ACPI_OPERAND_OBJECT *BufferDesc;
UINT32 Length;
void *Buffer;
+ BOOLEAN Locked;
FUNCTION_TRACE_PTR ("ExReadDataFromField", ObjDesc);
@@ -166,6 +166,22 @@ AcpiExReadDataFromField (
return_ACPI_STATUS (AE_AML_NO_OPERAND);
}
+ if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
+ {
+ /*
+ * If the BufferField arguments have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetBufferFieldArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
+
/*
* Allocate a buffer for the contents of the field.
*
@@ -200,7 +216,6 @@ AcpiExReadDataFromField (
BufferDesc->Buffer.Length = Length;
Buffer = BufferDesc->Buffer.Pointer;
}
-
else
{
/* Field will fit within an Integer (normal case) */
@@ -215,37 +230,30 @@ AcpiExReadDataFromField (
Buffer = &BufferDesc->Integer.Value;
}
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Obj=%p Type=%X Buf=%p Len=%X\n",
+ ObjDesc, ObjDesc->Common.Type, Buffer, Length));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "FieldWrite: BitLen=%X BitOff=%X ByteOff=%X\n",
+ ObjDesc->CommonField.BitLength,
+ ObjDesc->CommonField.StartFieldBitOffset,
+ ObjDesc->CommonField.BaseByteOffset));
- /* Read from the appropriate field */
-
- switch (ObjDesc->Common.Type)
- {
- case ACPI_TYPE_BUFFER_FIELD:
- Status = AcpiExAccessBufferField (ACPI_READ, ObjDesc, Buffer, Length);
- break;
-
- case INTERNAL_TYPE_REGION_FIELD:
- Status = AcpiExAccessRegionField (ACPI_READ, ObjDesc, Buffer, Length);
- break;
-
- case INTERNAL_TYPE_BANK_FIELD:
- Status = AcpiExAccessBankField (ACPI_READ, ObjDesc, Buffer, Length);
- break;
+ Locked = AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
- case INTERNAL_TYPE_INDEX_FIELD:
- Status = AcpiExAccessIndexField (ACPI_READ, ObjDesc, Buffer, Length);
- break;
+ /* Read from the field */
- default:
- Status = AE_AML_INTERNAL;
- }
+ Status = AcpiExExtractFromField (ObjDesc, Buffer, Length);
+ /*
+ * Release global lock if we acquired it earlier
+ */
+ AcpiExReleaseGlobalLock (Locked);
if (ACPI_FAILURE (Status))
{
AcpiUtRemoveReference (BufferDesc);
}
-
else if (RetBufferDesc)
{
*RetBufferDesc = BufferDesc;
@@ -259,18 +267,15 @@ AcpiExReadDataFromField (
*
* FUNCTION: AcpiExWriteDataToField
*
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Number of bytes to transfer
+ * PARAMETERS: SourceDesc - Contains data to write
+ * ObjDesc - The named field
*
* RETURN: Status
*
- * DESCRIPTION: Read or write a named field
+ * DESCRIPTION: Write to a named field
*
******************************************************************************/
-
ACPI_STATUS
AcpiExWriteDataToField (
ACPI_OPERAND_OBJECT *SourceDesc,
@@ -278,7 +283,10 @@ AcpiExWriteDataToField (
{
ACPI_STATUS Status;
UINT32 Length;
+ UINT32 RequiredLength;
void *Buffer;
+ void *NewBuffer;
+ BOOLEAN Locked;
FUNCTION_TRACE_PTR ("ExWriteDataToField", ObjDesc);
@@ -291,6 +299,21 @@ AcpiExWriteDataToField (
return_ACPI_STATUS (AE_AML_NO_OPERAND);
}
+ if (ObjDesc->Common.Type == ACPI_TYPE_BUFFER_FIELD)
+ {
+ /*
+ * If the BufferField arguments have not been previously evaluated,
+ * evaluate them now and save the results.
+ */
+ if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ {
+ Status = AcpiDsGetBufferFieldArguments (ObjDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+ }
/*
* Get a pointer to the data to be written
@@ -314,323 +337,67 @@ AcpiExWriteDataToField (
default:
return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
- }
-
-
- /*
- * Decode the type of field to be written
- */
- switch (ObjDesc->Common.Type)
- {
- case ACPI_TYPE_BUFFER_FIELD:
- Status = AcpiExAccessBufferField (ACPI_WRITE, ObjDesc, Buffer, Length);
- break;
-
- case INTERNAL_TYPE_REGION_FIELD:
- Status = AcpiExAccessRegionField (ACPI_WRITE, ObjDesc, Buffer, Length);
- break;
-
- case INTERNAL_TYPE_BANK_FIELD:
- Status = AcpiExAccessBankField (ACPI_WRITE, ObjDesc, Buffer, Length);
break;
-
- case INTERNAL_TYPE_INDEX_FIELD:
- Status = AcpiExAccessIndexField (ACPI_WRITE, ObjDesc, Buffer, Length);
- break;
-
- default:
- return_ACPI_STATUS (AE_AML_INTERNAL);
}
-
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiExAccessBufferField
- *
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Number of bytes to transfer
- *
- * RETURN: Status
- *
- * DESCRIPTION: Read or write a named field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExAccessBufferField (
- UINT32 Mode,
- ACPI_OPERAND_OBJECT *ObjDesc,
- void *Buffer,
- UINT32 BufferLength)
-{
- ACPI_STATUS Status;
-
-
- FUNCTION_TRACE_PTR ("ExAccessBufferField", ObjDesc);
-
-
/*
- * If the BufferField arguments have not been previously evaluated,
- * evaluate them now and save the results.
+ * We must have a buffer that is at least as long as the field
+ * we are writing to. This is because individual fields are
+ * indivisible and partial writes are not supported -- as per
+ * the ACPI specification.
*/
- if (!(ObjDesc->Common.Flags & AOPOBJ_DATA_VALID))
+ NewBuffer = NULL;
+ RequiredLength = ROUND_BITS_UP_TO_BYTES (ObjDesc->CommonField.BitLength);
+
+ if (Length < RequiredLength)
{
- Status = AcpiDsGetBufferFieldArguments (ObjDesc);
- if (ACPI_FAILURE (Status))
+ /* We need to create a new buffer */
+
+ NewBuffer = ACPI_MEM_CALLOCATE (RequiredLength);
+ if (!NewBuffer)
{
- return_ACPI_STATUS (Status);
+ return_ACPI_STATUS (AE_NO_MEMORY);
}
- }
-
- Status = AcpiExCommonAccessField (Mode, ObjDesc, Buffer, BufferLength);
-
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiExAccessRegionField
- *
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Number of bytes to transfer
- *
- * RETURN: Status
- *
- * DESCRIPTION: Read or write a named field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExAccessRegionField (
- UINT32 Mode,
- ACPI_OPERAND_OBJECT *ObjDesc,
- void *Buffer,
- UINT32 BufferLength)
-{
- ACPI_STATUS Status;
- BOOLEAN Locked;
-
-
- FUNCTION_TRACE_PTR ("ExAccessRegionField", ObjDesc);
-
-
- /*
- * Get the global lock if needed
- */
- Locked = AcpiExAcquireGlobalLock (ObjDesc->Field.LockRule);
-
- Status = AcpiExCommonAccessField (Mode, ObjDesc, Buffer, BufferLength);
-
-
- /*
- * Release global lock if we acquired it earlier
- */
- AcpiExReleaseGlobalLock (Locked);
-
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiExAccessBankField
- *
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Number of bytes to transfer
- *
- * RETURN: Status
- *
- * DESCRIPTION: Read or write a Bank Field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExAccessBankField (
- UINT32 Mode,
- ACPI_OPERAND_OBJECT *ObjDesc,
- void *Buffer,
- UINT32 BufferLength)
-{
- ACPI_STATUS Status;
- BOOLEAN Locked;
-
-
- FUNCTION_TRACE_PTR ("ExAccessBankField", ObjDesc);
-
-
- /*
- * Get the global lock if needed
- */
- Locked = AcpiExAcquireGlobalLock (ObjDesc->BankField.LockRule);
-
-
- /*
- * Write the BankValue to the BankRegister to select the bank.
- * The BankValue for this BankField is specified in the
- * BankField ASL declaration. The BankRegister is always a Field in
- * an operation region.
- */
- Status = AcpiExCommonAccessField (ACPI_WRITE,
- ObjDesc->BankField.BankRegisterObj,
- &ObjDesc->BankField.Value,
- sizeof (ObjDesc->BankField.Value));
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
+ /*
+ * Copy the original data to the new buffer, starting
+ * at Byte zero. All unused (upper) bytes of the
+ * buffer will be 0.
+ */
+ MEMCPY ((char *) NewBuffer, (char *) Buffer, Length);
+ Buffer = NewBuffer;
+ Length = RequiredLength;
}
- /*
- * The bank was successfully selected, now read or write the actual
- * data.
- */
- Status = AcpiExCommonAccessField (Mode, ObjDesc, Buffer, BufferLength);
-
-
-Cleanup:
- /*
- * Release global lock if we acquired it earlier
- */
- AcpiExReleaseGlobalLock (Locked);
-
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiExAccessIndexField
- *
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Number of bytes to transfer
- *
- * RETURN: Status
- *
- * DESCRIPTION: Read or write a Index Field
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiExAccessIndexField (
- UINT32 Mode,
- ACPI_OPERAND_OBJECT *ObjDesc,
- void *Buffer,
- UINT32 BufferLength)
-{
- ACPI_STATUS Status;
- BOOLEAN Locked;
-
-
- FUNCTION_TRACE_PTR ("ExAccessIndexField", ObjDesc);
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Obj=%p Type=%X Buf=%p Len=%X\n",
+ ObjDesc, ObjDesc->Common.Type, Buffer, Length));
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "FieldRead: BitLen=%X BitOff=%X ByteOff=%X\n",
+ ObjDesc->CommonField.BitLength,
+ ObjDesc->CommonField.StartFieldBitOffset,
+ ObjDesc->CommonField.BaseByteOffset));
+ Locked = AcpiExAcquireGlobalLock (ObjDesc->CommonField.FieldFlags);
/*
- * Get the global lock if needed
+ * Write to the field
*/
- Locked = AcpiExAcquireGlobalLock (ObjDesc->IndexField.LockRule);
-
+ Status = AcpiExInsertIntoField (ObjDesc, Buffer, Length);
/*
- * Set Index value to select proper Data register
- */
- Status = AcpiExCommonAccessField (ACPI_WRITE,
- ObjDesc->IndexField.IndexObj,
- &ObjDesc->IndexField.Value,
- sizeof (ObjDesc->IndexField.Value));
- if (ACPI_FAILURE (Status))
- {
- goto Cleanup;
- }
-
- /* Now read/write the data register */
-
- Status = AcpiExCommonAccessField (Mode, ObjDesc->IndexField.DataObj,
- Buffer, BufferLength);
-
-Cleanup:
- /*
* Release global lock if we acquired it earlier
*/
AcpiExReleaseGlobalLock (Locked);
- return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiExCommonAccessField
- *
- * PARAMETERS: Mode - ACPI_READ or ACPI_WRITE
- * *FieldNode - Parent node for field to be accessed
- * *Buffer - Value(s) to be read or written
- * BufferLength - Size of buffer, in bytes. Must be large
- * enough for all bits of the field.
- *
- * RETURN: Status
- *
- * DESCRIPTION: Read or write a named field
- *
- ******************************************************************************/
+ /* Free temporary buffer if we used one */
-ACPI_STATUS
-AcpiExCommonAccessField (
- UINT32 Mode,
- ACPI_OPERAND_OBJECT *ObjDesc,
- void *Buffer,
- UINT32 BufferLength)
-{
- ACPI_STATUS Status;
-
-
- FUNCTION_TRACE_PTR ("ExCommonAccessField", ObjDesc);
-
-
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Obj=%p Type=%X Buf=%p Len=%X\n",
- ObjDesc, ObjDesc->Common.Type, Buffer, BufferLength));
- ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode=%d BitLen=%X BitOff=%X ByteOff=%X\n",
- Mode, ObjDesc->CommonField.BitLength,
- ObjDesc->CommonField.StartFieldBitOffset,
- ObjDesc->CommonField.BaseByteOffset));
-
-
- /* Perform the actual read or write of the field */
-
- switch (Mode)
+ if (NewBuffer)
{
- case ACPI_READ:
-
- Status = AcpiExExtractFromField (ObjDesc, Buffer, BufferLength);
- break;
-
-
- case ACPI_WRITE:
-
- Status = AcpiExInsertIntoField (ObjDesc, Buffer, BufferLength);
- break;
-
-
- default:
-
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown I/O Mode: %X\n", Mode));
- Status = AE_BAD_PARAMETER;
- break;
+ ACPI_MEM_FREE (NewBuffer);
}
-
return_ACPI_STATUS (Status);
}
+
OpenPOWER on IntegriCloud