Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision d51ee2b4b8df06f1db92623840353f34771a405b)
+++ uspace/srv/devman/devman.c	(revision 957cfa58e9f28dbcaf9efd98ce73ec541a8166fe)
@@ -39,4 +39,39 @@
 #include "devman.h"
 
+// hash table operations
+
+static hash_index_t devices_hash(unsigned long key[])
+{
+	return key[0] % DEVICE_BUCKETS;
+}
+
+static int devman_devices_compare(unsigned long key[], hash_count_t keys, link_t *item)
+{
+	node_t *dev = hash_table_get_instance(item, node_t, devman_link);
+	return (dev->handle == (device_handle_t) key[0]);
+}
+
+static int devmap_devices_compare(unsigned long key[], hash_count_t keys, link_t *item)
+{
+	node_t *dev = hash_table_get_instance(item, node_t, devmap_link);
+	return (dev->devmap_handle == (dev_handle_t) key[0]);
+}
+
+static void devices_remove_callback(link_t *item)
+{
+}
+
+static hash_table_operations_t devman_devices_ops = {
+	.hash = devices_hash,
+	.compare = devman_devices_compare,
+	.remove_callback = devices_remove_callback
+};
+
+static hash_table_operations_t devmap_devices_ops = {
+	.hash = devices_hash,
+	.compare = devmap_devices_compare,
+	.remove_callback = devices_remove_callback
+};
+
 /** Allocate and initialize a new driver structure.
  * 
@@ -584,7 +619,10 @@
 	printf(NAME ": init_device_tree.\n");
 	
-	memset(tree->node_map, 0, MAX_DEV * sizeof(node_t *));
-	
-	atomic_set(&tree->current_handle, 0);
+	tree->current_handle = 0;
+	
+	hash_table_create(&tree->devman_devices, DEVICE_BUCKETS, 1, &devman_devices_ops);
+	hash_table_create(&tree->devmap_devices, DEVICE_BUCKETS, 1, &devmap_devices_ops);
+	
+	fibril_rwlock_initialize(&tree->rwlock);
 	
 	// create root node and add it to the device tree
@@ -630,4 +668,6 @@
 /** Insert new device into device tree.
  * 
+ * The device tree's rwlock should be already held exclusively when calling this function.
+ * 
  * @param tree the device tree.
  * @param node the newly added device node. 
@@ -644,25 +684,18 @@
 	node->name = dev_name;
 	if (!set_dev_path(node, parent)) {
+		fibril_rwlock_write_unlock(&tree->rwlock);
 		return false;		
 	}
 	
 	// add the node to the handle-to-node map
-	node->handle = atomic_postinc(&tree->current_handle);
-	if (node->handle >= MAX_DEV) {
-		printf(NAME ": failed to add device to device tree, because maximum number of devices was reached.\n");
-		free(node->pathname);
-		node->pathname = NULL;
-		atomic_postdec(&tree->current_handle);
-		return false;
-	}
-	tree->node_map[node->handle] = node;
+	node->handle = ++tree->current_handle;
+	unsigned long key = node->handle;
+	hash_table_insert(&tree->devman_devices, &key, &node->devman_link);
 
 	// add the node to the list of its parent's children
 	node->parent = parent;
 	if (NULL != parent) {
-		fibril_mutex_lock(&parent->children_mutex);
-		list_append(&node->sibling, &parent->children);
-		fibril_mutex_unlock(&parent->children_mutex);
-	}	
+		list_append(&node->sibling, &parent->children);		
+	}
 	return true;
 }
@@ -678,4 +711,6 @@
 node_t * find_dev_node_by_path(dev_tree_t *tree, char *path)
 {
+	fibril_rwlock_read_lock(&tree->rwlock);
+	
 	node_t *dev = tree->root_node;
 	// relative path to the device from its parent (but with '/' at the beginning)
@@ -702,4 +737,6 @@
 	}
 	
+	fibril_rwlock_read_unlock(&tree->rwlock);
+	
 	return dev;
 }
@@ -708,4 +745,6 @@
  * Find child device node with a specified name.
  * 
+ * Device tree rwlock should be held at least for reading. 
+ * 
  * @param parent the parent device node.
  * @param name the name of the child device node.
@@ -717,6 +756,5 @@
 	node_t *dev;
 	link_t *link;
-	
-	fibril_mutex_lock(&parent->children_mutex);		
+			
 	link = parent->children.next;
 	
@@ -725,5 +763,4 @@
 		
 		if (0 == str_cmp(name, dev->name)) {
-			fibril_mutex_unlock(&parent->children_mutex);
 			return dev;			
 		}
@@ -731,6 +768,5 @@
 		link = link->next;
 	}	
-	
-	fibril_mutex_unlock(&parent->children_mutex);	
+		
 	return NULL;
 }
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision d51ee2b4b8df06f1db92623840353f34771a405b)
+++ uspace/srv/devman/devman.h	(revision 957cfa58e9f28dbcaf9efd98ce73ec541a8166fe)
@@ -39,4 +39,5 @@
 #include <str.h>
 #include <adt/list.h>
+#include <adt/hash_table.h>
 #include <ipc/ipc.h>
 #include <ipc/devman.h>
@@ -50,5 +51,5 @@
 
 #define MATCH_EXT ".ma"
-#define MAX_DEV 256
+#define DEVICE_BUCKETS 256
 
 struct node;
@@ -115,6 +116,4 @@
 	/** List of child device nodes. */
 	link_t children;
