Index: uspace/lib/libc/include/ipc/driver.h
===================================================================
--- uspace/lib/libc/include/ipc/driver.h	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
+++ uspace/lib/libc/include/ipc/driver.h	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef IPC_DRIVER_H_
+#define IPC_DRIVER_H_
+
+typedef enum {
+	DRIVER_DEVMAN = 1,
+	DRIVER_CLIENT,
+	DRIVER_DRIVER
+} driver_interface_t;
+
+
+#endif
+
+
+/**
+ * @}
+ */
Index: uspace/lib/libdrv/generic/driver.c
===================================================================
--- uspace/lib/libdrv/generic/driver.c	(revision 67ba3090d4246ace5e0aefc167571850e5b115b1)
+++ uspace/lib/libdrv/generic/driver.c	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
@@ -50,11 +50,44 @@
 #include <devman.h>
 #include <ipc/devman.h>
+#include <ipc/driver.h>
 
 #include "driver.h"
 
 static driver_t *driver;
+LIST_INITIALIZE(devices);
+
+static device_t* driver_create_device()
+{
+	device_t *dev = (device_t *)malloc(sizeof(device_t));
+	if (NULL != dev) {
+		memset(dev, 0, sizeof(device_t));		
+	}	
+	return dev;	
+}
+
+static void driver_add_device(ipc_callid_t iid, ipc_call_t *icall) 
+{
+	printf("%s: driver_add_device\n", driver->name);
+	
+	// result of the operation - device was added, device is not present etc.
+	ipcarg_t ret = 0;	
+	ipcarg_t dev_handle =  IPC_GET_ARG1(*icall);
+	
+	printf("%s: adding device with handle = %x \n", driver->name, dev_handle);
+	
+	device_t *dev = driver_create_device();
+	dev->handle = dev_handle;
+	if (driver->driver_ops->add_device(dev)) {
+		list_append(&dev->link, &devices);
+		// TODO set return value
+	}
+	
+	ipc_answer_1(iid, EOK, ret);
+}
 
 static void driver_connection_devman(ipc_callid_t iid, ipc_call_t *icall)
 {
+	printf("%s: driver_connection_devman \n", driver->name);
+	
 	/* Accept connection */
 	ipc_answer_0(iid, EOK);
@@ -70,5 +103,5 @@
 			continue;
 		case DRIVER_ADD_DEVICE:
-			// TODO
+			driver_add_device(callid, &call);
 			break;
 		default:
Index: uspace/lib/libdrv/include/driver.h
===================================================================
--- uspace/lib/libdrv/include/driver.h	(revision 67ba3090d4246ace5e0aefc167571850e5b115b1)
+++ uspace/lib/libdrv/include/driver.h	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
@@ -32,19 +32,19 @@
 /** @file
  */
-
 #ifndef LIBDRV_DRIVER_H_
 #define LIBDRV_DRIVER_H_
 
-typedef enum {
-	DRIVER_DEVMAN = 1,
-	DRIVER_CLIENT,
-	DRIVER_DRIVER
-} driver_interface_t;
+
+#include <adt/list.h>
+
+
 
 typedef struct device {
-	int parent_handle;
+	long handle;
 	ipcarg_t parent_phone;	
+	
 	// TODO add more items - parent bus type etc.
-	int handle;	
+	
+	link_t link;
 } device_t;
 
Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 67ba3090d4246ace5e0aefc167571850e5b115b1)
+++ uspace/srv/devman/devman.c	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
@@ -34,4 +34,6 @@
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <ipc/driver.h>
+#include <ipc/devman.h>
 
 #include "devman.h"
@@ -308,20 +310,22 @@
 }
 
-/** Create root device node of the device tree.
- * 
- * @return root device node.
- */
-node_t * create_root_node()
+/** Create root device node in the device tree.
+ * 
+ * @param tree the device tree.
+ * @return true on success, false otherwise.
+ */
+bool create_root_node(dev_tree_t *tree)
 {
 	printf(NAME ": create_root_node\n");
 	node_t *node = create_dev_node();
 	if (node) {
-		init_dev_node(node, NULL);
+		insert_dev_node(tree, node, NULL);
 		match_id_t *id = create_match_id();
 		id->id = "root";
 		id->score = 100;
 		add_match_id(&node->match_ids, id);
-	}
-	return node;	
+		tree->root_node = node;
+	}
+	return node != NULL;	
 }
 
@@ -448,10 +452,17 @@
 	link_t *link;
 	
