Index: src/VBox/Devices/Serial/DrvHostSerial.cpp
===================================================================
--- src/VBox/Devices/Serial/DrvHostSerial.cpp	(revision 33444)
+++ src/VBox/Devices/Serial/DrvHostSerial.cpp	(working copy)
@@ -365,6 +365,16 @@
 
     tcsetattr(pThis->DeviceFile, TCSANOW, termiosSetup);
     RTMemTmpFree(termiosSetup);
+
+#ifdef RT_OS_LINUX
+    /* BUGBUG: In Linux 2.6.24 and earlier, if a thread calls tcsetattr while the monitor
+     * thread is waiting in ioctl for a modem status change then 8250.c wrongly disables
+     * modem irqs and so the monitor thread never gets released.  The workaround is to send
+     * a signal after each tcsetattr
+     */
+    RTThreadPoke(pThis->pMonitorThread->Thread);
+#endif
+
 #elif defined(RT_OS_WINDOWS)
     comSetup = (LPDCB)RTMemTmpAllocZ(sizeof(DCB));
 
@@ -961,69 +971,54 @@
 {
     PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
     int rc = VINF_SUCCESS;
-    unsigned uStatusLinesToCheck = 0;
+    unsigned long const uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS;
 
-    uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_LE | TIOCM_CTS;
-
     if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
         return VINF_SUCCESS;
 
-    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
+    do
     {
-        uint32_t newStatusLine = 0;
         unsigned int statusLines;
 
-# ifdef RT_OS_LINUX
-        /*
-         * Wait for status line change.
-         */
-        rc = ioctl(pThis->DeviceFile, TIOCMIWAIT, uStatusLinesToCheck);
-        if (pThread->enmState != PDMTHREADSTATE_RUNNING)
-            break;
-        if (rc < 0)
+        if ( 0 > (rc = ioctl( pThis->DeviceFile, TIOCMGET, &statusLines)))
         {
-ioctl_error:
             PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "DrvHostSerialFail",
                                        N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"),
                                        pThis->pszDevicePath, RTErrConvertFromErrno(errno));
             break;
         }
 
-        rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines);
-        if (rc < 0)
-            goto ioctl_error;
-# else  /* !RT_OS_LINUX */
-        /*
-         * Poll for the status line change.
-         */
-        rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines);
-        if (rc < 0)
-        {
-            PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "DrvHostSerialFail",
-                                       N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"),
-                                       pThis->pszDevicePath, RTErrConvertFromErrno(errno));
-            break;
-        }
-        if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck))
-        {
-            PDMR3ThreadSleep(pThread, 500); /* 0.5 sec */
-            continue;
-        }
-        pThis->fStatusLines = statusLines;
-# endif /* !RT_OS_LINUX */
-
+        uint32_t newStatusLine = 0;
         if (statusLines & TIOCM_CAR)
             newStatusLine |= PDMICHARPORT_STATUS_LINES_DCD;
         if (statusLines & TIOCM_RNG)
             newStatusLine |= PDMICHARPORT_STATUS_LINES_RI;
-        if (statusLines & TIOCM_LE)
+        if (statusLines & TIOCM_DSR)
             newStatusLine |= PDMICHARPORT_STATUS_LINES_DSR;
         if (statusLines & TIOCM_CTS)
             newStatusLine |= PDMICHARPORT_STATUS_LINES_CTS;
-        rc = pThis->pDrvCharPort->pfnNotifyStatusLinesChanged(pThis->pDrvCharPort, newStatusLine);
+        pThis->pDrvCharPort->pfnNotifyStatusLinesChanged(pThis->pDrvCharPort, newStatusLine);
+
+        if ( PDMTHREADSTATE_RUNNING != pThread->enmState)
+            break;
+# ifdef RT_OS_LINUX
+        /* Wait for status line change. */
+        /* BUGBUG: In Linux 2.6.24 and earlier, if a thread calls tcsetattr while the monitor
+         * thread is waiting in ioctl for a modem status change then 8250.c wrongly disables
+         * modem irqs and so the monitor thread never gets released.  The workaround is to send
+         * a signal after each tcsetattr
+         */
+        ioctl( pThis->DeviceFile, TIOCMIWAIT, uStatusLinesToCheck);
+# else
+        /* Poll for status line change. */
+        if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck))
+            PDMR3ThreadSleep( pThread, 500); /* 0.5 sec */
+        pThis->fStatusLines = statusLines;
+# endif
     }
+    while (PDMTHREADSTATE_RUNNING == pThread->enmState);
 
-    return VINF_SUCCESS;
+    return rc;
 }
 
 /**
