Index: trunk/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp
===================================================================
--- trunk/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp	(revision 53428)
+++ trunk/src/VBox/Devices/USB/freebsd/USBProxyDevice-freebsd.cpp	(revision 53429)
@@ -53,4 +53,5 @@
 #include <iprt/string.h>
 #include <iprt/file.h>
+#include <iprt/pipe.h>
 #include "../USBProxyDevice.h"
 
@@ -96,10 +97,14 @@
     /** The open file. */
     RTFILE                 hFile;
-    /** Software endpoint structures */
-    USBENDPOINTFBSD        aSwEndpoint[USBFBSD_MAXENDPOINTS];
     /** Flag whether an URB is cancelling. */
     bool                   fCancelling;
     /** Flag whether initialised or not */
     bool                   fInit;
+    /** Pipe handle for waking up - writing end. */
+    RTPIPE                 hPipeWakeupW;
+    /** Pipe handle for waking up - reading end. */
+    RTPIPE                 hPipeWakeupR;
+    /** Software endpoint structures */
+    USBENDPOINTFBSD        aSwEndpoint[USBFBSD_MAXENDPOINTS];
     /** Kernel endpoint structures */
     struct usb_fs_endpoint aHwEndpoint[USBFBSD_MAXENDPOINTS];
@@ -384,8 +389,15 @@
         if (RT_SUCCESS(rc))
         {
-            LogFlow(("usbProxyFreeBSDOpen(%p, %s): returns successfully hFile=%RTfile iActiveCfg=%d\n",
-                     pProxyDev, pszAddress, pDevFBSD->hFile, pProxyDev->iActiveCfg));
-
-            return VINF_SUCCESS;
+            /*
+             * Create wakeup pipe.
+             */
+            rc = RTPipeCreate(&pDevFBSD->hPipeWakeupR, &pDevFBSD->hPipeWakeupW, 0);
+            if (RT_SUCCESS(rc))
+            {
+                LogFlow(("usbProxyFreeBSDOpen(%p, %s): returns successfully hFile=%RTfile iActiveCfg=%d\n",
+                         pProxyDev, pszAddress, pDevFBSD->hFile, pProxyDev->iActiveCfg));
+
+                return VINF_SUCCESS;
+            }
         }
 
@@ -450,9 +462,9 @@
     usbProxyFreeBSDFsUnInit(pProxyDev);
 
+    RTPipeClose(pDevFBSD->hPipeWakeupR);
+    RTPipeClose(pDevFBSD->hPipeWakeupW);
+
     RTFileClose(pDevFBSD->hFile);
     pDevFBSD->hFile = NIL_RTFILE;
-
-    RTMemFree(pDevFBSD);
-    pProxyDev->Backend.pv = NULL;
 
     LogFlow(("usbProxyFreeBSDClose: returns\n"));
@@ -689,7 +701,8 @@
 
     ep_num = pUrb->EndPt;
-
-    if ((pUrb->enmType != VUSBXFERTYPE_MSG) && (pUrb->enmDir == VUSBDIRECTION_IN))
+    if ((pUrb->enmType != VUSBXFERTYPE_MSG) && (pUrb->enmDir == VUSBDIRECTION_IN)) {
+        /* set IN-direction bit */
         ep_num |= 0x80;
+    }
 
     index = 0;
@@ -823,5 +836,5 @@
     PVUSBURB pUrb;
     struct usb_fs_complete UsbFsComplete;
-    struct pollfd PollFd;
+    struct pollfd pfd[2];
     int rc;
 
@@ -947,21 +960,36 @@
 
     }
-    else if (cMillies && rc == VERR_RESOURCE_BUSY)
-    {
-        /* Poll for finished transfers */
-        PollFd.fd = RTFileToNative(pDevFBSD->hFile);
-        PollFd.events = POLLIN | POLLRDNORM;
-        PollFd.revents = 0;
-
-        rc = poll(&PollFd, 1, (cMillies == RT_INDEFINITE_WAIT) ? INFTIM : cMillies);
-        if (rc >= 1)
-        {
-            goto repeat;
-        }
-        else
-        {
-            LogFlow(("usbProxyFreeBSDUrbReap: "
-                     "poll returned rc=%d\n", rc));
-        }
+    else if (cMillies != 0 && rc == VERR_RESOURCE_BUSY)
+    {
+        for (;;)
+        {
+            pfd[0].fd = RTFileToNative(pDevFBSD->hFile);
+            pfd[0].events = POLLIN | POLLRDNORM;
+            pfd[0].revents = 0;
+
+            pfd[1].fd = RTPipeToNative(pDevFBSD->hPipeWakeupR);
+            pfd[1].events = POLLIN | POLLRDNORM;
+            pfd[1].revents = 0;
+
+            rc = poll(pfd, 2, (cMillies == RT_INDEFINITE_WAIT) ? INFTIM : cMillies);
+            if (rc > 0)
+            {
+                if (pfd[1].revents & POLLIN)
+                {
+                    /* Got woken up, drain pipe. */
+                    uint8_t bRead;
+                    size_t cbIgnored = 0;
+                    RTPipeRead(pDevFBSD->hPipeWakeupR, &bRead, 1, &cbIgnored);
+                    /* Make sure we return from this function */
+                    cMillies = 0;
+                }
+                break;
+            }
+            if (rc == 0)
+                return NULL;
+            if (errno != EAGAIN)
+                return NULL;
+        }
+        goto repeat;
     }
     return pUrb;
@@ -983,4 +1011,14 @@
     LogFlow(("usbProxyFreeBSDUrbCancel: epindex=%u\n", (unsigned)index));
     return usbProxyFreeBSDEndpointClose(pProxyDev, index);
+}
+
+static DECLCALLBACK(int) usbProxyFreeBSDWakeup(PUSBPROXYDEV pProxyDev)
+{
+    PUSBPROXYDEVFBSD pDevFBSD = USBPROXYDEV_2_DATA(pProxyDev, PUSBPROXYDEVFBSD);
+    size_t cbIgnored;
+
+    LogFlowFunc(("pProxyDev=%p\n", pProxyDev));
+
+    return RTPipeWrite(pDevFBSD->hPipeWakeupW, "", 1, &cbIgnored);
 }
 
@@ -993,5 +1031,5 @@
     "host",
     /* cbBackend */
-    sizeof(PUSBPROXYDEVFBSD),
+    sizeof(USBPROXYDEVFBSD),
     usbProxyFreeBSDOpen,
     usbProxyFreeBSDInit,
@@ -1006,4 +1044,5 @@
     usbProxyFreeBSDUrbCancel,
     usbProxyFreeBSDUrbReap,
+    usbProxyFreeBSDWakeup,
     0
 };
