Index: kernel/arch/ia64/src/drivers/ski.c
===================================================================
--- kernel/arch/ia64/src/drivers/ski.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ kernel/arch/ia64/src/drivers/ski.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -37,4 +37,5 @@
 #include <console/console.h>
 #include <console/chardev.h>
+#include <ddi/ddi.h>
 #include <sysinfo/sysinfo.h>
 #include <stdint.h>
@@ -69,4 +70,5 @@
 
 static ski_instance_t *instance = NULL;
+static parea_t ski_parea;
 
 /** Ask debug console if a key was pressed.
@@ -105,4 +107,7 @@
 	int count = POLL_LIMIT;
 
+	if (ski_parea.mapped && !console_override)
+		return;
+
 	while (count > 0) {
 		wchar_t ch = ski_getchar();
@@ -122,10 +127,5 @@
 
 	while (true) {
-		// TODO FIXME:
-		// This currently breaks the kernel console
-		// before we get the override from uspace.
-		if (console_override)
-			poll_keyboard(instance);
-
+		poll_keyboard(instance);
 		thread_usleep(POLL_INTERVAL);
 	}
@@ -140,4 +140,6 @@
 static void ski_init(void)
 {
+	uintptr_t faddr;
+
 	if (instance)
 		return;
@@ -150,4 +152,17 @@
 	    : "r15", "r8"
 	);
+
+	faddr = frame_alloc(1, FRAME_LOWMEM | FRAME_ATOMIC, 0);
+	if (faddr == 0)
+		panic("Cannot allocate page for ski console.");
+
+	ddi_parea_init(&ski_parea);
+	ski_parea.pbase = faddr;
+	ski_parea.frames = 1;
+	ski_parea.unpriv = false;
+	ski_parea.mapped = false;
+	ddi_parea_register(&ski_parea);
+
+	sysinfo_set_item_val("ski.paddr", NULL, (sysarg_t) faddr);
 
 	instance = malloc(sizeof(ski_instance_t));
@@ -190,16 +205,14 @@
 static void ski_putwchar(outdev_t *dev, wchar_t ch)
 {
-	// TODO FIXME:
-	// This currently breaks the kernel console
-	// before we get the override from uspace.
-	if (console_override) {
-		if (ascii_check(ch)) {
-			if (ch == '\n')
-				ski_do_putchar('\r');
-
-			ski_do_putchar(ch);
-		} else {
-			ski_do_putchar('?');
-		}
+	if (ski_parea.mapped && !console_override)
+		return;
+
+	if (ascii_check(ch)) {
+		if (ch == '\n')
+			ski_do_putchar('\r');
+
+		ski_do_putchar(ch);
+	} else {
+		ski_do_putchar('?');
 	}
 }
Index: kernel/generic/include/mm/as.h
===================================================================
--- kernel/generic/include/mm/as.h	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ kernel/generic/include/mm/as.h	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -268,5 +268,4 @@
 
 extern as_t *as_create(unsigned int);
-extern void as_destroy(as_t *);
 extern void as_hold(as_t *);
 extern void as_release(as_t *);
Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ kernel/generic/src/console/console.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -209,4 +209,5 @@
 void grab_console(void)
 {
+	sysinfo_set_item_val("kconsole", NULL, true);
 	event_notify_1(EVENT_KCONSOLE, false, true);
 	bool prev = console_override;
@@ -226,4 +227,5 @@
 void release_console(void)
 {
+	sysinfo_set_item_val("kconsole", NULL, false);
 	console_override = false;
 	event_notify_1(EVENT_KCONSOLE, false, false);
Index: kernel/generic/src/mm/as.c
===================================================================
--- kernel/generic/src/mm/as.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ kernel/generic/src/mm/as.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -187,5 +187,5 @@
  *
  */
