Index: trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk	(revision 60367)
+++ trunk/src/VBox/ValidationKit/utils/usb/Makefile.kmk	(revision 60375)
@@ -46,4 +46,5 @@
 	UsbTestServiceCfg.cpp \
 	UsbTestServiceGadgetCfg.cpp \
+	UsbTestServiceGadgetClassTest.cpp \
 	UsbTestServiceGadgetHost.cpp \
 	UsbTestServiceGadgetHostUsbIp.cpp \
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp	(revision 60367)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadget.cpp	(revision 60375)
@@ -21,4 +21,5 @@
 *********************************************************************************************************************************/
 
+#include <iprt/asm.h>
 #include <iprt/cdefs.h>
 #include <iprt/ctype.h>
@@ -27,6 +28,5 @@
 #include <iprt/types.h>
 
-#include "UsbTestServiceGadget.h"
-
+#include "UsbTestServiceGadgetInternal.h"
 
 /*********************************************************************************************************************************
@@ -34,6 +34,112 @@
 *********************************************************************************************************************************/
 
+/**
+ * Internal UTS gadget host instance data.
+ */
+typedef struct UTSGADGETINT
+{
+    /** Reference counter. */
+    volatile uint32_t         cRefs;
+    /** Pointer to the gadget class callback table. */
+    PCUTSGADGETCLASSIF        pClassIf;
+    /** The gadget host handle. */
+    UTSGADGETHOST             hGadgetHost;
+    /** Class specific instance data - variable in size. */
+    uint8_t                   abClassInst[1];
+} UTSGADGETINT;
+/** Pointer to the internal gadget host instance data. */
+typedef UTSGADGETINT *PUTSGADGETINT;
+
+
+/*********************************************************************************************************************************
+*   Global variables                                                                                                             *
+*********************************************************************************************************************************/
+
+/** Known gadget host interfaces. */
+static const PCUTSGADGETCLASSIF g_apUtsGadgetClass[] =
+{
+    &g_UtsGadgetClassTest
+};
+
 
 /*********************************************************************************************************************************
 *   Internal Functions                                                                                                           *
 *********************************************************************************************************************************/
