⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bm.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 *
 * Module Name: bm.c
 *   $Revision: 1.1 $
 *
 *****************************************************************************/

/*
 *  Copyright (C) 2000, 2001 Andrew Grover
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include <acpi.h>



#define _COMPONENT		ACPI_BUS_MANAGER
	MODULE_NAME		("bm")


/****************************************************************************
 *                                  Globals
 ****************************************************************************/

extern FADT_DESCRIPTOR_REV2	acpi_fadt;
/* TODO: Make dynamically sizeable. */
static BM_NODE_LIST		node_list;


/****************************************************************************
 *                            Internal Functions
 ****************************************************************************/

/****************************************************************************
 *
 * FUNCTION:    bm_print
 *
 * PARAMETERS:  <TBD>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

void
bm_print (
	BM_NODE			*node,
	u32                     flags)
{
	ACPI_BUFFER             buffer;
	BM_DEVICE		*device = NULL;
	char                    *type_string = NULL;

	if (!node) {
		return;
	}

	device = &(node->device);

	if (flags & BM_PRINT_PRESENT) {
		if (!BM_DEVICE_PRESENT(device)) {
			return;
		}
	}

	buffer.length = 256;
	buffer.pointer = acpi_os_callocate(buffer.length);
	if (!buffer.pointer) {
		return;
	}

	acpi_get_name(device->acpi_handle, ACPI_FULL_PATHNAME, &buffer);

	switch(device->id.type) {
	case BM_TYPE_SYSTEM:
		type_string = "System";
		break;
	case BM_TYPE_SCOPE:
		type_string = "Scope";
		break;
	case BM_TYPE_PROCESSOR:
		type_string = "Processor";
		break;
	case BM_TYPE_THERMAL_ZONE:
		type_string = "ThermalZone";
		break;
	case BM_TYPE_POWER_RESOURCE:
		type_string = "PowerResource";
		break;
	case BM_TYPE_FIXED_BUTTON:
		type_string = "Button";
		break;
	case BM_TYPE_DEVICE:
		type_string = "Device";
		break;
	default:
		type_string = "Unknown";
		break;
	}

	if (!(flags & BM_PRINT_GROUP)) {
		DEBUG_PRINT(ACPI_INFO, ("+------------------------------------------------------------\n"));
	}

		DEBUG_PRINT(ACPI_INFO, ("%s[0x%02x] hid[%s] %s\n", type_string, device->handle, device->id.hid, buffer.pointer));
		DEBUG_PRINT(ACPI_INFO, ("  acpi_handle[0x%08x] flags[0x%02x] status[0x%02x]\n", device->acpi_handle, device->flags, device->status));

	if (flags & BM_PRINT_IDENTIFICATION) {
		DEBUG_PRINT(ACPI_INFO, ("  identification: uid[%s] adr[0x%08x]\n", device->id.uid, device->id.adr));
	}

	if (flags & BM_PRINT_LINKAGE) {
		DEBUG_PRINT(ACPI_INFO, ("  linkage: this[%p] parent[%p] next[%p]\n", node, node->parent, node->next));
		DEBUG_PRINT(ACPI_INFO, ("    scope.head[%p] scope.tail[%p]\n", node->scope.head, node->scope.tail));
	}

	if (flags & BM_PRINT_POWER) {
		DEBUG_PRINT(ACPI_INFO, ("  power: state[D%d] flags[0x%08X]\n", device->power.state, device->power.flags));
		DEBUG_PRINT(ACPI_INFO, ("    S0[0x%02x] S1[0x%02x] S2[0x%02x]\n", device->power.dx_supported[0], device->power.dx_supported[1], device->power.dx_supported[2]));
		DEBUG_PRINT(ACPI_INFO, ("    S3[0x%02x] S4[0x%02x] S5[0x%02x]\n", device->power.dx_supported[3], device->power.dx_supported[4], device->power.dx_supported[5]));
	}

	if (!(flags & BM_PRINT_GROUP)) {
		DEBUG_PRINT(ACPI_INFO, ("+------------------------------------------------------------\n"));
	}

	acpi_os_free(buffer.pointer);

	return;
}


/****************************************************************************
 *
 * FUNCTION:    bm_print_hierarchy
 *
 * PARAMETERS:  <TBD>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

void
bm_print_hierarchy (void)
{
	u32			i = 0;

	FUNCTION_TRACE("bm_print_hierarchy");

	DEBUG_PRINT(ACPI_INFO, ("+------------------------------------------------------------\n"));

	for (i = 0; i < node_list.count; i++) {
		bm_print(node_list.nodes[i], BM_PRINT_GROUP | BM_PRINT_PRESENT);
	}

	DEBUG_PRINT(ACPI_INFO, ("+------------------------------------------------------------\n"));

	return_VOID;
}


/****************************************************************************
 *
 * FUNCTION:    bm_get_status
 *
 * PARAMETERS:  <TBD>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_get_status (
	BM_DEVICE		*device)
{
	ACPI_STATUS             status = AE_OK;

	if (!device) {
		return AE_BAD_PARAMETER;
	}

	device->status = BM_STATUS_UNKNOWN;

	/*
	 * Dynamic Status?
	 * ---------------
	 * If _STA isn't present we just return the default status.
	 */
	if (!(device->flags & BM_FLAGS_DYNAMIC_STATUS)) {
		device->status = BM_STATUS_DEFAULT;
		return AE_OK;
	}

	/*
	 * Evaluate _STA:
	 * --------------
	 */
	status = bm_evaluate_simple_integer(device->acpi_handle, "_STA",
		&(device->status));

	return status;
}