-void as_destroy(as_t *as)
+static void as_destroy(as_t *as)
 {
 	DEADLOCK_PROBE_INIT(p_asidlock);
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ kernel/generic/src/proc/program.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -150,5 +150,5 @@
 	prg->loader_status = elf_load((elf_header_t *) image_addr, as);
 	if (prg->loader_status != EE_OK) {
-		as_destroy(as);
+		as_release(as);
 		prg->task = NULL;
 		prg->main_thread = NULL;
@@ -176,5 +176,5 @@
 	void *loader = program_loader;
 	if (!loader) {
-		as_destroy(as);
+		as_release(as);
 		log(LF_OTHER, LVL_ERROR,
 		    "Cannot spawn loader as none was registered");
@@ -184,5 +184,5 @@
 	prg->loader_status = elf_load((elf_header_t *) program_loader, as);
 	if (prg->loader_status != EE_OK) {
-		as_destroy(as);
+		as_release(as);
 		log(LF_OTHER, LVL_ERROR, "Cannot spawn loader (%s)",
 		    elf_error(prg->loader_status));
Index: tools/xcw/bin/helenos-bld-config
===================================================================
--- tools/xcw/bin/helenos-bld-config	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ tools/xcw/bin/helenos-bld-config	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -33,7 +33,10 @@
 
 SRC_ROOT="$(dirname "$0")/../../.."
-MAKEFILE_COMMON="$SRC_ROOT"/Makefile.common
-MAKEFILE_CONFIG="$SRC_ROOT"/Makefile.config
-CONFIG_MK="$SRC_ROOT"/uspace/export/config.mk
+if [ -z "$EXPORT_DIR" ]; then
+	EXPORT_DIR="$SRC_ROOT/uspace/export"
+fi
+MAKEFILE_COMMON="$EXPORT_DIR"/Makefile.common
+MAKEFILE_CONFIG="$EXPORT_DIR"/Makefile.config
+CONFIG_MK="$EXPORT_DIR"/config.mk
 
 # Extract simple 'name = value' variable definition from Makefile
Index: tools/xcw/bin/helenos-cc
===================================================================
--- tools/xcw/bin/helenos-cc	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ tools/xcw/bin/helenos-cc	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -34,4 +34,7 @@
 XCW="$(dirname "$0")"
 SRC_ROOT="$XCW/../../.."
+if [ -z "$EXPORT_DIR" ]; then
+	EXPORT_DIR="$SRC_ROOT/uspace/export"
+fi
 UARCH="$("$XCW"/helenos-bld-config --uarch)"
 CC="$("$XCW"/helenos-bld-config --cc)"
@@ -49,5 +52,4 @@
     "$@" \
     -I"$XCW"/../include \
-    -I"$SRC_ROOT"/uspace/lib/c/include \
-    -I"$SRC_ROOT"/abi/include \
-    -I"$SRC_ROOT"/uspace/lib/c/arch/"$UARCH"/include
+    -I"$EXPORT_DIR"/include/libc \
+    -I"$EXPORT_DIR"/include
Index: tools/xcw/bin/helenos-ld
===================================================================
--- tools/xcw/bin/helenos-ld	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ tools/xcw/bin/helenos-ld	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -34,4 +34,7 @@
 XCW="$(dirname "$0")"
 SRC_ROOT="$XCW/../../.."
+if [ -z "$EXPORT_DIR" ]; then
+	EXPORT_DIR="$SRC_ROOT/uspace/export"
+fi
 UARCH="$("$XCW"/helenos-bld-config --uarch)"
 CFLAGS="$("$XCW"/helenos-bld-config --cflags)"
@@ -43,6 +46,6 @@
     $CFLAGS \
     "$@" \
-    "$SRC_ROOT"/uspace/lib/c/crt0.o \
-    "$SRC_ROOT"/uspace/lib/c/crt1.o \
-    "$SRC_ROOT"/uspace/lib/c/libc.a \
+    "$EXPORT_DIR"/lib/crt0.o \
+    "$EXPORT_DIR"/lib/crt1.o \
+    "$EXPORT_DIR"/lib/libc.a \
     -lgcc
Index: tools/xcw/bin/helenos-pkg-config
===================================================================
--- tools/xcw/bin/helenos-pkg-config	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ tools/xcw/bin/helenos-pkg-config	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -35,21 +35,24 @@
 SRC_ROOT="$XCW/../../.."
 UARCH="$("$XCW"/helenos-bld-config --uarch)"
+if [ -z "$EXPORT_DIR" ]; then
+	EXPORT_DIR="$SRC_ROOT/uspace/export"
+fi
+INCLUDE_DIR="$EXPORT_DIR/include"
+LIB_DIR="$EXPORT_DIR/lib"
 
-libmath_cflags="-I$SRC_ROOT/uspace/lib/math/include\
-    -I$SRC_ROOT/uspace/lib/math/arch/$UARCH/include"
-libmath_libs="$SRC_ROOT/uspace/lib/math/libmath.a"
+libmath_cflags="-I$INCLUDE_DIR/libmath"
+libmath_libs="$LIB_DIR/libmath.a"
 
-libgui_cflags="-I$SRC_ROOT/uspace/lib/gui"
-libgui_libs="$SRC_ROOT/uspace/lib/gui/libgui.a"
+libgui_cflags="-I$INCLUDE_DIR/libgui"
+libgui_libs="$LIB_DIR/libgui.a"
 
-libdraw_cflags="-I$SRC_ROOT/uspace/lib/draw"
-libdraw_libs="$SRC_ROOT/uspace/lib/draw/libdraw.a \
-    $SRC_ROOT/uspace/lib/softrend/libsoftrend.a"
+libdraw_cflags="-I$INCLUDE_DIR/libdraw"
+libdraw_libs="$LIB_DIR/libdraw.a $LIB_DIR/libsoftrend.a"
 
-libhound_cflags="-I$SRC_ROOT/uspace/lib/hound/include"
-libhound_libs="$SRC_ROOT/uspace/lib/hound/libhound.a"
+libhound_cflags="-I$INCLUDE_DIR/libhound"
+libhound_libs="$LIB_DIR/libhound.a"
 
-libpcm_cflags="-I$SRC_ROOT/uspace/lib/pcm/include"
-libpcm_libs="$SRC_ROOT/uspace/lib/pcm/libpcm.a"
+libpcm_cflags="-I$INCLUDE_DIR/libpcm"
+libpcm_libs="$LIB_DIR/libpcm.a"
 
 action=none
Index: uspace/Makefile
===================================================================
--- uspace/Makefile	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/Makefile	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -273,5 +273,5 @@
 	$(MAKE) -r -C $(basename $@) all-test PRECHECK=$(PRECHECK)
 
-export: lib/posix.build lib/math.build lib/clui.build
+export: $(BUILDS)
 	$(MAKE) -r -C lib/posix export EXPORT_DIR=$(EXPORT_DIR)
 
Index: uspace/app/fontviewer/fontviewer.c
===================================================================
--- uspace/app/fontviewer/fontviewer.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/app/fontviewer/fontviewer.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -170,17 +170,17 @@
 	source_t leading_bg = rgb(170, 238, 255);
 	source_t leading_fg = rgb(0, 170, 212);
-
-	font_t *font;
+	font_t *info_font = NULL;
+	font_t *font = NULL;
+
 	errno_t rc = create_font(&font, points);
 	if (rc != EOK) {
 		printf("Failed creating font\n");
-		return rc;
-	}
-
-	font_t *info_font;
+		goto out_err;
+	}
+
 	rc = embedded_font_create(&info_font, 16);
 	if (rc != EOK) {
 		printf("Failed creating info font\n");
-		return rc;
+		goto out_err;
 	}
 
@@ -188,5 +188,5 @@
 	rc = font_get_metrics(font, &font_metrics);
 	if (rc != EOK)
-		return rc;
+		goto out_err;
 
 	surface_coord_t top = 50;
@@ -238,6 +238,10 @@
 	}
 
-	font_release(font);
-	return EOK;
+out_err:
+	if (font)
+		font_release(font);
+	if (info_font)
+		font_release(info_font);
+	return rc;
 }
 
Index: uspace/drv/char/ski-con/ski-con.c
===================================================================
--- uspace/drv/char/ski-con/ski-con.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/drv/char/ski-con/ski-con.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -1,5 +1,5 @@
 /*
  * Copyright (c) 2005 Jakub Jermar
- * Copyright (c) 2017 Jiri Svoboda
+ * Copyright (c) 2018 Jiri Svoboda
  * All rights reserved.
  *
@@ -31,7 +31,9 @@
  */
 
+#include <as.h>
 #include <async.h>
 #include <ddf/driver.h>
 #include <ddf/log.h>
+#include <ddi.h>
 #include <errno.h>
 #include <fibril.h>
@@ -40,4 +42,5 @@
 #include <stdlib.h>
 #include <stdbool.h>
+#include <sysinfo.h>
 
 #include "ski-con.h"
@@ -68,4 +71,6 @@
 	ddf_fun_t *fun = NULL;
 	bool bound = false;
+	uintptr_t faddr;
+	void *addr = AS_AREA_ANY;
 	errno_t rc;
 
@@ -87,4 +92,18 @@
 	con->cds.sarg = con;
 
+	rc = sysinfo_get_value("ski.paddr", &faddr);
+	if (rc != EOK)
+		faddr = 0; /* No kernel driver to arbitrate with */
+
+	if (faddr != 0) {
+		addr = AS_AREA_ANY;
+		rc = physmem_map(faddr, 1, AS_AREA_READ | AS_AREA_CACHEABLE,
+		    &addr);
+		if (rc != EOK) {
+			ddf_msg(LVL_ERROR, "Cannot map kernel driver arbitration area.");
+			goto error;
+		}
+	}
+
 	rc = ddf_fun_bind(fun);
 	if (rc != EOK) {
@@ -107,4 +126,6 @@
 	return EOK;
 error:
+	if (addr != AS_AREA_ANY)
+		as_area_destroy(addr);
 	if (bound)
 		ddf_fun_unbind(fun);
@@ -127,4 +148,26 @@
 }
 
+/** Detect if SKI console is in use by the kernel.
+ *
+ * This is needed since the kernel has no way of fencing off the user-space
+ * driver.
+ *
+ * @return @c true if in use by the kernel.
+ */
+static bool ski_con_disabled(void)
+{
+	sysarg_t kconsole;
+
+	/*
+	 * XXX Ideally we should get information from our kernel counterpart
+	 * driver. But there needs to be a mechanism for the kernel console
+	 * to inform the kernel driver.
+	 */
+	if (sysinfo_get_value("kconsole", &kconsole) != EOK)
+		return false;
+
+	return kconsole != false;
+}
+
 /** Poll Ski for keypresses. */
 static errno_t ski_con_fibril(void *arg)
@@ -135,5 +178,5 @@
 
 	while (true) {
-		while (true) {
+		while (!ski_con_disabled()) {
 			c = ski_con_getchar();
 			if (c == 0)
@@ -246,6 +289,9 @@
 	uint8_t *dp = (uint8_t *) data;
 
-	for (i = 0; i < size; i++)
-		ski_con_putchar(con, dp[i]);
+	if (!ski_con_disabled()) {
+		for (i = 0; i < size; i++) {
+			ski_con_putchar(con, dp[i]);
+		}
+	}
 
 	*nwr = size;
Index: uspace/drv/char/ski-con/ski-con.h
===================================================================
--- uspace/drv/char/ski-con/ski-con.h	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/drv/char/ski-con/ski-con.h	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -56,4 +56,6 @@
 	fibril_mutex_t buf_lock;
 	fibril_condvar_t buf_cv;
+	/** Memory area mapped to arbitrate with the kernel driver */
+	void *mem_area;
 } ski_con_t;
 
Index: uspace/lib/c/generic/loader.c
===================================================================
--- uspace/lib/c/generic/loader.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/lib/c/generic/loader.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -200,5 +200,5 @@
 	}
 
-	rc = loader_set_program(ldr, path, fd);
+	rc = loader_set_program(ldr, abspath, fd);
 	vfs_put(fd);
 	return rc;
Index: uspace/lib/draw/font/bitmap_backend.c
===================================================================
--- uspace/lib/draw/font/bitmap_backend.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/lib/draw/font/bitmap_backend.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -212,4 +212,5 @@
 
 	data->decoder->release(data->decoder_data);
+	free(data);
 }
 
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/lib/drv/generic/driver.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -145,6 +145,4 @@
 	}
 
