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

📄 bm.c

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

		(*child) = node;
	}

	return_ACPI_STATUS(status);
}


/****************************************************************************
 *
 * FUNCTION:    bm_enumerate_namespace
 *
 * PARAMETERS:  <none>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_enumerate_namespace (void)
{
	ACPI_STATUS		status = AE_OK;
	ACPI_HANDLE             parent_handle = ACPI_ROOT_OBJECT;
	ACPI_HANDLE             child_handle = NULL;
	BM_NODE			*parent = NULL;
	BM_NODE			*child = NULL;
	ACPI_OBJECT_TYPE        acpi_type = 0;
	u32                     level = 1;

	FUNCTION_TRACE("bm_enumerate_namespace");

	parent = node_list.nodes[0];

	/*
	 * Enumerate ACPI Namespace:
	 * -------------------------
	 * Parse through the ACPI namespace, identify all 'devices',
	 * and create a new entry for each in our collection.
	 */
	while (level > 0) {

		/*
		 * Get the next object at this level.
		 */
		status = acpi_get_next_object(ACPI_TYPE_ANY, parent_handle, child_handle, &child_handle);
		if (ACPI_SUCCESS(status)) {

			/*
			 * TODO: This is a hack to get around the problem
			 *       identifying scope objects.  Scopes
			 *       somehow need to be uniquely identified.
			 */
			status = acpi_get_type(child_handle, &acpi_type);
			if (ACPI_SUCCESS(status) && (acpi_type == ACPI_TYPE_ANY)) {
				status = acpi_get_next_object(ACPI_TYPE_ANY, child_handle, 0, NULL);
				if (ACPI_SUCCESS(status)) {
					acpi_type = INTERNAL_TYPE_SCOPE;
				}
			}

			/*
			 * Device?
			 * -------
			 * If this object is a 'device', insert into the
			 * ACPI Bus Manager's local hierarchy and search
			 * the object's scope for any child devices (a
			 * depth-first search).
			 */
			switch (acpi_type) {
			case INTERNAL_TYPE_SCOPE:
			case ACPI_TYPE_DEVICE:
			case ACPI_TYPE_PROCESSOR:
			case ACPI_TYPE_THERMAL:
			case ACPI_TYPE_POWER:
				status = bm_add_namespace_device(child_handle, acpi_type, parent, &child);
				if (ACPI_SUCCESS(status)) {
					status = acpi_get_next_object(ACPI_TYPE_ANY, child_handle, 0, NULL);
					if (ACPI_SUCCESS(status)) {
						level++;
						parent_handle = child_handle;
						child_handle = 0;
						parent = child;
					}
				}
				break;
			}
		}

		/*
		 * Scope Exhausted:
		 * ----------------
		 * No more children in this object's scope, Go back up
		 * in the namespace tree to the object's parent.
		 */
		else {
			level--;
			child_handle = parent_handle;
			acpi_get_parent(parent_handle,
				&parent_handle);

			if (parent) {
				parent = parent->parent;
			}
			else {
				return_ACPI_STATUS(AE_NULL_ENTRY);
			}
		}
	}

	return_ACPI_STATUS(AE_OK);
}


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

ACPI_STATUS
bm_add_fixed_feature_device (
	BM_NODE			*parent,
	BM_DEVICE_TYPE		device_type,
	char			*device_hid)
{
	ACPI_STATUS             status = AE_OK;
	BM_NODE			*node = NULL;

	FUNCTION_TRACE("bm_add_fixed_feature_device");

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

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

	/*
	 * Allocate the new device and add to the device array.
	 */
	node = acpi_os_callocate(sizeof(BM_NODE));
	if (!node) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	/*
	 * Get device info.
	 */
	node->device.handle = node_list.count;
	node->device.acpi_handle = ACPI_ROOT_OBJECT;
	node->device.id.type = BM_TYPE_FIXED_BUTTON;
	if (device_hid) {
		MEMCPY((void*)node->device.id.hid, device_hid,
			sizeof(node->device.id.hid));
	}
	node->device.flags = BM_FLAGS_FIXED_FEATURE;
	node->device.status = BM_STATUS_DEFAULT;
	/* TODO: Device PM capabilities */

	/*
	 * 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).
	 */
	node->parent = parent;
	node->next = NULL;

	if (parent) {
		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;
	}

	return_ACPI_STATUS(status);
}


