Ejemplo n.º 1
0
ACPI_STATUS
LsDisplayNamespace (
    void)
{
    ACPI_STATUS             Status;


    if (!Gbl_NsOutputFlag)
    {
        return (AE_OK);
    }

    Gbl_NumNamespaceObjects = 0;

    /* File header */

    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Contents of ACPI Namespace\n\n");
    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "Count  Depth    Name - Type\n\n");

    /* Walk entire namespace from the root */

    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, FALSE, LsDoOneNamespaceObject, NULL,
                NULL, NULL);

    /* Print the full pathname for each namespace node */

    FlPrintFile (ASL_FILE_NAMESPACE_OUTPUT, "\nNamespace pathnames\n\n");

    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, FALSE, LsDoOnePathname, NULL,
                NULL, NULL);

    return (Status);
}
Ejemplo n.º 2
0
ACPI_STATUS
AcpiEvExecuteRegMethods (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_ADR_SPACE_TYPE     SpaceId)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (EvExecuteRegMethods);


    /*
     * Run all _REG methods for all Operation Regions for this space ID. This
     * is a separate walk in order to handle any interdependencies between
     * regions and _REG methods. (i.e. handlers must be installed for all
     * regions of this Space ID before we can run any _REG methods)
     */
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
                ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL,
                &SpaceId, NULL);

    /* Special case for EC: handle "orphan" _REG methods with no region */

    if (SpaceId == ACPI_ADR_SPACE_EC)
    {
        AcpiEvOrphanEcRegMethod (Node);
    }

    return_ACPI_STATUS (Status);
}
Ejemplo n.º 3
0
void
AcpiNsDumpRootDevices (
    void)
{
    ACPI_HANDLE             SysBusHandle;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_NAME (NsDumpRootDevices);


    /* Only dump the table if tracing is enabled */

    if (!(ACPI_LV_TABLES & AcpiDbgLevel))
    {
        return;
    }

    Status = AcpiGetHandle (NULL, METHOD_NAME__SB_, &SysBusHandle);
    if (ACPI_FAILURE (Status))
    {
        return;
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
                       "Display of all devices in the namespace:\n"));

    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, SysBusHandle,
                                  ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
                                  AcpiNsDumpOneDevice, NULL, NULL, NULL);
}
Ejemplo n.º 4
0
void
AcpiEvExecuteRegMethods (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_ADR_SPACE_TYPE     SpaceId,
    UINT32                  Function)
{
    ACPI_REG_WALK_INFO      Info;


    ACPI_FUNCTION_TRACE (EvExecuteRegMethods);

    /*
     * These address spaces do not need a call to _REG, since the ACPI
     * specification defines them as: "must always be accessible". Since
     * they never change state (never become unavailable), no need to ever
     * call _REG on them. Also, a DataTable is not a "real" address space,
     * so do not call _REG. September 2018.
     */
    if ((SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) ||
        (SpaceId == ACPI_ADR_SPACE_SYSTEM_IO) ||
        (SpaceId == ACPI_ADR_SPACE_DATA_TABLE))
    {
        return_VOID;
    }

    Info.SpaceId = SpaceId;
    Info.Function = Function;
    Info.RegRunCount = 0;

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
        "    Running _REG methods for SpaceId %s\n",
        AcpiUtGetRegionName (Info.SpaceId)));

    /*
     * Run all _REG methods for all Operation Regions for this space ID. This
     * is a separate walk in order to handle any interdependencies between
     * regions and _REG methods. (i.e. handlers must be installed for all
     * regions of this Space ID before we can run any _REG methods)
     */
    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
        ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL);

    /* Special case for EC: handle "orphan" _REG methods with no region */

    if (SpaceId == ACPI_ADR_SPACE_EC)
    {
        AcpiEvOrphanEcRegMethod (Node);
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
        "    Executed %u _REG methods for SpaceId %s\n",
        Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId)));

    return_VOID;
}
Ejemplo n.º 5
0
void
AcpiNsDumpObjectPaths (
    ACPI_OBJECT_TYPE        Type,
    UINT8                   DisplayType,
    UINT32                  MaxDepth,
    ACPI_OWNER_ID           OwnerId,
    ACPI_HANDLE             StartHandle)
{
    ACPI_STATUS             Status;
    UINT32                  MaxLevel = 0;


    ACPI_FUNCTION_ENTRY ();


    /*
     * Just lock the entire namespace for the duration of the dump.
     * We don't want any changes to the namespace during this time,
     * especially the temporary nodes since we are going to display
     * them also.
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("Could not acquire namespace mutex\n");
        return;
    }

    /* Get the max depth of the namespace tree, for formatting later */

    (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
        ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
        AcpiNsGetMaxDepth, NULL, (void *) &MaxLevel, NULL);

    /* Now dump the entire namespace */

    (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
        ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
        AcpiNsDumpOneObjectPath, NULL, (void *) &MaxLevel, NULL);

    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
}
Ejemplo n.º 6
0
void
LkFindUnreferencedObjects (
    void)
{

    /* Walk entire namespace from the supplied root */

    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, FALSE, LkIsObjectUsed, NULL,
                NULL, NULL);
}
Ejemplo n.º 7
0
ACPI_STATUS
AcpiGetDevices (
    char                    *HID,
    ACPI_WALK_CALLBACK      UserFunction,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_STATUS             Status;
    ACPI_GET_DEVICES_INFO   Info;


    ACPI_FUNCTION_TRACE (AcpiGetDevices);


    /* Parameter validation */

    if (!UserFunction)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /*
     * We're going to call their callback from OUR callback, so we need
     * to know what it is, and their context parameter.
     */
    Info.Hid = HID;
    Info.Context = Context;
    Info.UserFunction = UserFunction;

    /*
     * Lock the namespace around the walk.
     * The namespace will be unlocked/locked around each call
     * to the user function - since this function
     * must be allowed to make Acpi calls itself.
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
        ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
        AcpiNsGetDeviceCallback, NULL, &Info, ReturnValue);

    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 8
0
static void
MpEmitDeviceTree (
    void)
{

    FlPrintFile (ASL_FILE_MAP_OUTPUT, "\n\nACPI Device Tree\n");
    FlPrintFile (ASL_FILE_MAP_OUTPUT,     "----------------\n\n");

    FlPrintFile (ASL_FILE_MAP_OUTPUT, "Device Pathname                   "
        "_HID      Description\n\n");

    /* Walk the namespace from the root */

    (void) AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
            ACPI_UINT32_MAX, FALSE, MpEmitOneDevice, NULL, NULL, NULL);
}
Ejemplo n.º 9
0
static ACPI_STATUS
acpi_dock_insert_child(ACPI_HANDLE handle, UINT32 level, void *context,
    void **status)
{
	device_t	dock_dev, dev;
	ACPI_HANDLE	dock_handle;

	dock_dev = (device_t)context;
	dock_handle = acpi_get_handle(dock_dev);

	if (!acpi_dock_is_ejd_device(dock_handle, handle))
		goto out;

	ACPI_VPRINT(dock_dev, acpi_device_get_parent_softc(dock_dev),
		    "inserting device for %s\n", acpi_name(handle));

#if 0
	/*
	 * If the system boot up w/o Docking, the devices under the dock
	 * still un-initialized, also control methods such as _INI, _STA
	 * are not executed.
	 * Normal devices are initialized at booting by calling
	 * AcpiInitializeObjects(), however the devices under the dock
	 * need to be initialized here on the scheme of ACPICA.
	 */
	ACPI_INIT_WALK_INFO	Info;

	AcpiNsWalkNamespace(ACPI_TYPE_ANY, handle,
	    100, TRUE, AcpiNsInitOneDevice, &Info, NULL);
#endif

	dev = acpi_get_device(handle);
	if (dev == NULL) {
		device_printf(dock_dev, "error: %s has no associated device\n",
		    acpi_name(handle));
		goto out;
	}

	AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_dock_attach_later, dev);

