ACPI_STATUS AcpiNsRepairObject ( ACPI_PREDEFINED_DATA *Data, UINT32 ExpectedBtypes, UINT32 PackageIndex, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_OPERAND_OBJECT *NewObject; ACPI_STATUS Status; ACPI_FUNCTION_NAME (NsRepairObject); /* * At this point, we know that the type of the returned object was not * one of the expected types for this predefined name. Attempt to * repair the object by converting it to one of the expected object * types for this predefined name. */ if (ExpectedBtypes & ACPI_RTYPE_INTEGER) { Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_STRING) { Status = AcpiNsConvertToString (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_BUFFER) { Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) { Status = AcpiNsConvertToPackage (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } /* We cannot repair this object */ return (AE_AML_OPERAND_TYPE); ObjectRepaired: /* Object was successfully repaired */ /* * If the original object is a package element, we need to: * 1. Set the reference count of the new object to match the * reference count of the old object. * 2. Decrement the reference count of the original object. */ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) { NewObject->Common.ReferenceCount = ReturnObject->Common.ReferenceCount; if (ReturnObject->Common.ReferenceCount > 1) { ReturnObject->Common.ReferenceCount--; } ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Converted %s to expected %s at index %u\n", Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject), PackageIndex)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Converted %s to expected %s\n", Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject))); } /* Delete old object, install the new return object */ AcpiUtRemoveReference (ReturnObject); *ReturnObjectPtr = NewObject; Data->Flags |= ACPI_OBJECT_REPAIRED; return (AE_OK); }
ACPI_STATUS AcpiNsSimpleRepair ( ACPI_EVALUATE_INFO *Info, UINT32 ExpectedBtypes, UINT32 PackageIndex, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_OPERAND_OBJECT *NewObject = NULL; ACPI_STATUS Status; const ACPI_SIMPLE_REPAIR_INFO *Predefined; ACPI_FUNCTION_NAME (NsSimpleRepair); /* * Special repairs for certain names that are in the repair table. * Check if this name is in the list of repairable names. */ Predefined = AcpiNsMatchSimpleRepair (Info->Node, Info->ReturnBtype, PackageIndex); if (Predefined) { if (!ReturnObject) { ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, "Missing expected return value")); } Status = Predefined->ObjectConverter (Info->Node, ReturnObject, &NewObject); if (ACPI_FAILURE (Status)) { /* A fatal error occurred during a conversion */ ACPI_EXCEPTION ((AE_INFO, Status, "During return object analysis")); return (Status); } if (NewObject) { goto ObjectRepaired; } } /* * Do not perform simple object repair unless the return type is not * expected. */ if (Info->ReturnBtype & ExpectedBtypes) { return (AE_OK); } /* * At this point, we know that the type of the returned object was not * one of the expected types for this predefined name. Attempt to * repair the object by converting it to one of the expected object * types for this predefined name. */ /* * If there is no return value, check if we require a return value for * this predefined name. Either one return value is expected, or none, * for both methods and other objects. * * Try to fix if there was no return object. Warning if failed to fix. */ if (!ReturnObject) { if (ExpectedBtypes && (!(ExpectedBtypes & ACPI_RTYPE_NONE))) { if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) { ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, "Found unexpected NULL package element")); Status = AcpiNsRepairNullElement (Info, ExpectedBtypes, PackageIndex, ReturnObjectPtr); if (ACPI_SUCCESS (Status)) { return (AE_OK); /* Repair was successful */ } } else { ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, "Missing expected return value")); } return (AE_AML_NO_RETURN_VALUE); } } if (ExpectedBtypes & ACPI_RTYPE_INTEGER) { Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_STRING) { Status = AcpiNsConvertToString (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_BUFFER) { Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) { /* * A package is expected. We will wrap the existing object with a * new package object. It is often the case that if a variable-length * package is required, but there is only a single object needed, the * BIOS will return that object instead of wrapping it with a Package * object. Note: after the wrapping, the package will be validated * for correct contents (expected object type or types). */ Status = AcpiNsWrapWithPackage (Info, ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { /* * The original object just had its reference count * incremented for being inserted into the new package. */ *ReturnObjectPtr = NewObject; /* New Package object */ Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; return (AE_OK); } } /* We cannot repair this object */ return (AE_AML_OPERAND_TYPE); ObjectRepaired: /* Object was successfully repaired */ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) { /* * The original object is a package element. We need to * decrement the reference count of the original object, * for removing it from the package. * * However, if the original object was just wrapped with a * package object as part of the repair, we don't need to * change the reference count. */ if (!(Info->ReturnFlags & ACPI_OBJECT_WRAPPED)) { NewObject->Common.ReferenceCount = ReturnObject->Common.ReferenceCount; if (ReturnObject->Common.ReferenceCount > 1) { ReturnObject->Common.ReferenceCount--; } } ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Converted %s to expected %s at Package index %u\n", Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject), PackageIndex)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Converted %s to expected %s\n", Info->FullPathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject))); } /* Delete old object, install the new return object */ AcpiUtRemoveReference (ReturnObject); *ReturnObjectPtr = NewObject; Info->ReturnFlags |= ACPI_OBJECT_REPAIRED; return (AE_OK); }
ACPI_STATUS AcpiNsRepairObject ( ACPI_PREDEFINED_DATA *Data, UINT32 ExpectedBtypes, UINT32 PackageIndex, ACPI_OPERAND_OBJECT **ReturnObjectPtr) { ACPI_OPERAND_OBJECT *ReturnObject = *ReturnObjectPtr; ACPI_OPERAND_OBJECT *NewObject; ACPI_STATUS Status; ACPI_FUNCTION_NAME (NsRepairObject); /* * At this point, we know that the type of the returned object was not * one of the expected types for this predefined name. Attempt to * repair the object by converting it to one of the expected object * types for this predefined name. */ if (ExpectedBtypes & ACPI_RTYPE_INTEGER) { Status = AcpiNsConvertToInteger (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_STRING) { Status = AcpiNsConvertToString (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_BUFFER) { Status = AcpiNsConvertToBuffer (ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { goto ObjectRepaired; } } if (ExpectedBtypes & ACPI_RTYPE_PACKAGE) { /* * A package is expected. We will wrap the existing object with a * new package object. It is often the case that if a variable-length * package is required, but there is only a single object needed, the * BIOS will return that object instead of wrapping it with a Package * object. Note: after the wrapping, the package will be validated * for correct contents (expected object type or types). */ Status = AcpiNsWrapWithPackage (Data, ReturnObject, &NewObject); if (ACPI_SUCCESS (Status)) { /* * The original object just had its reference count * incremented for being inserted into the new package. */ *ReturnObjectPtr = NewObject; /* New Package object */ Data->Flags |= ACPI_OBJECT_REPAIRED; return (AE_OK); } } /* We cannot repair this object */ return (AE_AML_OPERAND_TYPE); ObjectRepaired: /* Object was successfully repaired */ if (PackageIndex != ACPI_NOT_PACKAGE_ELEMENT) { /* * The original object is a package element. We need to * decrement the reference count of the original object, * for removing it from the package. * * However, if the original object was just wrapped with a * package object as part of the repair, we don't need to * change the reference count. */ if (!(Data->Flags & ACPI_OBJECT_WRAPPED)) { NewObject->Common.ReferenceCount = ReturnObject->Common.ReferenceCount; if (ReturnObject->Common.ReferenceCount > 1) { ReturnObject->Common.ReferenceCount--; } } ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Converted %s to expected %s at Package index %u\n", Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject), PackageIndex)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_REPAIR, "%s: Converted %s to expected %s\n", Data->Pathname, AcpiUtGetObjectTypeName (ReturnObject), AcpiUtGetObjectTypeName (NewObject))); } /* Delete old object, install the new return object */ AcpiUtRemoveReference (ReturnObject); *ReturnObjectPtr = NewObject; Data->Flags |= ACPI_OBJECT_REPAIRED; return (AE_OK); }