Index: uspace/lib/block/libblock.c
===================================================================
--- uspace/lib/block/libblock.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/block/libblock.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -626,4 +626,5 @@
 			unsigned long key = block->lba;
 			hash_table_remove(&cache->block_hash, &key, 1);
+			fibril_mutex_unlock(&block->lock);
 			free(block->data);
 			free(block);
Index: uspace/lib/c/Makefile
===================================================================
--- uspace/lib/c/Makefile	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/c/Makefile	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -91,6 +91,6 @@
 	generic/loader.c \
 	generic/getopt.c \
-	generic/adt/list.o \
-	generic/adt/hash_table.o \
+	generic/adt/list.c \
+	generic/adt/hash_table.c \
 	generic/adt/dynamic_fifo.c \
 	generic/adt/measured_strings.c \
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/c/generic/devman.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -123,9 +123,13 @@
 }
 
-static int devman_send_match_id(int phone, match_id_t *match_id) \
-{
-	ipc_call_t answer;
-	aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
-	int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
+static int devman_send_match_id(int phone, match_id_t *match_id)
+{
+	ipc_call_t answer;
+
+	aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
+	    &answer);
+	int retval = async_data_write_start(phone, match_id->id,
+	    str_size(match_id->id));
+
 	async_wait_for(req, NULL);
 	return retval;
@@ -133,26 +137,43 @@
 
 
-static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 
+static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
 {
 	link_t *link = match_ids->ids.next;
 	match_id_t *match_id = NULL;
 	int ret = EOK;
-	
+
 	while (link != &match_ids->ids) {
 		match_id = list_get_instance(link, match_id_t, link); 
-		if (EOK != (ret = devman_send_match_id(phone, match_id))) 
-		{
-			printf("Driver failed to send match id, error number = %d\n", ret);
-			return ret;			
-		}
+		ret = devman_send_match_id(phone, match_id);
+		if (ret != EOK) {
+			printf("Driver failed to send match id, error %d\n",
+			    ret);
+			return ret;
+		}
+
 		link = link->next;
 	}
-	return ret;	
-}
-
-int devman_child_device_register(
-	const char *name, match_id_list_t *match_ids, devman_handle_t parent_handle, devman_handle_t *handle)
-{		
+
+	return ret;
+}
+
+/** Add function to a device.
+ *
+ * Request devman to add a new function to the specified device owned by
+ * this driver task.
+ *
+ * @param name		Name of the new function
+ * @param ftype		Function type, fun_inner or fun_exposed
+ * @param match_ids	Match IDs (should be empty for fun_exposed)
+ * @param devh		Devman handle of the device
+ * @param funh		Place to store handle of the new function
+ *
+ * @return		EOK on success or negative error code.
+ */
+int devman_add_function(const char *name, fun_type_t ftype,
+    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
+{
 	int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
+	int fun_handle;
 	
 	if (phone < 0)
@@ -161,7 +182,9 @@
 	async_serialize_start();
 	
-	int match_count = list_count(&match_ids->ids);	
-	ipc_call_t answer;
-	aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count, &answer);
+	int match_count = list_count(&match_ids->ids);
+	ipc_call_t answer;
+
+	aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
+	    devh, match_count, &answer);
 
 	sysarg_t retval = async_data_write_start(phone, name, str_size(name));
@@ -178,18 +201,16 @@
 	async_serialize_end();
 	
-	if (retval != EOK) {
-		if (handle != NULL) {
-			*handle = -1;
-		}
-		return retval;
-	}	
-	
-	if (handle != NULL)
-		*handle = (int) IPC_GET_ARG1(answer);	
-		
-	return retval;
-}
-
-int devman_add_device_to_class(devman_handle_t devman_handle, const char *class_name)
+	if (retval == EOK)
+		fun_handle = (int) IPC_GET_ARG1(answer);
+	else
+		fun_handle = -1;
+	
+	*funh = fun_handle;
+
+	return retval;
+}
+
+int devman_add_device_to_class(devman_handle_t devman_handle,
+    const char *class_name)
 {
 	int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
@@ -200,7 +221,9 @@
 	async_serialize_start();
 	ipc_call_t answer;
-	aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, devman_handle, &answer);
-	
-	sysarg_t retval = async_data_write_start(phone, class_name, str_size(class_name));
+	aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
+	    devman_handle, &answer);
+	
+	sysarg_t retval = async_data_write_start(phone, class_name,
+	    str_size(class_name));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
@@ -212,5 +235,5 @@
 	async_serialize_end();
 	
-	return retval;	
+	return retval;
 }
 
@@ -265,5 +288,6 @@
 }
 
-int devman_device_get_handle(const char *pathname, devman_handle_t *handle, unsigned int flags)
+int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
+    unsigned int flags)
 {
 	int phone = devman_get_phone(DEVMAN_CLIENT, flags);
@@ -278,5 +302,6 @@
 	    &answer);
 	
