Index: trunk/src/VBox/VMM/PDM.cpp
===================================================================
--- trunk/src/VBox/VMM/PDM.cpp	(revision 3850)
+++ trunk/src/VBox/VMM/PDM.cpp	(revision 3852)
@@ -627,5 +627,5 @@
      * Resume all threads.
      */
-    ///@todo pdmR3ThreadResumeAll(pVM);    
+    ///@todo pdmR3ThreadResumeAll(pVM);
 
     LogFlow(("PDMR3PowerOn: returns void\n"));
@@ -717,5 +717,5 @@
      * Suspend all threads.
      */
-    ///@todo pdmR3ThreadSuspendAll(pVM);    
+    ///@todo pdmR3ThreadSuspendAll(pVM);
 
     LogFlow(("PDMR3Suspend: returns void\n"));
@@ -760,5 +760,5 @@
      * Resume all threads.
      */
-    ///@todo pdmR3ThreadResumeAll(pVM);    
+    ///@todo pdmR3ThreadResumeAll(pVM);
 
     LogFlow(("PDMR3Resume: returns void\n"));
@@ -820,5 +820,5 @@
  * @param   iInstance       Device instance.
  * @param   ppBase          Where to store the pointer to the base device interface on success.
- * @remark  We're doing any locking ATM, so don't try call this at times when the
+ * @remark  We're not doing any locking ATM, so don't try call this at times when the
  *          device chain is known to be updated.
  */
@@ -877,5 +877,5 @@
  * @param   iLun            The Logical Unit to obtain the interface of.
  * @param   ppBase          Where to store the base interface pointer.
- * @remark  We're doing any locking ATM, so don't try call this at times when the
+ * @remark  We're not doing any locking ATM, so don't try call this at times when the
  *          device chain is known to be updated.
  */
@@ -910,5 +910,5 @@
  * @param   iLun            The Logical Unit to obtain the interface of.
  * @param   ppBase          Where to store the base interface pointer.
- * @remark  We're doing any locking ATM, so don't try call this at times when the
+ * @remark  We're not doing any locking ATM, so don't try call this at times when the
  *          device chain is known to be updated.
  */
Index: trunk/src/VBox/VMM/PDMDriver.cpp
===================================================================
--- trunk/src/VBox/VMM/PDMDriver.cpp	(revision 3850)
+++ trunk/src/VBox/VMM/PDMDriver.cpp	(revision 3852)
@@ -93,4 +93,5 @@
 static DECLCALLBACK(void) pdmR3DrvHlp_STAMRegisterV(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args);
 static DECLCALLBACK(int) pdmR3DrvHlp_SUPCallVMMR0Ex(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg);
+static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp);
 
 /** @def PDMDRV_ASSERT_DRVINS
@@ -138,4 +139,5 @@
     pdmR3DrvHlp_STAMRegisterV,
     pdmR3DrvHlp_SUPCallVMMR0Ex,
+    pdmR3DrvHlp_USBRegisterHub,
     0 /* the end */
 };
@@ -996,6 +998,23 @@
     }
 