out:
	return (AE_OK);
}
Ejemplo n.º 10
0
ACPI_STATUS
AcpiWalkNamespace (
    ACPI_OBJECT_TYPE        Type,
    ACPI_HANDLE             StartObject,
    UINT32                  MaxDepth,
    ACPI_WALK_CALLBACK      UserFunction,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (AcpiWalkNamespace);


    /* Parameter validation */

    if ((Type > ACPI_TYPE_LOCAL_MAX) ||
        (!MaxDepth)                  ||
        (!UserFunction))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /*
     * Lock the namespace around the walk.
     * The namespace will be unlocked/locked around each call
     * to the user function - since this function
     * must be allowed to make Acpi calls itself.
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
                    ACPI_NS_WALK_UNLOCK,
                    UserFunction, Context, ReturnValue);

    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 11
0
void
AcpiNsDumpObjects (
    ACPI_OBJECT_TYPE8       Type,
    UINT32                  MaxDepth,
    UINT32                  OwnerId,
    ACPI_HANDLE             StartHandle)
{
    ACPI_WALK_INFO          Info;


    FUNCTION_ENTRY ();


    Info.DebugLevel = ACPI_LV_TABLES;
    Info.OwnerId = OwnerId;

    AcpiNsWalkNamespace (Type, StartHandle, MaxDepth, NS_WALK_NO_UNLOCK, AcpiNsDumpOneObject,
                        (void *) &Info, NULL);
}
Ejemplo n.º 12
0
static void
AcpiDbCountNamespaceObjects (
    void)
{
    UINT32                  i;


    AcpiGbl_NumNodes = 0;
    AcpiGbl_NumObjects = 0;

    AcpiGbl_ObjTypeCountMisc = 0;
    for (i = 0; i < (ACPI_TYPE_NS_NODE_MAX -1); i++)
    {
        AcpiGbl_ObjTypeCount [i] = 0;
        AcpiGbl_NodeTypeCount [i] = 0;
    }

    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, FALSE, AcpiDbClassifyOneObject, NULL, NULL, NULL);
}
Ejemplo n.º 13
0
void
AcpiEvExecuteRegMethods (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_ADR_SPACE_TYPE     SpaceId,
    UINT32                  Function)
{
    ACPI_REG_WALK_INFO      Info;


    ACPI_FUNCTION_TRACE (EvExecuteRegMethods);

    Info.SpaceId = SpaceId;
    Info.Function = Function;
    Info.RegRunCount = 0;

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
        "    Running _REG methods for SpaceId %s\n",
        AcpiUtGetRegionName (Info.SpaceId)));

    /*
     * Run all _REG methods for all Operation Regions for this space ID. This
     * is a separate walk in order to handle any interdependencies between
     * regions and _REG methods. (i.e. handlers must be installed for all
     * regions of this Space ID before we can run any _REG methods)
     */
    (void) AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node, ACPI_UINT32_MAX,
        ACPI_NS_WALK_UNLOCK, AcpiEvRegRun, NULL, &Info, NULL);

    /* Special case for EC: handle "orphan" _REG methods with no region */

    if (SpaceId == ACPI_ADR_SPACE_EC)
    {
        AcpiEvOrphanEcRegMethod (Node);
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_NAMES,
        "    Executed %u _REG methods for SpaceId %s\n",
        Info.RegRunCount, AcpiUtGetRegionName (Info.SpaceId)));

    return_VOID;
}
Ejemplo n.º 14
0
static BOOLEAN
XfObjectExists (
    char                    *Name)
{
    ACPI_STATUS             Status;


    /* Walk entire namespace from the supplied root */

    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
        ACPI_UINT32_MAX, FALSE, XfCompareOneNamespaceObject, NULL,
        Name, NULL);
    if (Status == AE_CTRL_TRUE)
    {
        /* At least one instance of the name was found */

        return (TRUE);
    }

    return (FALSE);
}
Ejemplo n.º 15
0
void
AcpiNsDumpObjects (
    ACPI_OBJECT_TYPE        Type,
    UINT8                   DisplayType,
    UINT32                  MaxDepth,
    ACPI_OWNER_ID           OwnerId,
    ACPI_HANDLE             StartHandle)
{
    ACPI_WALK_INFO          Info;
    ACPI_STATUS             Status;


    ACPI_FUNCTION_ENTRY ();


    /*
     * Just lock the entire namespace for the duration of the dump.
     * We don't want any changes to the namespace during this time,
     * especially the temporary nodes since we are going to display
     * them also.
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        AcpiOsPrintf ("Could not acquire namespace mutex\n");
        return;
    }

    Info.Count = 0;
    Info.DebugLevel = ACPI_LV_TABLES;
    Info.OwnerId = OwnerId;
    Info.DisplayType = DisplayType;

    (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
        ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
        AcpiNsDumpOneObject, NULL, (void *) &Info, NULL);

    AcpiOsPrintf ("\nNamespace node count: %u\n\n", Info.Count);
    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
}
Ejemplo n.º 16
0
void
AcpiNsDumpObjects (
    ACPI_OBJECT_TYPE        Type,
    UINT8                   DisplayType,
    UINT32                  MaxDepth,
    ACPI_OWNER_ID           OwnerId,
    ACPI_HANDLE             StartHandle)
{
    ACPI_WALK_INFO          Info;


    ACPI_FUNCTION_ENTRY ();


    Info.DebugLevel = ACPI_LV_TABLES;
    Info.OwnerId = OwnerId;
    Info.DisplayType = DisplayType;

    (void) AcpiNsWalkNamespace (Type, StartHandle, MaxDepth,
                ACPI_NS_WALK_NO_UNLOCK | ACPI_NS_WALK_TEMP_NODES,
                AcpiNsDumpOneObject, (void *) &Info, NULL);
}
Ejemplo n.º 17
0
void
AcpiNsDumpRootDevices (void)
{
    ACPI_HANDLE             SysBusHandle;


    PROC_NAME ("NsDumpRootDevices");


    /* Only dump the table if tracing is enabled */

    if (!(ACPI_LV_TABLES & AcpiDbgLevel))
    {
        return;
    }

    AcpiGetHandle (0, NS_SYSTEM_BUS, &SysBusHandle);

    ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n"));
    AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, SysBusHandle, ACPI_UINT32_MAX, NS_WALK_NO_UNLOCK,
                        AcpiNsDumpOneDevice, NULL, NULL);
}
Ejemplo n.º 18
0
void
AcpiEvUpdateGpes (
    ACPI_OWNER_ID           TableOwnerId)
{
    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;
    ACPI_GPE_BLOCK_INFO     *GpeBlock;
    ACPI_GPE_WALK_INFO      WalkInfo;
    ACPI_STATUS             Status = AE_OK;


    /*
     * Find any _Lxx/_Exx GPE methods that have just been loaded.
     *
     * Any GPEs that correspond to new _Lxx/_Exx methods are immediately
     * enabled.
     *
     * Examine the namespace underneath each GpeDevice within the
     * GpeBlock lists.
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    if (ACPI_FAILURE (Status))
    {
        return;
    }

    WalkInfo.Count = 0;
    WalkInfo.OwnerId = TableOwnerId;
    WalkInfo.ExecuteByOwnerId = TRUE;

    /* Walk the interrupt level descriptor list */

    GpeXruptInfo = AcpiGbl_GpeXruptListHead;
    while (GpeXruptInfo)
    {
        /* Walk all Gpe Blocks attached to this interrupt level */

        GpeBlock = GpeXruptInfo->GpeBlockListHead;
        while (GpeBlock)
        {
            WalkInfo.GpeBlock = GpeBlock;
            WalkInfo.GpeDevice = GpeBlock->Node;

            Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD,
                        WalkInfo.GpeDevice, ACPI_UINT32_MAX,
                        ACPI_NS_WALK_NO_UNLOCK, AcpiEvMatchGpeMethod,
                        NULL, &WalkInfo, NULL);
            if (ACPI_FAILURE (Status))
            {
                ACPI_EXCEPTION ((AE_INFO, Status,
                    "While decoding _Lxx/_Exx methods"));
            }

            GpeBlock = GpeBlock->Next;
        }

        GpeXruptInfo = GpeXruptInfo->Next;
    }

    if (WalkInfo.Count)
    {
        ACPI_INFO ((AE_INFO, "Enabled %u new GPEs", WalkInfo.Count));
    }

    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    return;
}
Ejemplo n.º 19
0
ACPI_STATUS
AcpiWalkNamespace (
    ACPI_OBJECT_TYPE        Type,
    ACPI_HANDLE             StartObject,
    UINT32                  MaxDepth,
    ACPI_WALK_CALLBACK      DescendingCallback,
    ACPI_WALK_CALLBACK      AscendingCallback,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_STATUS             Status;


    ACPI_FUNCTION_TRACE (AcpiWalkNamespace);


    /* Parameter validation */

    if ((Type > ACPI_TYPE_LOCAL_MAX) ||
        (!MaxDepth)                  ||
        (!DescendingCallback && !AscendingCallback))
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    /*
     * Need to acquire the namespace reader lock to prevent interference
     * with any concurrent table unloads (which causes the deletion of
     * namespace objects). We cannot allow the deletion of a namespace node
     * while the user function is using it. The exception to this are the
     * nodes created and deleted during control method execution -- these
     * nodes are marked as temporary nodes and are ignored by the namespace
     * walk. Thus, control methods can be executed while holding the
     * namespace deletion lock (and the user function can execute control
     * methods.)
     */
    Status = AcpiUtAcquireReadLock (&AcpiGbl_NamespaceRwLock);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * Lock the namespace around the walk. The namespace will be
     * unlocked/locked around each call to the user function - since the user
     * function must be allowed to make ACPICA calls itself (for example, it
     * will typically execute control methods during device enumeration.)
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        goto UnlockAndExit;
    }

    /* Now we can validate the starting node */

    if (!AcpiNsValidateHandle (StartObject))
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit2;
    }

    Status = AcpiNsWalkNamespace (Type, StartObject, MaxDepth,
        ACPI_NS_WALK_UNLOCK, DescendingCallback,
        AscendingCallback, Context, ReturnValue);

UnlockAndExit2:
    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

UnlockAndExit:
    (void) AcpiUtReleaseReadLock (&AcpiGbl_NamespaceRwLock);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 20
0
ACPI_STATUS
AcpiEvCreateGpeBlock (
    ACPI_NAMESPACE_NODE     *GpeDevice,
    UINT64                  Address,
    UINT8                   SpaceId,
    UINT32                  RegisterCount,
    UINT16                  GpeBlockBaseNumber,
    UINT32                  InterruptNumber,
    ACPI_GPE_BLOCK_INFO     **ReturnGpeBlock)
{
    ACPI_STATUS             Status;
    ACPI_GPE_BLOCK_INFO     *GpeBlock;
    ACPI_GPE_WALK_INFO      WalkInfo;


    ACPI_FUNCTION_TRACE (EvCreateGpeBlock);


    if (!RegisterCount)
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Allocate a new GPE block */

    GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));
    if (!GpeBlock)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Initialize the new GPE block */

    GpeBlock->Address = Address;
    GpeBlock->SpaceId = SpaceId;
    GpeBlock->Node = GpeDevice;
    GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
    GpeBlock->Initialized = FALSE;
    GpeBlock->RegisterCount = RegisterCount;
    GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;

    /*
     * Create the RegisterInfo and EventInfo sub-structures
     * Note: disables and clears all GPEs in the block
     */
    Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (GpeBlock);
        return_ACPI_STATUS (Status);
    }

    /* Install the new block in the global lists */

    Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (GpeBlock->RegisterInfo);
        ACPI_FREE (GpeBlock->EventInfo);
        ACPI_FREE (GpeBlock);
        return_ACPI_STATUS (Status);
    }

    AcpiGbl_AllGpesInitialized = FALSE;

    /* Find all GPE methods (_Lxx or_Exx) for this block */

    WalkInfo.GpeBlock = GpeBlock;
    WalkInfo.GpeDevice = GpeDevice;
    WalkInfo.ExecuteByOwnerId = FALSE;

    Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
                ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
                AcpiEvMatchGpeMethod, NULL, &WalkInfo, NULL);

    /* Return the new block */

    if (ReturnGpeBlock)
    {
        (*ReturnGpeBlock) = GpeBlock;
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
        "    Initialized GPE %02X to %02X [%4.4s] %u regs on interrupt 0x%X%s\n",
        (UINT32) GpeBlock->BlockBaseNumber,
        (UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
        GpeDevice->Name.Ascii, GpeBlock->RegisterCount, InterruptNumber,
        InterruptNumber == AcpiGbl_FADT.SciInterrupt ? " (SCI)" : ""));

    /* Update global count of currently available GPEs */

    AcpiCurrentGpeCount += GpeBlock->GpeCount;
    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 21
