Index: uspace/drv/bus/usb/vhc/Makefile
===================================================================
--- uspace/drv/bus/usb/vhc/Makefile	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/Makefile	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -49,7 +49,5 @@
 	hub/virthubops.c \
 	conndev.c \
-	connhost.c \
 	devconn.c \
-	hub.c \
 	main.c \
 	transfer.c
Index: uspace/drv/bus/usb/vhc/conn.h
===================================================================
--- uspace/drv/bus/usb/vhc/conn.h	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ 	(revision )
@@ -1,54 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 drvusbvhc
- * @{
- */
-/** @file
- * @brief Connection handling of incoming calls.
- */
-#ifndef VHCD_CONN_H_
-#define VHCD_CONN_H_
-
-#include <usb/usb.h>
-#include <usbhc_iface.h>
-#include <usb_iface.h>
-#include "vhcd.h"
-
-extern usbhc_iface_t vhc_iface;
-extern usb_iface_t vhc_usb_iface;
-extern usb_iface_t rh_usb_iface;
-
-void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *);
-void on_client_close(ddf_fun_t *);
-
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/bus/usb/vhc/conndev.c
===================================================================
--- uspace/drv/bus/usb/vhc/conndev.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/conndev.c	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -38,6 +38,8 @@
 #include <ddf/driver.h>
 #include <usbvirt/ipc.h>
+#include <usb/debug.h>
 #include <async.h>
-#include "conn.h"
+
+#include "vhcd.h"
 
 static fibril_local uintptr_t plugged_device_handle = 0;
