Ticket #812: serhsk.diff
| File serhsk.diff, 4.5 KB (added by , 14 years ago) |
|---|
-
src/VBox/Devices/Serial/DrvHostSerial.cpp
365 365 366 366 tcsetattr(pThis->DeviceFile, TCSANOW, termiosSetup); 367 367 RTMemTmpFree(termiosSetup); 368 369 #ifdef RT_OS_LINUX 370 /* BUGBUG: In Linux 2.6.24 and earlier, if a thread calls tcsetattr while the monitor 371 * thread is waiting in ioctl for a modem status change then 8250.c wrongly disables 372 * modem irqs and so the monitor thread never gets released. The workaround is to send 373 * a signal after each tcsetattr 374 */ 375 RTThreadPoke(pThis->pMonitorThread->Thread); 376 #endif 377 368 378 #elif defined(RT_OS_WINDOWS) 369 379 comSetup = (LPDCB)RTMemTmpAllocZ(sizeof(DCB)); 370 380 … … 961 971 { 962 972 PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL); 963 973 int rc = VINF_SUCCESS; 964 unsigned uStatusLinesToCheck = 0;974 unsigned long const uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS; 965 975 966 uStatusLinesToCheck = TIOCM_CAR | TIOCM_RNG | TIOCM_LE | TIOCM_CTS;967 968 976 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 969 977 return VINF_SUCCESS; 970 978 971 while (pThread->enmState == PDMTHREADSTATE_RUNNING)979 do 972 980 { 973 uint32_t newStatusLine = 0;974 981 unsigned int statusLines; 975 982 976 # ifdef RT_OS_LINUX 977 /* 978 * Wait for status line change. 979 */ 980 rc = ioctl(pThis->DeviceFile, TIOCMIWAIT, uStatusLinesToCheck); 981 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 982 break; 983 if (rc < 0) 983 if ( 0 > (rc = ioctl( pThis->DeviceFile, TIOCMGET, &statusLines))) 984 984 { 985 ioctl_error:986 985 PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "DrvHostSerialFail", 987 986 N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"), 988 987 pThis->pszDevicePath, RTErrConvertFromErrno(errno)); 989 988 break; 990 989 } 991 990 992 rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines); 993 if (rc < 0) 994 goto ioctl_error; 995 # else /* !RT_OS_LINUX */ 996 /* 997 * Poll for the status line change. 998 */ 999 rc = ioctl(pThis->DeviceFile, TIOCMGET, &statusLines); 1000 if (rc < 0) 1001 { 1002 PDMDrvHlpVMSetRuntimeError(pDrvIns, 0 /*fFlags*/, "DrvHostSerialFail", 1003 N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"), 1004 pThis->pszDevicePath, RTErrConvertFromErrno(errno)); 1005 break; 1006 } 1007 if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck)) 1008 { 1009 PDMR3ThreadSleep(pThread, 500); /* 0.5 sec */ 1010 continue; 1011 } 1012 pThis->fStatusLines = statusLines; 1013 # endif /* !RT_OS_LINUX */ 1014 991 uint32_t newStatusLine = 0; 1015 992 if (statusLines & TIOCM_CAR) 1016 993 newStatusLine |= PDMICHARPORT_STATUS_LINES_DCD; 1017 994 if (statusLines & TIOCM_RNG) 1018 995 newStatusLine |= PDMICHARPORT_STATUS_LINES_RI; 1019 if (statusLines & TIOCM_ LE)996 if (statusLines & TIOCM_DSR) 1020 997 newStatusLine |= PDMICHARPORT_STATUS_LINES_DSR; 1021 998 if (statusLines & TIOCM_CTS) 1022 999 newStatusLine |= PDMICHARPORT_STATUS_LINES_CTS; 1023 rc = pThis->pDrvCharPort->pfnNotifyStatusLinesChanged(pThis->pDrvCharPort, newStatusLine); 1000 pThis->pDrvCharPort->pfnNotifyStatusLinesChanged(pThis->pDrvCharPort, newStatusLine); 1001 1002 if ( PDMTHREADSTATE_RUNNING != pThread->enmState) 1003 break; 1004 # ifdef RT_OS_LINUX 1005 /* Wait for status line change. */ 1006 /* BUGBUG: In Linux 2.6.24 and earlier, if a thread calls tcsetattr while the monitor 1007 * thread is waiting in ioctl for a modem status change then 8250.c wrongly disables 1008 * modem irqs and so the monitor thread never gets released. The workaround is to send 1009 * a signal after each tcsetattr 1010 */ 1011 ioctl( pThis->DeviceFile, TIOCMIWAIT, uStatusLinesToCheck); 1012 # else 1013 /* Poll for status line change. */ 1014 if (!((statusLines ^ pThis->fStatusLines) & uStatusLinesToCheck)) 1015 PDMR3ThreadSleep( pThread, 500); /* 0.5 sec */ 1016 pThis->fStatusLines = statusLines; 1017 # endif 1024 1018 } 1019 while (PDMTHREADSTATE_RUNNING == pThread->enmState); 1025 1020 1026 return VINF_SUCCESS;1021 return rc; 1027 1022 } 1028 1023 1029 1024 /**

