--- DrvHostSerial_orig.cpp	2008-11-26 18:57:06.000000000 +0100
+++ DrvHostSerial.cpp	2008-11-27 18:35:24.000000000 +0100
@@ -356,6 +356,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));
 
@@ -943,69 +953,53 @@
 {
     PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
     int rc = VINF_SUCCESS;
-    unsigned uStatusLinesToCheck = 0;
-
-    uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_LE | TIOCM_CTS;
+    unsigned long const uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS;
 
-    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
+    if ( PDMTHREADSTATE_INITIALIZING == pThread->enmState)
         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)
-        {
-ioctl_error:
-            PDMDrvHlpVMSetRuntimeError(pDrvIns, false, "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)
+        if ( 0 > (rc = ioctl( pThis->DeviceFile, TIOCMGET, &statusLines)))
         {
             PDMDrvHlpVMSetRuntimeError(pDrvIns, false, "DrvHostSerialFail",
                                        N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"),
-                                       pThis->pszDevicePath, RTErrConvertFromErrno(errno));
+                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 |= PDM_ICHAR_STATUS_LINES_DCD;
         if (statusLines & TIOCM_RNG)
             newStatusLine |= PDM_ICHAR_STATUS_LINES_RI;
-        if (statusLines & TIOCM_LE)
+        if ( statusLines & TIOCM_DSR)
             newStatusLine |= PDM_ICHAR_STATUS_LINES_DSR;
         if (statusLines & TIOCM_CTS)
             newStatusLine |= PDM_ICHAR_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;
 }
 
 /**