@@ -94,5 +96,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 +127,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 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ 	(revision )
@@ -1,533 +1,0 @@
-/*
- * Copyright (c) 2011 Vojtech Horky
- * 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 drvusbvhc
- * @{
- */
-/** @file
- * Host controller interface implementation.
- */
-#include <assert.h>
-#include <errno.h>
-#include <usb/usb.h>
-#include <usb/ddfiface.h>
-#include <usb/debug.h>
-#include <usbhc_iface.h>
-#include "vhcd.h"
-
-#define GET_VHC_DATA(fun) \
-	((vhc_data_t *)ddf_dev_data_get(ddf_fun_get_dev(fun)))
-#define VHC_DATA(vhc, fun) \
-	vhc_data_t *vhc = GET_VHC_DATA(fun); assert(vhc->magic == 0xdeadbeef)
-
-#define UNSUPPORTED(methodname) \
-	usb_log_warning("Unsupported interface method `%s()' in %s:%d.\n", \
-	    methodname, __FILE__, __LINE__)
-
-/** Found free USB address.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] speed Speed of the device that will get this address.
- * @param[out] address Non-null pointer where to store the free address.
- * @return Error code.
- */
-static int request_address(ddf_fun_t *fun, usb_address_t *address, bool strict,
-    usb_speed_t speed)
-{
-	VHC_DATA(vhc, fun);
-
-	assert(address);
-	return usb_device_manager_request_address(
-	    &vhc->dev_manager, address, strict, speed);
-}
-
-/** Bind USB address with device devman handle.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address of the device.
- * @param[in] handle Devman handle of the device.
- * @return Error code.
- */
-static int bind_address(ddf_fun_t *fun,
-    usb_address_t address, devman_handle_t handle)
-{
-	VHC_DATA(vhc, fun);
-	usb_log_debug("Binding handle %" PRIun " to address %d.\n",
-	    handle, address);
-	usb_device_manager_bind_address(&vhc->dev_manager, address, handle);
-
-	return EOK;
-}
-
-/** Find device handle by address interface function.
- *
- * @param[in] fun DDF function that was called.
- * @param[in] address Address in question.
- * @param[out] handle Where to store device handle if found.
- * @return Error code.
- */
-static int find_by_address(ddf_fun_t *fun, usb_address_t address,
-    devman_handle_t *handle)
-{
-	VHC_DATA(vhc, fun);
-	return usb_device_manager_get_info_by_address(
-	    &vhc->dev_manager, address, handle, NULL);
-}
-
-/** Release previously requested address.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address to be released.
- * @return Error code.
- */
-static int release_address(ddf_fun_t *fun, usb_address_t address)
-{
-	VHC_DATA(vhc, fun);
-	usb_log_debug("Releasing address %d...\n", address);
-	usb_device_manager_release_address(&vhc->dev_manager, address);
-
-	return ENOTSUP;
-}
-
-/** Register endpoint for bandwidth reservation.
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address of the device.
- * @param[in] speed Endpoint speed (invalid means to use device one).
- * @param[in] endpoint Endpoint number.
- * @param[in] transfer_type USB transfer type.
- * @param[in] direction Endpoint data direction.
- * @param[in] max_packet_size Max packet size of the endpoint.
- * @param[in] interval Polling interval.
- * @return Error code.
- */
-static int register_endpoint(ddf_fun_t *fun,
-    usb_address_t address, usb_endpoint_t endpoint,
-    usb_transfer_type_t transfer_type, usb_direction_t direction,
-    size_t max_packet_size, unsigned int interval)
-{
-	VHC_DATA(vhc, fun);
-
-	return usb_endpoint_manager_add_ep(&vhc->ep_manager,
-	    address, endpoint, direction, transfer_type, USB_SPEED_FULL, 1, 0,
-	    NULL, NULL);
-
-}
-
-/** Unregister endpoint (free some bandwidth reservation).
- *
- * @param[in] fun Device function the action was invoked on.
- * @param[in] address USB address of the device.
- * @param[in] endpoint Endpoint number.
- * @param[in] direction Endpoint data direction.
- * @return Error code.
- */
-static int unregister_endpoint(ddf_fun_t *fun, usb_address_t address,
-    usb_endpoint_t endpoint, usb_direction_t direction)
-{
-	VHC_DATA(vhc, fun);
-
-	int rc = usb_endpoint_manager_remove_ep(&vhc->ep_manager,
-	    address, endpoint, direction, NULL, NULL);
-
-	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,
-    usbhc_iface_transfer_in_callback_t callback, void *arg)
-{
-	VHC_DATA(vhc, fun);
-
-	endpoint_t *ep = usb_endpoint_manager_find_ep(&vhc->ep_manager,
-	    target.address, target.endpoint, USB_DIRECTION_IN);
-	if (ep == NULL) {
-		return ENOENT;
-	}
-	const usb_transfer_type_t transfer_type = ep->transfer_type;
-
-
-	vhc_transfer_t *transfer = vhc_transfer_create(target.address,
-	    target.endpoint, USB_DIRECTION_IN, transfer_type,
-	    fun, arg);
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-	if (transfer_type == USB_TRANSFER_CONTROL) {
-		transfer->setup_buffer = malloc(sizeof(uint64_t));
-		assert(transfer->setup_buffer);
-		memcpy(transfer->setup_buffer, &setup_buffer, sizeof(uint64_t));
-		transfer->setup_buffer_size = sizeof(uint64_t);
-	}
-	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) {
-		if (transfer->setup_buffer != NULL) {
-			free(transfer->setup_buffer);
-		}
-		free(transfer);
-		return rc;
-	}
-
-	return EOK;
-}
-
-static int usb_write(ddf_fun_t *fun, usb_target_t target, uint64_t setup_buffer,
-    const uint8_t *data_buffer, size_t data_buffer_size,
-    usbhc_iface_transfer_out_callback_t callback, void *arg)
-{
-	VHC_DATA(vhc, fun);
-
-	endpoint_t *ep = usb_endpoint_manager_find_ep(&vhc->ep_manager,
-	    target.address, target.endpoint, USB_DIRECTION_OUT);
-	if (ep == NULL) {
-		return ENOENT;
-	}
-	const usb_transfer_type_t transfer_type = ep->transfer_type;
-
-
-	vhc_transfer_t *transfer = vhc_transfer_create(target.address,
-	    target.endpoint, USB_DIRECTION_OUT, transfer_type,
-	    fun, arg);
-	if (transfer == NULL) {
-		return ENOMEM;
-	}
-	if (transfer_type == USB_TRANSFER_CONTROL) {
-		transfer->setup_buffer = malloc(sizeof(uint64_t));
-		assert(transfer->setup_buffer);
-		memcpy(transfer->setup_buffer, &setup_buffer, sizeof(uint64_t));
-		transfer->setup_buffer_size = sizeof(uint64_t);
-	}
-	transfer->data_buffer = (void*)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->setup_buffer);
-		free(transfer);
-		return rc;
-	}
-
-	return EOK;
-}
-
-static int tell_address(ddf_fun_t *fun, usb_address_t *address)
-{
-	UNSUPPORTED("tell_address");
-
-	return ENOTSUP;
-}
-
-static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
-    devman_handle_t *handle)
-{
-	VHC_DATA(vhc, root_hub_fun);
-
-	*handle = ddf_fun_get_handle(vhc->hc_fun);
-
-	return EOK;
-}
-
-static int tell_address_rh(ddf_fun_t *root_hub_fun, usb_address_t *address)
-{
-	VHC_DATA(vhc, root_hub_fun);
-
-	devman_handle_t handle = ddf_fun_get_handle(root_hub_fun);
-
-	usb_log_debug("tell_address_rh(handle=%" PRIun ")\n", handle);
-	const usb_address_t addr =
-	    usb_device_manager_find_address(&vhc->dev_manager, handle);
-	if (addr < 0) {
-		return addr;
-	} else {
-		*address = addr;
-		return EOK;
-	}
-}
-
-usbhc_iface_t vhc_iface = {
-	.request_address = request_address,
-	.bind_address = bind_address,
-	.get_handle = find_by_address,
-	.release_address = release_address,
-
-	.register_endpoint = register_endpoint,
-	.unregister_endpoint = unregister_endpoint,
-
-	.write = usb_write,
-	.read = usb_read,
-};
-
-usb_iface_t vhc_usb_iface = {
-	.get_hc_handle = usb_iface_get_hc_handle_hc_impl,
-	.get_my_address = tell_address
-};
-
-usb_iface_t rh_usb_iface = {
-	.get_hc_handle = usb_iface_get_hc_handle_rh_impl,
-	.get_my_address = tell_address_rh
-};
-
-
-/**
- * @}
- */
Index: uspace/drv/bus/usb/vhc/devconn.c
===================================================================
--- uspace/drv/bus/usb/vhc/devconn.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/devconn.c	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -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);
@@ -78,5 +79,5 @@
 	if (connect) {
 		// FIXME: check status
-		(void) virthub_connect_device(vhc->hub, dev);
+		(void) virthub_connect_device(&vhc->hub, dev);
 	}
 
@@ -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);
 }
 
@@ -104,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.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ 	(revision )
@@ -1,132 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 drvusbvhc
- * @{
- */
-/** @file
- * @brief Virtual USB hub.
- */
-
-#include <usb/classes/classes.h>
-#include <usbvirt/device.h>
-#include <errno.h>
-#include <async.h>
-#include <str_error.h>
-#include <stdlib.h>
-#include <ddf/driver.h>
-#include <devman.h>
-#include <usb/dev/hub.h>
-#include <usb/dev/recognise.h>
-
-#include "hub.h"
-#include "vhcd.h"
-#include "conn.h"
-
-usbvirt_device_t virtual_hub_device = {
-	.name = "root hub",
-	.ops = &hub_ops,
-	.address = 0
-};
-
-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(ddf_fun_t *hc_dev)
-{
-	virthub_init(&virtual_hub_device);
-
-	/*
-	 * We need to register the root hub.
-	 * This must be done in separate fibril because the device
-	 * we are connecting to are ourselves and we cannot connect
-	 * before leaving the add_device() function.
-	 */
-	fid_t root_hub_registration
-	    = fibril_create(hub_register_in_devman_fibril, hc_dev);
-	if (root_hub_registration == 0) {
-		usb_log_fatal("Failed to create hub registration fibril.\n");
-		return;
-	}
-
-	fibril_add_ready(root_hub_registration);
-}
-
-static int pretend_port_rest(void *unused2)
-{
-	return EOK;
-}
-
-/** Register root hub in devman.
- *
- * @param arg Host controller device (type <code>device_t *</code>).
- * @return Error code.
- */
-int hub_register_in_devman_fibril(void *arg)
-{
-	ddf_fun_t *hc_dev = (ddf_fun_t *) arg;
-	int rc;
-
-	usb_hc_connection_t hc_conn;
-	usb_hc_connection_initialize(&hc_conn, ddf_fun_get_handle(hc_dev));
-
-	rc = usb_hc_connection_open(&hc_conn);
-	assert(rc == EOK);
-
-	ddf_fun_t *hub_dev;
-
-	hub_dev = ddf_fun_create(ddf_fun_get_dev(hc_dev), fun_inner, NULL);
-	if (hub_dev == NULL) {
-		rc = ENOMEM;
-		usb_log_fatal("Failed to create root hub: %s.\n",
-		    str_error(rc));
-		return rc;
-	}
-
-	rc = usb_hc_new_device_wrapper(ddf_fun_get_dev(hc_dev), hub_dev,
-	    &hc_conn, USB_SPEED_FULL, pretend_port_rest, NULL, NULL, &rh_ops);
-	if (rc != EOK) {
-		usb_log_fatal("Failed to create root hub: %s.\n",
-		    str_error(rc));
-		ddf_fun_destroy(hub_dev);
-	}
-
-	usb_hc_connection_close(&hc_conn);
-
-	usb_log_info("Created root hub function (handle %zu).\n",
-	    (size_t) ddf_fun_get_handle(hub_dev));
-
-	return 0;
-}
-
-/**
- * @}
- */
Index: uspace/drv/bus/usb/vhc/hub.h
===================================================================
--- uspace/drv/bus/usb/vhc/hub.h	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/*
- * Copyright (c) 2010 Vojtech Horky
- * 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 drvusbvhc
- * @{
- */
-/** @file
- * @brief Virtual USB hub.
- */
-
-#ifndef VHCD_HUB_H_
-#define VHCD_HUB_H_
-
-#include <usbvirt/device.h>
-#include <ddf/driver.h>
-
-#include "hub/hub.h"
-#include "hub/virthub.h"
-
-extern usbvirt_device_t virtual_hub_device;
-
-void virtual_hub_device_init(ddf_fun_t *);
-
-#endif
-/**
- * @}
- */
Index: uspace/drv/bus/usb/vhc/hub/virthub.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub/virthub.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/hub/virthub.c	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -34,8 +34,10 @@
  */
 #include <usb/classes/classes.h>
+#include <usb/classes/hub.h>
 #include <usbvirt/device.h>
 #include <assert.h>
 #include <errno.h>
 #include <str_error.h>
+#include <stdio.h>
 #include <assert.h>
 #include <stdlib.h>
@@ -76,5 +78,5 @@
 	.type = USB_DESCTYPE_HUB,
 	.port_count = HUB_PORT_COUNT,
-	.characteristics = 0, 
+	.characteristics = HUB_CHAR_NO_POWER_SWITCH_FLAG | HUB_CHAR_NO_OC_FLAG,
 	.power_on_warm_up = 50, /* Huh? */
 	.max_current = 100, /* Huh again. */
@@ -97,5 +99,5 @@
 	.length = sizeof(usb_standard_configuration_descriptor_t),
 	.descriptor_type = USB_DESCTYPE_CONFIGURATION,
-	.total_length = 
+	.total_length =
 		sizeof(usb_standard_configuration_descriptor_t)
 		+ sizeof(std_interface_descriptor)
@@ -145,5 +147,5 @@
  * @return Error code.
  */
-int virthub_init(usbvirt_device_t *dev)
+int virthub_init(usbvirt_device_t *dev, const char* name)
 {
 	if (dev == NULL) {
@@ -152,7 +154,12 @@
 	dev->ops = &hub_ops;
 	dev->descriptors = &descriptors;
+	dev->address = 0;
+	dev->name = str_dup(name);
+	if (!dev->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 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/hub/virthub.h	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -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/hub/virthubops.c
===================================================================
--- uspace/drv/bus/usb/vhc/hub/virthubops.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/hub/virthubops.c	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -340,12 +340,4 @@
 
 
-/** IN class request. */
-#define CLASS_REQ_IN(recipient) \
-	USBVIRT_MAKE_CONTROL_REQUEST_TYPE(USB_DIRECTION_IN, \
-	USBVIRT_REQUEST_TYPE_CLASS, recipient)
-/** OUT class request. */
-#define CLASS_REQ_OUT(recipient) \
-	USBVIRT_MAKE_CONTROL_REQUEST_TYPE(USB_DIRECTION_OUT, \
-	USBVIRT_REQUEST_TYPE_CLASS, recipient)
 
 /** Recipient: other. */
@@ -353,88 +345,60 @@
 /** Recipient: device. */
 #define REC_DEVICE USB_REQUEST_RECIPIENT_DEVICE
-/** Direction: in. */
-#define DIR_IN USB_DIRECTION_IN
-/** Direction: out. */
-#define DIR_OUT USB_DIRECTION_OUT
-
-
-/** Create a class request.
- *
- * @param direction Request direction.
- * @param recipient Request recipient.
- * @param req Request code.
- */
-#define CLASS_REQ(direction, recipient, req) \
-	.req_direction = direction, \
-	.req_recipient = recipient, \
-	.req_type = USB_REQUEST_TYPE_CLASS, \
-	.request = req
-
-/** Create a standard request.
- *
- * @param direction Request direction.
- * @param recipient Request recipient.
- * @param req Request code.
- */
-#define STD_REQ(direction, recipient, req) \
-	.req_direction = direction, \
-	.req_recipient = recipient, \
-	.req_type = USB_REQUEST_TYPE_STANDARD, \
-	.request = req
+
 
 /** Hub operations on control endpoint zero. */
 static usbvirt_control_request_handler_t endpoint_zero_handlers[] = {
 	{
-		STD_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
+		STD_REQ_IN(USB_REQUEST_RECIPIENT_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
 		.name = "GetDescriptor",
 		.callback = req_get_descriptor
 	},
 	{
-		CLASS_REQ(DIR_IN, REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
+		CLASS_REQ_IN(REC_DEVICE, USB_DEVREQ_GET_DESCRIPTOR),
 		.name = "GetDescriptor",
 		.callback = req_get_descriptor
 	},
 	{
-		CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
+		CLASS_REQ_IN(REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
 		.name = "GetPortStatus",
 		.callback = req_get_port_status
 	},
 	{
-		CLASS_REQ(DIR_OUT, REC_DEVICE, USB_HUB_REQUEST_CLEAR_FEATURE),
+		CLASS_REQ_OUT(REC_DEVICE, USB_HUB_REQUEST_CLEAR_FEATURE),
 		.name = "ClearHubFeature",
 		.callback = req_clear_hub_feature
 	},
 	{
-		CLASS_REQ(DIR_OUT, REC_OTHER, USB_HUB_REQUEST_CLEAR_FEATURE),
+		CLASS_REQ_OUT(REC_OTHER, USB_HUB_REQUEST_CLEAR_FEATURE),
 		.name = "ClearPortFeature",
 		.callback = req_clear_port_feature
 	},
 	{
-		CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATE),
+		CLASS_REQ_IN(REC_OTHER, USB_HUB_REQUEST_GET_STATE),
 		.name = "GetBusState",
 		.callback = req_get_bus_state
 	},
 	{
-		CLASS_REQ(DIR_IN, REC_DEVICE, USB_HUB_REQUEST_GET_DESCRIPTOR),
+		CLASS_REQ_IN(REC_DEVICE, USB_HUB_REQUEST_GET_DESCRIPTOR),
 		.name = "GetHubDescriptor",
 		.callback = req_get_descriptor
 	},
 	{
-		CLASS_REQ(DIR_IN, REC_DEVICE, USB_HUB_REQUEST_GET_STATUS),
+		CLASS_REQ_IN(REC_DEVICE, USB_HUB_REQUEST_GET_STATUS),
 		.name = "GetHubStatus",
 		.callback = req_get_hub_status
 	},
 	{
-		CLASS_REQ(DIR_IN, REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
+		CLASS_REQ_IN(REC_OTHER, USB_HUB_REQUEST_GET_STATUS),
 		.name = "GetPortStatus",
 		.callback = req_get_port_status
 	},
 	{
-		CLASS_REQ(DIR_OUT, REC_DEVICE, USB_HUB_REQUEST_SET_FEATURE),
+		CLASS_REQ_OUT(REC_DEVICE, USB_HUB_REQUEST_SET_FEATURE),
 		.name = "SetHubFeature",
 		.callback = req_set_hub_feature
 	},
 	{
-		CLASS_REQ(DIR_OUT, REC_OTHER, USB_HUB_REQUEST_SET_FEATURE),
+		CLASS_REQ_OUT(REC_OTHER, USB_HUB_REQUEST_SET_FEATURE),
 		.name = "SetPortFeature",
 		.callback = req_set_port_feature
Index: uspace/drv/bus/usb/vhc/main.c
===================================================================
--- uspace/drv/bus/usb/vhc/main.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/main.c	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -34,9 +34,4 @@
  */
 
-#include <loc.h>
-#include <async.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sysinfo.h>
 #include <stdio.h>
 #include <errno.h>
@@ -44,84 +39,82 @@
 #include <ddf/driver.h>
 
-#include <usb/usb.h>
-#include <usb/ddfiface.h>
-#include <usb_iface.h>
+#include <usb/host/ddf_helpers.h>
+
+#include <usb/debug.h>
 #include "vhcd.h"
-#include "hub.h"
-#include "conn.h"
+
 
 static ddf_dev_ops_t vhc_ops = {
-	.interfaces[USBHC_DEV_IFACE] = &vhc_iface,
-	.interfaces[USB_DEV_IFACE] = &vhc_usb_iface,
 	.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_init(vhc);
+	return EOK;
+}
+
 static int vhc_dev_add(ddf_dev_t *dev)
 {
-	static int vhc_count = 0;
-	int rc;
+	/* 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);
 
-	if (vhc_count > 0) {
-		return ELIMIT;
+	/* Initialize generic structures */
+	ret = hcd_ddf_setup_hc(dev, 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));
+		ddf_fun_destroy(ctl_fun);
+		return ret;
 	}
 
-	vhc_data_t *data = ddf_dev_data_alloc(dev, sizeof(vhc_data_t));
-	if (data == NULL) {
-		usb_log_fatal("Failed to allocate memory.\n");
-		return ENOMEM;
-	}
-	data->magic = 0xDEADBEEF;
-	rc = usb_endpoint_manager_init(&data->ep_manager, (size_t) -1,
-	    bandwidth_count_usb11);
-	if (rc != EOK) {
-		usb_log_fatal("Failed to initialize endpoint manager.\n");
-		free(data);
-		return rc;
-	}
-	usb_device_manager_init(&data->dev_manager, USB_SPEED_MAX);
+	hcd_set_implementation(dev_to_hcd(dev), data, vhc_schedule, NULL, NULL, NULL, NULL);
 
-	ddf_fun_t *hc = ddf_fun_create(dev, fun_exposed, "hc");
-	if (hc == NULL) {
-		usb_log_fatal("Failed to create device function.\n");
-		free(data);
-		return ENOMEM;
+	/* Add virtual hub device */
+	ret = vhc_virtdev_plug_hub(data, &data->hub, NULL, 0);
+	if (ret != EOK) {
+		usb_log_error("Failed to plug root hub: %s.\n", str_error(ret));
+		ddf_fun_destroy(ctl_fun);
+		return ret;
 	}
 
-	ddf_fun_set_ops(hc, &vhc_ops);
-	list_initialize(&data->devices);
-	fibril_mutex_initialize(&data->guard);
-	data->hub = &virtual_hub_device;
-	data->hc_fun = hc;
-
-	rc = ddf_fun_bind(hc);
-	if (rc != EOK) {
-		usb_log_fatal("Failed to bind HC function: %s.\n",
-		    str_error(rc));
-		free(data);
-		return rc;
+	/*
+	 * Creating root hub registers a new USB device so HC
+	 * needs to be ready at this time.
+	 */
+	ret = hcd_ddf_setup_root_hub(dev);
+	if (ret != EOK) {
+		usb_log_error("Failed to init VHC root hub: %s\n",
+			str_error(ret));
+		// TODO do something here...
 	}
 
-	rc = ddf_fun_add_to_category(hc, USB_HC_CATEGORY);
-	if (rc != EOK) {
-		usb_log_fatal("Failed to add function to HC class: %s.\n",
-		    str_error(rc));
-		free(data);
-		return rc;
-	}
-
-	virtual_hub_device_init(hc);
-
-	usb_log_info("Virtual USB host controller ready (dev %zu, hc %zu).\n",
-	    (size_t) ddf_dev_get_handle(dev), (size_t) ddf_fun_get_handle(hc));
-
-	rc = vhc_virtdev_plug_hub(data, data->hub, NULL);
-	if (rc != EOK) {
-		usb_log_fatal("Failed to plug root hub: %s.\n", str_error(rc));
-		free(data);
-		return rc;
-	}
-
-	return EOK;
+	return ret;
 }
 
@@ -135,9 +128,7 @@
 };
 
-
 int main(int argc, char * argv[])
-{	
+{
 	log_init(NAME);
-
 	printf(NAME ": virtual USB host controller driver.\n");
 
@@ -145,5 +136,4 @@
 }
 
-
 /**
  * @}
Index: uspace/drv/bus/usb/vhc/transfer.c
===================================================================
--- uspace/drv/bus/usb/vhc/transfer.c	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/transfer.c	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -29,52 +29,23 @@
 #include <errno.h>
 #include <str_error.h>
+#include <usb/debug.h>
 #include <usbvirt/device.h>
 #include <usbvirt/ipc.h>
 #include "vhcd.h"
-
-vhc_transfer_t *vhc_transfer_create(usb_address_t address, usb_endpoint_t ep,
-    usb_direction_t dir, usb_transfer_type_t tr_type,
-    ddf_fun_t *fun, void *callback_arg)
-{
-	vhc_transfer_t *result = malloc(sizeof(vhc_transfer_t));
-	if (result == NULL) {
-		return NULL;
-	}
-	link_initialize(&result->link);
-	result->address = address;
-	result->endpoint = ep;
-	result->direction = dir;
-	result->transfer_type = tr_type;
-	result->setup_buffer = NULL;
-	result->setup_buffer_size = 0;
-	result->data_buffer = NULL;
-	result->data_buffer_size = 0;
-	result->ddf_fun = fun;
-	result->callback_arg = callback_arg;
-	result->callback_in = NULL;
-	result->callback_out = NULL;
-
-	usb_log_debug2("Created transfer %p (%d.%d %s %s)\n", result,
-	    address, ep, usb_str_transfer_type_short(tr_type),
-	    dir == USB_DIRECTION_IN ? "in" : "out");
-
-	return result;
-}
+#include "hub/virthub.h"
 
 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;
@@ -87,94 +58,70 @@
 }
 
-int vhc_virtdev_add_transfer(vhc_data_t *vhc, vhc_transfer_t *transfer)
-{
-	fibril_mutex_lock(&vhc->guard);
-
-	bool target_found = false;
-	list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
-		fibril_mutex_lock(&dev->guard);
-		if (dev->address == transfer->address) {
-			if (target_found) {
-				usb_log_warning("Transfer would be accepted by more devices!\n");
-				goto next;
-			}
-			target_found = true;
-			list_append(&transfer->link, &dev->transfer_queue);
-		}
-next:
-		fibril_mutex_unlock(&dev->guard);
-	}
-
-	fibril_mutex_unlock(&vhc->guard);
-
-	if (target_found) {
-		return EOK;
+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 {
-		return ENOENT;
-	}
-}
-
-static int process_transfer_local(vhc_transfer_t *transfer,
-    usbvirt_device_t *dev, size_t *actual_data_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(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;
 
-	if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
-		if (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_control_read(dev,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size,
-			    actual_data_size);
-		} else {
-			assert(transfer->direction == USB_DIRECTION_OUT);
-			rc = usbvirt_control_write(dev,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size);
+	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 (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_data_in(dev, transfer->transfer_type,
-			    transfer->endpoint,
-			    transfer->data_buffer, transfer->data_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);
-		}
-	}
-
-	return rc;
-}
-
-static int process_transfer_remote(vhc_transfer_t *transfer,
-    async_sess_t *sess, size_t *actual_data_size)
-{
-	int rc;
-
-	if (transfer->transfer_type == USB_TRANSFER_CONTROL) {
-		if (transfer->direction == USB_DIRECTION_IN) {
-			rc = usbvirt_ipc_send_control_read(sess,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_buffer_size,
-			    actual_data_size);
-		} else {
-			assert(transfer->direction == USB_DIRECTION_OUT);
-			rc = usbvirt_ipc_send_control_write(sess,
-			    transfer->setup_buffer, transfer->setup_buffer_size,
-			    transfer->data_buffer, transfer->data_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,
-			    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);
+		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);
 		}
 	}
@@ -195,23 +142,59 @@
 }
 
-
 static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
     size_t data_transfer_size, int outcome)
 {
 	assert(outcome != ENAK);
-
-	usb_log_debug2("Transfer %p ended: %s.\n",
-	    transfer, str_error(outcome));
-
-	if (transfer->direction == USB_DIRECTION_IN) {
-		transfer->callback_in(transfer->ddf_fun, outcome,
-		    data_transfer_size, transfer->callback_arg);
-	} else {
-		assert(transfer->direction == USB_DIRECTION_OUT);
-		transfer->callback_out(transfer->ddf_fun, outcome,
-		    transfer->callback_arg);
-	}
-
+	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)
+{
+	assert(hcd);
+	assert(batch);
+	vhc_data_t *vhc = hcd->driver.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, link, vhc_virtdev_t, dev) {
+		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;
 }
 
@@ -234,9 +217,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 +234,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",
@@ -284,3 +267,2 @@
 	return EOK;
 }
-
Index: uspace/drv/bus/usb/vhc/vhcd.h
===================================================================
--- uspace/drv/bus/usb/vhc/vhcd.h	(revision 193d280c34f38846eccfa1ecce71975f9ad92398)
+++ uspace/drv/bus/usb/vhc/vhcd.h	(revision b5143bd82217d3abb5c20adca5ee226d2e030878)
@@ -36,10 +36,10 @@
 #define VHCD_VHCD_H_
 
-#include <usb/debug.h>
 #include <usbvirt/device.h>
-#include <usb/host/usb_endpoint_manager.h>
-#include <usb/host/usb_device_manager.h>
 #include <usbhc_iface.h>
 #include <async.h>
+
+#include <usb/host/hcd.h>
+
 
 #define NAME "vhc"
@@ -59,36 +59,25 @@
 	list_t devices;
 	fibril_mutex_t guard;
-	usb_endpoint_manager_t ep_manager;
-	usb_device_manager_t dev_manager;
-	usbvirt_device_t *hub;
-	ddf_fun_t *hc_fun;
+	usbvirt_device_t hub;
 } vhc_data_t;
 
 typedef struct {
 	link_t link;
-	usb_address_t address;
-	usb_endpoint_t endpoint;
-	usb_direction_t direction;
-	usb_transfer_type_t transfer_type;
-	void *setup_buffer;
-	size_t setup_buffer_size;
-	void *data_buffer;
-	size_t data_buffer_size;
-	ddf_fun_t *ddf_fun;
-	void *callback_arg;
-	usbhc_iface_transfer_in_callback_t callback_in;
-	usbhc_iface_transfer_out_callback_t callback_out;
+	usb_transfer_batch_t *batch;
 } vhc_transfer_t;
 
-vhc_transfer_t *vhc_transfer_create(usb_address_t, usb_endpoint_t,
-    usb_direction_t, usb_transfer_type_t, ddf_fun_t *, void *);
+
+void on_client_close(ddf_fun_t *fun);
+void default_connection_handler(ddf_fun_t *fun, ipc_callid_t icallid,
+    ipc_call_t *icall);
+
 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 *);
 
+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);
-
 
 #endif
