Index: uspace/drv/vhc/conn.h
===================================================================
--- uspace/drv/vhc/conn.h	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/conn.h	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -46,10 +46,11 @@
 extern usbhc_iface_t vhc_iface;
 extern usb_iface_t vhc_usb_iface;
+extern usb_iface_t rh_usb_iface;
 
 void address_init(void);
 
 
-void default_connection_handler(device_t *, ipc_callid_t, ipc_call_t *);
-void on_client_close(device_t *);
+void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
+void on_client_close(ddf_fun_t *);
 
 
Index: uspace/drv/vhc/conndev.c
===================================================================
--- uspace/drv/vhc/conndev.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/conndev.c	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -76,9 +76,9 @@
 /** Default handler for IPC methods not handled by DDF.
  *
- * @param dev Device handling the call.
+ * @param fun Device handling the call.
  * @param icallid Call id.
  * @param icall Call data.
  */
-void default_connection_handler(device_t *dev,
+void default_connection_handler(ddf_fun_t *fun,
     ipc_callid_t icallid, ipc_call_t *icall)
 {
@@ -112,5 +112,5 @@
  * @param d Device the client was connected to.
  */
-void on_client_close(device_t *d)
+void on_client_close(ddf_fun_t *fun)
 {
 	/*
Index: uspace/drv/vhc/connhost.c
===================================================================
--- uspace/drv/vhc/connhost.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/connhost.c	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -48,5 +48,5 @@
 	usbhc_iface_transfer_out_callback_t out_callback;
 	usbhc_iface_transfer_in_callback_t in_callback;
-	device_t *dev;
+	ddf_fun_t *fun;
 	size_t reported_size;
 	void *arg;
@@ -58,5 +58,5 @@
 	usbhc_iface_transfer_out_callback_t out_callback;
 	usbhc_iface_transfer_in_callback_t in_callback;
-	device_t *dev;
+	ddf_fun_t *fun;
 	void *arg;
 	void *data_buffer;
@@ -75,10 +75,10 @@
 	switch (transfer->direction) {
 		case USB_DIRECTION_IN:
-			transfer->in_callback(transfer->dev,
+			transfer->in_callback(transfer->fun,
 			    outcome, size,
 			    transfer->arg);
 			break;
 		case USB_DIRECTION_OUT:
-			transfer->out_callback(transfer->dev,
+			transfer->out_callback(transfer->fun,
 			    outcome,
 			    transfer->arg);
@@ -92,5 +92,5 @@
 }
 
-static transfer_info_t *create_transfer_info(device_t *dev,
+static transfer_info_t *create_transfer_info(ddf_fun_t *fun,
     usb_direction_t direction, void *arg)
 {
@@ -101,5 +101,5 @@
 	transfer->out_callback = NULL;
 	transfer->arg = arg;
-	transfer->dev = dev;
+	transfer->fun = fun;
 	transfer->reported_size = (size_t) -1;
 
@@ -112,10 +112,10 @@
 	switch (transfer->direction) {
 		case USB_DIRECTION_IN:
-			transfer->in_callback(transfer->dev,
+			transfer->in_callback(transfer->fun,
 			    outcome, size,
 			    transfer->arg);
 			break;
 		case USB_DIRECTION_OUT:
-			transfer->out_callback(transfer->dev,
+			transfer->out_callback(transfer->fun,
 			    outcome,
 			    transfer->arg);
@@ -138,5 +138,5 @@
 	}
 
-	transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->dev,
+	transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->fun,
 	    ctrl_transfer->direction, ctrl_transfer->arg);
 	transfer->out_callback = ctrl_transfer->out_callback;
@@ -195,5 +195,5 @@
 }
 
-static control_transfer_info_t *create_control_transfer_info(device_t *dev,
+static control_transfer_info_t *create_control_transfer_info(ddf_fun_t *fun,
     usb_direction_t direction, usb_target_t target,
     void *data_buffer, size_t data_buffer_size,
@@ -208,5 +208,5 @@
 	transfer->out_callback = NULL;
 	transfer->arg = arg;
-	transfer->dev = dev;
+	transfer->fun = fun;
 	transfer->data_buffer = data_buffer;
 	transfer->data_buffer_size = data_buffer_size;
@@ -215,5 +215,5 @@
 }
 
-static int enqueue_transfer_out(device_t *dev,
+static int enqueue_transfer_out(ddf_fun_t *fun,
     usb_target_t target, usb_transfer_type_t transfer_type,
     void *buffer, size_t size,
@@ -226,5 +226,5 @@
 
 	transfer_info_t *transfer
-	    = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
+	    = create_transfer_info(fun, USB_DIRECTION_OUT, arg);
 	transfer->out_callback = callback;
 
@@ -235,5 +235,5 @@
 }
 
-static int enqueue_transfer_in(device_t *dev,
+static int enqueue_transfer_in(ddf_fun_t *fun,
     usb_target_t target, usb_transfer_type_t transfer_type,
     void *buffer, size_t size,
@@ -246,5 +246,5 @@
 
 	transfer_info_t *transfer
-	    = create_transfer_info(dev, USB_DIRECTION_IN, arg);
+	    = create_transfer_info(fun, USB_DIRECTION_IN, arg);
 	transfer->in_callback = callback;
 
@@ -256,25 +256,25 @@
 
 
-static int interrupt_out(device_t *dev, usb_target_t target,
+static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
     size_t max_packet_size,
     void *data, size_t size,
     usbhc_iface_transfer_out_callback_t callback, void *arg)
 {
-	return enqueue_transfer_out(dev, target, USB_TRANSFER_INTERRUPT,
+	return enqueue_transfer_out(fun, target, USB_TRANSFER_INTERRUPT,
 	    data, size,
 	    callback, arg);
 }
 
-static int interrupt_in(device_t *dev, usb_target_t target,
+static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
     size_t max_packet_size,
     void *data, size_t size,
     usbhc_iface_transfer_in_callback_t callback, void *arg)
 {
-	return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
+	return enqueue_transfer_in(fun, target, USB_TRANSFER_INTERRUPT,
 	    data, size,
 	    callback, arg);
 }
 
-static int control_write(device_t *dev, usb_target_t target,
+static int control_write(ddf_fun_t *fun, usb_target_t target,
     size_t max_packet_size,
     void *setup_packet, size_t setup_packet_size,
@@ -283,5 +283,5 @@
 {
 	control_transfer_info_t *transfer
-	    = create_control_transfer_info(dev, USB_DIRECTION_OUT, target,
+	    = create_control_transfer_info(fun, USB_DIRECTION_OUT, target,
 	    data, data_size, arg);
 	transfer->out_callback = callback;
@@ -294,5 +294,5 @@
 }
 
-static int control_read(device_t *dev, usb_target_t target,
+static int control_read(ddf_fun_t *fun, usb_target_t target,
     size_t max_packet_size,
     void *setup_packet, size_t setup_packet_size,
@@ -301,5 +301,5 @@
 {
 	control_transfer_info_t *transfer
-	    = create_control_transfer_info(dev, USB_DIRECTION_IN, target,
+	    = create_control_transfer_info(fun, USB_DIRECTION_IN, target,
 	    data, data_size, arg);
 	transfer->in_callback = callback;
@@ -314,7 +314,9 @@
 static usb_address_keeping_t addresses;
 
-static int tell_address(device_t *dev, devman_handle_t handle,
+static int tell_address(ddf_fun_t *fun, devman_handle_t handle,
     usb_address_t *address)
 {
+	usb_log_debug("tell_address(fun \"%s\", handle %zu)\n",
+	    fun->name, (size_t) fun->handle);
 	usb_address_t addr = usb_address_keeping_find(&addresses, handle);
 	if (addr < 0) {
@@ -326,5 +328,5 @@
 }
 
-static int reserve_default_address(device_t *dev, usb_speed_t ignored)
+static int reserve_default_address(ddf_fun_t *fun, usb_speed_t ignored)
 {
 	usb_address_keeping_reserve_default(&addresses);
@@ -332,5 +334,5 @@
 }
 
-static int release_default_address(device_t *dev)
+static int release_default_address(ddf_fun_t *fun)
 {
 	usb_address_keeping_release_default(&addresses);
@@ -338,5 +340,5 @@
 }
 
-static int request_address(device_t *dev, usb_speed_t ignored,
+static int request_address(ddf_fun_t *fun, usb_speed_t ignored,
     usb_address_t *address)
 {
@@ -350,14 +352,36 @@
 }
 
-static int release_address(device_t *dev, usb_address_t address)
+static int release_address(ddf_fun_t *fun, usb_address_t address)
 {
 	return usb_address_keeping_release(&addresses, address);
 }
 
-static int bind_address(device_t *dev, usb_address_t address,
+static int bind_address(ddf_fun_t *fun, usb_address_t address,
     devman_handle_t handle)
 {
 	usb_address_keeping_devman_bind(&addresses, address, handle);
 	return EOK;
+}
+
+static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
+    devman_handle_t *handle)
+{
+	ddf_fun_t *hc_fun = root_hub_fun->driver_data;
+	assert(hc_fun != NULL);
+
+	*handle = hc_fun->handle;
+
+	usb_log_debug("usb_iface_get_hc_handle_rh_impl returns %zu\n", *handle);
+
+	return EOK;
+}
+
+static int tell_address_rh(ddf_fun_t *root_hub_fun, devman_handle_t handle,
+    usb_address_t *address)
+{
+	ddf_fun_t *hc_fun = root_hub_fun->driver_data;
+	assert(hc_fun != NULL);
+
+	return tell_address(hc_fun, root_hub_fun->handle, address);
 }
 
@@ -386,4 +410,9 @@
 };
 
+usb_iface_t rh_usb_iface = {
+	.get_hc_handle = usb_iface_get_hc_handle_rh_impl,
+	.get_address = tell_address_rh
+};
+
 
 /**
Index: uspace/drv/vhc/hcd.c
===================================================================
--- uspace/drv/vhc/hcd.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/hcd.c	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -42,5 +42,5 @@
 #include <errno.h>
 #include <str_error.h>
-#include <driver.h>
+#include <ddf/driver.h>
 
 #include <usb/usb.h>
@@ -53,5 +53,5 @@
 #include "conn.h"
 
-static device_ops_t vhc_ops = {
+static ddf_dev_ops_t vhc_ops = {
 	.interfaces[USBHC_DEV_IFACE] = &vhc_iface,
 	.interfaces[USB_DEV_IFACE] = &vhc_usb_iface,
@@ -60,7 +60,9 @@
 };
 
-static int vhc_count = 0;
-static int vhc_add_device(device_t *dev)
+static int vhc_add_device(ddf_dev_t *dev)
 {
+	static int vhc_count = 0;
+	int rc;
+
 	/*
 	 * Currently, we know how to simulate only single HC.
@@ -70,17 +72,32 @@
 	}
 
-	vhc_count++;
+	/*
+	 * Create exposed function representing the host controller
+	 * itself.
+	 */
+	ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
+	if (hc == NULL) {
+		usb_log_fatal("Failed to create device function.\n");
+		return ENOMEM;
+	}
 
-	dev->ops = &vhc_ops;
+	hc->ops = &vhc_ops;
 
-	devman_add_device_to_class(dev->handle, "usbhc");
+	rc = ddf_fun_bind(hc);
+	if (rc != EOK) {
+		usb_log_fatal("Failed to bind HC function: %s.\n",
+		    str_error(rc));
+		return rc;
+	}
+
+	ddf_fun_add_to_class(hc, "usbhc");
 
 	/*
 	 * Initialize our hub and announce its presence.
 	 */
-	virtual_hub_device_init(dev);
+	virtual_hub_device_init(hc);
 
-	usb_log_info("Virtual USB host controller ready (id = %zu).\n",
-	    (size_t) dev->handle);
+	usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
+	    (size_t) dev->handle, (size_t) hc->handle);
 
 	return EOK;
@@ -103,7 +120,7 @@
 	 * in devman output.
 	 */
-	sleep(5);
+	//sleep(5);
 
-	usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
+	usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
 
 	printf(NAME ": virtual USB host controller driver.\n");
@@ -122,5 +139,5 @@
 	 * We are also a driver within devman framework.
 	 */
-	return driver_main(&vhc_driver);
+	return ddf_driver_main(&vhc_driver);
 }
 
Index: uspace/drv/vhc/hub.c
===================================================================
--- uspace/drv/vhc/hub.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/hub.c	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -39,5 +39,6 @@
 #include <str_error.h>
 #include <stdlib.h>
-#include <driver.h>
+#include <ddf/driver.h>
+#include <devman.h>
 #include <usb/hub.h>
 #include <usb/recognise.h>
@@ -46,10 +47,14 @@
 #include "hub/virthub.h"
 #include "vhcd.h"
+#include "conn.h"
 
 usbvirt_device_t virtual_hub_device;
+static ddf_dev_ops_t rh_ops = {
+	.interfaces[USB_DEV_IFACE] = &rh_usb_iface,
+};
 
 static int hub_register_in_devman_fibril(void *arg);
 
-void virtual_hub_device_init(device_t *hc_dev)
+void virtual_hub_device_init(ddf_fun_t *hc_dev)
 {
 	virthub_init(&virtual_hub_device);
@@ -83,5 +88,5 @@
 int hub_register_in_devman_fibril(void *arg)
 {
-	device_t *hc_dev = (device_t *) arg;
+	ddf_fun_t *hc_dev = (ddf_fun_t *) arg;
 
 	/*
@@ -94,12 +99,18 @@
 	async_hangup(phone);
 
+	int rc;
+
 	usb_hc_connection_t hc_conn;
-	usb_hc_connection_initialize(&hc_conn, hc_dev->handle);
+	rc = usb_hc_connection_initialize(&hc_conn, hc_dev->handle);
+	assert(rc == EOK);
 
-	usb_hc_connection_open(&hc_conn);
+	rc = usb_hc_connection_open(&hc_conn);
+	assert(rc == EOK);
 
-	int rc = usb_hc_new_device_wrapper(hc_dev, &hc_conn, USB_SPEED_FULL,
+	ddf_fun_t *hub_dev;
+	rc = usb_hc_new_device_wrapper(hc_dev->dev, &hc_conn,
+	    USB_SPEED_FULL,
 	    pretend_port_rest, 0, NULL,
-	    NULL, NULL);
+	    NULL, NULL, &rh_ops, hc_dev, &hub_dev);
 	if (rc != EOK) {
 		usb_log_fatal("Failed to create root hub: %s.\n",
@@ -108,4 +119,7 @@
 
 	usb_hc_connection_close(&hc_conn);
+
+	usb_log_info("Created root hub function (handle %zu).\n",
+	    (size_t) hub_dev->handle);
 
 	return 0;
Index: uspace/drv/vhc/hub.h
===================================================================
--- uspace/drv/vhc/hub.h	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/hub.h	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -37,5 +37,5 @@
 
 #include <usbvirt/device.h>
-#include <driver.h>
+#include <ddf/driver.h>
 
 #include "devices.h"
@@ -45,5 +45,5 @@
 extern usbvirt_device_t virtual_hub_device;
 
-void virtual_hub_device_init(device_t *);
+void virtual_hub_device_init(ddf_fun_t *);
 
 #endif
Index: uspace/drv/vhc/hub/hub.c
===================================================================
--- uspace/drv/vhc/hub/hub.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/hub/hub.c	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -38,6 +38,7 @@
 #include <errno.h>
 #include <str_error.h>
+#include <assert.h>
 #include <stdlib.h>
-#include <driver.h>
+#include <ddf/driver.h>
 
 #include "hub.h"
Index: uspace/drv/vhc/hub/virthub.c
===================================================================
--- uspace/drv/vhc/hub/virthub.c	(revision 0f21c0c8a600adbbfbe315431bff13a9695a1692)
+++ uspace/drv/vhc/hub/virthub.c	(revision 871579827dc035beaf1288f0f9b5b5390cb24eb1)
@@ -39,6 +39,7 @@
 #include <errno.h>
 #include <str_error.h>
+#include <assert.h>
 #include <stdlib.h>
-#include <driver.h>
+#include <ddf/driver.h>
 
 #include "virthub.h"
