244
244
static DECLCALLBACK(int) drvHostSerialSetParameters(PPDMICHAR pInterface, unsigned Bps, char chParity, unsigned cDataBits, unsigned cStopBits)
246
246
PDRVHOSTSERIAL pThis = PDMICHAR_2_DRVHOSTSERIAL(pInterface);
247
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
247
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
248
248
struct termios *termiosSetup;
250
250
#elif defined(RT_OS_WINDOWS)
518
518
uint64_t volatile u64Now = RTTimeNanoTS(); NOREF(u64Now);
520
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
520
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
522
522
size_t cbWritten;
523
523
rc = RTFileWrite(pThis->DeviceFile, abBuf, cb, &cbWritten);
598
598
uint8_t abBuf[1];
599
599
abBuf[0] = pThis->aSendQueue[iTail];
601
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
601
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
603
603
rc = RTFileWrite(pThis->DeviceFile, abBuf, cbProcessed, NULL);
849
849
cbRemaining = dwNumberOfBytesTransferred;
851
else if (dwEventMask & EV_BREAK)
853
Log(("HostSerial#%d: Detected break\n"));
854
rc = pThis->pDrvCharPort->pfnNotifyBreak(pThis->pDrvCharPort);
853
858
/* The status lines have changed. Notify the device. */
923
928
static DECLCALLBACK(int) drvHostSerialWakeupRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
925
930
PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
926
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
931
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
927
932
return RTFileWrite(pThis->WakeupPipeW, "", 1, NULL);
928
933
#elif defined(RT_OS_WINDOWS)
929
934
if (!SetEvent(pThis->hHaltEventSem))
1173
1178
return VINF_SUCCESS;
1182
* Sets the TD line into break condition.
1184
* @returns VBox status code.
1185
* @param pInterface Pointer to the interface structure containing the called function pointer.
1186
* @param fBreak Set to true to let the device send a break false to put into normal operation.
1187
* @thread Any thread.
1189
static DECLCALLBACK(int) drvHostSerialSetBreak(PPDMICHAR pInterface, bool fBreak)
1191
PDRVHOSTSERIAL pThis = PDMICHAR_2_DRVHOSTSERIAL(pInterface);
1193
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
1195
ioctl(pThis->DeviceFile, TIOCSBRK);
1197
ioctl(pThis->DeviceFile, TIOCCBRK);
1199
#elif defined(RT_OS_WINDOWS)
1201
SetCommBreak(pThis->hDeviceFile);
1203
ClearCommBreak(pThis->hDeviceFile);
1206
return VINF_SUCCESS;
1176
1209
/* -=-=-=-=- driver interface -=-=-=-=- */
1179
1212
* Construct a char driver instance.
1181
* @returns VBox status.
1182
* @param pDrvIns The driver instance data.
1183
* If the registration structure is needed,
1184
* pDrvIns->pDrvReg points to it.
1185
* @param pCfgHandle Configuration node handle for the driver. Use this to
1186
* obtain the configuration of the driver instance. It's
1187
* also found in pDrvIns->pCfgHandle as it's expected to
1188
* be used frequently in this function.
1214
* @copydoc FNPDMDRVCONSTRUCT
1190
static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
1216
static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
1192
1218
PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
1193
1219
LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
1196
1222
* Init basic data members and interfaces.
1198
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
1224
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
1199
1225
pThis->DeviceFile = NIL_RTFILE;
1200
1226
# ifdef RT_OS_DARWIN
1201
1227
pThis->DeviceFileR = NIL_RTFILE;
1204
1230
pThis->WakeupPipeW = NIL_RTFILE;
1207
pDrvIns->IBase.pfnQueryInterface = drvHostSerialQueryInterface;
1233
pDrvIns->IBase.pfnQueryInterface = drvHostSerialQueryInterface;
1209
pThis->IChar.pfnWrite = drvHostSerialWrite;
1210
pThis->IChar.pfnSetParameters = drvHostSerialSetParameters;
1211
pThis->IChar.pfnSetModemLines = drvHostSerialSetModemLines;
1235
pThis->IChar.pfnWrite = drvHostSerialWrite;
1236
pThis->IChar.pfnSetParameters = drvHostSerialSetParameters;
1237
pThis->IChar.pfnSetModemLines = drvHostSerialSetModemLines;
1238
pThis->IChar.pfnSetBreak = drvHostSerialSetBreak;
1213
1240
/** @todo Initialize all members with NIL values!! The destructor is ALWAYS called. */
1263
rc = RTFileOpen(&pThis->DeviceFile, pThis->pszDevicePath, RTFILE_O_OPEN | RTFILE_O_READWRITE);
1290
rc = RTFileOpen(&pThis->DeviceFile, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
1264
1291
# ifdef RT_OS_DARWIN
1265
1292
if (RT_SUCCESS(rc))
1266
rc = RTFileOpen(&pThis->DeviceFileR, pThis->pszDevicePath, RTFILE_O_OPEN | RTFILE_O_READ);
1293
rc = RTFileOpen(&pThis->DeviceFileR, pThis->pszDevicePath, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
1277
1304
case VERR_ACCESS_DENIED:
1278
1305
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
1279
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
1306
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
1280
1307
N_("Cannot open host device '%s' for read/write access. Check the permissions "
1281
1308
"of that device ('/bin/ls -l %s'): Most probably you need to be member "
1282
1309
"of the device group. Make sure that you logout/login after changing "
1296
1323
/* Set to non blocking I/O */
1297
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
1324
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
1299
1326
fcntl(pThis->DeviceFile, F_SETFL, O_NONBLOCK);
1300
1327
# ifdef RT_OS_DARWIN
1346
1373
if (RT_FAILURE(rc))
1347
1374
return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("HostSerial#%d cannot create send thread"), pDrvIns->iInstance);
1349
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
1376
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
1350
1377
/* Linux & darwin needs a separate thread which monitors the status lines. */
1351
1378
# ifndef RT_OS_LINUX
1352
1379
ioctl(pThis->DeviceFile, TIOCMGET, &pThis->fStatusLines);
1389
1416
RTSemEventDestroy(pThis->SendSem);
1390
1417
pThis->SendSem = NIL_RTSEMEVENT;
1392
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
1419
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
1394
1421
if (pThis->WakeupPipeW != NIL_RTFILE)