Index: trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py
===================================================================
--- trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py	(revision 60492)
+++ trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py	(revision 60493)
@@ -295,5 +295,5 @@
         if fRc is True:
             reporter.log('Connect succeeded');
-            self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost, [], []);
+            self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost + (':%s' % oUsbGadget.getUsbIpPort()), [], []);
 
             # Create device filter
@@ -341,5 +341,5 @@
         if fRc is True:
             reporter.log('Connect succeeded');
-            self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost, [], []);
+            self.oVBox.host.addUSBDeviceSource('USBIP', sGadgetHost, sGadgetHost + ':' + oUsbGadget.getUsbIpPort(), [], []);
 
             # Create device filter
Index: trunk/src/VBox/ValidationKit/tests/usb/usbgadget2.py
===================================================================
--- trunk/src/VBox/ValidationKit/tests/usb/usbgadget2.py	(revision 60492)
+++ trunk/src/VBox/ValidationKit/tests/usb/usbgadget2.py	(revision 60493)
@@ -416,4 +416,9 @@
                         return None;
                     abPayload.extend(u32ToByteArray(o));
+                elif isinstance(o, types.IntType):
+                    if o < 0 or o > 0xffffffff:
+                        reporter.fatal('sendMsg: uint32_t payload is out of range: %s' % (hex(o)));
+                        return None;
+                    abPayload.extend(u32ToByteArray(o));
                 elif isinstance(o, array.array):
                     abPayload.extend(o);
@@ -627,5 +632,5 @@
         if sOpcode == "ACK":
             return True;
-        return (sOpcode, getSZ(abPayload, 0, sOpcode));
+        return (sOpcode, getSZ(abPayload, 16, sOpcode));
 
     def recvAckLogged(self, sCommand, fNoDataOk = False):
@@ -659,5 +664,5 @@
         if sOpcode == "FALSE":
             return False;
-        reporter.maybeErr(self.fErr, 'recvAckLogged: %s response was %s: %s' % (sCommand, sOpcode, getSZ(abPayload, 0, sOpcode)));
+        reporter.maybeErr(self.fErr, 'recvAckLogged: %s response was %s: %s' % (sCommand, sOpcode, getSZ(abPayload, 16, sOpcode)));
         return None;
 
@@ -721,5 +726,5 @@
         sHostname = socket.gethostname().lower();
         cbFill = 68 - len(sHostname) - 1;
-        rc = self.sendMsg("HOWDY", (long((1 << 16) | 0), long(0x1), long(len(sHostname)), sHostname, zeroByteArray(cbFill)));
+        rc = self.sendMsg("HOWDY", ((1 << 16) | 0, 0x1, len(sHostname), sHostname, zeroByteArray(cbFill)));
         if rc is True:
             rc = self.recvAckLogged("HOWDY", self.fTryConnect);
@@ -746,5 +751,5 @@
     def taskGadgetCreate(self, iGadgetType, iGadgetAccess):
         """Creates a new gadget on UTS"""
-        fRc = self.sendMsg("GDGTCRT", (iGadgetType, iGadgetAccess, 0));
+        fRc = self.sendMsg("GDGTCRT", (iGadgetType, iGadgetAccess, 0, 0));
         if fRc is True:
             fRc = self.recvAckLogged("GDGTCRT");
@@ -842,5 +847,5 @@
         """
         return self.startTask(cMsTimeout, fIgnoreErrors, "GadgetCreate", self.taskGadgetCreate, \
-                              (long(iGadgetType), long(iGadgetAccess)));
+                              (iGadgetType, iGadgetAccess));
 
     def syncGadgetCreate(self, iGadgetType, iGadgetAccess, cMsTimeout = 30000, fIgnoreErrors = False):
@@ -857,5 +862,5 @@
         """
         return self.startTask(cMsTimeout, fIgnoreErrors, "GadgetDestroy", self.taskGadgetDestroy, \
-                              (long(iGadgetId), ));
+                              (iGadgetId, ));
 
     def syncGadgetDestroy(self, iGadgetId, cMsTimeout = 30000, fIgnoreErrors = False):
@@ -1327,5 +1332,5 @@
         fRc = False;
         if sImpersonation == g_ksGadgetImpersonationTest:
-            fRc = self.oUtsSession.syncGadgetCreate(g_kiGadgetTypeTest);
+            fRc = self.oUtsSession.syncGadgetCreate(g_kiGadgetTypeTest, g_kiGadgetAccessUsbIp);
         else:
             reporter.log('Invalid or unsupported impersonation');
@@ -1358,5 +1363,13 @@
                 print 'connect: waitForTask -> %s, result %s' % (fDone, self.oUtsSession.getResult());
                 if fDone is True and self.oUtsSession.isSuccess():
-                    fRc = True;
+                    # Parse the reply.
+                    _, _, abPayload = self.oUtsSession.getLastReply();
+
+                    if getU32(abPayload, 20) is g_kiGadgetAccessUsbIp:
+                        fRc = True;
+                        self.iUsbIpPort = getU32(abPayload, 24);
+                    else:
+                        reporter.log('Gadget doesn\'t support access over USB/IP despite being requested');
+                        fRc = False;
                 else:
                     fRc = False;
@@ -1376,5 +1389,4 @@
 
         self._clearImpersonation();