-	sysarg_t retval = async_data_write_start(phone, pathname, str_size(pathname));
+	sysarg_t retval = async_data_write_start(phone, pathname,
+	    str_size(pathname));
 	if (retval != EOK) {
 		async_wait_for(req, NULL);
Index: uspace/lib/c/generic/fibril.c
===================================================================
--- uspace/lib/c/generic/fibril.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/c/generic/fibril.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -115,4 +115,6 @@
 	fibril->retval = 0;
 	fibril->flags = 0;
+	
+	fibril->waits_for = NULL;
 	
 	return fibril;
@@ -276,6 +278,4 @@
 	fibril->arg = arg;
 
-	fibril->waits_for = NULL;
-	
 	context_save(&fibril->ctx);
 	context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack,
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/c/include/devman.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -45,5 +45,5 @@
 
 extern int devman_driver_register(const char *, async_client_conn_t);
-extern int devman_child_device_register(const char *, match_id_list_t *,
+extern int devman_add_function(const char *, fun_type_t, match_id_list_t *,
     devman_handle_t, devman_handle_t *);
 
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/c/include/ipc/devman.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -42,4 +42,13 @@
 
 typedef sysarg_t devman_handle_t;
+
+typedef enum {
+	/** Invalid value for debugging purposes */
+	fun_invalid = 0,
+	/** Function to which child devices attach */
+	fun_inner,
+	/** Fuction exported to external clients (leaf function) */
+	fun_exposed
+} fun_type_t;
 
 /** Ids of device models used for device-to-driver matching.
@@ -127,5 +136,5 @@
 typedef enum {
 	DEVMAN_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
-	DEVMAN_ADD_CHILD_DEVICE,
+	DEVMAN_ADD_FUNCTION,
 	DEVMAN_ADD_MATCH_ID,
 	DEVMAN_ADD_DEVICE_TO_CLASS
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/generic/driver.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -1,4 +1,5 @@
 /*
  * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -49,9 +50,11 @@
 #include <errno.h>
 #include <inttypes.h>
+#include <devman.h>
 
 #include <ipc/driver.h>
 
 #include "dev_iface.h"
-#include "driver.h"
+#include "ddf/driver.h"
+#include "ddf/interrupt.h"
 
 /** Driver structure */
@@ -59,6 +62,6 @@
 
 /** Devices */
-LIST_INITIALIZE(devices);
-FIBRIL_MUTEX_INITIALIZE(devices_mutex);
+LIST_INITIALIZE(functions);
+FIBRIL_MUTEX_INITIALIZE(functions_mutex);
 
 /** Interrupts */
@@ -76,4 +79,8 @@
 };
 
+static ddf_dev_t *create_device(void);
+static void delete_device(ddf_dev_t *);
+static remote_handler_t *function_get_default_handler(ddf_fun_t *);
+static void *function_get_ops(ddf_fun_t *, dev_inferface_idx_t);
 
 static void driver_irq_handler(ipc_callid_t iid, ipc_call_t *icall)
@@ -150,5 +157,5 @@
 
 interrupt_context_t *
-find_interrupt_context(interrupt_context_list_t *list, device_t *dev, int irq)
+find_interrupt_context(interrupt_context_list_t *list, ddf_dev_t *dev, int irq)
 {
 	fibril_mutex_lock(&list->mutex);
@@ -172,5 +179,5 @@
 
 int
-register_interrupt_handler(device_t *dev, int irq, interrupt_handler_t *handler,
+register_interrupt_handler(ddf_dev_t *dev, int irq, interrupt_handler_t *handler,
     irq_code_t *pseudocode)
 {
@@ -195,5 +202,5 @@
 }
 
-int unregister_interrupt_handler(device_t *dev, int irq)
+int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
 {
 	interrupt_context_t *ctx = find_interrupt_context(&interrupt_contexts,
@@ -209,35 +216,36 @@
 }
 
-static void add_to_devices_list(device_t *dev)
-{
-	fibril_mutex_lock(&devices_mutex);
-	list_append(&dev->link, &devices);
-	fibril_mutex_unlock(&devices_mutex);
-}
-
-static void remove_from_devices_list(device_t *dev)
-{
-	fibril_mutex_lock(&devices_mutex);
-	list_remove(&dev->link);
-	fibril_mutex_unlock(&devices_mutex);
-}
-
-static device_t *driver_get_device(link_t *devices, devman_handle_t handle)
-{
-	device_t *dev = NULL;
-	
-	fibril_mutex_lock(&devices_mutex);
-	link_t *link = devices->next;
-	
-	while (link != devices) {
-		dev = list_get_instance(link, device_t, link);
-		if (dev->handle == handle) {
-			fibril_mutex_unlock(&devices_mutex);
-			return dev;
+static void add_to_functions_list(ddf_fun_t *fun)
+{
+	fibril_mutex_lock(&functions_mutex);
+	list_append(&fun->link, &functions);
+	fibril_mutex_unlock(&functions_mutex);
+}
+
+static void remove_from_functions_list(ddf_fun_t *fun)
+{
+	fibril_mutex_lock(&functions_mutex);
+	list_remove(&fun->link);
+	fibril_mutex_unlock(&functions_mutex);
+}
+
+static ddf_fun_t *driver_get_function(link_t *functions, devman_handle_t handle)
+{
+	ddf_fun_t *fun = NULL;
+	
+	fibril_mutex_lock(&functions_mutex);
+	link_t *link = functions->next;
+	
+	while (link != functions) {
+		fun = list_get_instance(link, ddf_fun_t, link);
+		if (fun->handle == handle) {
+			fibril_mutex_unlock(&functions_mutex);
+			return fun;
 		}
+		
 		link = link->next;
 	}
 	
-	fibril_mutex_unlock(&devices_mutex);
+	fibril_mutex_unlock(&functions_mutex);
 	
 	return NULL;
@@ -250,14 +258,17 @@
 	
 	devman_handle_t dev_handle = IPC_GET_ARG1(*icall);
-    	devman_handle_t parent_dev_handle = IPC_GET_ARG2(*icall);
-	
-	device_t *dev = create_device();
+    	devman_handle_t parent_fun_handle = IPC_GET_ARG2(*icall);
+	
+	ddf_dev_t *dev = create_device();
 	dev->handle = dev_handle;
-	
+
 	async_data_write_accept((void **) &dev_name, true, 0, 0, 0, 0);
 	dev->name = dev_name;
-	
-	add_to_devices_list(dev);
-	dev->parent = driver_get_device(&devices, parent_dev_handle);
+
+	/*
+	 * Currently not used, parent fun handle is stored in context
+	 * of the connection to the parent device driver.
+	 */
+	(void) parent_fun_handle;
 	
 	res = driver->driver_ops->add_device(dev);
@@ -268,5 +279,4 @@
 		printf("%s: failed to add a new device with handle = %" PRIun ".\n",
 		    driver->name, dev_handle);
-		remove_from_devices_list(dev);
 		delete_device(dev);
 	}
@@ -311,8 +321,8 @@
 	 */
 	devman_handle_t handle = IPC_GET_ARG2(*icall);
-	device_t *dev = driver_get_device(&devices, handle);
-
-	if (dev == NULL) {
-		printf("%s: driver_connection_gen error - no device with handle"
+	ddf_fun_t *fun = driver_get_function(&functions, handle);
+
+	if (fun == NULL) {
+		printf("%s: driver_connection_gen error - no function with handle"
 		    " %" PRIun " was found.\n", driver->name, handle);
 		async_answer_0(iid, ENOENT);
@@ -327,7 +337,7 @@
 	
 	int ret = EOK;
-	/* open the device */
-	if (dev->ops != NULL && dev->ops->open != NULL)
-		ret = (*dev->ops->open)(dev);
+	/* Open device function */
+	if (fun->ops != NULL && fun->ops->open != NULL)
+		ret = (*fun->ops->open)(fun);
 	
 	async_answer_0(iid, ret);
@@ -344,7 +354,7 @@
 		switch  (method) {
 		case IPC_M_PHONE_HUNGUP:
-			/* close the device */
-			if (dev->ops != NULL && dev->ops->close != NULL)
-				(*dev->ops->close)(dev);
+			/* Close device function */
+			if (fun->ops != NULL && fun->ops->close != NULL)
+				(*fun->ops->close)(fun);
 			async_answer_0(callid, EOK);
 			return;
@@ -356,11 +366,12 @@
 			if (!is_valid_iface_idx(iface_idx)) {
 				remote_handler_t *default_handler =
-				    device_get_default_handler(dev);
+				    function_get_default_handler(fun);
 				if (default_handler != NULL) {
-					(*default_handler)(dev, callid, &call);
+					(*default_handler)(fun, callid, &call);
 					break;
 				}
+				
 				/*
-				 * This is not device's interface and the
+				 * Function has no such interface and
 				 * default handler is not provided.
 				 */
@@ -372,12 +383,12 @@
 			}
 			
-			/* calling one of the device's interfaces */
+			/* calling one of the function's interfaces */
 			
 			/* Get the interface ops structure. */
-			void *ops = device_get_ops(dev, iface_idx);
+			void *ops = function_get_ops(fun, iface_idx);
 			if (ops == NULL) {
 				printf("%s: driver_connection_gen error - ",
 				    driver->name);
-				printf("device with handle %" PRIun " has no interface "
+				printf("Function with handle %" PRIun " has no interface "
 				    "with id %d.\n", handle, iface_idx);
 				async_answer_0(callid, ENOTSUP);
@@ -408,7 +419,7 @@
 			 * receive parameters from the remote client and it will
 			 * pass it to the corresponding local interface method
-			 * associated with the device by its driver.
+			 * associated with the function by its driver.
 			 */
-			(*iface_method_ptr)(dev, ops, callid, &call);
+			(*iface_method_ptr)(fun, ops, callid, &call);
 			break;
 		}
@@ -425,5 +436,4 @@
 	driver_connection_gen(iid, icall, false);
 }
-
 
 /** Function for handling connections to device driver. */
@@ -454,125 +464,200 @@
  * @return		The device structure.
  */
-device_t *create_device(void)
-{
-	device_t *dev = malloc(sizeof(device_t));
-
-	if (dev != NULL) {
-		memset(dev, 0, sizeof(device_t));
-		init_match_ids(&dev->match_ids);
-	}
-
+static ddf_dev_t *create_device(void)
+{
+	ddf_dev_t *dev;
+
+	dev = malloc(sizeof(ddf_dev_t));
+	if (dev == NULL)
+		return NULL;
+
+	memset(dev, 0, sizeof(ddf_dev_t));
 	return dev;
 }
 
+/** Create new function structure.
+ *
+ * @return		The device structure.
+ */
+static ddf_fun_t *create_function(void)
+{
+	ddf_fun_t *fun;
+
+	fun = calloc(1, sizeof(ddf_fun_t));
+	if (fun == NULL)
+		return NULL;
+
+	init_match_ids(&fun->match_ids);
+	link_initialize(&fun->link);
+
+	return fun;
+}
+
 /** Delete device structure.
  *
  * @param dev		The device structure.
  */
-void delete_device(device_t *dev)
-{
-	clean_match_ids(&dev->match_ids);
-	if (dev->name != NULL)
-		free(dev->name);
+static void delete_device(ddf_dev_t *dev)
+{
 	free(dev);
 }
 
-void *device_get_ops(device_t *dev, dev_inferface_idx_t idx)
+/** Delete device structure.
+ *
+ * @param dev		The device structure.
+ */
+static void delete_function(ddf_fun_t *fun)
+{
+	clean_match_ids(&fun->match_ids);
+	if (fun->name != NULL)
+		free(fun->name);
+	free(fun);
+}
+
+/** Create a DDF function node.
+ *
+ * Create a DDF function (in memory). Both child devices and external clients
+ * communicate with a device via its functions.
+ *
+ * The created function node is fully formed, but only exists in the memory
+ * of the client task. In order to be visible to the system, the function
+ * must be bound using ddf_fun_bind().
+ *
+ * This function should only fail if there is not enough free memory.
+ * Specifically, this function succeeds even if @a dev already has
+ * a (bound) function with the same name.
+ *
+ * Type: A function of type fun_inner indicates that DDF should attempt
+ * to attach child devices to the function. fun_exposed means that
+ * the function should be exported to external clients (applications).
+ *
+ * @param dev		Device to which we are adding function
+ * @param ftype		Type of function (fun_inner or fun_exposed)
+ * @param name		Name of function
+ *
+ * @return		New function or @c NULL if memory is not available
+ */
+ddf_fun_t *ddf_fun_create(ddf_dev_t *dev, fun_type_t ftype, const char *name)
+{
+	ddf_fun_t *fun;
+
+	fun = create_function();
+	if (fun == NULL)
+		return NULL;
+
+	fun->bound = false;
+	fun->dev = dev;
+	fun->ftype = ftype;
+
+	fun->name = str_dup(name);
+	if (fun->name == NULL) {
+		delete_function(fun);
+		return NULL;
+	}
+
+	return fun;
+}
+
+/** Destroy DDF function node.
+ *
+ * Destroy a function previously created with ddf_fun_create(). The function
+ * must not be bound.
+ *
+ * @param fun		Function to destroy
+ */
+void ddf_fun_destroy(ddf_fun_t *fun)
+{
+	assert(fun->bound == false);
+	delete_function(fun);
+}
+
+static void *function_get_ops(ddf_fun_t *fun, dev_inferface_idx_t idx)
 {
 	assert(is_valid_iface_idx(idx));
-	if (dev->ops == NULL)
+	if (fun->ops == NULL)
 		return NULL;
-	return dev->ops->interfaces[idx];
-}
-
-int child_device_register(device_t *child, device_t *parent)
-{
-	assert(child->name != NULL);
+	return fun->ops->interfaces[idx];
+}
+
+/** Bind a function node.
+ *
+ * Bind the specified function to the system. This effectively makes
+ * the function visible to the system (uploads it to the server).
+ *
+ * This function can fail for several reasons. Specifically,
+ * it will fail if the device already has a bound function of
+ * the same name.
+ *
+ * @param fun		Function to bind
+ * @return		EOK on success or negative error code
+ */
+int ddf_fun_bind(ddf_fun_t *fun)
+{
+	assert(fun->name != NULL);
 	
 	int res;
 	
-	add_to_devices_list(child);
-	res = devman_child_device_register(child->name, &child->match_ids,
-	    parent->handle, &child->handle);
+	add_to_functions_list(fun);
+	res = devman_add_function(fun->name, fun->ftype, &fun->match_ids,
+	    fun->dev->handle, &fun->handle);
 	if (res != EOK) {
-		remove_from_devices_list(child);
+		remove_from_functions_list(fun);
 		return res;
 	}
 	
+	fun->bound = true;
 	return res;
 }
 
-/** Wrapper for child_device_register for devices with single match id.
- *
- * @param parent Parent device.
- * @param child_name Child device name.
- * @param child_match_id Child device match id.
- * @param child_match_score Child device match score.
- * @return Error code.
- */
-int child_device_register_wrapper(device_t *parent, const char *child_name,
-    const char *child_match_id, int child_match_score,
-    devman_handle_t *child_handle)
-{
-	device_t *child = NULL;
-	match_id_t *match_id = NULL;
-	int rc;
-	
-	child = create_device();
-	if (child == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-	
-	child->name = child_name;
+/** Add single match ID to inner function.
+ *
+ * Construct and add a single match ID to the specified function.
+ * Cannot be called when the function node is bound.
+ *
+ * @param fun			Function
+ * @param match_id_str		Match string
+ * @param match_score		Match score
+ * @return			EOK on success, ENOMEM if out of memory.
+ */
+int ddf_fun_add_match_id(ddf_fun_t *fun, const char *match_id_str,
+    int match_score)
+{
+	match_id_t *match_id;
+	
+	assert(fun->bound == false);
+	assert(fun->ftype == fun_inner);
 	
 	match_id = create_match_id();
-	if (match_id == NULL) {
-		rc = ENOMEM;
-		goto failure;
-	}
-	
-	match_id->id = child_match_id;
-	match_id->score = child_match_score;
-	add_match_id(&child->match_ids, match_id);
-	
-	rc = child_device_register(child, parent);
-	if (rc != EOK)
-		goto failure;
-
-	if (child_handle != NULL) {
-		*child_handle = child->handle;
-	}
-
+	if (match_id == NULL)
+		return ENOMEM;
+	
+	match_id->id = match_id_str;
+	match_id->score = 90;
+	
+	add_match_id(&fun->match_ids, match_id);
 	return EOK;
-	
-failure:
-	if (match_id != NULL) {
-		match_id->id = NULL;
-		delete_match_id(match_id);
-	}
-	
-	if (child != NULL) {
-		child->name = NULL;
-		delete_device(child);
-	}
-	
-	return rc;
 }
 
 /** Get default handler for client requests */
-remote_handler_t *device_get_default_handler(device_t *dev)
-{
-	if (dev->ops == NULL)
+static remote_handler_t *function_get_default_handler(ddf_fun_t *fun)
+{
+	if (fun->ops == NULL)
 		return NULL;
-	return dev->ops->default_handler;
-}
-
-int add_device_to_class(device_t *dev, const char *class_name)
-{
-	return devman_add_device_to_class(dev->handle, class_name);
-}
-
-int driver_main(driver_t *drv)
+	return fun->ops->default_handler;
+}
+
+/** Add exposed function to class.
+ *
+ * Must only be called when the function is bound.
+ */
+int ddf_fun_add_to_class(ddf_fun_t *fun, const char *class_name)
+{
+	assert(fun->bound == true);
+	assert(fun->ftype == fun_exposed);
+	
+	return devman_add_device_to_class(fun->handle, class_name);
+}
+
+int ddf_driver_main(driver_t *drv)
 {
 	/*
Index: uspace/lib/drv/generic/remote_char_dev.c
===================================================================
--- uspace/lib/drv/generic/remote_char_dev.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/generic/remote_char_dev.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -37,10 +37,10 @@
 
 #include "ops/char_dev.h"
-#include "driver.h"
+#include "ddf/driver.h"
 
 #define MAX_CHAR_RW_COUNT 256
 
-static void remote_char_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_char_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_char_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_char_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 
 /** Remote character interface operations. */
@@ -67,9 +67,9 @@
  * local interface to the remote client.
  *
- * @param dev		The device from which the data are read.
+ * @param fun		The function from which the data are read.
  * @param ops		The local ops structure.
  */
 static void
-remote_char_read(device_t *dev, void *ops, ipc_callid_t callid,
+remote_char_read(ddf_fun_t *fun, void *ops, ipc_callid_t callid,
     ipc_call_t *call)
 {
@@ -94,5 +94,5 @@
 	
 	char buf[MAX_CHAR_RW_COUNT];
-	int ret = (*char_dev_ops->read)(dev, buf, len);
+	int ret = (*char_dev_ops->read)(fun, buf, len);
 	
 	if (ret < 0) {
@@ -114,9 +114,9 @@
  * local interface to the remote client.
  *
- * @param dev		The device to which the data are written.
+ * @param fun		The function to which the data are written.
  * @param ops		The local ops structure.
  */
 static void
-remote_char_write(device_t *dev, void *ops, ipc_callid_t callid,
+remote_char_write(ddf_fun_t *fun, void *ops, ipc_callid_t callid,
     ipc_call_t *call)
 {
@@ -144,5 +144,5 @@
 	async_data_write_finalize(cid, buf, len);
 	
-	int ret = (*char_dev_ops->write)(dev, buf, len);
+	int ret = (*char_dev_ops->write)(fun, buf, len);
 	if (ret < 0) {
 		/* Some error occured. */
Index: uspace/lib/drv/generic/remote_hw_res.c
===================================================================
--- uspace/lib/drv/generic/remote_hw_res.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/generic/remote_hw_res.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -37,9 +37,9 @@
 
 #include "ops/hw_res.h"
-#include "driver.h"
+#include "ddf/driver.h"
 
-static void remote_hw_res_get_resource_list(device_t *, void *, ipc_callid_t,
+static void remote_hw_res_get_resource_list(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
-static void remote_hw_res_enable_interrupt(device_t *, void *, ipc_callid_t,
+static void remote_hw_res_enable_interrupt(ddf_fun_t *, void *, ipc_callid_t,
     ipc_call_t *);
 
@@ -55,5 +55,5 @@
 };
 
-static void remote_hw_res_enable_interrupt(device_t *dev, void *ops,
+static void remote_hw_res_enable_interrupt(ddf_fun_t *fun, void *ops,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -62,5 +62,5 @@
 	if (hw_res_ops->enable_interrupt == NULL)
 		async_answer_0(callid, ENOTSUP);
-	else if (hw_res_ops->enable_interrupt(dev))
+	else if (hw_res_ops->enable_interrupt(fun))
 		async_answer_0(callid, EOK);
 	else
@@ -68,5 +68,5 @@
 }
 
-static void remote_hw_res_get_resource_list(device_t *dev, void *ops,
+static void remote_hw_res_get_resource_list(ddf_fun_t *fun, void *ops,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -78,5 +78,5 @@
 	}
 	
-	hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(dev);
+	hw_resource_list_t *hw_resources = hw_res_ops->get_resource_list(fun);
 	if (hw_resources == NULL){
 		async_answer_0(callid, ENOENT);
Index: uspace/lib/drv/generic/remote_usb.c
===================================================================
--- uspace/lib/drv/generic/remote_usb.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/generic/remote_usb.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -37,10 +37,10 @@
 
 #include "usb_iface.h"
-#include "driver.h"
+#include "ddf/driver.h"
 
 
-static void remote_usb_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_get_interface(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usb_get_hc_handle(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_get_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_get_interface(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usb_get_hc_handle(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 //static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
 
@@ -61,5 +61,5 @@
 
 
-void remote_usb_get_address(device_t *device, void *iface,
+void remote_usb_get_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -74,5 +74,5 @@
 
 	usb_address_t address;
-	int rc = usb_iface->get_address(device, handle, &address);
+	int rc = usb_iface->get_address(fun, handle, &address);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -82,5 +82,5 @@
 }
 
-void remote_usb_get_interface(device_t *device, void *iface,
+void remote_usb_get_interface(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -95,5 +95,5 @@
 
 	int iface_no;
-	int rc = usb_iface->get_interface(device, handle, &iface_no);
+	int rc = usb_iface->get_interface(fun, handle, &iface_no);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -103,5 +103,5 @@
 }
 
-void remote_usb_get_hc_handle(device_t *device, void *iface,
+void remote_usb_get_hc_handle(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -114,5 +114,5 @@
 
 	devman_handle_t handle;
-	int rc = usb_iface->get_hc_handle(device, &handle);
+	int rc = usb_iface->get_hc_handle(fun, &handle);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
Index: uspace/lib/drv/generic/remote_usbhc.c
===================================================================
--- uspace/lib/drv/generic/remote_usbhc.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/generic/remote_usbhc.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -35,7 +35,8 @@
 #include <async.h>
 #include <errno.h>
+#include <assert.h>
 
 #include "usbhc_iface.h"
-#include "driver.h"
+#include "ddf/driver.h"
 
 #define USB_MAX_PAYLOAD_SIZE 1020
@@ -43,16 +44,16 @@
 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4
 
-static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_bulk_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_bulk_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
-//static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_interrupt_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_interrupt_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_bulk_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_bulk_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_control_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_control_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
+//static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *);
 
 /** Remote USB host controller interface operations. */
@@ -123,5 +124,5 @@
 }
 
-void remote_usbhc_reserve_default_address(device_t *device, void *iface,
+void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -135,10 +136,10 @@
 	usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
 	
-	int rc = usb_iface->reserve_default_address(device, speed);
+	int rc = usb_iface->reserve_default_address(fun, speed);
 
 	async_answer_0(callid, rc);
 }
 
-void remote_usbhc_release_default_address(device_t *device, void *iface,
+void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -150,10 +151,10 @@
 	}
 
-	int rc = usb_iface->release_default_address(device);
+	int rc = usb_iface->release_default_address(fun);
 
 	async_answer_0(callid, rc);
 }
 
-void remote_usbhc_request_address(device_t *device, void *iface,
+void remote_usbhc_request_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -168,5 +169,5 @@
 
 	usb_address_t address;
-	int rc = usb_iface->request_address(device, speed, &address);
+	int rc = usb_iface->request_address(fun, speed, &address);
 	if (rc != EOK) {
 		async_answer_0(callid, rc);
@@ -176,5 +177,5 @@
 }
 
-void remote_usbhc_bind_address(device_t *device, void *iface,
+void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -189,10 +190,10 @@
 	devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call);
 
-	int rc = usb_iface->bind_address(device, address, handle);
+	int rc = usb_iface->bind_address(fun, address, handle);
 
 	async_answer_0(callid, rc);
 }
 
-void remote_usbhc_release_address(device_t *device, void *iface,
+void remote_usbhc_release_address(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -206,5 +207,5 @@
 	usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call);
 
-	int rc = usb_iface->release_address(device, address);
+	int rc = usb_iface->release_address(fun, address);
 
 	async_answer_0(callid, rc);
@@ -212,5 +213,5 @@
 
 
-static void callback_out(device_t *device,
+static void callback_out(ddf_fun_t *fun,
     int outcome, void *arg)
 {
@@ -222,5 +223,5 @@
 }
 
-static void callback_in(device_t *device,
+static void callback_in(ddf_fun_t *fun,
     int outcome, size_t actual_size, void *arg)
 {
@@ -255,5 +256,5 @@
  * @param transfer_func Transfer function (might be NULL).
  */
-static void remote_usbhc_out_transfer(device_t *device,
+static void remote_usbhc_out_transfer(ddf_fun_t *fun,
     ipc_callid_t callid, ipc_call_t *call,
     usbhc_iface_transfer_out_t transfer_func)
@@ -294,5 +295,5 @@
 	trans->size = len;
 
-	rc = transfer_func(device, target, max_packet_size,
+	rc = transfer_func(fun, target, max_packet_size,
 	    buffer, len,
 	    callback_out, trans);
@@ -311,5 +312,5 @@
  * @param transfer_func Transfer function (might be NULL).
  */
-static void remote_usbhc_in_transfer(device_t *device,
+static void remote_usbhc_in_transfer(ddf_fun_t *fun,
     ipc_callid_t callid, ipc_call_t *call,
     usbhc_iface_transfer_in_t transfer_func)
@@ -342,5 +343,5 @@
 	trans->size = len;
 
-	int rc = transfer_func(device, target, max_packet_size,
+	int rc = transfer_func(fun, target, max_packet_size,
 	    trans->buffer, len,
 	    callback_in, trans);
@@ -352,5 +353,5 @@
 }
 
-void remote_usbhc_interrupt_out(device_t *device, void *iface,
+void remote_usbhc_interrupt_out(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -358,9 +359,9 @@
 	assert(usb_iface != NULL);
 
-	return remote_usbhc_out_transfer(device, callid, call,
+	return remote_usbhc_out_transfer(fun, callid, call,
 	    usb_iface->interrupt_out);
 }
 
-void remote_usbhc_interrupt_in(device_t *device, void *iface,
+void remote_usbhc_interrupt_in(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -368,9 +369,9 @@
 	assert(usb_iface != NULL);
 
-	return remote_usbhc_in_transfer(device, callid, call,
+	return remote_usbhc_in_transfer(fun, callid, call,
 	    usb_iface->interrupt_in);
 }
 
-void remote_usbhc_bulk_out(device_t *device, void *iface,
+void remote_usbhc_bulk_out(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -378,9 +379,9 @@
 	assert(usb_iface != NULL);
 
-	return remote_usbhc_out_transfer(device, callid, call,
+	return remote_usbhc_out_transfer(fun, callid, call,
 	    usb_iface->bulk_out);
 }
 
-void remote_usbhc_bulk_in(device_t *device, void *iface,
+void remote_usbhc_bulk_in(ddf_fun_t *fun, void *iface,
     ipc_callid_t callid, ipc_call_t *call)
 {
@@ -388,9 +389,9 @@
 	assert(usb_iface != NULL);
 
-	return remote_usbhc_in_transfer(device, callid, call,
+	return remote_usbhc_in_transfer(fun, callid, call,
 	    usb_iface->bulk_in);
 }
 
-void remote_usbhc_control_write(device_t *device, void *iface,
+void remote_usbhc_control_write(ddf_fun_t *fun, void *iface,
 ipc_callid_t callid, ipc_call_t *call)
 {
@@ -444,5 +445,5 @@
 	trans->size = data_buffer_len;
 
-	rc = usb_iface->control_write(device, target, max_packet_size,
+	rc = usb_iface->control_write(fun, target, max_packet_size,
 	    setup_packet, setup_packet_len,
 	    data_buffer, data_buffer_len,
@@ -456,5 +457,5 @@
 
 
-void remote_usbhc_control_read(device_t *device, void *iface,
+void remote_usbhc_control_read(ddf_fun_t *fun, void *iface,
 ipc_callid_t callid, ipc_call_t *call)
 {
@@ -509,5 +510,5 @@
 	}
 
-	rc = usb_iface->control_read(device, target, max_packet_size,
+	rc = usb_iface->control_read(fun, target, max_packet_size,
 	    setup_packet, setup_packet_len,
 	    trans->buffer, trans->size,
Index: uspace/lib/drv/include/ddf/driver.h
===================================================================
--- uspace/lib/drv/include/ddf/driver.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
+++ uspace/lib/drv/include/ddf/driver.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * Copyright (c) 2011 Jiri Svoboda
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef DDF_DRIVER_H_
+#define DDF_DRIVER_H_
+
+#include <ipc/devman.h>
+#include <ipc/dev_iface.h>
+
+#include "../dev_iface.h"
+
+typedef struct ddf_dev ddf_dev_t;
+typedef struct ddf_fun ddf_fun_t;
+
+/*
+ * Device
+ */
+
+/** Devices operations */
+typedef struct ddf_dev_ops {
+	/**
+	 * Optional callback function called when a client is connecting to the
+	 * device.
+	 */
+	int (*open)(ddf_fun_t *);
+	
+	/**
+	 * Optional callback function called when a client is disconnecting from
+	 * the device.
+	 */
+	void (*close)(ddf_fun_t *);
+	
+	/** The table of standard interfaces implemented by the device. */
+	void *interfaces[DEV_IFACE_COUNT];
+	
+	/**
+	 * The default handler of remote client requests. If the client's remote
+	 * request cannot be handled by any of the standard interfaces, the
+	 * default handler is used.
+	 */
+	remote_handler_t *default_handler;
+} ddf_dev_ops_t;
+
+/** Device structure */
+struct ddf_dev {
+	/**
+	 * Globally unique device identifier (assigned to the device by the
+	 * device manager).
+	 */
+	devman_handle_t handle;
+	
+	/**
+	 * Phone to the parent device driver (if it is different from this
+	 * driver)
+	 */
+	int parent_phone;
+	
+	/** Device name */
+	const char *name;
+	
+	/** Driver-specific data associated with this device */
+	void *driver_data;
+	
+	/** Link in the list of devices handled by the driver */
+	link_t link;
+};
+
+/** Function structure */
+struct ddf_fun {
+	/** True if bound to the device manager */
+	bool bound;
+	/** Function indentifier (asigned by device manager) */
+	devman_handle_t handle;
+	
+	/** Device which this function belogs to */
+	ddf_dev_t *dev;
+	
+	/** Function type */
+	fun_type_t ftype;
+	/** Function name */
+	const char *name;
+	/** List of device ids for driver matching */
+	match_id_list_t match_ids;
+	/** Driver-specific data associated with this function */
+	void *driver_data;
+	/** Implementation of operations provided by this function */
+	ddf_dev_ops_t *ops;
+	
+	/** Link in the list of functions handled by the driver */
+	link_t link;
+};
+
+/*
+ * Driver
+ */
+
+/** Generic device driver operations */
+typedef struct driver_ops {
+	/** Callback method for passing a new device to the device driver */
+	int (*add_device)(ddf_dev_t *dev);
+	/* TODO: add other generic driver operations */
+} driver_ops_t;
+
+/** Driver structure */
+typedef struct driver {
+	/** Name of the device driver */
+	const char *name;
+	/** Generic device driver operations */
+	driver_ops_t *driver_ops;
+} driver_t;
+
+extern int ddf_driver_main(driver_t *);
+
+extern ddf_fun_t *ddf_fun_create(ddf_dev_t *, fun_type_t, const char *);
+extern void ddf_fun_destroy(ddf_fun_t *);
+extern int ddf_fun_bind(ddf_fun_t *);
+extern int ddf_fun_add_match_id(ddf_fun_t *, const char *, int);
+
+extern int ddf_fun_add_to_class(ddf_fun_t *, const char *);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/ddf/interrupt.h
===================================================================
--- uspace/lib/drv/include/ddf/interrupt.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
+++ uspace/lib/drv/include/ddf/interrupt.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010 Lenka Trochtova
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup libdrv
+ * @{
+ */
+/** @file
+ */
+
+#ifndef DDF_INTERRUPT_H_
+#define DDF_INTERRUPT_H_
+
+#include <kernel/ddi/irq.h>
+#include <adt/list.h>
+#include <ddi.h>
+#include <fibril_synch.h>
+
+#include "driver.h"
+#include "../dev_iface.h"
+
+/*
+ * Interrupts
+ */
+
+typedef void interrupt_handler_t(ddf_dev_t *, ipc_callid_t, ipc_call_t *);
+
+typedef struct interrupt_context {
+	int id;
+	ddf_dev_t *dev;
+	int irq;
+	interrupt_handler_t *handler;
+	link_t link;
+} interrupt_context_t;
+
+typedef struct interrupt_context_list {
+	int curr_id;
+	link_t contexts;
+	fibril_mutex_t mutex;
+} interrupt_context_list_t;
+
+extern interrupt_context_t *create_interrupt_context(void);
+extern void delete_interrupt_context(interrupt_context_t *);
+extern void init_interrupt_context_list(interrupt_context_list_t *);
+extern void add_interrupt_context(interrupt_context_list_t *,
+    interrupt_context_t *);
+extern void remove_interrupt_context(interrupt_context_list_t *,
+    interrupt_context_t *);
+extern interrupt_context_t *find_interrupt_context_by_id(
+    interrupt_context_list_t *, int);
+extern interrupt_context_t *find_interrupt_context(
+    interrupt_context_list_t *, ddf_dev_t *, int);
+
+extern int register_interrupt_handler(ddf_dev_t *, int, interrupt_handler_t *,
+    irq_code_t *);
+extern int unregister_interrupt_handler(ddf_dev_t *, int);
+
+#endif
+
+/**
+ * @}
+ */
Index: uspace/lib/drv/include/dev_iface.h
===================================================================
--- uspace/lib/drv/include/dev_iface.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/include/dev_iface.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -43,5 +43,5 @@
  */
 
-struct device;
+struct ddf_fun;
 
 /*
@@ -49,8 +49,8 @@
  * devices driver.
  */
-typedef void remote_iface_func_t(struct device *, void *, ipc_callid_t,
+typedef void remote_iface_func_t(struct ddf_fun *, void *, ipc_callid_t,
     ipc_call_t *);
 typedef remote_iface_func_t *remote_iface_func_ptr_t;
-typedef void remote_handler_t(struct device *, ipc_callid_t, ipc_call_t *);
+typedef void remote_handler_t(struct ddf_fun *, ipc_callid_t, ipc_call_t *);
 
 typedef struct {
Index: uspace/lib/drv/include/driver.h
===================================================================
--- uspace/lib/drv/include/driver.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ 	(revision )
@@ -1,194 +1,0 @@
-/*
- * Copyright (c) 2010 Lenka Trochtova
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/** @addtogroup libdrv
- * @{
- */
-/** @file
- */
-
-#ifndef LIBDRV_DRIVER_H_
-#define LIBDRV_DRIVER_H_
-
-#include <sys/types.h>
-#include <kernel/ddi/irq.h>
-#include <adt/list.h>
-#include <devman.h>
-#include <ipc/devman.h>
-#include <ipc/dev_iface.h>
-#include <assert.h>
-#include <ddi.h>
-#include <libarch/ddi.h>
-#include <fibril_synch.h>
-#include <malloc.h>
-
-#include "dev_iface.h"
-
-struct device;
-typedef struct device device_t;
-
-/*
- * Device class
- */
-
-/** Devices operations */
-typedef struct device_ops {
-	/**
-	 * Optional callback function called when a client is connecting to the
-	 * device.
-	 */
-	int (*open)(device_t *);
-	
-	/**
-	 * Optional callback function called when a client is disconnecting from
-	 * the device.
-	 */
-	void (*close)(device_t *);
-	
-	/** The table of standard interfaces implemented by the device. */
-	void *interfaces[DEV_IFACE_COUNT];
-	
-	/**
-	 * The default handler of remote client requests. If the client's remote
-	 * request cannot be handled by any of the standard interfaces, the
-	 * default handler is used.
-	 */
-	remote_handler_t *default_handler;
-} device_ops_t;
-
-
-/*
- * Device
- */
-
-/** Device structure */
-struct device {
-	/**
-	 * Globally unique device identifier (assigned to the device by the
-	 * device manager).
-	 */
-	devman_handle_t handle;
-	
-	/**
-	 * Phone to the parent device driver (if it is different from this
-	 * driver)
-	 */
-	int parent_phone;
-	
-	/** Parent device if handled by this driver, NULL otherwise */
-	device_t *parent;
-	/** Device name */
-	const char *name;
-	/** List of device ids for device-to-driver matching */
-	match_id_list_t match_ids;
-	/** Driver-specific data associated with this device */
-	void *driver_data;
-	/** The implementation of operations provided by this device */
-	device_ops_t *ops;
-	
-	/** Link in the list of devices handled by the driver */
-	link_t link;
-};
-
-/*
- * Driver
- */
-
-/** Generic device driver operations */
-typedef struct driver_ops {
-	/** Callback method for passing a new device to the device driver */
-	int (*add_device)(device_t *dev);
-	/* TODO: add other generic driver operations */
-} driver_ops_t;
-
-/** Driver structure */
-typedef struct driver {
-	/** Name of the device driver */
-	const char *name;
-	/** Generic device driver operations */
-	driver_ops_t *driver_ops;
-} driver_t;
-
-int driver_main(driver_t *);
-
-/** Create new device structure.
- *
- * @return		The device structure.
- */
-extern device_t *create_device(void);
-extern void delete_device(device_t *);
-extern void *device_get_ops(device_t *, dev_inferface_idx_t);
-
-extern int child_device_register(device_t *, device_t *);
-extern int child_device_register_wrapper(device_t *, const char *, const char *,
-    int, devman_handle_t *);
-
-/*
- * Interrupts
- */
-
-typedef void interrupt_handler_t(device_t *, ipc_callid_t, ipc_call_t *);
-
-typedef struct interrupt_context {
-	int id;
-	device_t *dev;
-	int irq;
-	interrupt_handler_t *handler;
-	link_t link;
-} interrupt_context_t;
-
-typedef struct interrupt_context_list {
-	int curr_id;
-	link_t contexts;
-	fibril_mutex_t mutex;
-} interrupt_context_list_t;
-
-extern interrupt_context_t *create_interrupt_context(void);
-extern void delete_interrupt_context(interrupt_context_t *);
-extern void init_interrupt_context_list(interrupt_context_list_t *);
-extern void add_interrupt_context(interrupt_context_list_t *,
-    interrupt_context_t *);
-extern void remove_interrupt_context(interrupt_context_list_t *,
-    interrupt_context_t *);
-extern interrupt_context_t *find_interrupt_context_by_id(
-    interrupt_context_list_t *, int);
-extern interrupt_context_t *find_interrupt_context(
-    interrupt_context_list_t *, device_t *, int);
-
-extern int register_interrupt_handler(device_t *, int, interrupt_handler_t *,
-    irq_code_t *);
-extern int unregister_interrupt_handler(device_t *, int);
-
-extern remote_handler_t *device_get_default_handler(device_t *);
-extern int add_device_to_class(device_t *, const char *);
-
-#endif
-
-/**
- * @}
- */
Index: uspace/lib/drv/include/ops/char_dev.h
===================================================================
--- uspace/lib/drv/include/ops/char_dev.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/include/ops/char_dev.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -36,9 +36,9 @@
 #define LIBDRV_OPS_CHAR_DEV_H_
 
-#include "../driver.h"
+#include "../ddf/driver.h"
 
 typedef struct {
-	int (*read)(device_t *, char *, size_t);
-	int (*write)(device_t *, char *, size_t);
+	int (*read)(ddf_fun_t *, char *, size_t);
+	int (*write)(ddf_fun_t *, char *, size_t);
 } char_dev_ops_t;
 
Index: uspace/lib/drv/include/ops/hw_res.h
===================================================================
--- uspace/lib/drv/include/ops/hw_res.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/include/ops/hw_res.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -39,9 +39,9 @@
 #include <sys/types.h>
 
-#include "../driver.h"
+#include "../ddf/driver.h"
 
 typedef struct {
-	 hw_resource_list_t *(*get_resource_list)(device_t *);
-	 bool (*enable_interrupt)(device_t *);
+	 hw_resource_list_t *(*get_resource_list)(ddf_fun_t *);
+	 bool (*enable_interrupt)(ddf_fun_t *);
 } hw_res_ops_t;
 
Index: uspace/lib/drv/include/usb_iface.h
===================================================================
--- uspace/lib/drv/include/usb_iface.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/include/usb_iface.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -38,5 +38,5 @@
 #define LIBDRV_USB_IFACE_H_
 
-#include "driver.h"
+#include "ddf/driver.h"
 #include <usb/usb.h>
 typedef enum {
@@ -75,7 +75,7 @@
 /** USB device communication interface. */
 typedef struct {
-	int (*get_address)(device_t *, devman_handle_t, usb_address_t *);
-	int (*get_interface)(device_t *, devman_handle_t, int *);
-	int (*get_hc_handle)(device_t *, devman_handle_t *);
+	int (*get_address)(ddf_fun_t *, devman_handle_t, usb_address_t *);
+	int (*get_interface)(ddf_fun_t *, devman_handle_t, int *);
+	int (*get_hc_handle)(ddf_fun_t *, devman_handle_t *);
 } usb_iface_t;
 
Index: uspace/lib/drv/include/usbhc_iface.h
===================================================================
--- uspace/lib/drv/include/usbhc_iface.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/drv/include/usbhc_iface.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -38,5 +38,5 @@
 #define LIBDRV_USBHC_IFACE_H_
 
-#include "driver.h"
+#include "ddf/driver.h"
 #include <usb/usb.h>
 #include <bool.h>
@@ -171,14 +171,14 @@
 
 /** Callback for outgoing transfer. */
-typedef void (*usbhc_iface_transfer_out_callback_t)(device_t *,
+typedef void (*usbhc_iface_transfer_out_callback_t)(ddf_fun_t *,
     int, void *);
 
 /** Callback for incoming transfer. */
-typedef void (*usbhc_iface_transfer_in_callback_t)(device_t *,
+typedef void (*usbhc_iface_transfer_in_callback_t)(ddf_fun_t *,
     int, size_t, void *);
 
 
 /** Out transfer processing function prototype. */
-typedef int (*usbhc_iface_transfer_out_t)(device_t *, usb_target_t, size_t,
+typedef int (*usbhc_iface_transfer_out_t)(ddf_fun_t *, usb_target_t, size_t,
     void *, size_t,
     usbhc_iface_transfer_out_callback_t, void *);
@@ -188,5 +188,5 @@
 
 /** In transfer processing function prototype. */
-typedef int (*usbhc_iface_transfer_in_t)(device_t *, usb_target_t, size_t,
+typedef int (*usbhc_iface_transfer_in_t)(ddf_fun_t *, usb_target_t, size_t,
     void *, size_t,
     usbhc_iface_transfer_in_callback_t, void *);
@@ -194,9 +194,9 @@
 /** USB host controller communication interface. */
 typedef struct {
-	int (*reserve_default_address)(device_t *, usb_speed_t);
-	int (*release_default_address)(device_t *);
-	int (*request_address)(device_t *, usb_speed_t, usb_address_t *);
-	int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
-	int (*release_address)(device_t *, usb_address_t);
+	int (*reserve_default_address)(ddf_fun_t *, usb_speed_t);
+	int (*release_default_address)(ddf_fun_t *);
+	int (*request_address)(ddf_fun_t *, usb_speed_t, usb_address_t *);
+	int (*bind_address)(ddf_fun_t *, usb_address_t, devman_handle_t);
+	int (*release_address)(ddf_fun_t *, usb_address_t);
 
 	usbhc_iface_transfer_out_t interrupt_out;
@@ -206,10 +206,10 @@
 	usbhc_iface_transfer_in_t bulk_in;
 
-	int (*control_write)(device_t *, usb_target_t,
+	int (*control_write)(ddf_fun_t *, usb_target_t,
 	    size_t,
 	    void *, size_t, void *, size_t,
 	    usbhc_iface_transfer_out_callback_t, void *);
 
-	int (*control_read)(device_t *, usb_target_t,
+	int (*control_read)(ddf_fun_t *, usb_target_t,
 	    size_t,
 	    void *, size_t, void *, size_t,
Index: uspace/lib/usb/include/usb/ddfiface.h
===================================================================
--- uspace/lib/usb/include/usb/ddfiface.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/include/usb/ddfiface.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -40,15 +40,15 @@
 #include <usb_iface.h>
 
-int usb_iface_get_hc_handle_hub_impl(device_t *, devman_handle_t *);
-int usb_iface_get_address_hub_impl(device_t *, devman_handle_t,
+int usb_iface_get_hc_handle_hub_impl(ddf_fun_t *, devman_handle_t *);
+int usb_iface_get_address_hub_impl(ddf_fun_t *, devman_handle_t,
     usb_address_t *);
 extern usb_iface_t usb_iface_hub_impl;
 
-int usb_iface_get_hc_handle_hub_child_impl(device_t *, devman_handle_t *);
-int usb_iface_get_address_hub_child_impl(device_t *, devman_handle_t,
+int usb_iface_get_hc_handle_hub_child_impl(ddf_fun_t *, devman_handle_t *);
+int usb_iface_get_address_hub_child_impl(ddf_fun_t *, devman_handle_t,
     usb_address_t *);
 extern usb_iface_t usb_iface_hub_child_impl;
 
-int usb_iface_get_hc_handle_hc_impl(device_t *, devman_handle_t *);
+int usb_iface_get_hc_handle_hc_impl(ddf_fun_t *, devman_handle_t *);
 
 
Index: uspace/lib/usb/include/usb/hub.h
===================================================================
--- uspace/lib/usb/include/usb/hub.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/include/usb/hub.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -39,6 +39,8 @@
 #include <usb/usbdevice.h>
 
-int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t,
-    int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *);
+int usb_hc_new_device_wrapper(ddf_dev_t *, usb_hc_connection_t *, usb_speed_t,
+    int (*)(int, void *), int, void *,
+    usb_address_t *, devman_handle_t *,
+    ddf_dev_ops_t *, void *, ddf_fun_t **);
 
 /** Info about device attached to host controller.
Index: uspace/lib/usb/include/usb/pipes.h
===================================================================
--- uspace/lib/usb/include/usb/pipes.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/include/usb/pipes.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -41,5 +41,5 @@
 #include <usb/descriptor.h>
 #include <ipc/devman.h>
-#include <driver.h>
+#include <ddf/driver.h>
 
 /**
@@ -120,9 +120,9 @@
     usb_device_connection_t *, usb_hc_connection_t *);
 int usb_device_connection_initialize_from_device(usb_device_connection_t *,
-    device_t *);
+    ddf_dev_t *);
 int usb_device_connection_initialize(usb_device_connection_t *,
     devman_handle_t, usb_address_t);
 
-int usb_device_get_assigned_interface(device_t *);
+int usb_device_get_assigned_interface(ddf_dev_t *);
 
 int usb_endpoint_pipe_initialize(usb_endpoint_pipe_t *,
Index: uspace/lib/usb/include/usb/recognise.h
===================================================================
--- uspace/lib/usb/include/usb/recognise.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/include/usb/recognise.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -50,6 +50,6 @@
 int usb_device_create_match_ids(usb_endpoint_pipe_t *, match_id_list_t *);
 
-int usb_device_register_child_in_devman(usb_address_t address, devman_handle_t hc_handle,
-    device_t *parent, devman_handle_t *child_handle);
+int usb_device_register_child_in_devman(usb_address_t, devman_handle_t,
+    ddf_dev_t *, devman_handle_t *, ddf_dev_ops_t *, void *, ddf_fun_t **);
 
 #endif
Index: uspace/lib/usb/include/usb/usbdevice.h
===================================================================
--- uspace/lib/usb/include/usb/usbdevice.h	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/include/usb/usbdevice.h	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -38,5 +38,5 @@
 #include <sys/types.h>
 #include <ipc/devman.h>
-#include <driver.h>
+#include <ddf/driver.h>
 #include <bool.h>
 #include <usb/usb.h>
@@ -53,5 +53,5 @@
 
 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *,
-    device_t *);
+    ddf_dev_t *);
 int usb_hc_connection_initialize(usb_hc_connection_t *, devman_handle_t);
 
Index: uspace/lib/usb/src/ddfiface.c
===================================================================
--- uspace/lib/usb/src/ddfiface.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/src/ddfiface.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -34,6 +34,10 @@
  */
 #include <ipc/devman.h>
+#include <devman.h>
+#include <async.h>
 #include <usb/ddfiface.h>
+#include <usb/debug.h>
 #include <errno.h>
+#include <assert.h>
 
 /** DDF interface for USB device, implementation for typical hub. */
@@ -56,8 +60,8 @@
  * @return Error code.
  */
-int usb_iface_get_hc_handle_hub_impl(device_t *device, devman_handle_t *handle)
+int usb_iface_get_hc_handle_hub_impl(ddf_fun_t *fun, devman_handle_t *handle)
 {
-	assert(device);
-	return usb_hc_find(device->handle, handle);
+	assert(fun);
+	return usb_hc_find(fun->handle, handle);
 }
 
@@ -69,24 +73,26 @@
  * @return Error code.
  */
-int usb_iface_get_hc_handle_hub_child_impl(device_t *device,
+int usb_iface_get_hc_handle_hub_child_impl(ddf_fun_t *fun,
     devman_handle_t *handle)
 {
-	assert(device);
-	device_t *parent = device->parent;
+	assert(fun != NULL);
 
-	/* Default error, device does not support this operation. */
-	int rc = ENOTSUP;
-
-	if (parent && parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
-		usb_iface_t *usb_iface
-		    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
-		assert(usb_iface != NULL);
-
-		if (usb_iface->get_hc_handle) {
-			rc = usb_iface->get_hc_handle(parent, handle);
-		}
+	int parent_phone = devman_parent_device_connect(fun->handle,
+	    IPC_FLAG_BLOCKING);
+	if (parent_phone < 0) {
+		return parent_phone;
 	}
 
-	return rc;
+	sysarg_t hc_handle;
+	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
+	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
+
+	if (rc != EOK) {
+		return rc;
+	}
+
+	*handle = hc_handle;
+
+	return EOK;
 }
 
@@ -97,10 +103,10 @@
  * @return Always EOK.
  */
-int usb_iface_get_hc_handle_hc_impl(device_t *device, devman_handle_t *handle)
+int usb_iface_get_hc_handle_hc_impl(ddf_fun_t *fun, devman_handle_t *handle)
 {
-	assert(device);
+	assert(fun);
 
 	if (handle != NULL) {
-		*handle = device->handle;
+		*handle = fun->handle;
 	}
 
@@ -115,9 +121,9 @@
  * @return Error code.
  */
-int usb_iface_get_address_hub_impl(device_t *device, devman_handle_t handle,
+int usb_iface_get_address_hub_impl(ddf_fun_t *fun, devman_handle_t handle,
     usb_address_t *address)
 {
-	assert(device);
-	int parent_phone = devman_parent_device_connect(device->handle,
+	assert(fun);
+	int parent_phone = devman_parent_device_connect(fun->handle,
 	    IPC_FLAG_BLOCKING);
 	if (parent_phone < 0) {
@@ -150,24 +156,11 @@
  * @return Error code.
  */
-int usb_iface_get_address_hub_child_impl(device_t *device,
+int usb_iface_get_address_hub_child_impl(ddf_fun_t *fun,
     devman_handle_t handle, usb_address_t *address)
 {
-	assert(device);
-	device_t *parent = device->parent;
-
-	/* Default error, device does not support this operation. */
-	int rc = ENOTSUP;
-
-	if (parent && parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
-		usb_iface_t *usb_iface
-		    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
-		assert(usb_iface != NULL);
-
-		if (usb_iface->get_address) {
-			rc = usb_iface->get_address(parent, handle, address);
-		}
+	if (handle == 0) {
+		handle = fun->handle;
 	}
-
-	return rc;
+	return usb_iface_get_address_hub_impl(fun, handle, address);
 }
 
Index: uspace/lib/usb/src/hub.c
===================================================================
--- uspace/lib/usb/src/hub.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/src/hub.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -39,4 +39,5 @@
 #include <usbhc_iface.h>
 #include <errno.h>
+#include <assert.h>
 
 /** Check that HC connection is alright.
@@ -172,8 +173,9 @@
  *	request or requests for descriptors when creating match ids).
  */
-int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection,
+int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection,
     usb_speed_t dev_speed,
     int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
-    usb_address_t *assigned_address, devman_handle_t *assigned_handle)
+    usb_address_t *assigned_address, devman_handle_t *assigned_handle,
+    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
 {
 	CHECK_CONNECTION(connection);
@@ -251,5 +253,6 @@
 	devman_handle_t child_handle;
 	rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
-	    parent, &child_handle);
+	    parent, &child_handle,
+	    dev_ops, new_dev_data, new_fun);
 	if (rc != EOK) {
 		rc = ESTALL;
Index: uspace/lib/usb/src/pipes.c
===================================================================
--- uspace/lib/usb/src/pipes.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/src/pipes.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -35,6 +35,8 @@
 #include <usb/usb.h>
 #include <usb/pipes.h>
+#include <usb/debug.h>
 #include <usbhc_iface.h>
 #include <usb_iface.h>
+#include <devman.h>
 #include <errno.h>
 #include <assert.h>
@@ -46,10 +48,17 @@
  * @return USB address or error code.
  */
-static usb_address_t get_my_address(int phone, device_t *dev)
+static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
 {
 	sysarg_t address;
+
+
+	/*
+	 * We are sending special value as a handle - zero - to get
+	 * handle of the parent function (that handle was used
+	 * when registering our device @p dev.
+	 */
 	int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
 	    IPC_M_USB_GET_ADDRESS,
-	    dev->handle, &address);
+	    0, &address);
 
 	if (rc != EOK) {
@@ -65,5 +74,5 @@
  * @return Interface number (negative code means any).
  */
-int usb_device_get_assigned_interface(device_t *device)
+int usb_device_get_assigned_interface(ddf_dev_t *device)
 {
 	int parent_phone = devman_parent_device_connect(device->handle,
@@ -94,8 +103,8 @@
  */
 int usb_device_connection_initialize_from_device(
-    usb_device_connection_t *connection, device_t *device)
+    usb_device_connection_t *connection, ddf_dev_t *dev)
 {
 	assert(connection);
-	assert(device);
+	assert(dev);
 
 	int rc;
@@ -103,10 +112,10 @@
 	usb_address_t my_address;
 
-	rc = usb_hc_find(device->handle, &hc_handle);
+	rc = usb_hc_find(dev->handle, &hc_handle);
 	if (rc != EOK) {
 		return rc;
 	}
 
-	int parent_phone = devman_parent_device_connect(device->handle,
+	int parent_phone = devman_parent_device_connect(dev->handle,
 	    IPC_FLAG_BLOCKING);
 	if (parent_phone < 0) {
@@ -114,5 +123,5 @@
 	}
 
-	my_address = get_my_address(parent_phone, device);
+	my_address = get_my_address(parent_phone, dev);
 	if (my_address < 0) {
 		rc = my_address;
Index: uspace/lib/usb/src/recognise.c
===================================================================
--- uspace/lib/usb/src/recognise.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/src/recognise.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -34,4 +34,5 @@
  */
 #include <sys/types.h>
+#include <fibril_synch.h>
 #include <usb/pipes.h>
 #include <usb/recognise.h>
@@ -41,9 +42,10 @@
 #include <stdio.h>
 #include <errno.h>
+#include <assert.h>
 
 static size_t device_name_index = 0;
 static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
 
-device_ops_t child_ops = {
+ddf_dev_ops_t child_ops = {
 	.interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
 };
@@ -326,5 +328,6 @@
 int usb_device_register_child_in_devman(usb_address_t address,
     devman_handle_t hc_handle,
-    device_t *parent, devman_handle_t *child_handle)
+    ddf_dev_t *parent, devman_handle_t *child_handle,
+    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
 {
 	size_t this_device_name_index;
@@ -335,5 +338,5 @@
 	fibril_mutex_unlock(&device_name_index_mutex);
 
-	device_t *child = NULL;
+	ddf_fun_t *child = NULL;
 	char *child_name = NULL;
 	int rc;
@@ -352,5 +355,14 @@
 	}
 
-	child = create_device();
+	/*
+	 * TODO: Once the device driver framework support persistent
+	 * naming etc., something more descriptive could be created.
+	 */
+	rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index);
+	if (rc < 0) {
+		goto failure;
+	}
+
+	child = ddf_fun_create(parent, fun_inner, child_name);
 	if (child == NULL) {
 		rc = ENOMEM;
@@ -358,15 +370,11 @@
 	}
 
-	/*
-	 * TODO: Once the device driver framework support persistent
-	 * naming etc., something more descriptive could be created.
-	 */
-	rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index);
-	if (rc < 0) {
-		goto failure;
-	}
-	child->parent = parent;
-	child->name = child_name;
-	child->ops = &child_ops;
+	if (dev_ops != NULL) {
+		child->ops = dev_ops;
+	} else {
+		child->ops = &child_ops;
+	}
+
+	child->driver_data = dev_data;
 
 	rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
@@ -385,5 +393,5 @@
 	}
 
-	rc = child_device_register(child, parent);
+	rc = ddf_fun_bind(child);
 	if (rc != EOK) {
 		goto failure;
@@ -392,4 +400,8 @@
 	if (child_handle != NULL) {
 		*child_handle = child->handle;
+	}
+
+	if (child_fun != NULL) {
+		*child_fun = child;
 	}
 
@@ -400,5 +412,5 @@
 		child->name = NULL;
 		/* This takes care of match_id deallocation as well. */
-		delete_device(child);
+		ddf_fun_destroy(child);
 	}
 	if (child_name != NULL) {
Index: uspace/lib/usb/src/request.c
===================================================================
--- uspace/lib/usb/src/request.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/src/request.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -35,4 +35,5 @@
 #include <usb/request.h>
 #include <errno.h>
+#include <assert.h>
 
 #define MAX_DATA_LENGTH ((size_t)(0xFFFF))
Index: uspace/lib/usb/src/usbdevice.c
===================================================================
--- uspace/lib/usb/src/usbdevice.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usb/src/usbdevice.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -37,5 +37,7 @@
 #include <usb_iface.h>
 #include <usb/usbdevice.h>
+#include <usb/debug.h>
 #include <errno.h>
+#include <assert.h>
 
 /** Find host controller handle that is ancestor of given device.
@@ -55,4 +57,5 @@
 
 	devman_handle_t h;
+	usb_log_debug("asking for HC handle (my handle is %zu).\n", device_handle);
 	int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
 	    IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
@@ -78,5 +81,5 @@
  */
 int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
-    device_t *device)
+    ddf_dev_t *device)
 {
 	assert(connection);
Index: uspace/lib/usbvirt/src/main.c
===================================================================
--- uspace/lib/usbvirt/src/main.c	(revision 41b70d307312a9c2a116755c873ff6e8da5a9cb0)
+++ uspace/lib/usbvirt/src/main.c	(revision eb1a2f485e907e821965b3aafca2d8a5355f3518)
@@ -203,5 +203,5 @@
 	}
 	
-	const char *vhc_path = "/virt/usbhc";
+	const char *vhc_path = "/virt/usbhc/hc";
 	int rc;
 	devman_handle_t handle;