-	/** Fibril mutex for the list of child device nodes of this node. */
-	fibril_mutex_t children_mutex;
 	/** List of device ids for device-to-driver matching.*/
 	match_id_list_t match_ids;
@@ -128,5 +127,12 @@
 	/** The list of device classes to which this device belongs.*/
 	link_t classes;
+	/** Devmap handle if the device is registered by devmapper. */
+	dev_handle_t devmap_handle;
+	/** Used by the hash table of devices indexed by devman device handles.*/
+	link_t devman_link;
+	/** Used by the hash table of devices indexed by devmap device handles.*/
+	link_t devmap_link;
 };
+
 
 /** Represents device tree.
@@ -136,7 +142,12 @@
 	node_t *root_node;
 	/** The next available handle - handles are assigned in a sequential manner.*/
-	atomic_t current_handle;
-	/** Handle-to-node mapping. */
-	node_t * node_map[MAX_DEV];
+	device_handle_t current_handle;
+	/** Synchronize access to the device tree.*/
+	fibril_rwlock_t rwlock;
+	/** Hash table of all devices indexed by devman handles.*/
+	hash_table_t devman_devices;
+	/** Hash table of devices registered by devmapper, indexed by devmap handles.*/
+	hash_table_t devmap_devices;
+	
 } dev_tree_t;
 
@@ -277,5 +288,4 @@
 	list_initialize(&res->children);
 	list_initialize(&res->match_ids.ids);
-	fibril_mutex_initialize(&res->children_mutex);
 	
 	return res;
@@ -301,14 +311,35 @@
  * Find the device node structure of the device witch has the specified handle.
  * 
+ * Device tree's rwlock should be held at least for reading.
+ * 
  * @param tree the device tree where we look for the device node.
  * @param handle the handle of the device.
  * @return the device node. 
  */
-static inline node_t * find_dev_node(dev_tree_t *tree, long handle)
-{
-	if (handle < MAX_DEV) {
-		return tree->node_map[handle];
-	}
-	return NULL;
+static inline node_t * find_dev_node_no_lock(dev_tree_t *tree, device_handle_t handle)
+{
+	unsigned long key = handle;
+	link_t *link = hash_table_find(&tree->devman_devices, &key);
+	return hash_table_get_instance(link, node_t, devman_link);
+}
+
+/**
+ * Find the device node structure of the device witch has the specified handle.
+ * 
+ * @param tree the device tree where we look for the device node.
+ * @param handle the handle of the device.
+ * @return the device node. 
+ */
+static inline node_t * find_dev_node(dev_tree_t *tree, device_handle_t handle)
+{
+	node_t *node = NULL;
+	
+	fibril_rwlock_read_lock(&tree->rwlock);
+	
+	node = find_dev_node_no_lock(tree, handle);
+	
+	fibril_rwlock_read_unlock(&tree->rwlock);
+	
+	return node;
 }
 
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision d51ee2b4b8df06f1db92623840353f34771a405b)
+++ uspace/srv/devman/main.c	(revision 957cfa58e9f28dbcaf9efd98ce73ec541a8166fe)
@@ -246,12 +246,15 @@
 static void devman_add_child(ipc_callid_t callid, ipc_call_t *call)
 {
-	// printf(NAME ": devman_add_child\n");
+	//printf(NAME ": devman_add_child\n");
 	
 	device_handle_t parent_handle = IPC_GET_ARG1(*call);
 	ipcarg_t match_count = IPC_GET_ARG2(*call);
-	
-	node_t *parent =  find_dev_node(&device_tree, parent_handle);
+	dev_tree_t *tree = &device_tree;
+	
+	fibril_rwlock_write_lock(&tree->rwlock);
+	node_t *parent =  find_dev_node_no_lock(&device_tree, parent_handle);
 	
 	if (NULL == parent) {
+		fibril_rwlock_write_unlock(&tree->rwlock);
 		ipc_answer_0(callid, ENOENT);
 		return;
@@ -261,15 +264,18 @@
 	int rc = async_string_receive(&dev_name, DEVMAN_NAME_MAXLEN, NULL);	
 	if (EOK != rc) {
+		fibril_rwlock_write_unlock(&tree->rwlock);
 		ipc_answer_0(callid, rc);
 		return;
 	}
-	// printf(NAME ": newly added child device's name is '%s'.\n", dev_name);
+	//printf(NAME ": newly added child device's name is '%s'.\n", dev_name);
 	
 	node_t *node = create_dev_node();
 	if (!insert_dev_node(&device_tree, node, dev_name, parent)) {
+		fibril_rwlock_write_unlock(&tree->rwlock);
 		delete_dev_node(node);
 		ipc_answer_0(callid, ENOMEM);
 		return;
 	}	
+	fibril_rwlock_write_unlock(&tree->rwlock);
 	
 	printf(NAME ": devman_add_child %s\n", node->pathname);
@@ -281,5 +287,5 @@
 	
 	// try to find suitable driver and assign it to the device	
-	assign_driver(node, &drivers_list);
+	assign_driver(node, &drivers_list);	
 }
 
