From 3277aade49d84f4562a8bd20d165927104c802fb Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 7 Feb 2006 02:29:14 +0000 Subject: [PATCH] * Added get_root() to device_manager_info. Surprisingly enough, it returns the root device node. Now its actually possible to traverse the device node tree without a node to start with. * Fixed execution order problem in dm_get_next_child_node(). The supplied node was put first (which could cause its immediate deletion), but was still accessed thereafter. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16268 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/device_manager.h | 2 ++ .../kernel/device_manager/device_manager.c | 1 + .../device_manager/device_manager_private.h | 1 + src/system/kernel/device_manager/nodes.c | 23 +++++++++++++++---- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/headers/os/drivers/device_manager.h b/headers/os/drivers/device_manager.h index 539aa882e7..4df541a108 100644 --- a/headers/os/drivers/device_manager.h +++ b/headers/os/drivers/device_manager.h @@ -77,6 +77,7 @@ typedef struct device_manager_info { device_node_handle *node); status_t (*unregister_device)(device_node_handle node); + device_node_handle (*get_root)(); status_t (*get_next_child_device)(device_node_handle parent, device_node_handle *_node, const device_attr *attrs); device_node_handle (*get_parent)(device_node_handle node); @@ -165,6 +166,7 @@ struct driver_module_info { #define B_MISC_DRIVER_TYPE "misc" #define B_NETWORK_DRIVER_TYPE "net" #define B_VIDEO_DRIVER_TYPE "video" +#define B_INTERRUPT_CONTROLLER_DRIVER_TYPE "interrupt controller" #define PNP_DRIVER_CONNECTION "connection" // connection of parent the device is attached to (optional, string) diff --git a/src/system/kernel/device_manager/device_manager.c b/src/system/kernel/device_manager/device_manager.c index 4d0e4c67e2..c994a429d1 100644 --- a/src/system/kernel/device_manager/device_manager.c +++ b/src/system/kernel/device_manager/device_manager.c @@ -79,6 +79,7 @@ device_manager_info gDeviceManagerModule = { dm_register_node, dm_unregister_node, + dm_get_root, dm_get_next_child_node, dm_get_parent, dm_put_node, diff --git a/src/system/kernel/device_manager/device_manager_private.h b/src/system/kernel/device_manager/device_manager_private.h index 212c7244f3..6ddf8a6a18 100644 --- a/src/system/kernel/device_manager/device_manager_private.h +++ b/src/system/kernel/device_manager/device_manager_private.h @@ -173,6 +173,7 @@ status_t dm_init_nodes(void); void dm_put_node(device_node_info *node); status_t dm_get_next_child_node(device_node_info *parent, device_node_info **_node, const device_attr *attrs); +device_node_info *dm_get_root(void); device_node_info *dm_get_parent(device_node_info *node); diff --git a/src/system/kernel/device_manager/nodes.c b/src/system/kernel/device_manager/nodes.c index 5eb629e405..309fc7e7fd 100644 --- a/src/system/kernel/device_manager/nodes.c +++ b/src/system/kernel/device_manager/nodes.c @@ -328,7 +328,7 @@ dm_get_node(device_node_info *node) // remove node reference and clean it up if necessary -// (node_lock must be hold) +// (gNodeLock must be hold) void dm_put_node_nolock(device_node_info *node) @@ -453,6 +453,14 @@ dm_put_node(device_node_info *node) } +device_node_info * +dm_get_root(void) +{ + dm_get_node(gRootNode); + return gRootNode; +} + + device_node_info * dm_get_parent(device_node_info *node) { @@ -466,9 +474,8 @@ dm_get_next_child_node(device_node_info *parent, device_node_info **_node, const device_attr *attrs) { device_node_info *node = *_node; - if (node != NULL) - dm_put_node(node); - + device_node_info *nodeToPut = node; + benaphore_lock(&gNodeLock); while ((node = (device_node_info *)list_get_next_item(&parent->children, node)) != NULL) { @@ -490,10 +497,18 @@ dm_get_next_child_node(device_node_info *parent, device_node_info **_node, // we found a node dm_get_node_nolock(node); *_node = node; + + if (nodeToPut != NULL) + dm_put_node_nolock(nodeToPut); + benaphore_unlock(&gNodeLock); + return B_OK; } + if (nodeToPut != NULL) + dm_put_node_nolock(nodeToPut); + benaphore_unlock(&gNodeLock); return B_ENTRY_NOT_FOUND; }