0
ACPI_STATUS
AcpiNsInitializeDevices (
    UINT32                  Flags)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_DEVICE_WALK_INFO   Info;
    ACPI_HANDLE             Handle;


    ACPI_FUNCTION_TRACE (NsInitializeDevices);


    if (!(Flags & ACPI_NO_DEVICE_INIT))
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
            "[Init] Initializing ACPI Devices\n"));

        /* Init counters */

        Info.DeviceCount = 0;
        Info.Num_STA = 0;
        Info.Num_INI = 0;

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
            "Initializing Device/Processor/Thermal objects "
            "and executing _INI/_STA methods:\n"));

        /* Tree analysis: find all subtrees that contain _INI methods */

        Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
            ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
        if (ACPI_FAILURE (Status))
        {
            goto ErrorExit;
        }

        /* Allocate the evaluation information block */

        Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
        if (!Info.EvaluateInfo)
        {
            Status = AE_NO_MEMORY;
            goto ErrorExit;
        }

        /*
         * Execute the "global" _INI method that may appear at the root.
         * This support is provided for Windows compatibility (Vista+) and
         * is not part of the ACPI specification.
         */
        Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
        Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
        Info.EvaluateInfo->Parameters = NULL;
        Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;

        Status = AcpiNsEvaluate (Info.EvaluateInfo);
        if (ACPI_SUCCESS (Status))
        {
            Info.Num_INI++;
        }

        /*
         * Execute \_SB._INI.
         * There appears to be a strict order requirement for \_SB._INI,
         * which should be evaluated before any _REG evaluations.
         */
        Status = AcpiGetHandle (NULL, "\\_SB", &Handle);
        if (ACPI_SUCCESS (Status))
        {
            memset (Info.EvaluateInfo, 0, sizeof (ACPI_EVALUATE_INFO));
            Info.EvaluateInfo->PrefixNode = Handle;
            Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
            Info.EvaluateInfo->Parameters = NULL;
            Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;

            Status = AcpiNsEvaluate (Info.EvaluateInfo);
            if (ACPI_SUCCESS (Status))
            {
                Info.Num_INI++;
            }
        }
    }

    /*
     * Run all _REG methods
     *
     * Note: Any objects accessed by the _REG methods will be automatically
     * initialized, even if they contain executable AML (see the call to
     * AcpiNsInitializeObjects below).
     *
     * Note: According to the ACPI specification, we actually needn't execute
     * _REG for SystemMemory/SystemIo operation regions, but for PCI_Config
     * operation regions, it is required to evaluate _REG for those on a PCI
     * root bus that doesn't contain _BBN object. So this code is kept here
     * in order not to break things.
     */
    if (!(Flags & ACPI_NO_ADDRESS_SPACE_INIT))
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
            "[Init] Executing _REG OpRegion methods\n"));

        Status = AcpiEvInitializeOpRegions ();
        if (ACPI_FAILURE (Status))
        {
            goto ErrorExit;
        }
    }

    if (!(Flags & ACPI_NO_DEVICE_INIT))
    {
        /* Walk namespace to execute all _INIs on present devices */

        Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
            ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);

        /*
         * Any _OSI requests should be completed by now. If the BIOS has
         * requested any Windows OSI strings, we will always truncate
         * I/O addresses to 16 bits -- for Windows compatibility.
         */
        if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
        {
            AcpiGbl_TruncateIoAddresses = TRUE;
        }

        ACPI_FREE (Info.EvaluateInfo);
        if (ACPI_FAILURE (Status))
        {
            goto ErrorExit;
        }

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
            "    Executed %u _INI methods requiring %u _STA executions "
            "(examined %u objects)\n",
            Info.Num_INI, Info.Num_STA, Info.DeviceCount));
    }

    return_ACPI_STATUS (Status);


ErrorExit:
    ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 22