+
+
+/**
+ * Destroys a gadget instance.
+ *
+ * @returns nothing.
+ * @param   pThis    The gadget instance.
+ */
+static void utsGadgetDestroy(PUTSGADGETINT pThis)
+{
+    pThis->pClassIf->pfnTerm((PUTSGADGETCLASSINT)&pThis->abClassInst[0]);
+    RTMemFree(pThis);
+}
+
+
+DECLHIDDEN(int) utsGadgetCreate(UTSGADGETHOST hGadgetHost, UTSGADGETCLASS enmClass,
+                                PCUTSGADGETCFGITEM paCfg, PUTSGADET phGadget)
+{
+    int rc = VINF_SUCCESS;
+    PCUTSGADGETCLASSIF pClassIf = NULL;
+
+    /* Get the interface. */
+    for (unsigned i = 0; i < RT_ELEMENTS(g_apUtsGadgetClass); i++)
+    {
+        if (g_apUtsGadgetClass[i]->enmClass == enmClass)
+        {
+            pClassIf = g_apUtsGadgetClass[i];
+            break;
+        }
+    }
+
+    if (RT_LIKELY(pClassIf))
+    {
+        PUTSGADGETINT pThis = (PUTSGADGETINT)RTMemAllocZ(RT_OFFSETOF(UTSGADGETINT, abClassInst[pClassIf->cbClass]));
+        if (RT_LIKELY(pThis))
+        {
+            pThis->cRefs       = 1;
+            pThis->hGadgetHost = hGadgetHost;
+            pThis->pClassIf    = pClassIf;
+            rc = pClassIf->pfnInit((PUTSGADGETCLASSINT)&pThis->abClassInst[0], paCfg);
+            if (RT_SUCCESS(rc))
+                *phGadget = pThis;
+            else
+                RTMemFree(pThis);
+        }
+        else
+            rc = VERR_NO_MEMORY;
+    }
+    else
+        rc = VERR_INVALID_PARAMETER;
+
+    return rc;
+}
+
+
+DECLHIDDEN(uint32_t) utsGadgetRetain(UTSGADGET hGadget)
+{
+    PUTSGADGETINT pThis = hGadget;
+
+    AssertPtrReturn(pThis, 0);
+
+    return ASMAtomicIncU32(&pThis->cRefs);
+}
+
+
+DECLHIDDEN(uint32_t) utsGadgetRelease(UTSGADGET hGadget)
+{
+    PUTSGADGETINT pThis = hGadget;
+
+    AssertPtrReturn(pThis, 0);
+
+    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+    if (!cRefs)
+        utsGadgetDestroy(pThis);
+
+    return cRefs;
+}
+
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp	(revision 60375)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp	(revision 60375)
@@ -0,0 +1,145 @@
+/* $Id$ */
+/** @file
+ * UsbTestServ - Remote USB test configuration and execution server, USB gadget class
+ *               for the test device.
+ */
+
+/*
+ * 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/dir.h>
+#include <iprt/env.h>
+#include <iprt/mem.h>
+#include <iprt/path.h>
+#include <iprt/process.h>
+#include <iprt/string.h>
+#include <iprt/types.h>
+
+#include <iprt/linux/sysfs.h>
+
+#include "UsbTestServiceGadgetInternal.h"
+
+/*********************************************************************************************************************************
+*   Constants And Macros, Structures and Typedefs                                                                                *
+*********************************************************************************************************************************/
+
+/** Default configfs mount point. */
+#define UTS_GADGET_CLASS_CONFIGFS_MNT_DEF "/sys/kernel/config/usb_gadget"
+/** Gadget template name */
+#define UTS_GADGET_TEMPLATE_NAME "gadget_test"
+
+#define UTS_GADGET_TEST_VENDOR_ID_DEF    UINT16_C(0x0525)
+#define UTS_GADGET_TEST_PRODUCT_ID_DEF   UINT16_C(0xa4a0)
+#define UTS_GADGET_TEST_DEVICE_CLASS_DEF UINT8_C(0xff)
+
+
+/**
+ * Internal UTS gadget host instance data.
+ */
+typedef struct UTSGADGETCLASSINT
+{
+    /** Gadget template path. */
+    char                      *pszGadgetPath;
+    /** The UDC this gadget is connected to. */
+    char                      *pszUdc;
+    /** Bus identifier for the used UDC. */
+    uint32_t                   uBusId;
+    /** Device identifier. */
+    uint32_t                   uDevId;
+} UTSGADGETCLASSINT;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+
+
+/**
+ * @interface_method_impl{UTSGADGETCLASS,pfnInit}
+ */
+static DECLCALLBACK(int) utsGadgetClassTestInit(PUTSGADGETCLASSINT pClass, PCUTSGADGETCFGITEM paCfg)
+{
+    int rc = VINF_SUCCESS;
+
+    if (RTLinuxSysFsExists(UTS_GADGET_CLASS_CONFIGFS_MNT_DEF))
+    {
+        /* Create the gadget template */
+        unsigned idx = 0;
+        char aszPath[RTPATH_MAX];
+
+        do
+        {
+            RTStrPrintf(&aszPath[0], RT_ELEMENTS(aszPath), "%s/%s%u",
+                        UTS_GADGET_CLASS_CONFIGFS_MNT_DEF, UTS_GADGET_TEMPLATE_NAME,
+                        idx);
+            rc = RTDirCreateFullPath(aszPath, 0700);
+            if (RT_SUCCESS(rc))
+                break;
+            idx++;
+        } while (idx < 100);
+
+        if (RT_SUCCESS(rc))
+        {
+            pClass->pszGadgetPath = RTStrDup(aszPath);
+
+            uint16_t idVendor = 0;
+            uint16_t idProduct = 0;
+            uint8_t  bDeviceClass = 0;
+            rc = utsGadgetCfgQueryU16Def(paCfg, "Gadget/idVendor", &idVendor, UTS_GADGET_TEST_VENDOR_ID_DEF);
+            if (RT_SUCCESS(rc))
+                rc = utsGadgetCfgQueryU16Def(paCfg, "Gadget/idProduct", &idProduct, UTS_GADGET_TEST_PRODUCT_ID_DEF);
+            if (RT_SUCCESS(rc))
+                rc = utsGadgetCfgQueryU16Def(paCfg, "Gadget/bDeviceClass", &bDeviceClass, UTS_GADGET_TEST_DEVICE_CLASS_DEF);
+        }
+    }
+    else
+        rc = VERR_NOT_FOUND;
+
+    return rc;
+}
+
+
+/**
+ * @interface_method_impl{UTSGADGETCLASS,pfnTerm}
+ */
+static DECLCALLBACK(void) utsGadgetClassTestTerm(PUTSGADGETCLASSINT pClass)
+{
+
+}
+
+
+
+/**
+ * The gadget host interface callback table.
+ */
+const UTSGADGETCLASSIF g_UtsGadgetClassTest =
+{
+    /** enmType */
+    UTSGADGETCLASS_TEST,
+    /** pszDesc */
+    "UTS test device gadget class",
+    /** cbIf */
+    sizeof(UTSGADGETCLASSINT),
+    /** pfnInit */
+    utsGadgetClassTestInit,
+    /** pfnTerm */
+    utsGadgetClassTestTerm
+};
+
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp	(revision 60367)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHost.cpp	(revision 60375)
@@ -141,2 +141,3 @@
     return cRefs;
 }