-	/* Add one reference that will be dropped by driver_dev_remove() */
-	dev_add_ref(dev);
 	dev->handle = dev_handle;
 	dev->name = dev_name;
@@ -733,7 +731,6 @@
 		return NULL;
 
-	/* Add one reference that will be dropped by ddf_fun_destroy() */
 	fun->dev = dev;
-	fun_add_ref(fun);
+	dev_add_ref(fun->dev);
 
 	fun->bound = false;
@@ -743,5 +740,5 @@
 		fun->name = str_dup(name);
 		if (fun->name == NULL) {
-			delete_function(fun);
+			fun_del_ref(fun);	/* fun is destroyed */
 			return NULL;
 		}
Index: uspace/lib/hound/src/protocol.c
===================================================================
--- uspace/lib/hound/src/protocol.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/lib/hound/src/protocol.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -615,5 +615,12 @@
 			break;
 		default:
-			async_answer_0(&call, ENOTSUP);
+			/*
+			 * In case we called async_get_call() after we had
+			 * already received IPC_M_PHONE_HUNGUP deeper in the
+			 * protocol handling, the capability handle will be
+			 * invalid, so act carefully here.
+			 */
+			if (call.cap_handle != CAP_NIL)
+				async_answer_0(&call, ENOTSUP);
 			return;
 		}
