Index: trunk/include/VBox/pdmdrv.h
===================================================================
--- trunk/include/VBox/pdmdrv.h	(revision 28243)
+++ trunk/include/VBox/pdmdrv.h	(revision 28258)
@@ -868,6 +868,6 @@
      * @thread  The emulation thread.
      */
-    DECLR3CALLBACKMEMBER(int, pfnPDMQueueCreate,(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
-                                                 PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue));
+    DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+                                              PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue));
 
     /**
@@ -1073,6 +1073,6 @@
      * @param   pszName     See RTThreadCreate.
      */
-    DECLR3CALLBACKMEMBER(int, pfnPDMThreadCreate,(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
-                                                  PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
+    DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
+                                               PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
 
     /**
@@ -1088,7 +1088,7 @@
      * @param   pszDesc         Description.
      */
-    DECLR3CALLBACKMEMBER(int, pfnPDMAsyncCompletionTemplateCreate,(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
-                                                                   PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser,
-                                                                   const char *pszDesc));
+    DECLR3CALLBACKMEMBER(int, pfnAsyncCompletionTemplateCreate,(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
+                                                                PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser,
+                                                                const char *pszDesc));
 
 
@@ -1110,6 +1110,6 @@
      * @thread  EMT
      */
-    DECLR3CALLBACKMEMBER(int, pfnPDMLdrGetRCInterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
-                                                              const char *pszSymPrefix, const char *pszSymList));
+    DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
+                                                           const char *pszSymPrefix, const char *pszSymList));
 
     /**
@@ -1130,6 +1130,24 @@
      * @thread  EMT
      */
-    DECLR3CALLBACKMEMBER(int, pfnPDMLdrGetR0InterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
-                                                              const char *pszSymPrefix, const char *pszSymList));
+    DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
+                                                           const char *pszSymPrefix, const char *pszSymList));
+    /**
+     * Initializes a PDM critical section.
+     *
+     * The PDM critical sections are derived from the IPRT critical sections, but
+     * works in both RC and R0 as well as R3.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns             The device instance.
+     * @param   pCritSect           Pointer to the critical section.
+     * @param   RT_SRC_POS_DECL     Use RT_SRC_POS.
+     * @param   pszName             The base name of the critical section.  Will be
+     *                              mangeled with the instance number.  For
+     *                              statistics and lock validation.
+     * @param   va                  Arguments for the format string.
+     * @thread  EMT
+     */
+    DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect,
+                                               RT_SRC_POS_DECL, const char *pszName));
     /** Just a safety precaution. */
     uint32_t                        u32TheEnd;
