📄 bm.c
字号:
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. * * TBD: Inherit! */ if (BM_IS_POWER_CONTROL(device)) { 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; (*child) = node; } return_ACPI_STATUS(status);}/**************************************************************************** * * FUNCTION: bm_enumerate_namespace * * PARAMETERS: <none> * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_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)) { /* * TBD: 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: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_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; /* TBD: 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: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_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; /* TBD: 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: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_get_handle ( acpi_handle acpi_handle, BM_HANDLE *device_handle){ acpi_status status = AE_NOT_FOUND; 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]) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) node entry [%p] 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; status = AE_OK; break; } } return_ACPI_STATUS(status);}/**************************************************************************** * * FUNCTION: bm_get_node * * PARAMETERS: * * RETURN: * * DESCRIPTION: * ****************************************************************************/acpi_statusbm_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); } /* busmgr failed to init, but we're being called by subordinate drivers */ if (node_list.count < 1) { return_ACPI_STATUS(AE_NOT_FOUND); } /* * 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) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid node handle [%02x] detected.\n", device_handle)); return_ACPI_STATUS(AE_ERROR); } *node = node_list.nodes[device_handle]; /* * Valid node? */ if (!(*node)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) node entry [%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: * ****************************************************************************/acpi_statusbm_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_NODE_LIST)); status = acpi_get_timer(&start); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } ACPI_DEBUG_PRINT ((ACPI_DB_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); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Building device hierarchy took [%d] microseconds.\n", elapsed)); /* * Display hierarchy. */ bm_print_hierarchy(); /* * Register for all standard and device-specific notifications. */ ACPI_DEBUG_PRINT ((ACPI_DB_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)) { ACPI_DEBUG_PRINT ((ACPI_DB_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)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to register for device-specific notifications.\n")); return_ACPI_STATUS(status); } ACPI_DEBUG_PRINT ((ACPI_DB_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: * ****************************************************************************/acpi_statusbm_terminate (void){ acpi_status status = AE_OK; u32 i = 0; FUNCTION_TRACE("bm_terminate"); /* * Terminate built-in power resource driver. */ bm_pr_terminate(); /* * Unregister for all notifications. */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Unregistering for device notifications.\n")); status = acpi_remove_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY, &bm_notify); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT ((ACPI_DB_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)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unable to un-register for device-specific notifications.\n")); } /* * Parse through the device array, freeing all entries. */ ACPI_DEBUG_PRINT ((ACPI_DB_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]); } } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Bus Manager disabled.\n")); return_ACPI_STATUS(AE_OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -