Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/srv/devman/devman.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -62,4 +62,14 @@
 }
 
+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)
 {
@@ -75,4 +85,10 @@
 	.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
 };
@@ -376,4 +392,5 @@
 	printf(NAME ": create_root_node\n");
 
+	fibril_rwlock_write_lock(&tree->rwlock);
 	node = create_dev_node();
 	if (node != NULL) {
@@ -385,4 +402,5 @@
 		tree->root_node = node;
 	}
+	fibril_rwlock_write_unlock(&tree->rwlock);
 
 	return node != NULL;
@@ -447,6 +465,4 @@
 /** 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
@@ -457,4 +473,6 @@
 	int rc;
 
+	assert(fibril_mutex_is_locked(&drv->driver_mutex));
+	
 	printf(NAME ": start_driver '%s'\n", drv->name);
 	
@@ -678,5 +696,6 @@
 	}
 	
-	devmap_device_register(devmap_pathname, &node->devmap_handle);
+	devmap_device_register_with_iface(devmap_pathname,
+	    &node->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
 	
 	tree_add_devmap_device(tree, node);
@@ -850,6 +869,4 @@
 /** 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.
@@ -859,5 +876,9 @@
 {
 	unsigned long key = handle;
-	link_t *link = hash_table_find(&tree->devman_devices, &key);
+	link_t *link;
+	
+	assert(fibril_rwlock_is_locked(&tree->rwlock));
+	
+	link = hash_table_find(&tree->devman_devices, &key);
 	return hash_table_get_instance(link, node_t, devman_link);
 }
@@ -915,7 +936,4 @@
 /** 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. 
@@ -932,4 +950,5 @@
 	assert(tree != NULL);
 	assert(dev_name != NULL);
+	assert(fibril_rwlock_is_write_locked(&tree->rwlock));
 	
 	node->name = dev_name;
@@ -1050,6 +1069,10 @@
 	
 	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;
@@ -1175,5 +1198,5 @@
 	fibril_rwlock_initialize(&class_list->rwlock);
 	hash_table_create(&class_list->devmap_devices, DEVICE_BUCKETS, 1,
-	    &devmap_devices_ops);
+	    &devmap_devices_class_ops);
 }
 
@@ -1223,4 +1246,6 @@
 	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);
 }
 
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision 1f383dde20a2b1e39baa81fbc44a73c126e508e4)
+++ uspace/srv/devman/main.c	(revision 2b0db9835c1e32e672c7506f3f3c9de6201714cd)
@@ -281,5 +281,6 @@
 	 * handle.
 	 */
-	devmap_device_register(devmap_pathname, &cli->devmap_handle);
+	devmap_device_register_with_iface(devmap_pathname,
+	    &cli->devmap_handle, DEVMAN_CONNECT_FROM_DEVMAP);
 	
 	/*
@@ -457,6 +458,7 @@
 	
 	if (driver == NULL) {
-		printf(NAME ": devman_forward error - the device is not in %" PRIun
-		    " usable state.\n", handle);
+		printf(NAME ": devman_forward error - the device %" PRIun \
+		    " (%s) is not in usable state.\n",
+		    handle, dev->pathname);
 		ipc_answer_0(iid, ENOENT);
 		return;
@@ -486,5 +488,5 @@
 static void devman_connection_devmapper(ipc_callid_t iid, ipc_call_t *icall)
 {
-	devmap_handle_t devmap_handle = IPC_GET_IMETHOD(*icall);
+	devmap_handle_t devmap_handle = IPC_GET_ARG2(*icall);
 	node_t *dev;
 
@@ -503,8 +505,8 @@
 	}
 	
-	printf(NAME ": devman_connection_devmapper: forward connection to "
-	    "device %s to driver %s.\n", dev->pathname, dev->drv->name);
 	ipc_forward_fast(iid, dev->drv->phone, DRIVER_CLIENT, dev->handle, 0,
 	    IPC_FF_NONE);
+	printf(NAME ": devman_connection_devmapper: forwarded connection to "
+	    "device %s to driver %s.\n", dev->pathname, dev->drv->name);
 }
 
@@ -512,22 +514,4 @@
 static void devman_connection(ipc_callid_t iid, ipc_call_t *icall)
 {
-	/*
-	 * Silly hack to enable the device manager to register as a driver by
-	 * the device mapper. If the ipc method is not IPC_M_CONNECT_ME_TO, this
-	 * is not the forwarded connection from naming service, so it must be a
-	 * connection from the devmapper which thinks this is a devmapper-style
-	 * driver. So pretend this is a devmapper-style driver. (This does not
-	 * work for device with handle == IPC_M_CONNECT_ME_TO, because devmapper
-	 * passes device handle to the driver as an ipc method.)
-	 */
-	if (IPC_GET_IMETHOD(*icall) != IPC_M_CONNECT_ME_TO)
-		devman_connection_devmapper(iid, icall);
-
-	/*
-	 * ipc method is IPC_M_CONNECT_ME_TO, so this is forwarded connection
-	 * from naming service by which we registered as device manager, so be
-	 * device manager.
-	 */
-	
 	/* Select interface. */
 	switch ((sysarg_t) (IPC_GET_ARG1(*icall))) {
@@ -542,4 +526,8 @@
 		devman_forward(iid, icall, false);
 		break;
+	case DEVMAN_CONNECT_FROM_DEVMAP:
+		/* Someone connected through devmap node. */
+		devman_connection_devmapper(iid, icall);
+		break;
 	case DEVMAN_CONNECT_TO_PARENTS_DEVICE:
 		/* Connect client to selected device. */
