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;
 }