+
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp	(revision 60367)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp	(revision 60375)
@@ -158,5 +158,5 @@
 {
     /* Nothing to do so far. */
-    return VINF_SUCCESS;  
+    return VINF_SUCCESS;
 }
 
@@ -167,5 +167,5 @@
 static DECLCALLBACK(int) utsGadgetHostUsbIpGadgetConnect(PUTSGADGETHOSTTYPEINT pIf, UTSGADGET hGadget)
 {
-   return VINF_SUCCESS; 
+   return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetInternal.h
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetInternal.h	(revision 60375)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetInternal.h	(revision 60375)
@@ -0,0 +1,82 @@
+/* $Id$ */
+/** @file
+ * UsbTestServ - Remote USB test configuration and execution server, Interal gadget interfaces.
+ */
+
+/*
+ * 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 ___UsbTestServiceGadgetInternal_h___
+#define ___UsbTestServiceGadgetInternal_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 UTSGADGETCLASSINT *PUTSGADGETCLASSINT;
+/** Pointer to a gadget host instance pointer. */
+typedef PUTSGADGETCLASSINT *PPUTSGADGETCLASSINT;
+
+/**
+ * Gadget class interface.
+ */
+typedef struct UTSGADGETCLASSIF
+{
+    /** The gadget class type implemented. */
+    UTSGADGETCLASS            enmClass;
+    /** Description. */
+    const char               *pszDesc;
+    /** Size of the class specific instance data. */
+    size_t                    cbClass;
+
+    /**
+     * Initializes the gadget class instance.
+     *
+     * @returns IPRT status code.
+     * @param   pClass        The interface specific instance data.
+     * @param   paCfg         The configuration of the interface.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnInit, (PUTSGADGETCLASSINT pClass, PCUTSGADGETCFGITEM paCfg));
+
+    /**
+     * Terminates the gadget class instance.
+     *
+     * @returns nothing.
+     * @param   pClass        The interface specific instance data.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnTerm, (PUTSGADGETCLASSINT pClass));
+
+} UTSGADGETCLASSIF;
+/** Pointer to a gadget class callback table. */
+typedef UTSGADGETCLASSIF *PUTSGADGETCLASSIF;
+/** Pointer to a const gadget host callback table. */
+typedef const struct UTSGADGETCLASSIF *PCUTSGADGETCLASSIF;
+
+extern UTSGADGETCLASSIF const g_UtsGadgetClassTest;
+
+RT_C_DECLS_END
+
+#endif
+