/****************************************************************************
 *
 * FUNCTION:    bm_get_identification
 *
 * PARAMETERS:  <TBD>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_get_identification (
	BM_DEVICE		*device)
{
	ACPI_STATUS             status = AE_OK;
	ACPI_DEVICE_INFO        info;

	if (!device) {
		return AE_BAD_PARAMETER;
	}

	if (!(device->flags & BM_FLAGS_IDENTIFIABLE)) {
		return AE_OK;
	}

	MEMSET(&(device->id.uid), 0, sizeof(device->id.uid));
	MEMSET(&(device->id.hid), 0, sizeof(device->id.hid));
	device->id.adr = BM_ADDRESS_UNKNOWN;

	/*
	 * Get Object Info:
	 * ----------------
	 * Evalute _UID, _HID, _ADR, and _STA...
	 */
	status = acpi_get_object_info(device->acpi_handle, &info);
	if (ACPI_FAILURE(status)) {
		return status;
	}

	if (info.valid & ACPI_VALID_UID) {
		MEMCPY((void*)device->id.uid, (void*)info.unique_id,
			sizeof(BM_DEVICE_UID));
	}

	if (info.valid & ACPI_VALID_HID) {
		MEMCPY((void*)device->id.hid, (void*)info.hardware_id,
			sizeof(BM_DEVICE_HID));
	}

	if (info.valid & ACPI_VALID_ADR) {
		device->id.adr = info.address;
	}

	return status;
}


/****************************************************************************
 *
 * FUNCTION:    bm_get_flags
 *
 * PARAMETERS:  <TBD>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_get_flags (
	BM_DEVICE		*device)
{
	ACPI_HANDLE             acpi_handle = NULL;

	if (!device) {
		return AE_BAD_PARAMETER;
	}

	device->flags = BM_FLAGS_UNKNOWN;

	switch (device->id.type) {

	case BM_TYPE_DEVICE:

		/*
		 * Presence of _DCK indicates a docking station.
		 */
		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_DCK", &acpi_handle))) {
			device->flags |= BM_FLAGS_DOCKING_STATION;
		}

		/*
		 * Presence of _EJD and/or _EJx indicates 'ejectable'.
		 * TODO: _EJx...
		 */
		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_EJD", &acpi_handle))) {
			device->flags |= BM_FLAGS_EJECTABLE;
		}

		/*
		 * Presence of _PR0 or _PS0 indicates 'power manageable'.
		 */
		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_PR0", &acpi_handle)) ||
			ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_PS0", &acpi_handle))) {
			device->flags |= BM_FLAGS_POWER_CONTROL;
		}

		/*
		 * Presence of _CRS indicates 'configurable'.
		 */
		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_CRS", &acpi_handle))) {
			device->flags |= BM_FLAGS_CONFIGURABLE;
		}

		/* Fall through to next case statement. */

	case BM_TYPE_PROCESSOR:
	case BM_TYPE_THERMAL_ZONE:
	case BM_TYPE_POWER_RESOURCE:
		/*
		 * Presence of _HID or _ADR indicates 'identifiable'.
		 */
		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_HID", &acpi_handle)) ||
		   ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
		   "_ADR", &acpi_handle))) {
			device->flags |= BM_FLAGS_IDENTIFIABLE;
		}

		/*
		 * Presence of _STA indicates 'dynamic status'.
		 */
		if (ACPI_SUCCESS(acpi_get_handle(device->acpi_handle,
			"_STA", &acpi_handle))) {
			device->flags |= BM_FLAGS_DYNAMIC_STATUS;
		}

		break;
	}

	return AE_OK;
}