0
ACPI_STATUS
AcpiInstallAddressSpaceHandler (
    ACPI_HANDLE             Device,
    ACPI_ADR_SPACE_TYPE     SpaceId,
    ACPI_ADR_SPACE_HANDLER  Handler,
    ACPI_ADR_SPACE_SETUP    Setup,
    void                    *Context)
{
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_NAMESPACE_NODE     *Node;
    ACPI_STATUS             Status;
    ACPI_OBJECT_TYPE        Type;
    UINT16                  Flags = 0;


    ACPI_FUNCTION_TRACE ("AcpiInstallAddressSpaceHandler");


    /* Parameter validation */

    if (!Device)
    {
        return_ACPI_STATUS (AE_BAD_PARAMETER);
    }

    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* Convert and validate the device handle */

    Node = AcpiNsMapHandleToNode (Device);
    if (!Node)
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    /*
     * This registration is valid for only the types below
     * and the root.  This is where the default handlers
     * get placed.
     */
    if ((Node->Type != ACPI_TYPE_DEVICE)     &&
        (Node->Type != ACPI_TYPE_PROCESSOR)  &&
        (Node->Type != ACPI_TYPE_THERMAL)    &&
        (Node != AcpiGbl_RootNode))
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    if (Handler == ACPI_DEFAULT_HANDLER)
    {
        Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;

        switch (SpaceId)
        {
        case ACPI_ADR_SPACE_SYSTEM_MEMORY:
            Handler = AcpiExSystemMemorySpaceHandler;
            Setup   = AcpiEvSystemMemoryRegionSetup;
            break;

        case ACPI_ADR_SPACE_SYSTEM_IO:
            Handler = AcpiExSystemIoSpaceHandler;
            Setup   = AcpiEvIoSpaceRegionSetup;
            break;

        case ACPI_ADR_SPACE_PCI_CONFIG:
            Handler = AcpiExPciConfigSpaceHandler;
            Setup   = AcpiEvPciConfigRegionSetup;
            break;

        case ACPI_ADR_SPACE_CMOS:
            Handler = AcpiExCmosSpaceHandler;
            Setup   = AcpiEvCmosRegionSetup;
            break;

        case ACPI_ADR_SPACE_PCI_BAR_TARGET:
            Handler = AcpiExPciBarSpaceHandler;
            Setup   = AcpiEvPciBarRegionSetup;
            break;

        case ACPI_ADR_SPACE_DATA_TABLE:
            Handler = AcpiExDataTableSpaceHandler;
            Setup   = NULL;
            break;

        default:
            Status = AE_NOT_EXIST;
            goto UnlockAndExit;
        }
    }

    /*
     * If the caller hasn't specified a setup routine, use the default
     */
    if (!Setup)
    {
        Setup = AcpiEvDefaultRegionSetup;
    }

    /*
     * Check for an existing internal object
     */
    ObjDesc = AcpiNsGetAttachedObject (Node);
    if (ObjDesc)
    {
        /*
         * The object exists.
         * Make sure the handler is not already installed.
         */

        /* check the address handler the user requested */

        HandlerObj = ObjDesc->Device.AddrHandler;
        while (HandlerObj)
        {
            /*
             * We have an Address handler, see if user requested this
             * address space.
             */
            if(HandlerObj->AddrHandler.SpaceId == SpaceId)
            {
                Status = AE_ALREADY_EXISTS;
                goto UnlockAndExit;
            }

            /*
             * Move through the linked list of handlers
             */
            HandlerObj = HandlerObj->AddrHandler.Next;
        }
    }
    else
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
            "Creating object on Device %p while installing handler\n", Node));

        /* ObjDesc does not exist, create one */

        if (Node->Type == ACPI_TYPE_ANY)
        {
            Type = ACPI_TYPE_DEVICE;
        }
        else
        {
            Type = Node->Type;
        }

        ObjDesc = AcpiUtCreateInternalObject (Type);
        if (!ObjDesc)
        {
            Status = AE_NO_MEMORY;
            goto UnlockAndExit;
        }

        /* Init new descriptor */

        ObjDesc->Common.Type = (UINT8) Type;

        /* Attach the new object to the Node */

        Status = AcpiNsAttachObject (Node, ObjDesc, Type);
        if (ACPI_FAILURE (Status))
        {
            AcpiUtRemoveReference (ObjDesc);
            goto UnlockAndExit;
        }
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
        "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
        AcpiUtGetRegionName (SpaceId), SpaceId, Node->Name.Ascii, Node, ObjDesc));

    /*
     * Now we can install the handler
     *
     * At this point we know that there is no existing handler.
     * So, we just allocate the object for the handler and link it
     * into the list.
     */
    HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
    if (!HandlerObj)
    {
        Status = AE_NO_MEMORY;
        goto UnlockAndExit;
    }

    HandlerObj->AddrHandler.SpaceId     = (UINT8) SpaceId;
    HandlerObj->AddrHandler.Hflags      = Flags;
    HandlerObj->AddrHandler.Next        = ObjDesc->Device.AddrHandler;
    HandlerObj->AddrHandler.RegionList  = NULL;
    HandlerObj->AddrHandler.Node        = Node;
    HandlerObj->AddrHandler.Handler     = Handler;
    HandlerObj->AddrHandler.Context     = Context;
    HandlerObj->AddrHandler.Setup       = Setup;

    /*
     * Now walk the namespace finding all of the regions this
     * handler will manage.
     *
     * We start at the device and search the branch toward
     * the leaf nodes until either the leaf is encountered or
     * a device is detected that has an address handler of the
     * same type.
     *
     * In either case we back up and search down the remainder
     * of the branch
     */
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Device,
                                  ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
                                  AcpiEvAddrHandlerHelper,
                                  HandlerObj, NULL);

    /*
     * Place this handler 1st on the list
     */
    HandlerObj->Common.ReferenceCount =
                            (UINT16) (HandlerObj->Common.ReferenceCount +
                            ObjDesc->Common.ReferenceCount - 1);
    ObjDesc->Device.AddrHandler = HandlerObj;


UnlockAndExit:
    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 23
