Index: /trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py	(revision 54117)
+++ /trunk/src/VBox/ValidationKit/testdriver/vboxwrappers.py	(revision 54118)
@@ -1024,5 +1024,5 @@
             fRc = False;
         else:
-            reporter.log('changed UsbHid to %s for "%s"' % (fEnable, self.sName));
+            reporter.log('changed OHCI to %s for "%s"' % (fEnable, self.sName));
         self.oTstDrv.processPendingEvents();
         return fRc;
@@ -1049,5 +1049,5 @@
             else:
                 if self.fpApiVer >= 4.3:
-                    cEhciCtls = self.o.machine.getUSBControllerCountByType(vboxcon.USBControllerType_ECI);
+                    cEhciCtls = self.o.machine.getUSBControllerCountByType(vboxcon.USBControllerType_EHCI);
                     if cEhciCtls == 1:
                         self.o.machine.RemoveUSBController('EHCI');
@@ -1058,8 +1058,29 @@
             fRc = False;
         else:
-            reporter.log('changed UsbHid to %s for "%s"' % (fEnable, self.sName));
+            reporter.log('changed EHCI to %s for "%s"' % (fEnable, self.sName));
         self.oTstDrv.processPendingEvents();
         return fRc;
 
+    def enableUsbXhci(self, fEnable):
+        """
+        Enables or disables the USB XHCI controller. Error information is logged.
+        """
+        fRc = True;
+        try:
+            if fEnable:
+                    cXhciCtls = self.o.machine.getUSBControllerCountByType(vboxcon.USBControllerType_XHCI);
+                    if cXhciCtls == 0:
+                        self.o.machine.addUSBController('XHCI', vboxcon.USBControllerType_XHCI);
+            else:
+                cXhciCtls = self.o.machine.getUSBControllerCountByType(vboxcon.USBControllerType_XHCI);
+                if cXhciCtls == 1:
+                    self.o.machine.RemoveUSBController('XHCI');
+        except:
+            reporter.errorXcpt('failed to change XHCI to %s for "%s"' % (fEnable, self.sName));
+            fRc = False;
+        else:
+            reporter.log('changed XHCI to %s for "%s"' % (fEnable, self.sName));
+        self.oTstDrv.processPendingEvents();
+        return fRc;
 
     def setFirmwareType(self, eType):
Index: /trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py
===================================================================
--- /trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py	(revision 54117)
+++ /trunk/src/VBox/ValidationKit/tests/usb/tdUsb1.py	(revision 54118)
@@ -34,4 +34,5 @@
 import os;
 import sys;
+import socket;
 
 # Only the main script needs to modify the path.
