Index: uspace/drv/bus/usb/vhc/conndev.c
===================================================================
--- uspace/drv/bus/usb/vhc/conndev.c	(revision 2b0929ee5e8d739ac79c3b2185063a8370dc73ab)
+++ uspace/drv/bus/usb/vhc/conndev.c	(revision 01eeaaf85eb7046c2ec99330000b8aa116e605b9)
@@ -94,5 +94,5 @@
     ipc_call_t *icall)
 {
-	vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun));
+	vhc_data_t *vhc = ddf_fun_data_get(fun);
 	
 	async_sess_t *callback =
@@ -125,5 +125,5 @@
 void on_client_close(ddf_fun_t *fun)
 {
-	vhc_data_t *vhc = ddf_dev_data_get(ddf_fun_get_dev(fun));
+	vhc_data_t *vhc = ddf_fun_data_get(fun);
 
 	if (plugged_device_handle != 0) {
Index: uspace/drv/bus/usb/vhc/connhost.c
===================================================================
--- uspace/drv/bus/usb/vhc/connhost.c	(revision 2b0929ee5e8d739ac79c3b2185063a8370dc73ab)
+++ uspace/drv/bus/usb/vhc/connhost.c	(revision 01eeaaf85eb7046c2ec99330000b8aa116e605b9)
@@ -158,235 +158,5 @@
 	return rc;
 }
-#if 0
-/** Schedule interrupt out transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
- *	by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	VHC_DATA(vhc, fun);
-
-	vhc_transfer_t *transfer = vhc_transfer_create(target.address,
-	    target.endpoint, USB_DIRECTION_OUT, USB_TRANSFER_INTERRUPT,
-	    fun, arg);
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->data_buffer = data;
-	transfer->data_buffer_size = size;
-	transfer->callback_out = callback;
-
-	int rc = vhc_virtdev_add_transfer(vhc, transfer);
-	if (rc != EOK) {
-		free(transfer);
-		return rc;
-	}
-
-	return EOK;
-}
-
-/** Schedule interrupt in transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Buffer where to store the data (in USB endianess,
- *	allocated and deallocated by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	VHC_DATA(vhc, fun);
-
-	vhc_transfer_t *transfer = vhc_transfer_create(target.address,
-	    target.endpoint, USB_DIRECTION_IN, USB_TRANSFER_INTERRUPT,
-	    fun, arg);
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->data_buffer = data;
-	transfer->data_buffer_size = size;
-	transfer->callback_in = callback;
-
-	int rc = vhc_virtdev_add_transfer(vhc, transfer);
-	if (rc != EOK) {
-		free(transfer);
-		return rc;
-	}
-
-	return EOK;
-}
-
-/** Schedule bulk out transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Data to be sent (in USB endianess, allocated and deallocated
- *	by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int bulk_out(ddf_fun_t *fun, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	UNSUPPORTED("bulk_out");
-
-	return ENOTSUP;
-}
-
-/** Schedule bulk in transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] data Buffer where to store the data (in USB endianess,
- *	allocated and deallocated by the caller).
- * @param[in] size Size of the @p data buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int bulk_in(ddf_fun_t *fun, usb_target_t target,
-    void *data, size_t size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	UNSUPPORTED("bulk_in");
-
-	return ENOTSUP;
-}
-
-/** Schedule control write transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
- *	and deallocated by the caller).
- * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
- * @param[in] data_buffer Data buffer (in USB endianess, allocated and
- *	deallocated by the caller).
- * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int control_write(ddf_fun_t *fun, usb_target_t target,
-    void *setup_packet, size_t setup_packet_size,
-    void *data_buffer, size_t data_buffer_size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	VHC_DATA(vhc, fun);
-
-	vhc_transfer_t *transfer = vhc_transfer_create(target.address,
-	    target.endpoint, USB_DIRECTION_OUT, USB_TRANSFER_CONTROL,
-	    fun, arg);
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->setup_buffer = setup_packet;
-	transfer->setup_buffer_size = setup_packet_size;
-	transfer->data_buffer = data_buffer;
-	transfer->data_buffer_size = data_buffer_size;
-	transfer->callback_out = callback;
-
-	int rc = vhc_virtdev_add_transfer(vhc, transfer);
-	if (rc != EOK) {
-		free(transfer);
-		return rc;
-	}
-
-	return EOK;
-}
-
-/** Schedule control read transfer.
- *
- * The callback is supposed to be called once the transfer (on the wire) is
- * complete regardless of the outcome.
- * However, the callback could be called only when this function returns
- * with success status (i.e. returns EOK).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] target Target pipe (address and endpoint number) specification.
- * @param[in] setup_packet Setup packet buffer (in USB endianess, allocated
- *	and deallocated by the caller).
- * @param[in] setup_packet_size Size of @p setup_packet buffer in bytes.
- * @param[in] data_buffer Buffer where to store the data (in USB endianess,
- *	allocated and deallocated by the caller).
- * @param[in] data_buffer_size Size of @p data_buffer buffer in bytes.
- * @param[in] callback Callback to be issued once the transfer is complete.
- * @param[in] arg Pass-through argument to the callback.
- * @return Error code.
- */
-static int control_read(ddf_fun_t *fun, usb_target_t target,
-    void *setup_packet, size_t setup_packet_size,
-    void *data_buffer, size_t data_buffer_size,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	VHC_DATA(vhc, fun);
-
-	vhc_transfer_t *transfer = vhc_transfer_create(target.address,
-	    target.endpoint, USB_DIRECTION_IN, USB_TRANSFER_CONTROL,
-	    fun, arg);
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-
-	transfer->setup_buffer = setup_packet;
-	transfer->setup_buffer_size = setup_packet_size;
-	transfer->data_buffer = data_buffer;
-	transfer->data_buffer_size = data_buffer_size;
-	transfer->callback_in = callback;
-
-	int rc = vhc_virtdev_add_transfer(vhc, transfer);
-	if (rc != EOK) {
-		free(transfer);
-		return rc;
-	}
-
-	return EOK;
-}
-#endif
+
 static int usb_read(ddf_fun_t *fun, usb_target_t target, uint64_t setup_buffer,
     uint8_t *data_buffer, size_t data_buffer_size,
Index: uspace/drv/bus/usb/vhc/devconn.c
===================================================================
--- uspace/drv/bus/usb/vhc/devconn.c	(revision 2b0929ee5e8d739ac79c3b2185063a8370dc73ab)
+++ uspace/drv/bus/usb/vhc/devconn.c	(revision 01eeaaf85eb7046c2ec99330000b8aa116e605b9)
@@ -51,5 +51,5 @@
 static int vhc_virtdev_plug_generic(vhc_data_t *vhc,
     async_sess_t *sess, usbvirt_device_t *virtdev,
-    uintptr_t *handle, bool connect)
+    uintptr_t *handle, bool connect, usb_address_t address)
 {
 	vhc_virtdev_t *dev = vhc_virtdev_create();
@@ -60,4 +60,5 @@
 	dev->dev_sess = sess;
 	dev->dev_local = virtdev;
+	dev->address = address;
 
 	fibril_mutex_lock(&vhc->guard);
@@ -86,15 +87,15 @@
 int vhc_virtdev_plug(vhc_data_t *vhc, async_sess_t *sess, uintptr_t *handle)
 {
-	return vhc_virtdev_plug_generic(vhc, sess, NULL, handle, true);
+	return vhc_virtdev_plug_generic(vhc, sess, NULL, handle, true, 0);
 }
 
 int vhc_virtdev_plug_local(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle)
 {
-	return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, true);
+	return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, true, 0);
 }
 