0
void
AcpiEvUpdateGpes (
    ACPI_OWNER_ID           TableOwnerId)
{
    ACPI_GPE_XRUPT_INFO     *GpeXruptInfo;
    ACPI_GPE_BLOCK_INFO     *GpeBlock;
    ACPI_GPE_WALK_INFO      WalkInfo;
    ACPI_STATUS             Status = AE_OK;
    UINT32                  NewWakeGpeCount = 0;


    /* We will examine only _PRW/_Lxx/_Exx methods owned by this table */

    WalkInfo.OwnerId = TableOwnerId;
    WalkInfo.ExecuteByOwnerId = TRUE;
    WalkInfo.Count = 0;

    if (AcpiGbl_LeaveWakeGpesDisabled)
    {
        /*
         * 1) Run any newly-loaded _PRW methods to find any GPEs that
         * can now be marked as CAN_WAKE GPEs. Note: We must run the
         * _PRW methods before we process the _Lxx/_Exx methods because
         * we will enable all runtime GPEs associated with the new
         * _Lxx/_Exx methods at the time we process those methods.
         *
         * Unlock interpreter so that we can run the _PRW methods.
         */
        WalkInfo.GpeBlock = NULL;
        WalkInfo.GpeDevice = NULL;

        AcpiExExitInterpreter ();

        Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
                    ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
                    AcpiEvMatchPrwAndGpe, NULL, &WalkInfo, NULL);
        if (ACPI_FAILURE (Status))
        {
            ACPI_EXCEPTION ((AE_INFO, Status,
                "While executing _PRW methods"));
        }

        AcpiExEnterInterpreter ();
        NewWakeGpeCount = WalkInfo.Count;
    }

    /*
     * 2) Find any _Lxx/_Exx GPE methods that have just been loaded.
     *
     * Any GPEs that correspond to new _Lxx/_Exx methods and are not
     * marked as CAN_WAKE are immediately enabled.
     *
     * Examine the namespace underneath each GpeDevice within the
     * GpeBlock lists.
     */
    Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
    if (ACPI_FAILURE (Status))
    {
        return;
    }

    WalkInfo.Count = 0;
    WalkInfo.EnableThisGpe = TRUE;

    /* Walk the interrupt level descriptor list */

    GpeXruptInfo = AcpiGbl_GpeXruptListHead;
    while (GpeXruptInfo)
    {
        /* Walk all Gpe Blocks attached to this interrupt level */

        GpeBlock = GpeXruptInfo->GpeBlockListHead;
        while (GpeBlock)
        {
            WalkInfo.GpeBlock = GpeBlock;
            WalkInfo.GpeDevice = GpeBlock->Node;

            Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD,
                        WalkInfo.GpeDevice, ACPI_UINT32_MAX,
                        ACPI_NS_WALK_NO_UNLOCK, AcpiEvMatchGpeMethod,
                        NULL, &WalkInfo, NULL);
            if (ACPI_FAILURE (Status))
            {
                ACPI_EXCEPTION ((AE_INFO, Status,
                    "While decoding _Lxx/_Exx methods"));
            }

            GpeBlock = GpeBlock->Next;
        }

        GpeXruptInfo = GpeXruptInfo->Next;
    }

    if (WalkInfo.Count || NewWakeGpeCount)
    {
        ACPI_INFO ((AE_INFO,
            "Enabled %u new runtime GPEs, added %u new wakeup GPEs",
            WalkInfo.Count, NewWakeGpeCount));
    }

    (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
    return;
}
Ejemplo n.º 24
0
ACPI_STATUS
AcpiEvInstallSpaceHandler (
    ACPI_NAMESPACE_NODE     *Node,
    ACPI_ADR_SPACE_TYPE     SpaceId,
    ACPI_ADR_SPACE_HANDLER  Handler,
    ACPI_ADR_SPACE_SETUP    Setup,
    void                    *Context)
{
    ACPI_OPERAND_OBJECT     *ObjDesc;
    ACPI_OPERAND_OBJECT     *HandlerObj;
    ACPI_STATUS             Status = AE_OK;
    ACPI_OBJECT_TYPE        Type;
    UINT8                   Flags = 0;


    ACPI_FUNCTION_TRACE (EvInstallSpaceHandler);


    /*
     * This registration is valid for only the types below and the root.
     * The root node is where the default handlers get installed.
     */
    if ((Node->Type != ACPI_TYPE_DEVICE)     &&
            (Node->Type != ACPI_TYPE_PROCESSOR)  &&
            (Node->Type != ACPI_TYPE_THERMAL)    &&
            (Node != AcpiGbl_RootNode))
    {
        Status = AE_BAD_PARAMETER;
        goto UnlockAndExit;
    }

    if (Handler == ACPI_DEFAULT_HANDLER)
    {
        Flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;

        switch (SpaceId)
        {
        case ACPI_ADR_SPACE_SYSTEM_MEMORY:

            Handler = AcpiExSystemMemorySpaceHandler;
            Setup   = AcpiEvSystemMemoryRegionSetup;
            break;

        case ACPI_ADR_SPACE_SYSTEM_IO:

            Handler = AcpiExSystemIoSpaceHandler;
            Setup   = AcpiEvIoSpaceRegionSetup;
            break;

        case ACPI_ADR_SPACE_PCI_CONFIG:

            Handler = AcpiExPciConfigSpaceHandler;
            Setup   = AcpiEvPciConfigRegionSetup;
            break;

        case ACPI_ADR_SPACE_CMOS:

            Handler = AcpiExCmosSpaceHandler;
            Setup   = AcpiEvCmosRegionSetup;
            break;

        case ACPI_ADR_SPACE_PCI_BAR_TARGET:

            Handler = AcpiExPciBarSpaceHandler;
            Setup   = AcpiEvPciBarRegionSetup;
            break;

        case ACPI_ADR_SPACE_DATA_TABLE:

            Handler = AcpiExDataTableSpaceHandler;
            Setup   = NULL;
            break;

        default:

            Status = AE_BAD_PARAMETER;
            goto UnlockAndExit;
        }
    }

    /* If the caller hasn't specified a setup routine, use the default */

    if (!Setup)
    {
        Setup = AcpiEvDefaultRegionSetup;
    }

    /* Check for an existing internal object */

    ObjDesc = AcpiNsGetAttachedObject (Node);
    if (ObjDesc)
    {
        /*
         * The attached device object already exists. Now make sure
         * the handler is not already installed.
         */
        HandlerObj = AcpiEvFindRegionHandler (SpaceId,
                                              ObjDesc->CommonNotify.Handler);

        if (HandlerObj)
        {
            if (HandlerObj->AddressSpace.Handler == Handler)
            {
                /*
                 * It is (relatively) OK to attempt to install the SAME
                 * handler twice. This can easily happen with the
                 * PCI_Config space.
                 */
                Status = AE_SAME_HANDLER;
                goto UnlockAndExit;
            }
            else
            {
                /* A handler is already installed */

                Status = AE_ALREADY_EXISTS;
            }

            goto UnlockAndExit;
        }
    }
    else
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                           "Creating object on Device %p while installing handler\n",
                           Node));

        /* ObjDesc does not exist, create one */

        if (Node->Type == ACPI_TYPE_ANY)
        {
            Type = ACPI_TYPE_DEVICE;
        }
        else
        {
            Type = Node->Type;
        }

        ObjDesc = AcpiUtCreateInternalObject (Type);
        if (!ObjDesc)
        {
            Status = AE_NO_MEMORY;
            goto UnlockAndExit;
        }

        /* Init new descriptor */

        ObjDesc->Common.Type = (UINT8) Type;

        /* Attach the new object to the Node */

        Status = AcpiNsAttachObject (Node, ObjDesc, Type);

        /* Remove local reference to the object */

        AcpiUtRemoveReference (ObjDesc);

        if (ACPI_FAILURE (Status))
        {
            goto UnlockAndExit;
        }
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
                       "Installing address handler for region %s(%X) "
                       "on Device %4.4s %p(%p)\n",
                       AcpiUtGetRegionName (SpaceId), SpaceId,
                       AcpiUtGetNodeName (Node), Node, ObjDesc));

    /*
     * Install the handler
     *
     * At this point there is no existing handler. Just allocate the object
     * for the handler and link it into the list.
     */
    HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
    if (!HandlerObj)
    {
        Status = AE_NO_MEMORY;
        goto UnlockAndExit;
    }

    /* Init handler obj */

    HandlerObj->AddressSpace.SpaceId = (UINT8) SpaceId;
    HandlerObj->AddressSpace.HandlerFlags = Flags;
    HandlerObj->AddressSpace.RegionList = NULL;
    HandlerObj->AddressSpace.Node = Node;
    HandlerObj->AddressSpace.Handler = Handler;
    HandlerObj->AddressSpace.Context = Context;
    HandlerObj->AddressSpace.Setup = Setup;

    /* Install at head of Device.AddressSpace list */

    HandlerObj->AddressSpace.Next = ObjDesc->CommonNotify.Handler;

    /*
     * The Device object is the first reference on the HandlerObj.
     * Each region that uses the handler adds a reference.
     */
    ObjDesc->CommonNotify.Handler = HandlerObj;

    /*
     * Walk the namespace finding all of the regions this handler will
     * manage.
     *
     * Start at the device and search the branch toward the leaf nodes
     * until either the leaf is encountered or a device is detected that
     * has an address handler of the same type.
     *
     * In either case, back up and search down the remainder of the branch
     */
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, Node,
                                  ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
                                  AcpiEvInstallHandler, NULL, HandlerObj, NULL);

