Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 01b87dc5664e19efa4e06cec91860b0ef1ece7da)
+++ uspace/srv/devman/devman.c	(revision 0b5a41318bb6a61d594dc8dff3453b5d212638ba)
@@ -62,14 +62,4 @@
 }
 
-static int devmap_devices_class_compare(unsigned long key[], hash_count_t keys,
-    link_t *item)
-{
-	dev_class_info_t *class_info
-	    = hash_table_get_instance(item, dev_class_info_t, devmap_link);
-	assert(class_info != NULL);
-
-	return (class_info->devmap_handle == (devmap_handle_t) key[0]);
-}
-
 static void devices_remove_callback(link_t *item)
 {
@@ -85,10 +75,4 @@
 	.hash = devices_hash,
 	.compare = devmap_devices_compare,
-	.remove_callback = devices_remove_callback
-};
-
-static hash_table_operations_t devmap_devices_class_ops = {
-	.hash = devices_hash,
-	.compare = devmap_devices_class_compare,
 	.remove_callback = devices_remove_callback
 };
@@ -384,5 +368,4 @@
 	printf(NAME ": create_root_node\n");
 
-	fibril_rwlock_write_lock(&tree->rwlock);
 	node = create_dev_node();
 	if (node != NULL) {
@@ -394,5 +377,4 @@
 		tree->root_node = node;
 	}
-	fibril_rwlock_write_unlock(&tree->rwlock);
 
 	return node != NULL;
@@ -457,4 +439,6 @@
 /** Start a driver
  *
+ * The driver's mutex is assumed to be locked.
+ *
  * @param drv		The driver's structure.
  * @return		True if the driver's task is successfully spawned, false
@@ -465,6 +449,4 @@
 	int rc;
 
-	assert(fibril_mutex_is_locked(&drv->driver_mutex));
-	
 	printf(NAME ": start_driver '%s'\n", drv->name);
 	
@@ -516,5 +498,5 @@
  * @param phone		The phone to the driver.
  */
-void set_driver_phone(driver_t *driver, sysarg_t phone)
+void set_driver_phone(driver_t *driver, ipcarg_t phone)
 {
 	fibril_mutex_lock(&driver->driver_mutex);
@@ -526,4 +508,6 @@
 /** 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.
  */
@@ -534,75 +518,18 @@
 	int phone;
 
-	printf(NAME ": pass_devices_to_driver(`%s')\n", driver->name);
-
-	fibril_mutex_lock(&driver->driver_mutex);
-
-	phone = async_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 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) {
+	printf(NAME ": pass_devices_to_driver\n");
+
+	phone = ipc_connect_me_to(driver->phone, DRIVER_DEVMAN, 0, 0);
+	if (phone > 0) {
+		
+		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;
-			continue;
 		}
-
-		/*
-		 * We remove the device from the list to allow safe adding
-		 * of new devices (no one will touch our item this way).
-		 */
-		list_remove(link);
-
-		/*
-		 * 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);
-
-		/*
-		 * Insert the device back.
-		 * The order is not relevant here so no harm is done
-		 * (actually, the order would be preserved in most cases).
-		 */
-		list_append(link, &driver->devices);
-
-		/*
-		 * Restart the cycle to go through all devices again.
-		 */
-		link = driver->devices.next;
-	}
-
-	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.
-	 */
-	printf(NAME ": driver %s goes into running state.\n", driver->name);
-	driver->state = DRIVER_RUNNING;
-
-	fibril_mutex_unlock(&driver->driver_mutex);
+		
+		ipc_hangup(phone);
+	}
 }
 
@@ -618,5 +545,6 @@
 void initialize_running_driver(driver_t *driver, dev_tree_t *tree)
 {
-	printf(NAME ": initialize_running_driver (`%s')\n", driver->name);
+	printf(NAME ": initialize_running_driver\n");
+	fibril_mutex_lock(&driver->driver_mutex);
 	
 	/*
@@ -625,4 +553,9 @@
 	 */
 	pass_devices_to_driver(driver, tree);
+	
+	/* Change driver's state to running. */
+	driver->state = DRIVER_RUNNING;
+	
+	fibril_mutex_unlock(&driver->driver_mutex);
 }
 
@@ -688,6 +621,5 @@
 	}
 	
-	devmap_device_register_with_iface(devmap_pathname,
-	    &node->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
+	devmap_device_register(devmap_pathname, &node->devmap_handle);
 	
 	tree_add_devmap_device(tree, node);
@@ -697,4 +629,5 @@
 }
 
