Index: uspace/srv/devman/devman.c
===================================================================
--- uspace/srv/devman/devman.c	(revision aff587ffd456eec701b28134f8ec9a4e58c66001)
+++ uspace/srv/devman/devman.c	(revision c1a04886f6fc4fd68787bad7a58a1e5f594797ce)
@@ -846,4 +846,12 @@
 		add_device(drv, dev, tree);
 	
+	fibril_mutex_lock(&drv->driver_mutex);
+	fibril_mutex_unlock(&drv->driver_mutex);
+
+	fibril_rwlock_write_lock(&tree->rwlock);
+	if (dev->pfun != NULL) {
+		dev->pfun->state = FUN_ON_LINE;
+	}
+	fibril_rwlock_write_unlock(&tree->rwlock);
 	return true;
 }
@@ -1106,4 +1114,5 @@
 		return NULL;
 	
+	fun->state = FUN_INIT;
 	atomic_set(&fun->refcnt, 0);
 	link_initialize(&fun->dev_functions);
@@ -1275,4 +1284,6 @@
 	dev->pfun->child = NULL;
 	dev->pfun = NULL;
+	
+	dev->state = DEVICE_REMOVED;
 }
 
@@ -1338,4 +1349,5 @@
 	
 	fun->dev = NULL;
+	fun->state = FUN_REMOVED;
 }
 
Index: uspace/srv/devman/devman.h
===================================================================
--- uspace/srv/devman/devman.h	(revision aff587ffd456eec701b28134f8ec9a4e58c66001)
+++ uspace/srv/devman/devman.h	(revision c1a04886f6fc4fd68787bad7a58a1e5f594797ce)
@@ -118,10 +118,12 @@
 } driver_list_t;
 
-/** The state of the device. */
+/** Device state */
 typedef enum {
 	DEVICE_NOT_INITIALIZED = 0,
 	DEVICE_USABLE,
 	DEVICE_NOT_PRESENT,
-	DEVICE_INVALID
+	DEVICE_INVALID,
+	/** Device node has been removed from the tree */
+	DEVICE_REMOVED
 } device_state_t;
 
@@ -157,8 +159,19 @@
 };
 
+/** Function state */
+typedef enum {
+	FUN_INIT = 0,
+	FUN_OFF_LINE,
+	FUN_ON_LINE,
+	/** Function node has been removed from the tree */
+	FUN_REMOVED
+} fun_state_t;
+
 /** Function node in the device tree. */
 struct fun_node {
 	/** Reference count */
 	atomic_t refcnt;
+	/** State */
+	fun_state_t state;
 	
 	/** The global unique identifier of the function */
Index: uspace/srv/devman/main.c
===================================================================
--- uspace/srv/devman/main.c	(revision aff587ffd456eec701b28134f8ec9a4e58c66001)
+++ uspace/srv/devman/main.c	(revision c1a04886f6fc4fd68787bad7a58a1e5f594797ce)
@@ -234,4 +234,7 @@
 	dev_node_t *dev_node = (dev_node_t *) arg;
 	assign_driver(dev_node, &drivers_list, &device_tree);
+
+	/* Delete one reference we got from the caller. */
+	dev_del_ref(dev_node);
 	return EOK;
 }
@@ -243,4 +246,11 @@
 	fibril_rwlock_write_lock(&device_tree.rwlock);
 
+	if (fun->state == FUN_ON_LINE) {
+		fibril_rwlock_write_unlock(&device_tree.rwlock);
+		log_msg(LVL_WARN, "Function %s is already on line.",
+		    fun->pathname);
+		return EOK;
+	}
+	
 	if (fun->ftype == fun_inner) {
 		dev = create_dev_node();
@@ -260,4 +270,6 @@
 		assert(dev != NULL);
 		
+		/* Give one reference over to assign_driver_fibril(). */
+		dev_add_ref(dev);
 		/*
 		 * Try to find a suitable driver and assign it to the device.  We do
@@ -269,12 +281,11 @@
 		fid_t assign_fibril = fibril_create(assign_driver_fibril, dev);
 		if (assign_fibril == 0) {
-			/*
-			 * Fallback in case we are out of memory.
-			 * Probably not needed as we will die soon anyway ;-).
-			 */
-			(void) assign_driver_fibril(fun);
-		} else {
-			fibril_add_ready(assign_fibril);
+			log_msg(LVL_ERROR, "Failed to create fibril for "
+			    "assigning driver.");
+			/* XXX Cleanup */
+			fibril_rwlock_write_unlock(&device_tree.rwlock);
+			return ENOMEM;
 		}
+		fibril_add_ready(assign_fibril);
 	} else {
 		loc_register_tree_function(fun, &device_tree);
@@ -291,4 +302,11 @@
 	
 	fibril_rwlock_write_lock(&device_tree.rwlock);
+	
+	if (fun->state == FUN_OFF_LINE) {
+		fibril_rwlock_write_unlock(&device_tree.rwlock);
+		log_msg(LVL_WARN, "Function %s is already off line.",
+		    fun->pathname);
+		return EOK;
+	}
 	
 	if (fun->ftype == fun_inner) {
@@ -329,4 +347,5 @@
 	}
 	
+	fun->state = FUN_OFF_LINE;
 	fibril_rwlock_write_unlock(&device_tree.rwlock);
 	
