Index: uspace/drv/test/test1/test1.c
===================================================================
--- uspace/drv/test/test1/test1.c	(revision deac215ea66a4a2ddb5875cf4489fe576060ec0d)
+++ uspace/drv/test/test1/test1.c	(revision c0e53ff034d0a99a6874c040a2e2e51a88c674a8)
@@ -42,4 +42,5 @@
 static int test1_add_device(ddf_dev_t *dev);
 static int test1_dev_remove(ddf_dev_t *dev);
+static int test1_dev_gone(ddf_dev_t *dev);
 static int test1_fun_online(ddf_fun_t *fun);
 static int test1_fun_offline(ddf_fun_t *fun);
@@ -48,4 +49,5 @@
 	.add_device = &test1_add_device,
 	.dev_remove = &test1_dev_remove,
+	.dev_gone = &test1_dev_gone,
 	.fun_online = &test1_fun_online,
 	.fun_offline = &test1_fun_offline
@@ -213,4 +215,19 @@
 }
 
+static int fun_unbind(ddf_fun_t *fun, const char *name)
+{
+	int rc;
+
+	ddf_msg(LVL_DEBUG, "fun_unbind(%p, '%s')", fun, name);
+	rc = ddf_fun_unbind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
+		return rc;
+	}
+
+	ddf_fun_destroy(fun);
+	return EOK;
+}
+
 static int test1_dev_remove(ddf_dev_t *dev)
 {
@@ -234,4 +251,32 @@
 	if (test1->child != NULL) {
 		rc = fun_remove(test1->child, "child");
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
+}
+
+static int test1_dev_gone(ddf_dev_t *dev)
+{
+	test1_t *test1 = (test1_t *)dev->driver_data;
+	int rc;
+
+	ddf_msg(LVL_DEBUG, "test1_dev_remove(%p)", dev);
+
+	if (test1->fun_a != NULL) {
+		rc = fun_unbind(test1->fun_a, "a");
+		if (rc != EOK)
+			return rc;
+	}
+
+	if (test1->clone != NULL) {
+		rc = fun_unbind(test1->clone, "clone");
+		if (rc != EOK)
+			return rc;
+	}
+
+	if (test1->child != NULL) {
+		rc = fun_unbind(test1->child, "child");
 		if (rc != EOK)
 			return rc;
Index: uspace/drv/test/test2/test2.c
===================================================================
--- uspace/drv/test/test2/test2.c	(revision deac215ea66a4a2ddb5875cf4489fe576060ec0d)
+++ uspace/drv/test/test2/test2.c	(revision c0e53ff034d0a99a6874c040a2e2e51a88c674a8)
@@ -42,4 +42,5 @@
 static int test2_add_device(ddf_dev_t *dev);
 static int test2_dev_remove(ddf_dev_t *dev);
+static int test2_dev_gone(ddf_dev_t *dev);
 static int test2_fun_online(ddf_fun_t *fun);
 static int test2_fun_offline(ddf_fun_t *fun);
@@ -48,4 +49,5 @@
 	.add_device = &test2_add_device,
 	.dev_remove = &test2_dev_remove,
+	.dev_gone = &test2_dev_gone,
 	.fun_online = &test2_fun_online,
 	.fun_offline = &test2_fun_offline
@@ -111,10 +113,10 @@
 }
 
-/** Add child devices after some sleep.
+/** Simulate plugging and surprise unplugging.
  *
  * @param arg Parent device structure (ddf_dev_t *).
  * @return Always EOK.
  */
-static int postponed_birth(void *arg)
+static int plug_unplug(void *arg)
 {
 	test2_t *test2 = (test2_t *) arg;
@@ -144,4 +146,12 @@
 	test2->fun_a = fun_a;
 
+	async_usleep(10000000);
+
+	ddf_msg(LVL_NOTE, "Unbinding function test1.");
+	ddf_fun_unbind(test2->test1);
+	async_usleep(1000000);
+	ddf_msg(LVL_NOTE, "Unbinding function child.");
+	ddf_fun_unbind(test2->child);
+
 	return EOK;
 }
@@ -158,4 +168,19 @@
 	}
 
+	rc = ddf_fun_unbind(fun);
+	if (rc != EOK) {
+		ddf_msg(LVL_ERROR, "Failed unbinding function '%s'.", name);
+		return rc;
+	}
+
+	ddf_fun_destroy(fun);
+	return EOK;
+}
+
+static int fun_unbind(ddf_fun_t *fun, const char *name)
+{
+	int rc;
+
+	ddf_msg(LVL_DEBUG, "fun_unbind(%p, '%s')", fun, name);
 	rc = ddf_fun_unbind(fun);
 	if (rc != EOK) {
@@ -184,5 +209,5 @@
 
 	if (str_cmp(dev->name, "child") != 0) {
-		fid_t postpone = fibril_create(postponed_birth, test2);
+		fid_t postpone = fibril_create(plug_unplug, test2);
 		if (postpone == 0) {
 			ddf_msg(LVL_ERROR, "fibril_create() failed.");
@@ -232,4 +257,38 @@
 }
 
+static int test2_dev_gone(ddf_dev_t *dev)
+{
+	test2_t *test2 = (test2_t *)dev->driver_data;
+	int rc;
+
+	ddf_msg(LVL_DEBUG, "test2_dev_gone(%p)", dev);
+
+	if (test2->fun_a != NULL) {
+		rc = fun_unbind(test2->fun_a, "a");
+		if (rc != EOK)
+			return rc;
+	}
+
+	if (test2->fun_err != NULL) {
+		rc = fun_unbind(test2->fun_err, "ERROR");
+		if (rc != EOK)
+			return rc;
+	}
+
+	if (test2->child != NULL) {
+		rc = fun_unbind(test2->child, "child");
+		if (rc != EOK)
+			return rc;
+	}
+
+	if (test2->test1 != NULL) {
+		rc = fun_unbind(test2->test1, "test1");
+		if (rc != EOK)
+			return rc;
+	}
+
+	return EOK;
+}
+
 
 static int test2_fun_online(ddf_fun_t *fun)
@@ -248,5 +307,5 @@
 {
 	printf(NAME ": HelenOS test2 virtual device driver\n");
-	ddf_log_init(NAME, LVL_ERROR);
+	ddf_log_init(NAME, LVL_NOTE);
 	return ddf_driver_main(&test2_driver);
 }
