diff options
Diffstat (limited to 'sys/contrib/dev/acpica/exfield.c')
-rw-r--r-- | sys/contrib/dev/acpica/exfield.c | 423 |
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); } + |