Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 1b2981aa4534d1e72927b34c33a3551d89bdf9d8)
+++ uspace/srv/devman/devman.c	(revision 5bee89701dfeeaf6af54574b17587ff273a9d444)
@@ -508,6 +508,4 @@
 /** Notify driver about the devices to which it was assigned.
  *
- * The driver's mutex must be locked.
- *
  * @param driver	The driver to which the devices are passed.
  */
@@ -520,16 +518,59 @@
 	printf(NAME ": pass_devices_to_driver\n");
 
+	fibril_mutex_lock(&driver->driver_mutex);
+
 	phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
-	if (phone > 0) {
-		
+
+	if (phone < 0) {
+		fibril_mutex_unlock(&driver->driver_mutex);
+		return;
+	}
+
+	/*
+	 * Go through devices list as long as there is some device
+	 * that has not been passed to the driver.
+	 */
+	link = driver->devices.next;
+	while (link != &driver->devices) {
+		dev = list_get_instance(link, node_t, driver_devices);
+		if (dev->passed_to_driver) {
+			link = link->next;
+			continue;
+		}
+
+		/*
+		 * Unlock to avoid deadlock when adding device
+		 * handled by itself.
+		 */
+		fibril_mutex_unlock(&driver->driver_mutex);
+
+		add_device(phone, driver, dev, tree);
+
+		/*
+		 * Lock again as we will work with driver's
+		 * structure.
+		 */
+		fibril_mutex_lock(&driver->driver_mutex);
+
+		/*
+		 * Restart the cycle to go through all devices again.
+		 */
 		link = driver->devices.next;
-		while (link != &driver->devices) {
-			dev = list_get_instance(link, node_t, driver_devices);
-			add_device(phone, driver, dev, tree);
-			link = link->next;
-		}
-		
-		ipc_hangup(phone);
-	}
+	}
+
+	ipc_hangup(phone);
+
+	/*
+	 * Once we passed all devices to the driver, we need to mark the
+	 * driver as running.
+	 * It is vital to do it here and inside critical section.
+	 *
+	 * If we would change the state earlier, other devices added to
+	 * the driver would be added to the device list and started
+	 * immediately and possibly started here as well.
+	 */
+	driver->state = DRIVER_RUNNING;
+
+	fibril_mutex_unlock(&driver->driver_mutex);
 }
 
@@ -546,5 +587,4 @@
 {
 	printf(NAME ": initialize_running_driver\n");
-	fibril_mutex_lock(&driver->driver_mutex);
 	
 	/*
@@ -553,9 +593,4 @@
 	 */
 	pass_devices_to_driver(driver, tree);
-	
-	/* Change driver's state to running. */
-	driver->state = DRIVER_RUNNING;
-	
-	fibril_mutex_unlock(&driver->driver_mutex);
 }
 
@@ -637,5 +672,10 @@
 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
 {
-	printf(NAME ": add_device\n");
+	/*
+	 * We do not expect to have driver's mutex locked as we do not
+	 * access any structures that would affect driver_t.
+	 */
+	printf(NAME ": add_device (driver `%s', device `%s')\n", drv->name,
+	    node->name);
 	
 	ipcarg_t rc;
@@ -649,4 +689,5 @@
 		parent_handle = 0;
 	}
+
 	aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,
 	    parent_handle, &answer);
@@ -661,4 +702,5 @@
 	/* Wait for answer from the driver. */
 	async_wait_for(req, &rc);
+
 	switch(rc) {
 	case EOK:
@@ -673,4 +715,6 @@
 	}
 	
+	node->passed_to_driver = true;
+
 	return;
 }
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision 1b2981aa4534d1e72927b34c33a3551d89bdf9d8)
+++ uspace/srv/devman/devman.h	(revision 5bee89701dfeeaf6af54574b17587ff273a9d444)
@@ -168,4 +168,9 @@
 	 */
 	link_t devmap_link;
+
+	/**
+	 * Whether this device was already passed to the driver.
+	 */
+	bool passed_to_driver;
 };
 