-	link = driver->devices.next;
-	while (link != &driver->devices) {
-		dev = list_get_instance(link, node_t, driver_devices);
-		add_device(driver, dev);
-		link = link->next;
-	}	
+	int phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
+	
+	if (0 < phone) {
+		
+		link = driver->devices.next;
+		while (link != &driver->devices) {
+			dev = list_get_instance(link, node_t, driver_devices);
+			add_device(phone, driver, dev);
+			link = link->next;
+		}
+		
+		ipc_hangup(phone);
+	}
 }
 
@@ -463,5 +474,5 @@
  */
 void initialize_running_driver(driver_t *driver) 
-{
+{	
 	fibril_mutex_lock(&driver->driver_mutex);
 	
@@ -480,19 +491,21 @@
  * @param node the device's node in the device tree.
  */
-void add_device(driver_t *drv, node_t *node)
+void add_device(int phone, driver_t *drv, node_t *node)
 {
 	printf(NAME ": add_device\n");
-	
-	// TODO
-	
-	// pass a new device to the running driver, which was previously assigned to it
-		// send the phone of the parent's driver and device's handle within the parent's driver to the driver 
-		// let the driver to probe the device and specify whether the device is actually present
-		// if the device is present, remember its handle within the driver
+
+	ipcarg_t ret;
+	ipcarg_t rc = async_req_1_1(phone, DRIVER_ADD_DEVICE, node->handle, &ret);
+	if (rc != EOK) {
+		// TODO handle error
+		return false;
+	}
+	
+	// TODO inspect return value (ret) to find out whether the device was successfully probed and added
 	
 	return true;
 }
 
-/**
+/** 
  * Find suitable driver for a device and assign the driver to it.
  * 
@@ -523,5 +536,9 @@
 	if (DRIVER_RUNNING == drv->state) {
 		// notify driver about new device
-		add_device(drv, node);		
+		int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
+		if (phone > 0) {
+			add_device(phone, drv, node);		
+			ipc_hangup(phone);
+		}
 	}
 	
@@ -542,6 +559,8 @@
 	printf(NAME ": init_device_tree.\n");
 	
+	atomic_set(&tree->current_handle, 0);
+	
 	// create root node and add it to the device tree
-	if (NULL == (tree->root_node = create_root_node())) {
+	if (!create_root_node(tree)) {
 		return false;
 	}
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision 67ba3090d4246ace5e0aefc167571850e5b115b1)
+++ uspace/srv/devman/devman.h	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
@@ -41,4 +41,5 @@
 #include <ipc/ipc.h>
 #include <fibril_synch.h>
+#include <atomic.h>
 
 #include "util.h"
@@ -115,4 +116,6 @@
 /** Representation of a node in the device tree.*/
 struct node {
+	/** The global unique identifier of the device.*/
+	long handle;
 	/** The node of the parent device. */
 	node_t *parent;
@@ -137,4 +140,5 @@
 	/** Root device node. */
 	node_t *root_node;
+	atomic_t current_handle;
 } dev_tree_t;
 
@@ -191,5 +195,5 @@
 void add_driver(driver_list_t *drivers_list, driver_t *drv);
 void attach_driver(node_t *node, driver_t *drv);
-void add_device(driver_t *drv, node_t *node);
+void add_device(int phone, driver_t *drv, node_t *node);
 bool start_driver(driver_t *drv);
 
@@ -230,5 +234,4 @@
 
 // Device nodes
-node_t * create_root_node();
 
 static inline node_t * create_dev_node()
@@ -238,19 +241,23 @@
 		memset(res, 0, sizeof(node_t));
 	}
+	
+	list_initialize(&res->children);
+	list_initialize(&res->match_ids.ids);
+	
 	return res;
 }
 
-static inline void init_dev_node(node_t *node, node_t *parent)
-{
-	assert(NULL != node);
+static inline void insert_dev_node(dev_tree_t *tree, node_t *node, node_t *parent)
+{
+	assert(NULL != node && NULL != tree);
+	
+	node->handle = atomic_postinc(&tree->current_handle);
 
 	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_initialize(&node->children);
-
-	list_initialize(&node->match_ids.ids);
 }
 
@@ -259,4 +266,5 @@
 
 bool init_device_tree(dev_tree_t *tree, driver_list_t *drivers_list);
+bool create_root_node(dev_tree_t *tree);
 
 
Index: uspace/srv/drivers/root/root.c
===================================================================
--- uspace/srv/drivers/root/root.c	(revision 67ba3090d4246ace5e0aefc167571850e5b115b1)
+++ uspace/srv/drivers/root/root.c	(revision 084ff99a2c165918dddaf6cfa41eaf8810507a93)
@@ -65,4 +65,5 @@
 static bool root_add_device(device_t *dev) 
 {
+	printf(NAME ": root_add_device, device handle = %s", dev->handle);
 	// TODO add root device and register its children
 	return true;