UnlockAndExit:
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 25
0
ACPI_STATUS
AcpiEvCreateGpeBlock (
    ACPI_NAMESPACE_NODE     *GpeDevice,
    ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
    UINT32                  RegisterCount,
    UINT8                   GpeBlockBaseNumber,
    UINT32                  InterruptNumber,
    ACPI_GPE_BLOCK_INFO     **ReturnGpeBlock)
{
    ACPI_STATUS             Status;
    ACPI_GPE_BLOCK_INFO     *GpeBlock;


    ACPI_FUNCTION_TRACE (EvCreateGpeBlock);


    if (!RegisterCount)
    {
        return_ACPI_STATUS (AE_OK);
    }

    /* Allocate a new GPE block */

    GpeBlock = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_BLOCK_INFO));
    if (!GpeBlock)
    {
        return_ACPI_STATUS (AE_NO_MEMORY);
    }

    /* Initialize the new GPE block */

    GpeBlock->Node = GpeDevice;
    GpeBlock->RegisterCount = RegisterCount;
    GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;

    ACPI_MEMCPY (&GpeBlock->BlockAddress, GpeBlockAddress,
        sizeof (ACPI_GENERIC_ADDRESS));

    /*
     * Create the RegisterInfo and EventInfo sub-structures
     * Note: disables and clears all GPEs in the block
     */
    Status = AcpiEvCreateGpeInfoBlocks (GpeBlock);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (GpeBlock);
        return_ACPI_STATUS (Status);
    }

    /* Install the new block in the global lists */

    Status = AcpiEvInstallGpeBlock (GpeBlock, InterruptNumber);
    if (ACPI_FAILURE (Status))
    {
        ACPI_FREE (GpeBlock);
        return_ACPI_STATUS (Status);
    }

    /* Find all GPE methods (_Lxx, _Exx) for this block */

    Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
                ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
                AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL);

    /* Return the new block */

    if (ReturnGpeBlock)
    {
        (*ReturnGpeBlock) = GpeBlock;
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
        "GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
        (UINT32) GpeBlock->BlockBaseNumber,
        (UINT32) (GpeBlock->BlockBaseNumber +
                ((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
        GpeDevice->Name.Ascii,
        GpeBlock->RegisterCount,
        InterruptNumber));

    /* Update global count of currently available GPEs */

    AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH;
    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 26
0
ACPI_STATUS
AcpiEvInitializeGpeBlock (
    ACPI_NAMESPACE_NODE     *GpeDevice,
    ACPI_GPE_BLOCK_INFO     *GpeBlock)
{
    ACPI_STATUS             Status;
    ACPI_GPE_EVENT_INFO     *GpeEventInfo;
    ACPI_GPE_WALK_INFO      GpeInfo;
    UINT32                  WakeGpeCount;
    UINT32                  GpeEnabledCount;
    UINT32                  i;
    UINT32                  j;


    ACPI_FUNCTION_TRACE (EvInitializeGpeBlock);


    /* Ignore a null GPE block (e.g., if no GPE block 1 exists) */

    if (!GpeBlock)
    {
        return_ACPI_STATUS (AE_OK);
    }

    /*
     * Runtime option: Should wake GPEs be enabled at runtime?  The default
     * is no, they should only be enabled just as the machine goes to sleep.
     */
    if (AcpiGbl_LeaveWakeGpesDisabled)
    {
        /*
         * Differentiate runtime vs wake GPEs, via the _PRW control methods.
         * Each GPE that has one or more _PRWs that reference it is by
         * definition a wake GPE and will not be enabled while the machine
         * is running.
         */
        GpeInfo.GpeBlock = GpeBlock;
        GpeInfo.GpeDevice = GpeDevice;

        Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
                    ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
                    AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL);
    }

    /*
     * Enable all GPEs in this block that have these attributes:
     * 1) are "runtime" or "run/wake" GPEs, and
     * 2) have a corresponding _Lxx or _Exx method
     *
     * Any other GPEs within this block must be enabled via the
     * AcpiEnableGpe() external interface.
     */
    WakeGpeCount = 0;
    GpeEnabledCount = 0;

    for (i = 0; i < GpeBlock->RegisterCount; i++)
    {
        for (j = 0; j < 8; j++)
        {
            /* Get the info block for this particular GPE */

            GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
                ACPI_GPE_REGISTER_WIDTH) + j];

            if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
                    ACPI_GPE_DISPATCH_METHOD) &&
                 (GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
            {
                GpeEnabledCount++;
            }

            if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
            {
                WakeGpeCount++;
            }
        }
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
        "Found %u Wake, Enabled %u Runtime GPEs in this block\n",
        WakeGpeCount, GpeEnabledCount));

    /* Enable all valid runtime GPEs found above */

    Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL);
    if (ACPI_FAILURE (Status))
    {
        ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",
            GpeBlock));
    }

    return_ACPI_STATUS (Status);
}
Ejemplo n.º 27
0
ACPI_STATUS
AcpiNsInitializeDevices (
    void)
{
    ACPI_STATUS             Status;
    ACPI_DEVICE_WALK_INFO   Info;


    ACPI_FUNCTION_TRACE (NsInitializeDevices);


    /* Init counters */

    Info.DeviceCount = 0;
    Info.Num_STA = 0;
    Info.Num_INI = 0;

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
        "Initializing Device/Processor/Thermal objects "
        "and executing _INI/_STA methods:\n"));

    /* Tree analysis: find all subtrees that contain _INI methods */

    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, FALSE, AcpiNsFindIniMethods, NULL, &Info, NULL);
    if (ACPI_FAILURE (Status))
    {
        goto ErrorExit;
    }

    /* Allocate the evaluation information block */

    Info.EvaluateInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
    if (!Info.EvaluateInfo)
    {
        Status = AE_NO_MEMORY;
        goto ErrorExit;
    }

    /*
     * Execute the "global" _INI method that may appear at the root. This
     * support is provided for Windows compatibility (Vista+) and is not
     * part of the ACPI specification.
     */
    Info.EvaluateInfo->PrefixNode = AcpiGbl_RootNode;
    Info.EvaluateInfo->RelativePathname = METHOD_NAME__INI;
    Info.EvaluateInfo->Parameters = NULL;
    Info.EvaluateInfo->Flags = ACPI_IGNORE_RETURN_VALUE;

    Status = AcpiNsEvaluate (Info.EvaluateInfo);
    if (ACPI_SUCCESS (Status))
    {
        Info.Num_INI++;
    }

    /* Walk namespace to execute all _INIs on present devices */

    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT,
                ACPI_UINT32_MAX, FALSE, AcpiNsInitOneDevice, NULL, &Info, NULL);

    /*
     * Any _OSI requests should be completed by now. If the BIOS has
     * requested any Windows OSI strings, we will always truncate
     * I/O addresses to 16 bits -- for Windows compatibility.
     */
    if (AcpiGbl_OsiData >= ACPI_OSI_WIN_2000)
    {
        AcpiGbl_TruncateIoAddresses = TRUE;
    }

    ACPI_FREE (Info.EvaluateInfo);
    if (ACPI_FAILURE (Status))
    {
        goto ErrorExit;
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
        "    Executed %u _INI methods requiring %u _STA executions "
        "(examined %u objects)\n",
        Info.Num_INI, Info.Num_STA, Info.DeviceCount));

    return_ACPI_STATUS (Status);