+
 /** Pass a device to running driver.
  *
@@ -704,24 +637,12 @@
 void add_device(int phone, driver_t *drv, node_t *node, dev_tree_t *tree)
 {
-	/*
-	 * 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);
-	
-	sysarg_t rc;
+	printf(NAME ": add_device\n");
+	
+	ipcarg_t rc;
 	ipc_call_t answer;
 	
 	/* Send the device to the driver. */
-	devman_handle_t parent_handle;
-	if (node->parent) {
-		parent_handle = node->parent->handle;
-	} else {
-		parent_handle = 0;
-	}
-
-	aid_t req = async_send_2(phone, DRIVER_ADD_DEVICE, node->handle,
-	    parent_handle, &answer);
+	aid_t req = async_send_1(phone, DRIVER_ADD_DEVICE, node->handle,
+	    &answer);
 	
 	/* Send the device's name to the driver. */
@@ -731,8 +652,7 @@
 		/* TODO handle error */
 	}
-
+	
 	/* Wait for answer from the driver. */
 	async_wait_for(req, &rc);
-
 	switch(rc) {
 	case EOK:
@@ -747,6 +667,4 @@
 	}
 	
-	node->passed_to_driver = true;
-
 	return;
 }
@@ -774,15 +692,12 @@
 	attach_driver(node, drv);
 	
-	fibril_mutex_lock(&drv->driver_mutex);
 	if (drv->state == DRIVER_NOT_STARTED) {
 		/* Start the driver. */
 		start_driver(drv);
 	}
-	bool is_running = drv->state == DRIVER_RUNNING;
-	fibril_mutex_unlock(&drv->driver_mutex);
-
-	if (is_running) {
+	
+	if (drv->state == DRIVER_RUNNING) {
 		/* Notify the driver about the new device. */
-		int phone = async_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
+		int phone = ipc_connect_me_to(drv->phone, DRIVER_DEVMAN, 0, 0);
 		if (phone > 0) {
 			add_device(phone, drv, node, tree);
@@ -861,4 +776,6 @@
 /** 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.
@@ -868,9 +785,5 @@
 {
 	unsigned long key = handle;
-	link_t *link;
-	
-	assert(fibril_rwlock_is_locked(&tree->rwlock));
-	
-	link = hash_table_find(&tree->devman_devices, &key);
+	link_t *link = hash_table_find(&tree->devman_devices, &key);
 	return hash_table_get_instance(link, node_t, devman_link);
 }
@@ -928,4 +841,7 @@
 /** 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. 
@@ -942,8 +858,8 @@
 	assert(tree != NULL);
 	assert(dev_name != NULL);
-	assert(fibril_rwlock_is_write_locked(&tree->rwlock));
 	
 	node->name = dev_name;
 	if (!set_dev_path(node, parent)) {
+		fibril_rwlock_write_unlock(&tree->rwlock);
 		return false;
 	}
@@ -1061,10 +977,6 @@
 	
 	info = (dev_class_info_t *) malloc(sizeof(dev_class_info_t));
-	if (info != NULL) {
+	if (info != NULL)
 		memset(info, 0, sizeof(dev_class_info_t));
-		list_initialize(&info->dev_classes);
-		list_initialize(&info->devmap_link);
-		list_initialize(&info->link);
-	}
 	
 	return info;
@@ -1102,5 +1014,5 @@
 	
 	size_t idx = get_new_class_dev_idx(cl);
-	asprintf(&dev_name, "%s%zu", base_name, idx);
+	asprintf(&dev_name, "%s%d", base_name, idx);
 	
 	return dev_name;
@@ -1171,8 +1083,6 @@
 	while (link != &class_list->classes) {
 		cl = list_get_instance(link, dev_class_t, link);
-		if (str_cmp(cl->name, class_name) == 0) {
+		if (str_cmp(cl->name, class_name) == 0)
 			return cl;
-		}
-		link = link->next;
 	}
 	
@@ -1190,5 +1100,5 @@
 	fibril_rwlock_initialize(&class_list->rwlock);
 	hash_table_create(&class_list->devmap_devices, DEVICE_BUCKETS, 1,
-	    &devmap_devices_class_ops);
+	    &devmap_devices_ops);
 }
 
@@ -1238,6 +1148,4 @@
 	hash_table_insert(&class_list->devmap_devices, &key, &cli->devmap_link);
 	fibril_rwlock_write_unlock(&class_list->rwlock);
-
-	assert(find_devmap_class_device(class_list, cli->devmap_handle) != NULL);
 }
 
