Index: uspace/drv/bus/usb/vhc/devconn.c
===================================================================
--- uspace/drv/bus/usb/vhc/devconn.c	(revision f6577d9a0f34fa9e3b2839f6f69457ff37b6bb3d)
+++ uspace/drv/bus/usb/vhc/devconn.c	(revision f5f0cfb5359fd9d4e6a83407ce99674f51f11b64)
@@ -79,5 +79,5 @@
 	if (connect) {
 		// FIXME: check status
-		(void) virthub_connect_device(vhc->hub, dev);
+		(void) virthub_connect_device(&vhc->hub, dev);
 	}
 
@@ -105,5 +105,5 @@
 
 	// FIXME: check status
-	(void) virthub_disconnect_device(vhc->hub, dev);
+	(void) virthub_disconnect_device(&vhc->hub, dev);
 
 	fibril_mutex_lock(&vhc->guard);
Index: uspace/drv/bus/usb/vhc/hub/virthub.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub/virthub.c	(revision f6577d9a0f34fa9e3b2839f6f69457ff37b6bb3d)
+++ uspace/drv/bus/usb/vhc/hub/virthub.c	(revision f5f0cfb5359fd9d4e6a83407ce99674f51f11b64)
@@ -146,5 +146,5 @@
  * @return Error code.
  */
-int virthub_init(usbvirt_device_t *dev)
+int virthub_init(usbvirt_device_t *dev, const char* name)
 {
 	if (dev == NULL) {
@@ -153,7 +153,12 @@
 	dev->ops = &hub_ops;
 	dev->descriptors = &descriptors;
+	dev->address = 0;
+	dev->name = str_dup(name);
+	if (!name)
+		return ENOMEM;
 
 	hub_t *hub = malloc(sizeof(hub_t));
 	if (hub == NULL) {
+		free(dev->name);
 		return ENOMEM;
 	}
Index: uspace/drv/bus/usb/vhc/hub/virthub.h
===================================================================
--- uspace/drv/bus/usb/vhc/hub/virthub.h	(revision f6577d9a0f34fa9e3b2839f6f69457ff37b6bb3d)
+++ uspace/drv/bus/usb/vhc/hub/virthub.h	(revision f5f0cfb5359fd9d4e6a83407ce99674f51f11b64)
@@ -79,5 +79,5 @@
 extern hub_descriptor_t hub_descriptor;
 
-int virthub_init(usbvirt_device_t *);
+int virthub_init(usbvirt_device_t *, const char *name);
 int virthub_connect_device(usbvirt_device_t *, vhc_virtdev_t *);
 int virthub_disconnect_device(usbvirt_device_t *, vhc_virtdev_t *);
Index: uspace/drv/bus/usb/vhc/main.c
===================================================================
--- uspace/drv/bus/usb/vhc/main.c	(revision f6577d9a0f34fa9e3b2839f6f69457ff37b6bb3d)
+++ uspace/drv/bus/usb/vhc/main.c	(revision f5f0cfb5359fd9d4e6a83407ce99674f51f11b64)
@@ -44,12 +44,5 @@
 #include <usb/debug.h>
 #include "vhcd.h"
-#include "hub/hub.h"
-#include "hub/virthub.h"
 
-static usbvirt_device_t virtual_hub_device = {
-	.name = "root hub",
-	.ops = &hub_ops,
-	.address = 0
-};
 
 static ddf_dev_ops_t vhc_ops = {
@@ -57,4 +50,5 @@
 	.default_handler = default_connection_handler
 };
+
 
 static int vhc_control_node(ddf_dev_t *dev, ddf_fun_t **fun)
@@ -78,11 +72,7 @@
 		return ret;
 	}
-	vhc_data_init(vhc);
-	// TODO: This limits us to single vhc instance.
-	virthub_init(&virtual_hub_device);
-	vhc->hub = &virtual_hub_device;
+	vhc_init(vhc);
 	return EOK;
 }
-
 
 static int vhc_dev_add(ddf_dev_t *dev)
@@ -111,5 +101,5 @@
 	/* Add virtual hub device */
 	usb_address_t address = 1;