ErrorExit:
    ACPI_EXCEPTION ((AE_INFO, Status, "During device initialization"));
    return_ACPI_STATUS (Status);
}
Ejemplo n.º 28
0
ACPI_STATUS
AcpiDsInitializeObjects (
    UINT32                  TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_STATUS             Status;
    ACPI_INIT_WALK_INFO     Info;
    ACPI_TABLE_HEADER       *Table;
    ACPI_OWNER_ID           OwnerId;


    ACPI_FUNCTION_TRACE (DsInitializeObjects);


    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "**** Starting initialization of namespace objects ****\n"));
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));

    /* Set all init info to zero */

    ACPI_MEMSET (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));

    Info.OwnerId = OwnerId;
    Info.TableIndex = TableIndex;

    /* Walk entire namespace from the supplied root */

    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /*
     * We don't use AcpiWalkNamespace since we do not want to acquire
     * the namespace reader lock.
     */
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
                ACPI_NS_WALK_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
    }
    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);

    Status = AcpiGetTableByIndex (TableIndex, &Table);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
        "\nTable [%4.4s](id %4.4X) - %u Objects with %u Devices %u Methods %u Regions\n",
        Table->Signature, OwnerId, Info.ObjectCount,
        Info.DeviceCount, Info.MethodCount, Info.OpRegionCount));

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "%u Methods, %u Regions\n", Info.MethodCount, Info.OpRegionCount));

    return_ACPI_STATUS (AE_OK);
}
Ejemplo n.º 29
0
ACPI_STATUS
AcpiDsInitializeObjects (
    UINT32                  TableIndex,
    ACPI_NAMESPACE_NODE     *StartNode)
{
    ACPI_STATUS             Status;
    ACPI_INIT_WALK_INFO     Info;
    ACPI_TABLE_HEADER       *Table;
    ACPI_OWNER_ID           OwnerId;


    ACPI_FUNCTION_TRACE (DsInitializeObjects);


    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
        "**** Starting initialization of namespace objects ****\n"));

    /* Set all init info to zero */

    memset (&Info, 0, sizeof (ACPI_INIT_WALK_INFO));

    Info.OwnerId = OwnerId;
    Info.TableIndex = TableIndex;

    /* Walk entire namespace from the supplied root */

    /*
     * We don't use AcpiWalkNamespace since we do not want to acquire
     * the namespace reader lock.
     */
    Status = AcpiNsWalkNamespace (ACPI_TYPE_ANY, StartNode, ACPI_UINT32_MAX,
        ACPI_NS_WALK_NO_UNLOCK, AcpiDsInitOneObject, NULL, &Info, NULL);
    if (ACPI_FAILURE (Status))
    {
        ACPI_EXCEPTION ((AE_INFO, Status, "During WalkNamespace"));
    }

    Status = AcpiGetTableByIndex (TableIndex, &Table);
    if (ACPI_FAILURE (Status))
    {
        return_ACPI_STATUS (Status);
    }

    /* DSDT is always the first AML table */

    if (ACPI_COMPARE_NAME (Table->Signature, ACPI_SIG_DSDT))
    {
        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
            "\nInitializing Namespace objects:\n"));
    }

    /* Summary of objects initialized */

    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
        "Table [%4.4s: %-8.8s] (id %.2X) - %4u Objects with %3u Devices, "
        "%3u Regions, %4u Methods (%u/%u/%u Serial/Non/Cvt)\n",
        Table->Signature, Table->OemTableId, OwnerId, Info.ObjectCount,
        Info.DeviceCount,Info.OpRegionCount, Info.MethodCount,
        Info.SerialMethodCount, Info.NonSerialMethodCount,
        Info.SerializedMethodCount));

    ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "%u Methods, %u Regions\n",
        Info.MethodCount, Info.OpRegionCount));

    return_ACPI_STATUS (AE_OK);
}