Index: trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk	(revision 60303)
+++ trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk	(revision 60324)
@@ -46,4 +46,7 @@
 	UsbTestServiceCfg.cpp \
 	UsbTestServiceGadgetCfg.cpp \
+	UsbTestServiceGadgetHost.cpp \
+	UsbTestServiceGadgetHostUsbIp.cpp \
+	UsbTestServiceGadget.cpp \
 	UsbTestServiceProtocol.cpp \
 	UsbTestServiceTcp.cpp
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp	(revision 60324)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp	(revision 60324)
@@ -0,0 +1,39 @@
+/* $Id$ */
+/** @file
+ * UsbTestServ - Remote USB test configuration and execution server, USB gadget host API.
+ */
+
+/*
+ * Copyright (C) 2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+
+#include <iprt/cdefs.h>
+#include <iprt/ctype.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/types.h>
+
+#include "UsbTestServiceGadget.h"
+
+
+/*********************************************************************************************************************************
+*   Constants And Macros, Structures and Typedefs                                                                                *
+*********************************************************************************************************************************/
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.h
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.h	(revision 60303)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.h	(revision 60324)
@@ -34,5 +34,5 @@
 
 /** Opaque gadget host handle. */
-typedef struct UTSGADGETHOSTINT UTSGADGETHOST;
+typedef struct UTSGADGETHOSTINT *UTSGADGETHOST;
 /** Pointer to a gadget host handle. */
 typedef UTSGADGETHOST *PUTSGADGETHOST; 
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp	(revision 60324)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp	(revision 60324)
@@ -0,0 +1,142 @@
+/* $Id$ */
+/** @file
+ * UsbTestServ - Remote USB test configuration and execution server, USB gadget host API.
+ */
+
+/*
+ * Copyright (C) 2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+
+#include <iprt/asm.h>
+#include <iprt/cdefs.h>
+#include <iprt/ctype.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/types.h>
+
+#include "UsbTestServiceGadget.h"
+#include "UsbTestServiceGadgetHostInternal.h"
+
+/*********************************************************************************************************************************
+*   Constants And Macros, Structures and Typedefs                                                                                *
+*********************************************************************************************************************************/
+
+/**
+ * Internal UTS gadget host instance data.
+ */
+typedef struct UTSGADGETHOSTINT
+{
+    /** Reference counter. */
+    volatile uint32_t         cRefs;
+    /** Pointer to the gadget host callback table. */
+    PCUTSGADGETHOSTIF         pHstIf;
+    /** Interface specific instance data - variable in size. */
+    uint8_t                   abIfInst[1];
+} UTSGADGETHOSTINT;
+/** Pointer to the internal gadget host instance data. */
+typedef UTSGADGETHOSTINT *PUTSGADGETHOSTINT;
+
+
+/*********************************************************************************************************************************
+*   Global variables                                                                                                             *
+*********************************************************************************************************************************/
+
+/** Known gadget host interfaces. */
+static const PCUTSGADGETHOSTIF g_apUtsGadgetHostIf[] =
+{
+    &g_UtsGadgetHostIfUsbIp,
+};
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+
+
+/**
+ * Destroys a gadget host instance.
+ *
+ * @returns nothing.
+ * @param   pThis    The gadget host instance.
+ */
+static void utsGadgetHostDestroy(PUTSGADGETHOSTINT pThis)
+{
+    /** @todo: Remove all gadgets. */
+    pThis->pHstIf->pfnTerm((PUTSGADGETHOSTTYPEINT)&pThis->abIfInst[0]);
+    RTMemFree(pThis);
+}
+
+
+DECLHIDDEN(int) utsGadgetHostCreate(UTSGADGETHOSTTYPE enmType, PCUTSGADGETCFGITEM paCfg,
+                                    PUTSGADGETHOST phGadgetHost)
+{
+    int rc = VINF_SUCCESS;
+    PCUTSGADGETHOSTIF pIf = NULL;
+
+    /* Get the interface. */
+    for (unsigned i = 0; i < RT_ELEMENTS(g_apUtsGadgetHostIf); i++)
+    {
+        if (g_apUtsGadgetHostIf[i]->enmType == enmType)
+        {
+            pIf = g_apUtsGadgetHostIf[i];
+            break;
+        }
+    }
+
+    if (RT_LIKELY(pIf))
+    {
+        PUTSGADGETHOSTINT pThis = (PUTSGADGETHOSTINT)RTMemAllocZ(RT_OFFSETOF(UTSGADGETHOSTINT, abIfInst[pIf->cbIf]));
+        if (RT_LIKELY(pThis))
+        {
+            pThis->cRefs = 1;
+            pThis->pHstIf = pIf;
+            rc = pIf->pfnInit((PUTSGADGETHOSTTYPEINT)&pThis->abIfInst[0], paCfg);
+            if (RT_SUCCESS(rc))
+                *phGadgetHost = pThis;
+            else
+                RTMemFree(pThis);
+        }
+        else
+            rc = VERR_NO_MEMORY;
+    }
+    else
+        rc = VERR_INVALID_PARAMETER;
+
+    return rc;
+}
+
+
+DECLHIDDEN(uint32_t) utsGadgetHostRetain(UTSGADGETHOST hGadgetHost)
+{
+    PUTSGADGETHOSTINT pThis = hGadgetHost;
+
+    AssertPtrReturn(pThis, 0);
+
+    return ASMAtomicIncU32(&pThis->cRefs);
+}
+
+
+DECLHIDDEN(uint32_t) utsGadgetHostRelease(UTSGADGETHOST hGadgetHost)
+{
+    PUTSGADGETHOSTINT pThis = hGadgetHost;
+
+    AssertPtrReturn(pThis, 0);
+
+    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+    if (!cRefs)
+        utsGadgetHostDestroy(pThis);
+
+    return cRefs;
+}
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostInternal.h
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostInternal.h	(revision 60324)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostInternal.h	(revision 60324)
@@ -0,0 +1,120 @@
+/* $Id$ */
+/** @file
+ * UsbTestServ - Remote USB test configuration and execution server, Gadget API.
+ */
+
+/*
+ * Copyright (C) 2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___UsbTestServiceGadgetHostInternal_h___
+#define ___UsbTestServiceGadgetHostInternal_h___
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+#include "UsbTestServiceGadget.h"
+
+RT_C_DECLS_BEGIN
+
+/** Pointer to an opaque type dependent gadget host instance data. */
+typedef struct UTSGADGETHOSTTYPEINT *PUTSGADGETHOSTTYPEINT;
+/** Pointer to a gadget host instance pointer. */
+typedef PUTSGADGETHOSTTYPEINT *PPUTSGADETHOSTTYPEINT;
+
+/**
+ * Gadget host interface.
+ */
+typedef struct UTSGADGETHOSTIF
+{
+    /** The gadget host type implemented. */
+    UTSGADGETHOSTTYPE         enmType;
+    /** Description. */
+    const char               *pszDesc;
+    /** Size of the interface specific instance data. */
+    size_t                    cbIf;
+
+    /**
+     * Initializes the gadget host interface.
+     *
+     * @returns IPRT status code.
+     * @param   pIf           The interface specific instance data.
+     * @param   paCfg         The configuration of the interface.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnInit, (PUTSGADGETHOSTTYPEINT pIf, PCUTSGADGETCFGITEM paCfg));
+
+    /**
+     * Terminates the gadget host interface.
+     *
+     * @returns nothing.
+     * @param   pIf           The interface specific instance data.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnTerm, (PUTSGADGETHOSTTYPEINT pIf));
+
+    /**
+     * Adds the given gadget to the host interface.
+     *
+     * @returns IPRT status code.
+     * @param   pIf           The interface specific instance data.
+     * @param   hGadget       The gadget handle to add.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGadgetAdd, (PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget));
+
+    /**
+     * Removes the given gadget from the host interface.
+     *
+     * @returns IPRT status code.
+     * @param   pIf           The interface specific instance data.
+     * @param   hGadget       The gadget handle to remove.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGadgetRemove, (PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget));
+
+    /**
+     * Connects the given gadget to the host interface so it appears as connected to the client
+     * of the gadget host.
+     *
+     * @returns IPRT status code.
+     * @param   pIf           The interface specific instance data.
+     * @param   hGadget       The gadget handle to add.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGadgetConnect, (PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget));
+
+    /**
+     * Disconnects the given gadget from the host interface so it appears as disconnected to the client
+     * of the gadget host.
+     *
+     * @returns IPRT status code.
+     * @param   pIf           The interface specific instance data.
+     * @param   hGadget       The gadget handle to add.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnGadgetDisconnect, (PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget));
+
+} UTSGADGETHOSTIF;
+/** Pointer to a gadget host callback table. */
+typedef UTSGADGETHOSTIF *PUTSGADGETHOSTIF;
+/** Pointer to a const gadget host callback table. */
+typedef const struct UTSGADGETHOSTIF *PCUTSGADGETHOSTIF;
+
+extern UTSGADGETHOSTIF const g_UtsGadgetHostIfUsbIp;
+
+RT_C_DECLS_END
+
+#endif
+
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp	(revision 60324)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp	(revision 60324)
@@ -0,0 +1,206 @@
+/* $Id$ */
+/** @file
+ * UsbTestServ - Remote USB test configuration and execution server, USB gadget host interface
+ *               for USB/IP.
+ */
+
+/*
+ * Copyright (C) 2016 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+
+#include <iprt/asm.h>
+#include <iprt/cdefs.h>
+#include <iprt/ctype.h>
+#include <iprt/env.h>
+#include <iprt/mem.h>
+#include <iprt/process.h>
+#include <iprt/string.h>
+#include <iprt/types.h>
+
+#include "UsbtestServiceGadgetHostInternal.h"
+
+/*********************************************************************************************************************************
+*   Constants And Macros, Structures and Typedefs                                                                                *
+*********************************************************************************************************************************/
+
+/**
+ * Internal UTS gadget host instance data.
+ */
+typedef struct UTSGADGETHOSTTYPEINT
+{
+    /** Handle to the USB/IP daemon process. */
+    RTPROCESS                 hProcUsbIp;
+} UTSGADGETHOSTTYPEINT;
+
+/** Default port of the USB/IP server. */
+#define UTS_GADGET_HOST_USBIP_PORT_DEF 3240
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+
+
+/**
+ * Load a kernel module on a Linux host.
+ *
+ * @returns IPRT status code.
+ * @param   pszModule    The module to load.
+ */
+static int utsGadgetHostUsbIpLoadModule(const char *pszModule)
+{
+    RTPROCESS hProcModprobe = NIL_RTPROCESS;
+    const char *apszArgv[3];
+
+    apszArgv[0] = "modprobe";
+    apszArgv[1] = pszModule;
+    apszArgv[2] = NULL;
+
+    int rc = RTProcCreate("modprobe", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &hProcModprobe);
+    if (RT_SUCCESS(rc))
+    {
+        RTPROCSTATUS ProcSts;
+        rc = RTProcWait(hProcModprobe, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
+        if (RT_SUCCESS(rc))
+        {
+            /* Evaluate the process status. */
+            if (   ProcSts.enmReason != RTPROCEXITREASON_NORMAL
+                || ProcSts.iStatus != 0)
+                rc = VERR_UNRESOLVED_ERROR; /** @todo: Log and give finer grained status code. */
+        }
+    }
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETHOSTIF,pfnInit}
+ */
+static DECLCALLBACK(int) utsGadgetHostUsbIpInit(PUTSGADGETHOSTTYPEINT pIf, PCUTSGADGETCFGITEM paCfg)
+{
+    int rc = VINF_SUCCESS;
+    uint16_t uPort = 0;
+
+    pIf->hProcUsbIp = NIL_RTPROCESS;
+
+    rc = utsGadgetCfgQueryU16Def(paCfg, "UsbIp/Port", &uPort, UTS_GADGET_HOST_USBIP_PORT_DEF);
+    if (RT_FAILURE(rc))
+    {
+        /* Make sure the kernel drivers are loaded. */
+        rc = utsGadgetHostUsbIpLoadModule("usbip-core.ko");
+        if (RT_SUCCESS(rc))
+        {
+            rc = utsGadgetHostUsbIpLoadModule("usbip-host.ko");
+            if (RT_SUCCESS(rc))
+            {
+                char aszPort[10];
+                char aszPidFile[64];
+                const char *apszArgv[5];
+
+                RTStrPrintf(aszPort, RT_ELEMENTS(aszPort), "%u", uPort);
+                RTStrPrintf(aszPidFile, RT_ELEMENTS(aszPidFile), "/var/run/usbipd-%u.pid", uPort);
+                /* Start the USB/IP server process. */
+                apszArgv[0] = "usbipd";
+                apszArgv[1] = "--tcp-port";
+                apszArgv[2] = aszPort;
+                apszArgv[3] = "--pid-file";
+                apszArgv[4] = aszPidFile;
+                rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
+                if (RT_SUCCESS(rc))
+                {
+                    /* We are done setting it up at the moment. */
+                }
+            }
+        }
+    }
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETHOSTIF,pfnTerm}
+ */
+static DECLCALLBACK(void) utsGadgetHostUsbIpTerm(PUTSGADGETHOSTTYPEINT pIf)
+{
+    /* Kill the process. */
+    RTProcTerminate(pIf->hProcUsbIp);
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetAdd}
+ */
+static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetAdd(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
+{
+    /* Nothing to do so far. */
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetRemove}
+ */
+static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetRemove(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
+{
+    /* Nothing to do so far. */
+    return VINF_SUCCESS;  
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetConnect}
+ */
+static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetConnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
+{
+   return VINF_SUCCESS; 
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETHOSTIF,pfnGadgetDisconnect}
+ */
+static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetDisconnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
+{
+    return VINF_SUCCESS;
+}
+
+
+
+/**
+ * The gadget host interface callback table.
+ */
+const UTSGADGETHOSTIF g_UtsGadgetHostIfUsbIp =
+{
+    /** enmType */
+    UTSGADGETHOSTTYPE_USBIP,
+    /** pszDesc */
+    "UTS USB/IP gadget host",
+    /** cbIf */
+    sizeof(UTSGADGETHOSTTYPEINT),
+    /** pfnInit */
+    utsGadgetHostUsbIpInit,
+    /** pfnTerm */
+    utsGadgetHostUsbIpTerm,
+    /** pfnGadgetAdd */
+    utsGadgetHostUsbIpGadgetAdd,
+    /** pfnGadgetRemove */
+    utsGadgetHostUsbIpGadgetRemove,
+    /** pfnGadgetConnect */
+    utsGadgetHostUsbIpGadgetConnect,
+    /** pfnGadgetDisconnect */
+    utsGadgetHostUsbIpGadgetDisconnect
+};