-    LogFlow(("pdmR3DrvHlp_SSMDeregister: caller='%s'/%d: returns %Vrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
-    return rc;
-}
-
+    LogFlow(("pdmR3DrvHlp_SUPCallVMMR0Ex: caller='%s'/%d: returns %Vrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
+    return rc;
+}
+
+
+
+/** @copydoc PDMDRVHLP::pfnUSBRegisterHub */
+static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp)
+{
+    PDMDRV_ASSERT_DRVINS(pDrvIns);
+    VM_ASSERT_EMT(pDrvIns->Internal.s.pVM);
+    LogFlow(("pdmR3DrvHlp_USBRegisterHub: caller='%s'/%d: pvReservedIn=%p ppvReservedHlp=%p\n",
+             pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pvReservedIn, ppvReservedHlp));
+
+//    int rc = PDMUSBRegisterHub(pDrvIns->Internal.s.pVM, pvReservedIn, ppvReservedHlp);
+    int rc = VERR_NOT_IMPLEMENTED;
+
+    LogFlow(("pdmR3DrvHlp_USBRegisterHub: caller='%s'/%d: returns %Vrc\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc));
+    return rc;
+}
+
Index: trunk/src/VBox/VMM/PDMInternal.h
===================================================================
--- trunk/src/VBox/VMM/PDMInternal.h	(revision 3850)
+++ trunk/src/VBox/VMM/PDMInternal.h	(revision 3852)
@@ -48,4 +48,9 @@
 typedef PPDMDEV *PPPDMDEV;
 
+/** Pointer to a PDM USB Device. */
+typedef struct PDMUSB *PPDMUSB;
+/** Pointer to a pointer to a PDM USB Device. */
+typedef PPDMUSB *PPPDMUSB;
+
 /** Pointer to a PDM Driver. */
 typedef struct PDMDRV *PPDMDRV;
@@ -65,7 +70,9 @@
 typedef struct PDMRTC *PPDMRTC;
 
-
-/**
- * Private instance data.
+/** Pointer to an USB HUB registration record. */
+typedef struct PDMUSBHUB *PPDMUSBHUB;
+
+/**
+ * Private device instance data.
  */
 typedef struct PDMDEVINSINT
@@ -105,5 +112,39 @@
 
 /**
- * Private instance data.
+ * Private USB device instance data.
+ */
+typedef struct PDMUSBINSINT
+{
+    /** Pointer to the next instance.
+     * (Head is pointed to by PDM::pUsbInstances.) */
+    R3PTRTYPE(PPDMUSBINS)           pNext;
+    /** Pointer to the next per USB device instance.
+     * (Head is pointed to by PDMUSB::pInstances.) */
+    R3PTRTYPE(PPDMUSBINS)           pPerDeviceNext;
+
+    /** Pointer to device structure. */
+    R3PTRTYPE(PPDMUSB)              pUsb;
+
+    /** Pointer to the VM this instance was created for. */
+    PVMR3                           pVM;
+    /** Pointer to the list of logical units associated with the device. (FIFO) */
+    R3PTRTYPE(PPDMLUN)              pLuns;
+    /** The per instance device configuration. */
+    R3PTRTYPE(PCFGMNODE)            pCfg;
+    /** The global device configuration. */
+    R3PTRTYPE(PCFGMNODE)            pCfgGlobal;
+
+    /** Pointer to the USB hub this device is connected to. */
+    R3PTRTYPE(PPDMUSBHUB)           pHub;
+    /** The port number that we're connected to. */
+    uint32_t                        iPort;
+#if HC_ARCH_BITS == 64
+    uint32_t                        Alignment0;
+#endif
+} PDMUSBINSINT;
+
+
+/**
+ * Private driver instance data.
  */
 typedef struct PDMDRVINSINT
@@ -206,4 +247,5 @@
 /* Must be included after PDMDEVINSINT is defined. */
 #define PDMDEVINSINT_DECLARED
+#define PDMUSBINSINT_DECLARED
 #define PDMDRVINSINT_DECLARED
 #define PDMCRITSECTINT_DECLARED
@@ -213,5 +255,4 @@
 #endif
 #include <VBox/pdm.h>
-
 
 
@@ -232,6 +273,9 @@
     /** Pointer to the top driver in the driver chain. */
     PPDMDRVINS          pTop;
-    /** Pointer to the device instance which the LUN belongs to. */
+    /** Pointer to the device instance which the LUN belongs to.
+     * Either this is set or pUsbIns is set. Both is never set at the same time. */
     PPDMDEVINS          pDevIns;
+    /** Pointer to the USB device instance which the LUN belongs to. */
+    PPDMUSBINS          pUsbIns;
     /** Pointer to the device base interface. */
     PPDMIBASE           pBase;
@@ -256,9 +300,26 @@
     /** Pointer to chain of instances (HC Ptr). */
     HCPTRTYPE(PPDMDEVINS)               pInstances;
-
 } PDMDEV;
 
 
 /**
+ * PDM USB Device.
+ */
+typedef struct PDMUSB
+{
+    /** Pointer to the next device (R3 Ptr). */
+    R3PTRTYPE(PPDMUSB)                  pNext;
+    /** Device name length. (search optimization) */
+    RTUINT                              cchName;
+    /** Registration structure. */
+    R3PTRTYPE(const struct PDMUSBREG *) pUsbReg;
+    /** Number of instances. */
+    RTUINT                              cInstances;
+    /** Pointer to chain of instances (R3 Ptr). */
+    R3PTRTYPE(PPDMUSBINS)               pInstances;
+} PDMUSB;
+
+
+/**
  * PDM Driver.
  */
@@ -266,10 +327,9 @@
 {
     /** Pointer to the next device. */
-    PPDMDRV                 pNext;
+    PPDMDRV                             pNext;
     /** Registration structure. */
-    const struct PDMDRVREG *pDrvReg;
+    const struct PDMDRVREG *            pDrvReg;
     /** Number of instances. */
-    RTUINT                  cInstances;
-
+    RTUINT                              cInstances;
 } PDMDRV;
 
@@ -657,4 +717,25 @@
 
 /**
+ * An USB hub registration record.
+ */
+typedef struct PDMUSBHUB
+{
+    /** The USB versions this hub support.
+     * Note that 1.1 hubs can take on 2.0 devices. */
+    uint32_t            fVersions;
+    /** The number of occupied ports. */
+    uint32_t            cAvailablePorts;
+    /** Pointer to the next hub in the list. */
+    struct PDMUSBHUB   *pNext;
+    /** The driver instance of the hub.. */
+    PPDMDRVINS          pDrvIns;
+
+} PDMUSBHUB;
+
+/** Pointer to a const USB HUB registration record. */
+typedef const PDMUSBHUB *PCPDMUSBHUB;
+
+
+/**
  * Converts a PDM pointer into a VM pointer.
  * @returns Pointer to the VM structure the PDM is part of.
@@ -682,4 +763,8 @@
     /** List of devices instances. (FIFO) */
     HCPTRTYPE(PPDMDEVINS)           pDevInstances;
+    /** List of registered USB devices. (FIFO) */
+    R3PTRTYPE(PPDMUSB)              pUsbDevs;
+    /** List of USB devices instances. (FIFO) */
+    R3PTRTYPE(PPDMUSBINS)           pUsbInstances;
     /** List of registered drivers. (FIFO) */
     HCPTRTYPE(PPDMDRV)              pDrvs;
@@ -698,4 +783,6 @@
     /** The registered RTC device. */
     HCPTRTYPE(PPDMRTC)              pRtc;
+    /** The registered USB HUBs. (FIFO) */
+    R3PTRTYPE(PPDMUSBHUB)           pUSBHubs;
 
     /** Queue in which devhlp tasks are queued for R3 execution - HC Ptr. */
@@ -719,5 +806,4 @@
     /** Pointer to the queue which should be manually flushed - GCPtr. */
     GCPTRTYPE(struct PDMQUEUE *)    pQueueFlushGC;
-
 #if HC_ARCH_BITS == 64
     uint32_t                        padding0;
@@ -778,4 +864,8 @@
 int         pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
 
+int         pdmR3UsbInit(PVM pVM);
+PPDMUSB     pdmR3UsbLookup(PVM pVM, const char *pszName);
+int         pdmR3UsbFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
+
 int         pdmR3DrvInit(PVM pVM);
 int         pdmR3DrvDetach(PPDMDRVINS pDrvIns);
@@ -790,4 +880,5 @@
 
 void        pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
+void        pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
 void        pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
 void        pdmR3ThreadDestroyAll(PVM pVM);
Index: trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp	(revision 3850)
+++ trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp	(revision 3852)
@@ -177,4 +177,6 @@
     GEN_CHECK_OFF(PDM, pDevs);
     GEN_CHECK_OFF(PDM, pDevInstances);
+    GEN_CHECK_OFF(PDM, pUsbDevs);
+    GEN_CHECK_OFF(PDM, pUsbInstances);
     GEN_CHECK_OFF(PDM, pDrvs);
     GEN_CHECK_OFF(PDM, pCritSects);
@@ -233,4 +235,5 @@
     GEN_CHECK_OFF(PDM, pDmac);
     GEN_CHECK_OFF(PDM, pRtc);
+    GEN_CHECK_OFF(PDM, pUSBHubs);
     GEN_CHECK_OFF(PDM, pDevHlpQueueGC);
     GEN_CHECK_OFF(PDM, pDevHlpQueueHC);
@@ -241,4 +244,6 @@
     GEN_CHECK_OFF(PDM, pQueueFlushGC);
     GEN_CHECK_OFF(PDM, pQueueFlushHC);
+    GEN_CHECK_OFF(PDM, pThreads);
+    GEN_CHECK_OFF(PDM, pThreadsTail);
     GEN_CHECK_OFF(PDM, cPollers);
     GEN_CHECK_OFF(PDM, apfnPollers);
@@ -804,5 +809,5 @@
     GEN_CHECK_OFF(PATCHINFO, aPrivInstr[MAX_INSTR_SIZE - 1]);
     GEN_CHECK_OFF(PATCHINFO, cbPrivInstr);
-    GEN_CHECK_OFF(PATCHINFO, opcode);     
+    GEN_CHECK_OFF(PATCHINFO, opcode);
     GEN_CHECK_OFF(PATCHINFO, cbPatchJump);
     GEN_CHECK_OFF(PATCHINFO, pPatchJumpDestGC);
Index: trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 3850)
+++ trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 3852)
@@ -3,5 +3,5 @@
  * tstVMStructSize - testcase for check structure sizes/alignment
  *                   and to verify that HC and GC uses the same
- *                   representation of the structures.                
+ *                   representation of the structures.
  */
 
@@ -202,9 +202,11 @@
         rc++;
     }
-#endif 
+#endif
 
     /* pdm */
     CHECK_MEMBER_ALIGNMENT(PDMDEVINS, achInstanceData, 16);
     CHECK_PADDING(PDMDEVINS, Internal);
+    CHECK_MEMBER_ALIGNMENT(PDMUSBINS, achInstanceData, 16);
+    CHECK_PADDING(PDMUSBINS, Internal);
     CHECK_MEMBER_ALIGNMENT(PDMDRVINS, achInstanceData, 16);
     CHECK_PADDING(PDMDRVINS, Internal);
