Changeset 71956 in vbox for trunk/src/VBox
- Timestamp:
- Apr 22, 2018 11:50:09 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/serialport-posix.cpp
r71028 r71956 5 5 6 6 /* 7 * Copyright (C) 2017 Oracle Corporation7 * Copyright (C) 2017-2018 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 108 108 /** The current active config (we assume no one changes this behind our back). */ 109 109 struct termios PortCfg; 110 /** Flag whether a custom baud rate was chosen (for hosts supporting this.). */ 111 bool fBaudrateCust; 112 /** The custom baud rate. */ 113 uint32_t uBaudRateCust; 110 114 } RTSERIALPORTINTERNAL; 111 115 /** Pointer to the internal serial port state. */ … … 196 200 * could be found. 197 201 * @param uBaudRate The baud rate to convert. 198 */ 199 DECLINLINE(speed_t) rtSerialPortGetTermiosSpeedFromBaudrate(uint32_t uBaudRate) 200 { 202 * @param pfBaudrateCust Where to store the flag whether a custom baudrate was selected. 203 */ 204 DECLINLINE(speed_t) rtSerialPortGetTermiosSpeedFromBaudrate(uint32_t uBaudRate, bool *pfBaudrateCust) 205 { 206 *pfBaudrateCust = false; 207 201 208 for (unsigned i = 0; i < RT_ELEMENTS(s_rtSerialPortBaudrateConv); i++) 202 209 { … … 205 212 } 206 213 214 #ifdef RT_OS_LINUX 215 *pfBaudrateCust = true; 216 return B38400; 217 #else 207 218 return B0; 219 #endif 208 220 } 209 221 … … 217 229 static int rtSerialPortSetDefaultCfg(PRTSERIALPORTINTERNAL pThis) 218 230 { 231 pThis->fBaudrateCust = false; 232 pThis->uBaudRateCust = 0; 219 233 pThis->PortCfg.c_iflag = INPCK; /* Input parity checking. */ 220 234 cfsetispeed(&pThis->PortCfg, B9600); … … 275 289 * @param pCfg Pointer to the serial port config descriptor. 276 290 * @param pTermios Pointer to the termios structure to fill. 291 * @param pfBaudrateCust Where to store the flag whether a custom baudrate was selected. 277 292 * @param pErrInfo Additional error to be set when the conversion fails. 278 293 */ 279 static int rtSerialPortCfg2Termios(PRTSERIALPORTINTERNAL pThis, PCRTSERIALPORTCFG pCfg, struct termios *pTermios, PRTERRINFO pErrInfo) 294 static int rtSerialPortCfg2Termios(PRTSERIALPORTINTERNAL pThis, PCRTSERIALPORTCFG pCfg, struct termios *pTermios, 295 bool *pfBaudrateCust, PRTERRINFO pErrInfo) 280 296 { 281 297 RT_NOREF(pErrInfo); /** @todo Make use of the error info. */ 282 speed_t enmSpeed = rtSerialPortGetTermiosSpeedFromBaudrate(pCfg->uBaudRate );298 speed_t enmSpeed = rtSerialPortGetTermiosSpeedFromBaudrate(pCfg->uBaudRate, pfBaudrateCust); 283 299 if (enmSpeed != B0) 284 300 { … … 367 383 return VERR_SERIALPORT_INVALID_BAUDRATE; 368 384 369 #ifdef RT_OS_LINUX370 /** @todo Handle custom baudrates supported by Linux. */371 #endif372 373 385 return VINF_SUCCESS; 374 386 } … … 379 391 * 380 392 * @returns IPRT status code. 393 * @param pThis The internal serial port instance data. 381 394 * @param pTermios The termios structure to convert. 382 395 * @param pCfg The serial port config to fill in. 383 396 */ 384 static int rtSerialPortTermios2Cfg( struct termios *pTermios, PRTSERIALPORTCFG pCfg)397 static int rtSerialPortTermios2Cfg(PRTSERIALPORTINTERNAL pThis, struct termios *pTermios, PRTSERIALPORTCFG pCfg) 385 398 { 386 399 int rc = VINF_SUCCESS; … … 389 402 Assert(enmSpeedIn == cfgetospeed(pTermios)); /* Should always be the same. */ 390 403 391 pCfg->uBaudRate = rtSerialPortGetBaudrateFromTermiosSpeed(enmSpeedIn); 392 if (!pCfg->uBaudRate) 393 rc = VERR_SERIALPORT_INVALID_BAUDRATE; 404 if (!pThis->fBaudrateCust) 405 { 406 pCfg->uBaudRate = rtSerialPortGetBaudrateFromTermiosSpeed(enmSpeedIn); 407 if (!pCfg->uBaudRate) 408 rc = VERR_SERIALPORT_INVALID_BAUDRATE; 409 } 410 else 411 pCfg->uBaudRate = pThis->uBaudRateCust; 394 412 395 413 switch (pTermios->c_cflag & CSIZE) … … 937 955 AssertReturn(pThis->u32Magic == RTSERIALPORT_MAGIC, VERR_INVALID_HANDLE); 938 956 939 return rtSerialPortTermios2Cfg( &pThis->PortCfg, pCfg);957 return rtSerialPortTermios2Cfg(pThis, &pThis->PortCfg, pCfg); 940 958 } 941 959 … … 948 966 949 967 struct termios PortCfgNew; RT_ZERO(PortCfgNew); 950 int rc = rtSerialPortCfg2Termios(pThis, pCfg, &PortCfgNew, pErrInfo); 968 bool fBaudrateCust = false; 969 int rc = rtSerialPortCfg2Termios(pThis, pCfg, &PortCfgNew, &fBaudrateCust, pErrInfo); 951 970 if (RT_SUCCESS(rc)) 952 971 { … … 954 973 if (!rcPsx) 955 974 { 956 rcPsx = tcsetattr(pThis->iFd, TCSANOW, &PortCfgNew); 975 #ifdef RT_OS_LINUX 976 if (fBaudrateCust) 977 { 978 struct serial_struct SerLnx; 979 rcPsx = ioctl(pThis->iFd, TIOCGSERIAL, &SerLnx); 980 if (!rcPsx) 981 { 982 SerLnx.custom_divisor = SerLnx.baud_base / pCfg->uBaudRate; 983 if (!SerLnx.custom_divisor) 984 SerLnx.custom_divisor = 1; 985 SerLnx.flags &= ~ASYNC_SPD_MASK; 986 SerLnx.flags |= ASYNC_SPD_CUST; 987 rcPsx = ioctl(pThis->iFd, TIOCSSERIAL, &SerLnx); 988 } 989 } 990 #else /* !RT_OS_LINUX */ 991 /* Hosts not supporting custom baud rates should already fail in rtSerialPortCfg2Termios(). */ 992 AssertMsgFailed(("Should not get here!\n")); 993 #endif /* !RT_OS_LINUX */ 994 pThis->fBaudrateCust = fBaudrateCust; 995 pThis->uBaudRateCust = pCfg->uBaudRate; 996 997 if (!rcPsx) 998 rcPsx = tcsetattr(pThis->iFd, TCSANOW, &PortCfgNew); 957 999 if (rcPsx == -1) 958 1000 rc = RTErrConvertFromErrno(errno);
Note:
See TracChangeset
for help on using the changeset viewer.