-	ret = vhc_virtdev_plug_hub(data, data->hub, NULL, address);
+	ret = vhc_virtdev_plug_hub(data, &data->hub, NULL, address);
 	if (ret != EOK) {
 		usb_log_error("Failed to plug root hub: %s.\n", str_error(ret));
Index: uspace/drv/bus/usb/vhc/transfer.c
===================================================================
--- uspace/drv/bus/usb/vhc/transfer.c	(revision f6577d9a0f34fa9e3b2839f6f69457ff37b6bb3d)
+++ uspace/drv/bus/usb/vhc/transfer.c	(revision f5f0cfb5359fd9d4e6a83407ce99674f51f11b64)
@@ -33,4 +33,133 @@
 #include <usbvirt/ipc.h>
 #include "vhcd.h"
+#include "hub/virthub.h"
+
+static bool is_set_address_transfer(vhc_transfer_t *transfer)
+{
+	if (transfer->batch->ep->endpoint != 0) {
+		return false;
+	}
+	if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
+		return false;
+	}
+	if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) {
+		return false;
+	}
+	const usb_device_request_setup_packet_t *setup =
+	    (void*)transfer->batch->setup_buffer;
+	if (setup->request_type != 0) {
+		return false;
+	}
+	if (setup->request != USB_DEVREQ_SET_ADDRESS) {
+		return false;
+	}
+
+	return true;
+}
+
+static int process_transfer_local(usb_transfer_batch_t *batch,
+    usbvirt_device_t *dev, size_t *actual_data_size)
+{
+	int rc;
+	
+	const usb_direction_t dir = usb_transfer_batch_direction(batch);
+
+	if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
+		if (dir == USB_DIRECTION_IN) {
+			rc = usbvirt_control_read(dev,
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size,
+			    actual_data_size);
+		} else {
+			assert(dir == USB_DIRECTION_OUT);
+			rc = usbvirt_control_write(dev,
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size);
+		}
+	} else {
+		if (dir == USB_DIRECTION_IN) {
+			rc = usbvirt_data_in(dev, batch->ep->transfer_type,
+			    batch->ep->endpoint,
+			    batch->buffer, batch->buffer_size,
+			    actual_data_size);
+		} else {
+			assert(dir == USB_DIRECTION_OUT);
+			rc = usbvirt_data_out(dev, batch->ep->transfer_type,
+			    batch->ep->endpoint,
+			    batch->buffer, batch->buffer_size);
+		}
+	}
+
+	return rc;
+}
+
+static int process_transfer_remote(usb_transfer_batch_t *batch,
+    async_sess_t *sess, size_t *actual_data_size)
+{
+	int rc;
+
+	const usb_direction_t dir = usb_transfer_batch_direction(batch);
+
+	if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
+		if (dir == USB_DIRECTION_IN) {
+			rc = usbvirt_ipc_send_control_read(sess,
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size,
+			    actual_data_size);
+		} else {
+			assert(dir == USB_DIRECTION_OUT);
+			rc = usbvirt_ipc_send_control_write(sess,
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size);
+		}
+	} else {
+		if (dir == USB_DIRECTION_IN) {
+			rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
+			    batch->ep->transfer_type,
+			    batch->buffer, batch->buffer_size,
+			    actual_data_size);
+		} else {
+			assert(dir == USB_DIRECTION_OUT);
+			rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
+			    batch->ep->transfer_type,
+			    batch->buffer, batch->buffer_size);
+		}
+	}
+
+	return rc;
+}
+
+static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev)
+{
+	assert(fibril_mutex_is_locked(&dev->guard));
+	assert(!list_empty(&dev->transfer_queue));
+
+	vhc_transfer_t *transfer = list_get_instance(
+	    list_first(&dev->transfer_queue), vhc_transfer_t, link);
+	list_remove(&transfer->link);
+
+	return transfer;
+}
+
+static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
+    size_t data_transfer_size, int outcome)
+{
+	assert(outcome != ENAK);
+	assert(transfer);
+	assert(transfer->batch);
+	usb_transfer_batch_finish_error(transfer->batch, NULL,
+	    data_transfer_size, outcome);
+	usb_transfer_batch_destroy(transfer->batch);
+	free(transfer);
+}
+
+int vhc_init(vhc_data_t *instance)
+{
+	assert(instance);
+	list_initialize(&instance->devices);
+	fibril_mutex_initialize(&instance->guard);
+	instance->magic = 0xDEADBEEF;
+	return virthub_init(&instance->hub, "root hub");
+}
 
 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
@@ -69,123 +198,4 @@
 
 	return targets ? EOK : ENOENT;