Index: uspace/lib/posix/Makefile
===================================================================
--- uspace/lib/posix/Makefile	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/lib/posix/Makefile	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -36,4 +36,9 @@
 	../math/libmath.a \
 	../clui/libclui.a \
+	../gui/libgui.a \
+	../draw/libdraw.a \
+	../softrend/libsoftrend.a \
+	../hound/libhound.a \
+	../pcm/libpcm.a \
 	$(LIBC_PREFIX)/libc.a \
 	$(LIBC_PREFIX)/crt0.o \
@@ -93,5 +98,6 @@
 include $(USPACE_PREFIX)/Makefile.common
 
-export: $(EXPORT_DIR)/config.mk $(EXPORT_DIR)/config.rc
+export: $(EXPORT_DIR)/config.mk $(EXPORT_DIR)/config.rc \
+    $(EXPORT_DIR)/Makefile.common $(EXPORT_DIR)/Makefile.config
 
 $(EXPORT_DIR)/config.mk: export-libs export-includes
@@ -111,4 +117,10 @@
 	sed 's:$$(HELENOS_EXPORT_ROOT):$$HELENOS_EXPORT_ROOT:g' < $< >$@
 
+$(EXPORT_DIR)/Makefile.common: ../../../Makefile.common
+	cp $< $@
+
+$(EXPORT_DIR)/Makefile.config: ../../../Makefile.config
+	cp $< $@
+
 export-libs: $(EXPORT_FILES) export-includes
 	mkdir -p $(EXPORT_DIR)/lib