/****************************************************************************
 *
 * FUNCTION:    bm_enumerate_fixed_features
 *
 * PARAMETERS:  <none>
 *
 * RETURN:      <TBD>
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_enumerate_fixed_features (void)
{
	FUNCTION_TRACE("bm_enumerate_fixed_features");

	/*
	 * Root Object:
	 * ------------
	 * Fabricate the root object, which happens to always get a
	 * device_handle of zero.
	 */
	node_list.nodes[0] = acpi_os_callocate(sizeof(BM_NODE));
	if (NULL == (node_list.nodes[0])) {
		return_ACPI_STATUS(AE_NO_MEMORY);
	}

	node_list.nodes[0]->device.handle = BM_HANDLE_ROOT;
	node_list.nodes[0]->device.acpi_handle = ACPI_ROOT_OBJECT;
	node_list.nodes[0]->device.flags = BM_FLAGS_UNKNOWN;
	node_list.nodes[0]->device.status = BM_STATUS_DEFAULT;
	node_list.nodes[0]->device.id.type = BM_TYPE_SYSTEM;
	/* TODO: Get system PM capabilities (Sx states?) */

	node_list.count++;

	/*
	 * Fixed Features:
	 * ---------------
	 * Enumerate fixed-feature devices (e.g. power and sleep buttons).
	 */
	if (acpi_fadt.pwr_button == 0) {
		bm_add_fixed_feature_device(node_list.nodes[0],
			BM_TYPE_FIXED_BUTTON, BM_HID_POWER_BUTTON);
	}

	if (acpi_fadt.sleep_button == 0) {
		bm_add_fixed_feature_device(node_list.nodes[0],
			BM_TYPE_FIXED_BUTTON, BM_HID_SLEEP_BUTTON);
	}

	return_ACPI_STATUS(AE_OK);
}


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

ACPI_STATUS
bm_get_handle (
	ACPI_HANDLE             acpi_handle,
	BM_HANDLE               *device_handle)
{
	ACPI_STATUS             status = AE_OK;
	u32			i = 0;

	FUNCTION_TRACE("bm_get_handle");

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

	*device_handle = BM_HANDLE_UNKNOWN;

	/*
	 * Search all devices for a match on the ACPI handle.
	 */
	for (i=0; i<node_list.count; i++) {

		if (!node_list.nodes[i]) {
			DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) node entry [0x%02x] detected.\n", device_handle));
			status = AE_NULL_ENTRY;
			break;
		}

		if (node_list.nodes[i]->device.acpi_handle == acpi_handle) {
			*device_handle = node_list.nodes[i]->device.handle;
			break;
		}
	}

	return_ACPI_STATUS(status);
}


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

ACPI_STATUS
bm_get_node (
	BM_HANDLE               device_handle,
	ACPI_HANDLE             acpi_handle,
	BM_NODE			**node)
{
	ACPI_STATUS             status = AE_OK;

	FUNCTION_TRACE("bm_get_node");

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

	/*
	 * If no device handle, resolve acpi handle to device handle.
	 */
	if (!device_handle && acpi_handle) {
		status = bm_get_handle(acpi_handle, &device_handle);
		if (ACPI_FAILURE(status))
			return_ACPI_STATUS(status);
	}

	/*
	 * Valid device handle?
	 */
	if (device_handle > BM_HANDLES_MAX) {
		DEBUG_PRINT(ACPI_ERROR, ("Invalid node handle [0x%02x] detected.\n", device_handle));
		return_ACPI_STATUS(AE_ERROR);
	}

	*node = node_list.nodes[device_handle];

	/*
	 * Valid node?
	 */
	if (!(*node)) {
		DEBUG_PRINT(ACPI_ERROR, ("Invalid (NULL) node entry [0x%02x] detected.\n", device_handle));
		return_ACPI_STATUS(AE_NULL_ENTRY);
	}

	return_ACPI_STATUS(AE_OK);
}


/****************************************************************************
 *                            External Functions
 ****************************************************************************/