@@ -54,4 +55,28 @@
     USB benchmark.
     """
+
+    # The available test devices
+    #
+    # The first key is the hostname of the host the test is running on.
+    # It contains a new dictionary with the attached gadgets based on the
+    # USB speed we want to test (Low, Full, High, Super).
+    # The parameters consist of the hostname of the gadget in the network
+    # and the hardware type.
+    kdGadgetParams = {
+        # The following is for local testing and not for the test lab.
+        'adaris': {
+            'Low':   ('beaglebone', 'BeagleBoneBlack'),
+            'Full':  ('beaglebone', 'BeagleBoneBlack'),
+            'High':  ('beaglebone', 'BeagleBoneBlack'),
+            'Super': ('odroidxu3', 'ODroid-XU3')
+        },
+    };
+
+    # Mappings of USB controllers to supported USB device speeds.
+    kdUsbSpeedMappings = {
+        'OHCI': ['Low', 'Full'],
+        'EHCI': ['High'],
+        'XHCI': ['Low', 'Full', 'High', 'Super']
+    };
 
     def __init__(self):
@@ -61,11 +86,16 @@
         self.oGuestToGuestSess = None;
         self.oGuestToGuestTxs  = None;
-        self.asTestVMsDef      = ['tst-debian', 'tst-arch'];
+        self.asTestVMsDef      = ['tst-arch'];
         self.asTestVMs         = self.asTestVMsDef;
         self.asSkipVMs         = [];
-        self.asVirtModesDef    = ['hwvirt', 'hwvirt-np', 'raw',]
-        self.asVirtModes       = self.asVirtModesDef
-        self.acCpusDef         = [1, 2,]
+        self.asVirtModesDef    = ['hwvirt', 'hwvirt-np', 'raw'];
+        self.asVirtModes       = self.asVirtModesDef;
+        self.acCpusDef         = [1, 2,];
         self.acCpus            = self.acCpusDef;
+        self.asUsbCtrlsDef     = ['OHCI', 'EHCI', 'XHCI'];
+        self.asUsbCtrls        = self.asUsbCtrlsDef;
+        self.asUsbSpeedDef     = ['Low', 'Full', 'High', 'Super'];
+        self.asUsbSpeed        = self.asUsbSpeedDef;
+        self.sHostname         = socket.gethostname().lower();
 
     #
@@ -86,4 +116,8 @@
         reporter.log('  --skip-vms      <vm1[:vm2[:...]]>');
         reporter.log('      Skip the specified VMs when testing.');
+        reporter.log('  --usb-ctrls     <u1[:u2[:]]');
+        reporter.log('      Default: %s' % (':'.join(str(c) for c in self.asUsbCtrlsDef)));
+        reporter.log('  --usb-speed     <s1[:s2[:]]');
+        reporter.log('      Default: %s' % (':'.join(str(c) for c in self.asUsbSpeedDef)));
         return rc;
 
@@ -121,4 +155,18 @@
                 if s not in self.asTestVMsDef:
                     reporter.log('warning: The "--test-vms" value "%s" does not specify any of our test VMs.' % (s));
+        elif asArgs[iArg] == '--usb-ctrls':
+            iArg += 1;
+            if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-ctrls" takes a colon separated list of USB controllers');
+            self.asUsbCtrls = asArgs[iArg].split(':');
+            for s in self.asUsbCtrls:
+                if s not in self.asUsbCtrlsDef:
+                    reporter.log('warning: The "--usb-ctrls" value "%s" is not a valid USB controller.' % (s));
+        elif asArgs[iArg] == '--usb-speed':
+            iArg += 1;
+            if iArg >= len(asArgs): raise base.InvalidOption('The "--usb-speed" takes a colon separated list of USB speeds');
+            self.asUsbSpeed = asArgs[iArg].split(':');
+            for s in self.asUsbSpeed:
+                if s not in self.asUsbSpeedDef:
+                    reporter.log('warning: The "--usb-speed" value "%s" is not a valid USB speed.' % (s));
         else:
             return vbox.TestDriver.parseOption(self, asArgs, iArg);
@@ -137,6 +185,4 @@
         if self.asRsrcs is None:
             self.asRsrcs = [];
-            if 'tst-debian' in self.asTestVMs:
-                self.asRsrcs.append('4.2/storage/debian.vdi');
 
             if 'tst-arch' in self.asTestVMs:
@@ -180,11 +226,4 @@
 
         # Linux VMs
-        if 'tst-debian' in self.asTestVMs:
-            oVM = self.createTestVM('tst-debian', 1, '4.2/storage/debian.vdi', sKind = 'Debian_64', fIoApic = True, \
-                                    eNic0AttachType = vboxcon.NetworkAttachmentType_NAT, \
-                                    sDvdImage = sVBoxValidationKit_iso);
-            if oVM is None:
-                return False;
-
         if 'tst-arch' in self.asTestVMs:
             oVM = self.createTestVM('tst-arch', 1, '4.2/usb/tst-arch.vdi', sKind = 'ArchLinux_64', fIoApic = True, \
@@ -203,13 +242,24 @@
         return fRc;
 
+    def getGadgetParams(self, sHostname, sSpeed):
+        """
+        Returns the gadget hostname and type from the
+        given hostname the test is running on and device speed we want to test.
+        """
+        kdGadgetsConfigured = self.kdGadgetParams.get(sHostname);
+        if kdGadgetsConfigured is not None:
+            return kdGadgetsConfigured.get(sSpeed);
+
+        return None;
 
     #
     # Test execution helpers.
     #
-    def testUsbCompliance(self, oSession, oTxsSession, sVmName):
-        """
-        Test VirtualBoxs autostart feature in a VM.
-        """
-        reporter.testStart('USB ' + sVmName);
+    def testUsbCompliance(self, oSession, oTxsSession, sVmName, sSpeed):
+        """
+        Test VirtualBoxs USB stack in a VM.
+        """
+        # Get configured USB test devices from hostname we are running on
+        sGadgetHost, sGadgetType = self.getGadgetParams(self.sHostname, sSpeed);
 
         # Create device filter
@@ -217,5 +267,5 @@
         if fRc is True:
             oUsbGadget = UsbGadget();
-            fRc = oUsbGadget.connectTo(30 * 1000, '192.168.2.213');
+            fRc = oUsbGadget.connectTo(30 * 1000, sGadgetType, sGadgetHost);
             if fRc is True:
                 fRc = oUsbGadget.impersonate('Test');
@@ -223,12 +273,9 @@
 
                     # Wait a moment to let the USB device appear
-                    self.sleep(2);
-
-                    reporter.testStart('USB Test');
-
-                    fRc = self.txsRunTest(oTxsSession, 'USB compliance test', 240 * 1000, \
+                    self.sleep(3);
+
+                    fRc = self.txsRunTest(oTxsSession, 'Compliance', 3600 * 1000, \
                         '${CDROM}/${OS/ARCH}/UsbTest${EXESUFF}', ('UsbTest', ));
 
-                    reporter.testDone();
                 else:
                     reporter.testFailure('Failed to impersonate test device');
@@ -240,8 +287,7 @@
             reporter.testFailure('Failed to create USB device filter');
 
-        reporter.testDone(not fRc);
-        return fRc;
-
-    def testUsbOneCfg(self, sVmName):
+        return fRc;
+
+    def testUsbOneCfg(self, sVmName, sUsbCtrl, sSpeed):
         """
         Runs the specified VM thru test #1.
