* 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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user