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 38b4a2594129c2f92ce12a9a6511d3bb82a8f3b6)
@@ -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);
 }
 