@@ -124,3 +136,13 @@
 	cp -L ../clui/tinput.h $(EXPORT_DIR)/include.new/libclui
 	rm -rf $(EXPORT_DIR)/include
+	mkdir -p $(EXPORT_DIR)/include.new/libdraw
+	cp -r -L -t $(EXPORT_DIR)/include.new/libdraw ../draw/*.h
+	mkdir -p $(EXPORT_DIR)/include.new/libdraw/codec
+	cp -r -L -t $(EXPORT_DIR)/include.new/libdraw/codec ../draw/codec/*.h
+	mkdir -p $(EXPORT_DIR)/include.new/libgui
+	cp -L -t $(EXPORT_DIR)/include.new/libgui ../gui/*.h
+	mkdir -p $(EXPORT_DIR)/include.new/libhound
+	cp -r -L -t $(EXPORT_DIR)/include.new/libhound ../hound/include/*
+	mkdir -p $(EXPORT_DIR)/include.new/libpcm
+	cp -r -L -t $(EXPORT_DIR)/include.new/libpcm ../pcm/include/*
 	mv $(EXPORT_DIR)/include.new $(EXPORT_DIR)/include
Index: uspace/lib/usbhost/src/bus.c
===================================================================
--- uspace/lib/usbhost/src/bus.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/lib/usbhost/src/bus.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -370,5 +370,5 @@
 int bus_endpoint_add(device_t *device, const usb_endpoint_descriptors_t *desc, endpoint_t **out_ep)
 {
-	int err;
+	int err = EINVAL;
 	assert(device);
 
@@ -392,7 +392,4 @@
 	assert((ep->required_transfer_buffer_policy & ~ep->transfer_buffer_policy) == 0);
 
-	/* Bus reference */
-	endpoint_add_ref(ep);
-
 	const size_t idx = bus_endpoint_index(ep->endpoint, ep->direction);
 	if (idx >= ARRAY_SIZE(device->endpoints)) {
@@ -425,8 +422,6 @@
 	}
 	fibril_mutex_unlock(&device->guard);