/****************************************************************************
 *
 * FUNCTION:    bm_add_namespace_device
 *
 * PARAMETERS:  <TBD>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_add_namespace_device (
	ACPI_HANDLE             acpi_handle,
	ACPI_OBJECT_TYPE        acpi_type,
	BM_NODE			*parent,
	BM_NODE			**child)
{
	ACPI_STATUS             status = AE_OK;
	BM_NODE			*node = NULL;
	BM_DEVICE		*device = NULL;

	FUNCTION_TRACE("bm_add_namespace_device");

	if (!parent || !child) {
		return_ACPI_STATUS(AE_BAD_PARAMETER);
	}

	if (node_list.count > BM_HANDLES_MAX) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	(*child) = NULL;

	/*
	 * Create Node:
	 * ------------
	 */
	node = acpi_os_callocate(sizeof(BM_NODE));
	if (!node) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	node->parent = parent;
	node->next = NULL;

	device = &(node->device);

	device->handle = node_list.count;
	device->acpi_handle = acpi_handle;

	/*
	 * Device Type:
	 * ------------
	 */
	switch (acpi_type) {
	case INTERNAL_TYPE_SCOPE:
		device->id.type = BM_TYPE_SCOPE;
		break;
	case ACPI_TYPE_PROCESSOR:
		device->id.type = BM_TYPE_PROCESSOR;
		break;
	case ACPI_TYPE_THERMAL:
		device->id.type = BM_TYPE_THERMAL_ZONE;
		break;
	case ACPI_TYPE_POWER:
		device->id.type = BM_TYPE_POWER_RESOURCE;
		break;
	case ACPI_TYPE_DEVICE:
		device->id.type = BM_TYPE_DEVICE;
		break;
	}

	/*
	 * Get Other Device Info:
	 * ----------------------
	 * But only if this device's parent is present (which implies
	 * this device MAY be present).
	 */
	if (BM_NODE_PRESENT(node->parent)) {
		/*
		 * Device Flags
		 */
		status = bm_get_flags(device);
		if (ACPI_FAILURE(status)) {
			goto end;
		}

		/*
		 * Device Identification
		 */
		status = bm_get_identification(device);
		if (ACPI_FAILURE(status)) {
			goto end;
		}

		/*
		 * Device Status
		 */
		status = bm_get_status(device);
		if (ACPI_FAILURE(status)) {
			goto end;
		}

		/*
		 * Power Management:
		 * -----------------
		 * If this node doesn't provide direct power control
		 * then we inherit PM capabilities from its parent.
		 *
		 * TODO: Inherit!
		 */
		if (device->flags & BM_FLAGS_POWER_CONTROL) {
			status = bm_get_pm_capabilities(node);
			if (ACPI_FAILURE(status)) {
				goto end;
			}
		}
	}

end:
	if (ACPI_FAILURE(status)) {
		acpi_os_free(node);
	}
	else {
		/*
		 * Add to the node_list.
		 */
		node_list.nodes[node_list.count++] = node;

		/*
		 * Formulate Hierarchy:
		 * --------------------
		 * Arrange within the namespace by assigning the parent and
		 * adding to the parent device's list of children (scope).
		 */
		if (!parent->scope.head) {
			parent->scope.head = node;
		}
		else {
			if (!parent->scope.tail) {
				(parent->scope.head)->next = node;
			}
			else {
				(parent->scope.tail)->next = node;
			}
		}
		parent->scope.tail = node;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -