Index: uspace/srv/hw/bus/usb/hcd/virtual/Makefile
===================================================================
--- uspace/srv/hw/bus/usb/hcd/virtual/Makefile	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
+++ uspace/srv/hw/bus/usb/hcd/virtual/Makefile	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+USPACE_PREFIX = ../../../../../..
+LIBS = $(LIBUSB_PREFIX)/libusb.a
+EXTRA_CFLAGS = -I$(LIB_PREFIX)
+BINARY = vhcd
+
+SOURCES = \
+	hc.c \
+	hcd.c
+
+include $(USPACE_PREFIX)/Makefile.common
Index: uspace/srv/hw/bus/usb/hcd/virtual/hc.c
===================================================================
--- uspace/srv/hw/bus/usb/hcd/virtual/hc.c	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
+++ uspace/srv/hw/bus/usb/hcd/virtual/hc.c	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
@@ -0,0 +1,195 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual HC (implementation).
+ */
+
+#include <ipc/ipc.h>
+#include <adt/list.h>
+#include <bool.h>
+#include <async.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "vhcd.h"
+#include "hc.h"
+
+#define USLEEP_BASE (500 * 1000)
+
+#define USLEEP_VAR 10000
+
+#define SHORTENING_VAR 15
+
+#define PROB_OUTCOME_BABBLE 5
+#define PROB_OUTCOME_CRCERROR 7
+
+#define PROB_TEST(var, new_value, prob, number) \
+	do { \
+		if (((number) % (prob)) == 0) { \
+			var = (new_value); \
+		} \
+	} while (0)
+
+static link_t transaction_list;
+
+
+typedef struct {
+	link_t link;
+	usb_target_t target;
+	usb_direction_t direction;
+	usb_transfer_type_t type;
+	void * buffer;
+	size_t len;
+	hc_transaction_done_callback_t callback;
+	void * callback_arg;
+} transaction_t;
+
+#define TRANSACTION_FORMAT "T[%d:%d %s %s (%d)]"
+#define TRANSACTION_PRINTF(t) \
+	(t).target.address, (t).target.endpoint, \
+	usb_str_transfer_type((t).type), \
+	((t).direction == USB_DIRECTION_IN ? "in" : "out"), \
+	(int)(t).len
+
+#define transaction_get_instance(lnk) \
+	list_get_instance(lnk, transaction_t, link)
+
+static inline unsigned int pseudo_random(unsigned int *seed)
+{
+	*seed = ((*seed) * 873511) % 22348977 + 7;
+	return ((*seed) >> 8);
+}
+
+static void process_transaction_with_outcome(transaction_t * transaction,
+    usb_transaction_outcome_t outcome)
+{
+	dprintf("processing transaction " TRANSACTION_FORMAT ", outcome: %s",
+	    TRANSACTION_PRINTF(*transaction),
+	    usb_str_transaction_outcome(outcome));
+	
+	transaction->callback(transaction->buffer, transaction->len, outcome,
+	    transaction->callback_arg);
+}
+
+static void process_transaction(transaction_t * transaction)
+{
+	static unsigned int seed = 4089;
+	
+	unsigned int roulette = pseudo_random(&seed);
+	usb_transaction_outcome_t outcome = USB_OUTCOME_OK;
+	
+	PROB_TEST(outcome, USB_OUTCOME_BABBLE, PROB_OUTCOME_BABBLE, roulette);
+	PROB_TEST(outcome, USB_OUTCOME_CRCERROR, PROB_OUTCOME_CRCERROR, roulette);
+	
+	process_transaction_with_outcome(transaction, outcome);
+}
+
+void hc_manager(void)
+{
+	list_initialize(&transaction_list);
+	
+	static unsigned int seed = 4573;
+	
+	printf("%s: transaction processor ready.\n", NAME);
+	
+	while (true) {
+		async_usleep(USLEEP_BASE + (pseudo_random(&seed) % USLEEP_VAR));
+		
+		if (list_empty(&transaction_list)) {
+			continue;
+		}
+		
+		link_t * first_transaction_link = transaction_list.next;
+		transaction_t * first_transaction
+		    = transaction_get_instance(first_transaction_link);
+		list_remove(first_transaction_link);
+		
+		process_transaction(first_transaction);
+		
+		free(first_transaction);
+	}
+}
+
+static void hc_add_transaction(usb_transfer_type_t type, usb_target_t target,
+    usb_direction_t direction,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg)
+{
+	transaction_t * transaction = malloc(sizeof(transaction_t));
+	
+	list_initialize(&transaction->link);
+	transaction->type = type;
+	transaction->target = target;
+	transaction->direction = direction;
+	transaction->buffer = buffer;
+	transaction->len = len;
+	transaction->callback = callback;
+	transaction->callback_arg = arg;
+	
+	dprintf("adding transaction " TRANSACTION_FORMAT,
+	    TRANSACTION_PRINTF(*transaction));
+
+	list_append(&transaction->link, &transaction_list);
+}
+
+void hc_add_out_transaction(usb_transfer_type_t type, usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg)
+{
+	hc_add_transaction(type, target, USB_DIRECTION_OUT,
+	    buffer, len, callback, arg);
+}
+
+void hc_add_in_transaction(usb_transfer_type_t type, usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg)
+{
+	static unsigned int seed = 216;
+	
+	size_t i;
+	char * data = (char *)buffer;
+	for (i = 0; i < len; i++, data++) {
+		*data = 'A' + (pseudo_random(&seed) % ('Z' - 'A'));
+	}
+	
+	unsigned int shortening = pseudo_random(&seed) % SHORTENING_VAR;
+	if (len > shortening) {
+		len -= shortening;
+	}
+	
+	hc_add_transaction(type, target, USB_DIRECTION_IN,
+	    buffer, len, callback, arg);
+}
+
+/**
+ * @}
+ */
Index: uspace/srv/hw/bus/usb/hcd/virtual/hc.h
===================================================================
--- uspace/srv/hw/bus/usb/hcd/virtual/hc.h	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
+++ uspace/srv/hw/bus/usb/hcd/virtual/hc.h	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
@@ -0,0 +1,56 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual HC.
+ */
+#ifndef VHCD_HC_H_
+#define VHCD_HC_H_
+
+#include <usb/hcd.h>
+
+typedef void (*hc_transaction_done_callback_t)(void *, size_t, usb_transaction_outcome_t, void *);
+
+void hc_manager(void);
+
+void hc_add_out_transaction(usb_transfer_type_t type, usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg);
+
+void hc_add_in_transaction(usb_transfer_type_t type, usb_target_t target,
+    void * buffer, size_t len,
+    hc_transaction_done_callback_t callback, void * arg);
+
+
+#endif
+/**
+ * @}
+ */
Index: uspace/srv/hw/bus/usb/hcd/virtual/hcd.c
===================================================================
--- uspace/srv/hw/bus/usb/hcd/virtual/hcd.c	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
+++ uspace/srv/hw/bus/usb/hcd/virtual/hcd.c	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
@@ -0,0 +1,268 @@
+/*
+ * 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 usb
+ * @{
+ */ 
+/** @file
+ * @brief Virtual host controller driver.
+ */
+
+#include <devmap.h>
+#include <ipc/ipc.h>
+#include <async.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <errno.h>
+#include <str_error.h>
+
+#include <usb/hcd.h>
+#include "vhcd.h"
+#include "hc.h"
+
+static usb_transaction_handle_t g_handle_seed = 1;
+static usb_transaction_handle_t create_transaction_handle(int phone)
+{
+	return g_handle_seed++;
+}
+
+typedef struct {
+	int phone;
+	usb_transaction_handle_t handle;
+} transaction_details_t;
+
+static void out_callback(void * buffer, size_t len, usb_transaction_outcome_t outcome, void * arg)
+{
+	(void)len;
+	transaction_details_t * trans = (transaction_details_t *)arg;
+	
+	async_msg_2(trans->phone, IPC_M_USB_HCD_DATA_SENT, trans->handle, outcome);
+	
+	free(trans);
+	free(buffer);
+}
+
+static void in_callback(void * buffer, size_t len, usb_transaction_outcome_t outcome, void * arg)
+{
+	transaction_details_t * trans = (transaction_details_t *)arg;
+	
+	ipc_call_t answer_data;
+	ipcarg_t answer_rc;
+	aid_t req;
+	int rc;
+	
+	req = async_send_3(trans->phone,
+	    IPC_M_USB_HCD_DATA_RECEIVED,
+	    trans->handle, outcome,
+	    len,
+	    &answer_data);
+	
+	rc = async_data_write_start(trans->phone, buffer, len);
+	if (rc != EOK) {
+		async_wait_for(req, NULL);
+		goto leave;
+	}
+	
+	async_wait_for(req, &answer_rc);
+	rc = (int)answer_rc;
+	if (rc != EOK) {
+		goto leave;
+	}
+	
+leave:
+	free(trans);
+	free(buffer);
+}
+
+
+
+static void handle_data_to_function(ipc_callid_t iid, ipc_call_t icall, int callback_phone)
+{
+	usb_transfer_type_t transf_type = IPC_GET_ARG3(icall);
+	usb_target_t target = {
+		.address = IPC_GET_ARG1(icall),
+		.endpoint = IPC_GET_ARG2(icall)
+	};
+	
+	dprintf("pretending transfer to function (dev=%d:%d, type=%s)",
+	    target.address, target.endpoint,
+	    usb_str_transfer_type(transf_type));
+	
+	if (callback_phone == -1) {
+		ipc_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	usb_transaction_handle_t handle
+	    = create_transaction_handle(callback_phone);
+	
+	size_t len;
+	void * buffer;
+	int rc = async_data_write_accept(&buffer, false,
+	    1, USB_MAX_PAYLOAD_SIZE,
+	    0, &len);
+	
+	if (rc != EOK) {
+		ipc_answer_0(iid, rc);
+		return;
+	}
+	
+	transaction_details_t * trans = malloc(sizeof(transaction_details_t));
+	trans->phone = callback_phone;
+	trans->handle = handle;
+	
+	dprintf("adding transaction to HC", NAME);
+	hc_add_out_transaction(transf_type, target,
+	    buffer, len,
+	    out_callback, trans);
+	
+	ipc_answer_1(iid, EOK, handle);
+	dprintf("transfer to function scheduled (handle %d)", handle);
+}
+
+static void handle_data_from_function(ipc_callid_t iid, ipc_call_t icall, int callback_phone)
+{
+	usb_transfer_type_t transf_type = IPC_GET_ARG3(icall);
+	usb_target_t target = {
+		.address = IPC_GET_ARG1(icall),
+		.endpoint = IPC_GET_ARG2(icall)
+	};
+	size_t len = IPC_GET_ARG4(icall);
+	
+	dprintf("pretending transfer from function (dev=%d:%d, type=%s)",
+	    target.address, target.endpoint,
+	    usb_str_transfer_type(transf_type));
+	
+	if (callback_phone == -1) {
+		ipc_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	usb_transaction_handle_t handle
+	    = create_transaction_handle(callback_phone);
+	
+	void * buffer = malloc(len);
+	
+	transaction_details_t * trans = malloc(sizeof(transaction_details_t));
+	trans->phone = callback_phone;
+	trans->handle = handle;
+	
+	dprintf("adding transaction to HC", NAME);
+	hc_add_in_transaction(transf_type, target,
+	    buffer, len,
+	    in_callback, trans);
+	
+	ipc_answer_1(iid, EOK, handle);
+	dprintf("transfer from function scheduled (handle %d)", handle);
+}
+
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipcarg_t phone_hash = icall->in_phone_hash;
+	
+	ipc_answer_0(iid, EOK);
+	printf("%s: new client connected (phone %#x).\n", NAME, phone_hash);
+	
+	int callback_phone = -1;
+	
+	while (true) {
+		ipc_callid_t callid; 
+		ipc_call_t call; 
+		
+		callid = async_get_call(&call);
+		dprintf("%#x calls method %d", phone_hash, IPC_GET_METHOD(call));
+		switch (IPC_GET_METHOD(call)) {
+			case IPC_M_PHONE_HUNGUP:
+				if (callback_phone != -1) {
+					ipc_hangup(callback_phone);
+				}
+				ipc_answer_0(callid, EOK);
+				printf("%s: hung-up on %#x.\n", NAME, phone_hash);
+				return;
+			
+			case IPC_M_CONNECT_TO_ME:
+				if (callback_phone != -1) {
+					ipc_answer_0(callid, ELIMIT);
+				} else {
+					callback_phone = IPC_GET_ARG5(call);
+					ipc_answer_0(callid, EOK);
+				}
+				break;
+			
+			case IPC_M_USB_HCD_SEND_DATA:
+				handle_data_to_function(callid, call, callback_phone);
+				break;
+			
+			case IPC_M_USB_HCD_RECEIVE_DATA:
+				handle_data_from_function(callid, call, callback_phone);
+				break;
+			
+			case IPC_M_USB_HCD_TRANSACTION_SIZE:
+				ipc_answer_1(callid, EOK, USB_MAX_PAYLOAD_SIZE);
+				break;
+			
+			default:
+				ipc_answer_0(callid, EINVAL);
+				break;
+		}
+	}
+}
+
+int main(int argc, char * argv[])
+{
+	printf("%s: Virtual USB host controller driver.\n", NAME);
+	
+	int rc;
+	
+	rc = devmap_driver_register(NAME, client_connection); 
+	if (rc != EOK) {
+		printf("%s: unable to register driver (%s).\n",
+		    NAME, str_error(rc));
+		return 1;
+	}
+
+	rc = devmap_device_register(DEVMAP_PATH, NULL);
+	if (rc != EOK) {
+		printf("%s: unable to register device %s (%s).\n",
+		    NAME, DEVMAP_PATH, str_error(rc));
+		return 1;
+	}
+	
+	printf("%s: accepting connections.\n", NAME);
+	hc_manager();
+	
+	return 0;
+}
+
+
+/**
+ * @}
+ */
Index: uspace/srv/hw/bus/usb/hcd/virtual/vhcd.h
===================================================================
--- uspace/srv/hw/bus/usb/hcd/virtual/vhcd.h	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
+++ uspace/srv/hw/bus/usb/hcd/virtual/vhcd.h	(revision c0e1be7d7b843208f87d11b9ec15b42235037122)
@@ -0,0 +1,56 @@
+/*
+ * 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 usb
+ * @{
+ */
+/** @file
+ * @brief Virtual USB host controller common definitions.
+ */
+#ifndef VHCD_VHCD_H_
+#define VHCD_VHCD_H_
+
+#define NAME "hcd-virt"
+#define NAMESPACE "usb"
+
+#define DEVMAP_PATH NAMESPACE "/" NAME
+
+static inline void dprintf(const char * format, ...)
+{
+	printf("%s:   ", NAME);
+	va_list args;
+	va_start(args, format);
+	vprintf(format, args);
+	va_end(args);
+	printf("\n");
+}
+
+#endif
+/**
+ * @}
+ */
