diff options
Diffstat (limited to 'source/components/tables/tbxface.c')
-rw-r--r-- | source/components/tables/tbxface.c | 133 |
1 files changed, 105 insertions, 28 deletions
diff --git a/source/components/tables/tbxface.c b/source/components/tables/tbxface.c index 4c8c065cf3730..9346933cf5274 100644 --- a/source/components/tables/tbxface.c +++ b/source/components/tables/tbxface.c @@ -184,6 +184,7 @@ AcpiReallocateRootTable ( void) { ACPI_STATUS Status; + UINT32 i; ACPI_FUNCTION_TRACE (AcpiReallocateRootTable); @@ -198,6 +199,22 @@ AcpiReallocateRootTable ( return_ACPI_STATUS (AE_SUPPORT); } + /* + * Ensure OS early boot logic, which is required by some hosts. If the + * table state is reported to be wrong, developers should fix the + * issue by invoking AcpiPutTable() for the reported table during the + * early stage. + */ + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) + { + if (AcpiGbl_RootTableList.Tables[i].Pointer) + { + ACPI_ERROR ((AE_INFO, + "Table [%4.4s] is not invalidated during early boot stage", + AcpiGbl_RootTableList.Tables[i].Signature.Ascii)); + } + } + AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE; Status = AcpiTbResizeRootTableList (); @@ -307,6 +324,11 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableHeader) * * DESCRIPTION: Finds and verifies an ACPI table. Table must be in the * RSDT/XSDT. + * Note that an early stage AcpiGetTable() call must be paired + * with an early stage AcpiPutTable() call. otherwise the table + * pointer mapped by the early stage mapping implementation may be + * erroneously unmapped by the late stage unmapping implementation + * in an AcpiPutTable() invoked during the late stage. * ******************************************************************************/ @@ -318,7 +340,8 @@ AcpiGetTable ( { UINT32 i; UINT32 j; - ACPI_STATUS Status; + ACPI_STATUS Status = AE_NOT_FOUND; + ACPI_TABLE_DESC *TableDesc; /* Parameter validation */ @@ -328,12 +351,22 @@ AcpiGetTable ( return (AE_BAD_PARAMETER); } + /* + * Note that the following line is required by some OSPMs, they only + * check if the returned table is NULL instead of the returned status + * to determined if this function is succeeded. + */ + *OutTable = NULL; + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + /* Walk the root table list */ for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) { - if (!ACPI_COMPARE_NAME ( - &(AcpiGbl_RootTableList.Tables[i].Signature), Signature)) + TableDesc = &AcpiGbl_RootTableList.Tables[i]; + + if (!ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) { continue; } @@ -343,19 +376,66 @@ AcpiGetTable ( continue; } - Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); - if (ACPI_SUCCESS (Status)) + Status = AcpiTbGetTable (TableDesc, OutTable); + break; + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return (Status); +} + +ACPI_EXPORT_SYMBOL (AcpiGetTable) + + +/******************************************************************************* + * + * FUNCTION: AcpiPutTable + * + * PARAMETERS: Table - The pointer to the table + * + * RETURN: None + * + * DESCRIPTION: Release a table returned by AcpiGetTable() and its clones. + * Note that it is not safe if this function was invoked after an + * uninstallation happened to the original table descriptor. + * Currently there is no OSPMs' requirement to handle such + * situations. + * + ******************************************************************************/ + +void +AcpiPutTable ( + ACPI_TABLE_HEADER *Table) +{ + UINT32 i; + ACPI_TABLE_DESC *TableDesc; + + + ACPI_FUNCTION_TRACE (AcpiPutTable); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + /* Walk the root table list */ + + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) + { + TableDesc = &AcpiGbl_RootTableList.Tables[i]; + + if (TableDesc->Pointer != Table) { - *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; + continue; } - return (Status); + AcpiTbPutTable (TableDesc); + break; } - return (AE_NOT_FOUND); + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_VOID; } -ACPI_EXPORT_SYMBOL (AcpiGetTable) +ACPI_EXPORT_SYMBOL (AcpiPutTable) /******************************************************************************* @@ -363,7 +443,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable) * FUNCTION: AcpiGetTableByIndex * * PARAMETERS: TableIndex - Table index - * Table - Where the pointer to the table is returned + * OutTable - Where the pointer to the table is returned * * RETURN: Status and pointer to the requested table * @@ -375,7 +455,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable) ACPI_STATUS AcpiGetTableByIndex ( UINT32 TableIndex, - ACPI_TABLE_HEADER **Table) + ACPI_TABLE_HEADER **OutTable) { ACPI_STATUS Status; @@ -385,37 +465,34 @@ AcpiGetTableByIndex ( /* Parameter validation */ - if (!Table) + if (!OutTable) { return_ACPI_STATUS (AE_BAD_PARAMETER); } + /* + * Note that the following line is required by some OSPMs, they only + * check if the returned table is NULL instead of the returned status + * to determined if this function is succeeded. + */ + *OutTable = NULL; + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); /* Validate index */ if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) { - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (AE_BAD_PARAMETER); + Status = AE_BAD_PARAMETER; + goto UnlockAndExit; } - if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer) - { - /* Table is not mapped, map it */ - - Status = AcpiTbValidateTable ( - &AcpiGbl_RootTableList.Tables[TableIndex]); - if (ACPI_FAILURE (Status)) - { - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); - } - } + Status = AcpiTbGetTable ( + &AcpiGbl_RootTableList.Tables[TableIndex], OutTable); - *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer; +UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (AE_OK); + return_ACPI_STATUS (Status); } ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex) |