@@ -1278,10 +1296,10 @@
 
 /**
- * @copydoc PDMDRVHLP::pfnPDMQueueCreate
- */
-DECLINLINE(int) PDMDrvHlpPDMQueueCreate(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ * @copydoc PDMDRVHLP::pfnQueueCreate
+ */
+DECLINLINE(int) PDMDrvHlpQueueCreate(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
                                         PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue)
 {
-    return pDrvIns->pHlpR3->pfnPDMQueueCreate(pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
+    return pDrvIns->pHlpR3->pfnQueueCreate(pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
 }
 
@@ -1463,22 +1481,30 @@
 
 /**
- * @copydoc PDMDRVHLP::pfnPDMThreadCreate
- */
-DECLINLINE(int) PDMDrvHlpPDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
+ * @copydoc PDMDRVHLP::pfnThreadCreate
+ */
+DECLINLINE(int) PDMDrvHlpThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
                                          PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
 {
-    return pDrvIns->pHlpR3->pfnPDMThreadCreate(pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
+    return pDrvIns->pHlpR3->pfnThreadCreate(pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
 }
 
 # ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
 /**
- * @copydoc PDMDRVHLP::pfnPDMAsyncCompletionTemplateCreate
- */
-DECLINLINE(int) PDMDrvHlpPDMAsyncCompletionTemplateCreate(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
-                                                          PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc)
-{
-    return pDrvIns->pHlpR3->pfnPDMAsyncCompletionTemplateCreate(pDrvIns, ppTemplate, pfnCompleted, pvTemplateUser, pszDesc);
+ * @copydoc PDMDRVHLP::pfnAsyncCompletionTemplateCreate
+ */
+DECLINLINE(int) PDMDrvHlpAsyncCompletionTemplateCreate(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
+                                                       PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc)
+{
+    return pDrvIns->pHlpR3->pfnAsyncCompletionTemplateCreate(pDrvIns, ppTemplate, pfnCompleted, pvTemplateUser, pszDesc);
 }
 # endif
+
+/**
+ * @copydoc PDMDRVHLP::pfnCritSectInit
+ */
+DECLINLINE(int) PDMDrvHlpCritSectInit(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszName)
+{
+    return pDrvIns->pHlpR3->pfnCritSectInit(pDrvIns, pCritSect, RT_SRC_POS_ARGS, pszName);
+}
 
 
Index: trunk/include/VBox/pdmnetifs.h
===================================================================
--- trunk/include/VBox/pdmnetifs.h	(revision 28243)
+++ trunk/include/VBox/pdmnetifs.h	(revision 28258)
@@ -142,18 +142,20 @@
 
     /**
-     * Called when there is a buffered of the required size available.
-     *
-     * When a PDMINETWORKUP::pfnAllocBuf call fails with VERR_TRY_AGAIN, the
-     * driver will notify the device/driver up stream when a large enough buffer
-     * becomes available via this method.
+     * Do transmit work on the XMIT thread.
+     *
+     * When a PDMINETWORKUP::pfnBeginTransmit or PDMINETWORKUP::pfnAllocBuf call
+     * fails with VERR_TRY_AGAIN, the leaf drivers XMIT thread will offer to process
+     * the upstream device/driver when the the VERR_TRY_AGAIN condition has been
+     * removed.  In some cases the VERR_TRY_AGAIN condition is simply being in an
+     * inconvenient context and the XMIT thread will start working ASAP.
      *
      * @param   pInterface      Pointer to this interface.
      * @thread  Non-EMT.
      */
-    DECLR3CALLBACKMEMBER(void, pfnNotifyBufAvailable,(PPDMINETWORKDOWN pInterface));
+    DECLR3CALLBACKMEMBER(void, pfnDoTransmitWork,(PPDMINETWORKDOWN pInterface));
 
 } PDMINETWORKDOWN;
 /** PDMINETWORKDOWN inteface ID. */
-#define PDMINETWORKDOWN_IID                     "eb66670b-7998-4470-8e72-886e30f6a9c3"
+#define PDMINETWORKDOWN_IID                     "52b8cdbb-a087-493b-baa7-81ec3b803e06"
 
 
@@ -182,4 +184,24 @@
 typedef struct PDMINETWORKUP
 {
+    /**
+     * Begins a transmit session.
+     *
+     * The leaf driver guarantees that there are no concurrent sessions.
+     *
+     * @retval  VINF_SUCCESS on success.  Must always call
+     *          PDMINETWORKUP::pfnEndXmit.
+     * @retval  VERR_TRY_AGAIN if there is already an open transmit session or some
+     *          important resource was unavailable (like buffer space).  If it's a
+     *          resources issue, the driver will signal its XMIT thread and have it
+     *          work the device thru the PDMINETWORKDOWN::pfnNotifyBufAvailable
+     *          callback method.
+     *
+     * @param   pInterface      Pointer to the interface structure containing the
+     *                          called function pointer.
+     *
+     * @thread  Any, but normally EMT or the XMIT thread.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnBeginXmit,(PPDMINETWORKUP pInterface));
+
     /**
      * Get a send buffer for passing to pfnSendBuf.
@@ -206,5 +228,5 @@
      *                          owned by the caller, designation owner number 1.
      *
-     * @thread  Any, but normally EMT.
+     * @thread  Any, but normally EMT or the XMIT thread.
      */
     DECLR3CALLBACKMEMBER(int, pfnAllocBuf,(PPDMINETWORKUP pInterface, size_t cbMin, PCPDMNETWORKGSO pGso,
@@ -221,5 +243,5 @@
      *                          ownership shall be 1.
      *
-     * @thread  Any.
+     * @thread  Any, but normally EMT or the XMIT thread.
      */
     DECLR3CALLBACKMEMBER(int, pfnFreeBuf,(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf));
@@ -243,7 +265,19 @@
      *                          if an EMT.
      *
-     * @thread  Any.
+     * @thread  Any, but normally EMT or the XMIT thread.
      */
     DECLR3CALLBACKMEMBER(int, pfnSendBuf,(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread));
+
+    /**
+     * Ends a transmit session.
+     *
+     * Pairs with successful PDMINETWORKUP::pfnBeginXmit calls.
+     *
+     * @param   pInterface      Pointer to the interface structure containing the
+     *                          called function pointer.
+     *
+     * @thread  Any, but normally EMT or the XMIT thread.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnEndXmit,(PPDMINETWORKUP pInterface));
 
     /**
@@ -272,5 +306,5 @@
 } PDMINETWORKUP;
 /** PDMINETWORKUP interface ID. */
-#define PDMINETWORKUP_IID                       "3415a37c-4415-43e8-be18-26d9fd2c26a8"
+#define PDMINETWORKUP_IID                       "67e7e7a8-2594-4649-a1e3-7cee680c6083"
 
 
Index: trunk/include/VBox/uvm.h
===================================================================
--- trunk/include/VBox/uvm.h	(revision 28243)
+++ trunk/include/VBox/uvm.h	(revision 28258)
@@ -115,5 +115,5 @@
         struct PDMUSERPERVM     s;
 #endif
-        uint8_t                 padding[32];
+        uint8_t                 padding[64];
     } pdm;
 