-int vhc_virtdev_plug_hub(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle)
+int vhc_virtdev_plug_hub(vhc_data_t *vhc, usbvirt_device_t *dev, uintptr_t *handle, usb_address_t address)
 {
-	return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, false);
+	return vhc_virtdev_plug_generic(vhc, NULL, dev, handle, false, address);
 }
 
Index: uspace/drv/bus/usb/vhc/main.c
===================================================================
--- uspace/drv/bus/usb/vhc/main.c	(revision 2b0929ee5e8d739ac79c3b2185063a8370dc73ab)
+++ uspace/drv/bus/usb/vhc/main.c	(revision 01eeaaf85eb7046c2ec99330000b8aa116e605b9)
@@ -44,4 +44,6 @@
 #include <ddf/driver.h>
 
+#include <usb/host/ddf_helpers.h>
+
 #include <usb/usb.h>
 #include <usb/ddfiface.h>
@@ -52,12 +54,82 @@
 
 static ddf_dev_ops_t vhc_ops = {
+#if 0
 	.interfaces[USBHC_DEV_IFACE] = &vhc_iface,
 	.interfaces[USB_DEV_IFACE] = &vhc_usb_iface,
+#endif
 	.close = on_client_close,
 	.default_handler = default_connection_handler
 };
 
+static int vhc_control_node(ddf_dev_t *dev, ddf_fun_t **fun)
+{
+	assert(dev);
+	assert(fun);
+
+	*fun = ddf_fun_create(dev, fun_exposed, "ctl");
+	if (!*fun)
+		return ENOMEM;
+
+	vhc_data_t *vhc = ddf_fun_data_alloc(*fun, sizeof(vhc_data_t));
+	if (!vhc) {
+		ddf_fun_destroy(*fun);
+	}
+	ddf_fun_set_ops(*fun, &vhc_ops);
+	const int ret = ddf_fun_bind(*fun);
+	if (ret != EOK) {
+		ddf_fun_destroy(*fun);
+		*fun = NULL;
+		return ret;
+	}
+	vhc_data_init(vhc);
+	// TODO: This limits us to single vhc instance.
+	virthub_init(&virtual_hub_device);
+	vhc->hub = &virtual_hub_device;
+	return EOK;
+}
+
+
 static int vhc_dev_add(ddf_dev_t *dev)
 {
+	/* Initialize virtual structure */
+	ddf_fun_t *ctl_fun = NULL;
+	int ret = vhc_control_node(dev, &ctl_fun);
+	if (ret != EOK) {
+		usb_log_error("Failed to setup control node.\n");
+		return ret;
+	}
+	vhc_data_t *data = ddf_fun_data_get(ctl_fun);
+
+	/* Initialize generic structures */
+	ret = hcd_ddf_setup_device(dev, NULL, USB_SPEED_FULL,
+	    BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
+	if (ret != EOK) {
+		usb_log_error("Failed to init HCD structures: %s.\n",
+		   str_error(ret));
+		free(data);
+		return ret;
+	}
+
+	hcd_set_implementation(dev_to_hcd(dev), data, vhc_schedule, NULL, NULL);
+
+	/* Add virtual hub device */
+	usb_address_t address = 1;
+	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));
+		free(data);
+		return ret;
+	}
+
+	// TODO fix the address hack
+	ret = hcd_ddf_setup_hub(dev, &address);
+	if (ret != EOK) {
+		usb_log_error("Failed to init VHC root hub: %s\n",
+			str_error(ret));
+		// TODO do something here...
+	}
+
+	return ret;
+#if 0
 	static int vhc_count = 0;
 	int rc;