/****************************************************************************
 *
 * FUNCTION:    bm_initialize
 *
 * PARAMETERS:  <none>
 *
 * RETURN:      Exception code.
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_initialize (void)
{
	ACPI_STATUS             status = AE_OK;
	u32                     start = 0;
	u32                     stop = 0;
	u32                     elapsed = 0;

	FUNCTION_TRACE("bm_initialize");

	MEMSET(&node_list, 0, sizeof(BM_HANDLE_LIST));

	acpi_get_timer(&start);

	DEBUG_PRINT(ACPI_INFO, ("Building device hierarchy.\n"));

	/*
	 * Enumerate ACPI fixed-feature devices.
	 */
	status = bm_enumerate_fixed_features();
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	/*
	 * Enumerate the ACPI namespace.
	 */
	status = bm_enumerate_namespace();
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
	}

	acpi_get_timer(&stop);
	acpi_get_timer_duration(start, stop, &elapsed);

	DEBUG_PRINT(ACPI_INFO, ("Device heirarchy build took [%d] microseconds.\n", elapsed));

	/*
	 * Display hierarchy.
	 */
#ifdef ACPI_DEBUG
	bm_print_hierarchy();
#endif /*ACPI_DEBUG*/

	/*
	 * Register for all standard and device-specific notifications.
	 */
	DEBUG_PRINT(ACPI_INFO, ("Registering for all device notifications.\n"));

	status = acpi_install_notify_handler(ACPI_ROOT_OBJECT,
		ACPI_SYSTEM_NOTIFY, &bm_notify, NULL);
	if (ACPI_FAILURE(status)) {
		DEBUG_PRINT(ACPI_ERROR, ("Unable to register for standard notifications.\n"));
		return_ACPI_STATUS(status);
	}

	status = acpi_install_notify_handler(ACPI_ROOT_OBJECT,
		ACPI_DEVICE_NOTIFY, &bm_notify, NULL);
	if (ACPI_FAILURE(status)) {
		DEBUG_PRINT(ACPI_ERROR, ("Unable to register for device-specific notifications.\n"));
		return_ACPI_STATUS(status);
	}

	/*
	 * Initialize /proc interface.
	 */
	//DEBUG_PRINT(ACPI_INFO, ("Initializing /proc interface.\n"));
	//status = bm_proc_initialize();

	DEBUG_PRINT(ACPI_INFO, ("ACPI Bus Manager enabled.\n"));

	/*
	 * Initialize built-in power resource driver.
	 */
	bm_pr_initialize();

	return_ACPI_STATUS(status);
}


/****************************************************************************
 *
 * FUNCTION:    bm_terminate
 *
 * PARAMETERS:  <none>
 *
 * RETURN:      Exception code.
 *
 * DESCRIPTION: <TBD>
 *
 ****************************************************************************/

ACPI_STATUS
bm_terminate (void)
{
	ACPI_STATUS             status = AE_OK;
	u32                     i = 0;

	FUNCTION_TRACE("bm_terminate");

	/*
	 * Terminate built-in power resource driver.
	 */
	bm_pr_terminate();

	/*
	 * Remove the /proc interface.
	 */
	//DEBUG_PRINT(ACPI_INFO, ("Removing /proc interface.\n"));
	//status = bm_proc_terminate();


	/*
	 * Unregister for all notifications.
	 */

	DEBUG_PRINT(ACPI_INFO, ("Unregistering for device notifications.\n"));

	status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT,
		ACPI_SYSTEM_NOTIFY, &bm_notify);
	if (ACPI_FAILURE(status)) {
		DEBUG_PRINT(ACPI_ERROR, ("Unable to un-register for standard notifications.\n"));
	}

	status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT,
		ACPI_DEVICE_NOTIFY, &bm_notify);
	if (ACPI_FAILURE(status)) {
		DEBUG_PRINT(ACPI_ERROR, ("Unable to un-register for device-specific notifications.\n"));
	}

	/*
	 * Parse through the device array, freeing all entries.
	 */
	DEBUG_PRINT(ACPI_INFO, ("Removing device hierarchy.\n"));
	for (i = 0; i < node_list.count; i++) {
		if (node_list.nodes[i]) {
			acpi_os_free(node_list.nodes[i]);
		}
	}

	DEBUG_PRINT(ACPI_INFO, ("ACPI Bus Manager disabled.\n"));

	return_ACPI_STATUS(AE_OK);
}

⌨️ 快捷键说明

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