-        self._cleanupGadget();
         if self.oUtsSession is not None:
             fRc = self.oUtsSession.syncDisconnect();
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp	(revision 60492)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestService.cpp	(revision 60493)
@@ -566,5 +566,4 @@
     else
         rc = utsReplyBadSize(pClient, pPktHdr, sizeof(UTSPKTHDR));
-    g_pTransport->pfnNotifyBye(pClient->pTransportClient);
     return rc;
 }
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetCfg.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetCfg.cpp	(revision 60492)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetCfg.cpp	(revision 60493)
@@ -171,5 +171,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_UINT8)
+    {
         *pu8 = pCfgItem ? pCfgItem->Val.u.u8 : u8Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -206,5 +209,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_UINT16)
+    {
         *pu16 = pCfgItem ? pCfgItem->Val.u.u16 : u16Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -241,5 +247,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_UINT32)
+    {
         *pu32 = pCfgItem ? pCfgItem->Val.u.u32 : u32Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -276,5 +285,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_UINT64)
+    {
         *pu64 = pCfgItem ? pCfgItem->Val.u.u64 : u64Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -311,5 +323,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_INT8)
+    {
         *pi8 = pCfgItem ? pCfgItem->Val.u.i8 : i8Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -346,5 +361,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_INT16)
+    {
         *pi16 = pCfgItem ? pCfgItem->Val.u.i16 : i16Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -381,5 +399,8 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_INT32)
+    {
         *pi32 = pCfgItem ? pCfgItem->Val.u.i32 : i32Def;
+        rc = VINF_SUCCESS;
+    }
 
     return rc;
@@ -416,7 +437,10 @@
     if (   !pCfgItem
         || pCfgItem->Val.enmType == UTSGADGETCFGTYPE_INT64)
+    {
         *pi64 = pCfgItem ? pCfgItem->Val.u.i64 : i64Def;
-
-    return rc;
-}
-
+        rc = VINF_SUCCESS;
+    }
+
+    return rc;
+}
+
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp	(revision 60492)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetClassTest.cpp	(revision 60493)
@@ -184,6 +184,6 @@
     if (cbStr <= sizeof(aszPathFunc) - 1)
     {
-        cbStr = RTStrPrintf(&aszPathCfg[0], sizeof(aszPathCfg), "%s/configs/%s",
-                            pClass->pszGadgetPath, pszCfg);
+        cbStr = RTStrPrintf(&aszPathCfg[0], sizeof(aszPathCfg), "%s/configs/%s/%s",
+                            pClass->pszGadgetPath, pszCfg, pszFunc);
         if (cbStr <= sizeof(aszPathCfg) - 1)
             rc = RTSymlinkCreate(&aszPathCfg[0], &aszPathFunc[0], RTSYMLINKTYPE_DIR, 0);
Index: trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp
===================================================================
--- trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp	(revision 60492)
+++ trunk/src/VBox/ValidationKit/utils/usb/UsbTestServiceGadgetHostUsbIp.cpp	(revision 60493)
@@ -29,4 +29,6 @@
 #include <iprt/process.h>
 #include <iprt/string.h>
+#include <iprt/thread.h>
+#include <iprt/time.h>
 #include <iprt/types.h>
 
@@ -98,5 +100,5 @@
 
     rc = utsGadgetCfgQueryU16Def(paCfg, "UsbIp/Port", &uPort, UTS_GADGET_HOST_USBIP_PORT_DEF);
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
     {
         /* Make sure the kernel drivers are loaded. */
@@ -107,21 +109,38 @@
             if (RT_SUCCESS(rc))
             {
-                char aszPort[10];
-                char aszPidFile[64];
-                const char *apszArgv[6];
-
-                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";
-                apszArgv[4] = aszPidFile;
-                apszArgv[5] = NULL;
-                rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
+                rc = utsGadgetHostUsbIpLoadModule("libcomposite");
                 if (RT_SUCCESS(rc))
                 {
-                    /* We are done setting it up at the moment. */
+                    char aszPort[10];
+                    char aszPidFile[64];
+                    const char *apszArgv[6];
+
+                    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";
+                    apszArgv[4] = aszPidFile;
+                    apszArgv[5] = NULL;
+                    rc = RTProcCreate("usbipd", apszArgv, RTENV_DEFAULT, RTPROC_FLAGS_SEARCH_PATH, &pIf->hProcUsbIp);
+                    if (RT_SUCCESS(rc))
+                    {
+                        /* Wait for a bit to make sure the server started up successfully. */
+                        uint64_t tsStart = RTTimeMilliTS();
+                        do
+                        {
+                            RTPROCSTATUS ProcSts;
+                            rc = RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_NOBLOCK, &ProcSts);
+                            if (rc != VERR_PROCESS_RUNNING)
+                            {
+                                rc = VERR_INVALID_HANDLE;
+                                break;
+                            }
+                            RTThreadSleep(1);
+                            rc = VINF_SUCCESS;
+                        } while (RTTimeMilliTS() - tsStart < 2 * 1000); /* 2 seconds. */
+                    }
                 }
             }
@@ -138,6 +157,9 @@
 static DECLCALLBACK(void) utsGadgetHostUsbIpTerm(PUTSGADGETHOSTTYPEINT pIf)
 {
-    /* Kill the process. */
+    /* Kill the process and wait for it to terminate. */
     RTProcTerminate(pIf->hProcUsbIp);
+
+    RTPROCSTATUS ProcSts;
+    RTProcWait(pIf->hProcUsbIp, RTPROCWAIT_FLAGS_BLOCK, &ProcSts);
 }
 