@@ -258,5 +304,16 @@
             fRc = fRc and oSession.enableVirtEx(True);
             fRc = fRc and oSession.enableNestedPaging(True);
-            fRc = fRc and oSession.enableUsbEhci(True);
+
+            # Make sure controllers are disabled initially.
+            fRc = fRc and oSession.enableUsbOhci(False);
+            fRc = fRc and oSession.enableUsbEhci(False);
+            fRc = fRc and oSession.enableUsbXhci(False);
+
+            if sUsbCtrl == 'OHCI':
+                fRc = fRc and oSession.enableUsbOhci(True);
+            elif sUsbCtrl == 'EHCI':
+                fRc = fRc and oSession.enableUsbEhci(True);
+            elif sUsbCtrl == 'XHCI':
+                fRc = fRc and oSession.enableUsbXhci(True);
             fRc = fRc and oSession.saveSettings();
             fRc = oSession.close() and fRc and True; # pychecker hack.
@@ -275,5 +332,5 @@
                 self.sleep(5);
 
-                fRc = self.testUsbCompliance(oSession, oTxsSession, sVmName);
+                fRc = self.testUsbCompliance(oSession, oTxsSession, sVmName, sSpeed);
 
                 # cleanup.
@@ -289,6 +346,13 @@
         """
         reporter.testStart(sVmName);
-        fRc = True;
-        self.testUsbOneCfg(sVmName);
+        for sUsbCtrl in self.asUsbCtrls:
+            reporter.testStart(sUsbCtrl)
+            for sUsbSpeed in self.asUsbSpeed:
+                asSupportedSpeeds = self.kdUsbSpeedMappings.get(sUsbCtrl);
+                if sUsbSpeed in asSupportedSpeeds:
+                    reporter.testStart(sUsbSpeed)
+                    fRc = self.testUsbOneCfg(sVmName, sUsbCtrl, sUsbSpeed);
+                    reporter.testDone(not fRc);
+            reporter.testDone();
         reporter.testDone();
         return fRc;
@@ -296,6 +360,8 @@
     def testUsb(self):
         """
-        Executes autostart test.
-        """
+        Executes USB test.
+        """
+
+        reporter.log("Running on host: " + self.sHostname);
 
         # Loop thru the test VMs.
Index: /trunk/src/VBox/ValidationKit/tests/usb/usbgadget.py
===================================================================
--- /trunk/src/VBox/ValidationKit/tests/usb/usbgadget.py	(revision 54117)
+++ /trunk/src/VBox/ValidationKit/tests/usb/usbgadget.py	(revision 54118)
@@ -45,4 +45,5 @@
         self.oTxsSession = None;
         self.sImpersonation = 'Invalid';
+        self.sGadgetType    = 'Invalid';
 
     def _loadModule(self, sModule):
@@ -55,4 +56,7 @@
         if self.oTxsSession is not None:
             fRc = self.oTxsSession.syncExecEx('/usr/bin/modprobe', ('/usr/bin/modprobe', sModule));
+            # For the ODroid-XU3 gadget we have to do a soft connect for the attached host to recognise the device.
+            if self.sGadgetType == 'ODroid-XU3':
+                fRc = self.oTxsSession.syncExecEx('/usr/bin/sh', ('/usr/bin/sh', '-c', 'echo connect > /sys/class/udc/12400000.dwc3/soft_connect'));
 
         return fRc;
@@ -66,4 +70,7 @@
         fRc = False;
         if self.oTxsSession is not None:
+            # For the ODroid-XU3 gadget we do a soft disconnect before unloading the gadget driver.
+            if self.sGadgetType == 'ODroid-XU3':
+                fRc = self.oTxsSession.syncExecEx('/usr/bin/sh', ('/usr/bin/sh', '-c', 'echo disconnect > /sys/class/udc/12400000.dwc3/soft_connect'));
             fRc = self.oTxsSession.syncExecEx('/usr/bin/rmmod', ('/usr/bin/rmmod', sModule));
 
@@ -119,5 +126,5 @@
         return False;
 
-    def connectTo(self, cMsTimeout, sHostname, uPort = None):
+    def connectTo(self, cMsTimeout, sGadgetType, sHostname, uPort = None):
         """
         Connects to the specified target device.
@@ -139,4 +146,7 @@
             fRc = False;
 
+        if fRc is True:
+            self.sGadgetType = sGadgetType;
+
         return fRc;
 