-	if (err) {
-		endpoint_del_ref(ep);
-		return err;
-	}
+	if (err)
+		goto drop;
 
 	if (out_ep) {
@@ -438,7 +433,6 @@
 	return EOK;
 drop:
-	/* Bus reference */
 	endpoint_del_ref(ep);
-	return EINVAL;
+	return err;
 }
 
Index: uspace/srv/devman/devtree.c
===================================================================
--- uspace/srv/devman/devtree.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/srv/devman/devtree.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -144,6 +144,9 @@
 	}
 
-	fun_add_ref(fun);
-	insert_fun_node(tree, fun, str_dup(""), NULL);
+	if (!insert_fun_node(tree, fun, str_dup(""), NULL)) {
+		fun_del_ref(fun);	/* fun is destroyed */
+		fibril_rwlock_write_unlock(&tree->rwlock);
+		return false;
+	}
 
 	match_id_t *id = create_match_id();
@@ -162,5 +165,4 @@
 	}
 
-	dev_add_ref(dev);
 	insert_dev_node(tree, dev, fun);
 
Index: uspace/srv/devman/driver.c
===================================================================
--- uspace/srv/devman/driver.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/srv/devman/driver.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -462,8 +462,11 @@
 			list_remove(&dev->driver_devices);
 			fibril_mutex_unlock(&driver->driver_mutex);
+			/* Give an extra reference to driver_reassign_fibril */
+			dev_add_ref(dev);
 			fid_t fid = fibril_create(driver_reassign_fibril, dev);
 			if (fid == 0) {
 				log_msg(LOG_DEFAULT, LVL_ERROR,
 				    "Error creating fibril to assign driver.");
+				dev_del_ref(dev);
 			}
 			fibril_add_ready(fid);
Index: uspace/srv/devman/drv_conn.c
===================================================================
--- uspace/srv/devman/drv_conn.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/srv/devman/drv_conn.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -284,6 +284,8 @@
 
 	fun_node_t *fun = create_fun_node();
-	/* One reference for creation, one for us */
-	fun_add_ref(fun);
+	/*
+	 * Hold a temporary reference while we work with fun. The reference from
+	 * create_fun_node() moves to the device tree.
+	 */
 	fun_add_ref(fun);
 	fun->ftype = ftype;
@@ -300,5 +302,5 @@
 		fun_busy_unlock(fun);
 		fun_del_ref(fun);
-		delete_fun_node(fun);
+		fun_del_ref(fun);	/* fun is destroyed */
 		async_answer_0(call, ENOMEM);
 		return;
Index: uspace/srv/devman/fun.c
===================================================================
--- uspace/srv/devman/fun.c	(revision c7429547358535d8d60f28154ac021e54964726e)
+++ uspace/srv/devman/fun.c	(revision c483fca0263f4b26f181c7f35c6de491be6e53d5)
@@ -317,5 +317,4 @@
 
 		insert_dev_node(&device_tree, dev, fun);
-		dev_add_ref(dev);
 	}
 