@@ -124,4 +196,5 @@
 
 	return EOK;
+#endif
 }
 
@@ -137,5 +210,5 @@
 
 int main(int argc, char * argv[])
-{	
+{
 	log_init(NAME);
 
@@ -145,5 +218,4 @@
 }
 
-
 /**
  * @}
Index: uspace/drv/bus/usb/vhc/transfer.c
===================================================================
--- uspace/drv/bus/usb/vhc/transfer.c	(revision 2b0929ee5e8d739ac79c3b2185063a8370dc73ab)
+++ uspace/drv/bus/usb/vhc/transfer.c	(revision 01eeaaf85eb7046c2ec99330000b8aa116e605b9)
@@ -64,17 +64,15 @@
 static bool is_set_address_transfer(vhc_transfer_t *transfer)
 {
-	if (transfer->endpoint != 0) {
-		return false;
-	}
-	if (transfer->transfer_type != USB_TRANSFER_CONTROL) {
-		return false;
-	}
-	if (transfer->direction != USB_DIRECTION_OUT) {
-		return false;
-	}
-	if (transfer->setup_buffer_size != sizeof(usb_device_request_setup_packet_t)) {
-		return false;
-	}
-	usb_device_request_setup_packet_t *setup = transfer->setup_buffer;
+	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;
@@ -85,4 +83,41 @@
 
 	return true;
+}
+
+int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
+{
+	assert(hcd);
+	assert(batch);
+	vhc_data_t *vhc = hcd->private_data;
+	assert(vhc);
+
+	vhc_transfer_t *transfer = malloc(sizeof(vhc_transfer_t));
+	if (!transfer)
+		return ENOMEM;
+	link_initialize(&transfer->link);
+	transfer->batch = batch;
+
+	fibril_mutex_lock(&vhc->guard);
+
+	int targets = 0;
+
+	list_foreach(vhc->devices, pos) {
+		vhc_virtdev_t *dev = list_get_instance(pos, vhc_virtdev_t, link);
+		fibril_mutex_lock(&dev->guard);
+		if (dev->address == transfer->batch->ep->address) {
+			if (!targets) {
+				list_append(&transfer->link, &dev->transfer_queue);
+			}
+			++targets;
+		}
+		fibril_mutex_unlock(&dev->guard);
+	}
+
+	fibril_mutex_unlock(&vhc->guard);
+	
+	if (targets > 1)
+		usb_log_warning("Transfer would be accepted by more devices!\n");
+
+	return targets ? EOK : ENOENT;
 }
 
@@ -116,32 +151,34 @@
 }
 
-static int process_transfer_local(vhc_transfer_t *transfer,
+static int process_transfer_local(usb_transfer_batch_t *batch,
     usbvirt_device_t *dev, size_t *actual_data_size)
 {
 	int rc;
-
-	if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
-		if (transfer->direction == USB_DIRECTION_IN) {
+	
+	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,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size,
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size,
 			    actual_data_size);
 		} else {
-			assert(transfer->direction == USB_DIRECTION_OUT);
+			assert(dir == USB_DIRECTION_OUT);
 			rc = usbvirt_control_write(dev,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size);
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size);
 		}
 	} else {
-		if (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_data_in(dev, transfer->transfer_type,
-			    transfer->endpoint,
-			    transfer->data_buffer, transfer->data_buffer_size,
+		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(transfer->direction == USB_DIRECTION_OUT);
-			rc = usbvirt_data_out(dev, transfer->transfer_type,
-			    transfer->endpoint,
-			    transfer->data_buffer, transfer->data_buffer_size);
+			assert(dir == USB_DIRECTION_OUT);
+			rc = usbvirt_data_out(dev, batch->ep->transfer_type,
+			    batch->ep->endpoint,
+			    batch->buffer, batch->buffer_size);
 		}
 	}
@@ -150,32 +187,34 @@
 }
 
-static int process_transfer_remote(vhc_transfer_t *transfer,
+static int process_transfer_remote(usb_transfer_batch_t *batch,
     async_sess_t *sess, size_t *actual_data_size)
 {
 	int rc;
 
-	if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
-		if (transfer->direction == USB_DIRECTION_IN) {
+	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,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size,
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size,
 			    actual_data_size);
 		} else {
-			assert(transfer->direction == USB_DIRECTION_OUT);
+			assert(dir == USB_DIRECTION_OUT);
 			rc = usbvirt_ipc_send_control_write(sess,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size);
+			    batch->setup_buffer, batch->setup_size,
+			    batch->buffer, batch->buffer_size);
 		}
 	} else {
-		if (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_ipc_send_data_in(sess, transfer->endpoint,
-			    transfer->transfer_type,
-			    transfer->data_buffer, transfer->data_buffer_size,
+		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(transfer->direction == USB_DIRECTION_OUT);
-			rc = usbvirt_ipc_send_data_out(sess, transfer->endpoint,
-			    transfer->transfer_type,
-			    transfer->data_buffer, transfer->data_buffer_size);
+			assert(dir == USB_DIRECTION_OUT);
+			rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
+			    batch->ep->transfer_type,
+			    batch->buffer, batch->buffer_size);
 		}
 	}
@@ -200,4 +239,12 @@
     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);
+#if 0
 	assert(outcome != ENAK);
 
@@ -214,4 +261,5 @@
 
 	free(transfer);
+#endif
 }
 
@@ -234,9 +282,9 @@
 		size_t data_transfer_size = 0;
 		if (dev->dev_sess) {
-			rc = process_transfer_remote(transfer, dev->dev_sess,
-			    &data_transfer_size);
+			rc = process_transfer_remote(transfer->batch,
+			    dev->dev_sess, &data_transfer_size);
 		} else if (dev->dev_local != NULL) {
-			rc = process_transfer_local(transfer, dev->dev_local,
-			    &data_transfer_size);
+			rc = process_transfer_local(transfer->batch,
+			    dev->dev_local, &data_transfer_size);
 		} else {
 			usb_log_warning("Device has no remote phone nor local node.\n");
@@ -251,5 +299,5 @@
 			if (is_set_address_transfer(transfer)) {
 				usb_device_request_setup_packet_t *setup
-				    = transfer->setup_buffer;
+				    = (void*)transfer->batch->setup_buffer;
 				dev->address = setup->value;
 				usb_log_debug2("Address changed to %d\n",
Index: uspace/drv/bus/usb/vhc/vhcd.h
===================================================================
--- uspace/drv/bus/usb/vhc/vhcd.h	(revision 2b0929ee5e8d739ac79c3b2185063a8370dc73ab)
+++ uspace/drv/bus/usb/vhc/vhcd.h	(revision 01eeaaf85eb7046c2ec99330000b8aa116e605b9)
@@ -43,4 +43,7 @@
 #include <async.h>
 
+#include <usb/host/hcd.h>
+
+
 #define NAME "vhc"
 
@@ -67,4 +70,7 @@
 typedef struct {
 	link_t link;
+
+	usb_transfer_batch_t *batch;
+
 	usb_address_t address;
 	usb_endpoint_t endpoint;
@@ -81,9 +87,18 @@
 } 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;
+}
+
+
 vhc_transfer_t *vhc_transfer_create(usb_address_t, usb_endpoint_t,
     usb_direction_t, usb_transfer_type_t, ddf_fun_t *, void *);
 int vhc_virtdev_plug(vhc_data_t *, async_sess_t *, uintptr_t *);
 int vhc_virtdev_plug_local(vhc_data_t *, usbvirt_device_t *, uintptr_t *);
-int vhc_virtdev_plug_hub(vhc_data_t *, usbvirt_device_t *, uintptr_t *);
+int vhc_virtdev_plug_hub(vhc_data_t *, usbvirt_device_t *, uintptr_t *, usb_address_t address);
 void vhc_virtdev_unplug(vhc_data_t *, uintptr_t);
 int vhc_virtdev_add_transfer(vhc_data_t *, vhc_transfer_t *);
@@ -92,4 +107,6 @@
 
 
+int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
+
 #endif
 /**