-}
-
-static bool is_set_address_transfer(vhc_transfer_t *transfer)
-{
-	if (transfer->batch->ep->endpoint != 0) {
-		return false;
-	}
-	if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
-		return false;
-	}
-	if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) {
-		return false;
-	}
-	const usb_device_request_setup_packet_t *setup =
-	    (void*)transfer->batch->setup_buffer;
-	if (setup->request_type != 0) {
-		return false;
-	}
-	if (setup->request != USB_DEVREQ_SET_ADDRESS) {
-		return false;
-	}
-
-	return true;
-}
-
-static int process_transfer_local(usb_transfer_batch_t *batch,
-    usbvirt_device_t *dev, size_t *actual_data_size)
-{
-	int rc;
-	
-	const usb_direction_t dir = usb_transfer_batch_direction(batch);
-
-	if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
-		if (dir == USB_DIRECTION_IN) {
-			rc = usbvirt_control_read(dev,
-			    batch->setup_buffer, batch->setup_size,
-			    batch->buffer, batch->buffer_size,
-			    actual_data_size);
-		} else {
-			assert(dir == USB_DIRECTION_OUT);
-			rc = usbvirt_control_write(dev,
-			    batch->setup_buffer, batch->setup_size,
-			    batch->buffer, batch->buffer_size);
-		}
-	} else {
-		if (dir == USB_DIRECTION_IN) {
-			rc = usbvirt_data_in(dev, batch->ep->transfer_type,
-			    batch->ep->endpoint,
-			    batch->buffer, batch->buffer_size,
-			    actual_data_size);
-		} else {
-			assert(dir == USB_DIRECTION_OUT);
-			rc = usbvirt_data_out(dev, batch->ep->transfer_type,
-			    batch->ep->endpoint,
-			    batch->buffer, batch->buffer_size);
-		}
-	}
-
-	return rc;
-}
-
-static int process_transfer_remote(usb_transfer_batch_t *batch,
-    async_sess_t *sess, size_t *actual_data_size)
-{
-	int rc;
-
-	const usb_direction_t dir = usb_transfer_batch_direction(batch);
-
-	if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
-		if (dir == USB_DIRECTION_IN) {
-			rc = usbvirt_ipc_send_control_read(sess,
-			    batch->setup_buffer, batch->setup_size,
-			    batch->buffer, batch->buffer_size,
-			    actual_data_size);
-		} else {
-			assert(dir == USB_DIRECTION_OUT);
-			rc = usbvirt_ipc_send_control_write(sess,
-			    batch->setup_buffer, batch->setup_size,
-			    batch->buffer, batch->buffer_size);
-		}
-	} else {
-		if (dir == USB_DIRECTION_IN) {
-			rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
-			    batch->ep->transfer_type,
-			    batch->buffer, batch->buffer_size,
-			    actual_data_size);
-		} else {
-			assert(dir == USB_DIRECTION_OUT);
-			rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
-			    batch->ep->transfer_type,
-			    batch->buffer, batch->buffer_size);
-		}
-	}
-
-	return rc;
-}
-
-static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev)
-{
-	assert(fibril_mutex_is_locked(&dev->guard));
-	assert(!list_empty(&dev->transfer_queue));
-
-	vhc_transfer_t *transfer = list_get_instance(
-	    list_first(&dev->transfer_queue), vhc_transfer_t, link);
-	list_remove(&transfer->link);
-
-	return transfer;
-}
-
-static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
-    size_t data_transfer_size, int outcome)
-{
-	assert(outcome != ENAK);
-	assert(transfer);
-	assert(transfer->batch);
-	usb_transfer_batch_finish_error(transfer->batch, NULL,
-	    data_transfer_size, outcome);
-	usb_transfer_batch_destroy(transfer->batch);
-	free(transfer);
 }
 
Index: uspace/drv/bus/usb/vhc/vhcd.h
===================================================================
--- uspace/drv/bus/usb/vhc/vhcd.h	(revision f6577d9a0f34fa9e3b2839f6f69457ff37b6bb3d)
+++ uspace/drv/bus/usb/vhc/vhcd.h	(revision f5f0cfb5359fd9d4e6a83407ce99674f51f11b64)
@@ -59,6 +59,5 @@
 	list_t devices;
 	fibril_mutex_t guard;
-	usbvirt_device_t *hub;
-	ddf_fun_t *hc_fun;
+	usbvirt_device_t hub;
 } vhc_data_t;
 
@@ -68,11 +67,4 @@
 } vhc_transfer_t;
 
-static inline void vhc_data_init(vhc_data_t *instance)
-{
-	assert(instance);
-	list_initialize(&instance->devices);
-	fibril_mutex_initialize(&instance->guard);
-	instance->magic = 0xDEADBEEF;
-}
 
 void on_client_close(ddf_fun_t *fun);
@@ -85,5 +77,5 @@
 void vhc_virtdev_unplug(vhc_data_t *, uintptr_t);
 
-
+int vhc_init(vhc_data_t *instance);
 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
 int vhc_transfer_queue_processor(void *arg);
