Changeset 73712 in vbox for trunk/src/VBox
- Timestamp:
- Aug 16, 2018 1:32:54 PM (6 years ago)
- Location:
- trunk/src/VBox/Devices/Serial
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DrvCharNew.cpp
r73331 r73712 59 59 /** Flag to notify the receive thread it should terminate. */ 60 60 volatile bool fShutdown; 61 /** Flag whether data is available from the device/driver above as notified by the driver. */ 62 volatile bool fAvailWrExt; 63 /** Internal copy of the flag which gets reset when there is no data anymore. */ 64 bool fAvailWrInt; 61 65 /** I/O thread. */ 62 66 PPDMTHREAD pThrdIo; 63 67 64 /** Amount of data available for sending from the device/driver above. */65 volatile size_t cbAvailWr;66 68 /** Small send buffer. */ 67 69 uint8_t abTxBuf[16]; … … 112 114 * @interface_method_impl{PDMISERIALCONNECTOR,pfnDataAvailWrNotify} 113 115 */ 114 static DECLCALLBACK(int) drvCharDataAvailWrNotify(PPDMISERIALCONNECTOR pInterface , size_t cbAvail)115 { 116 LogFlowFunc(("pInterface=%#p cbAvail=%zu\n", pInterface, cbAvail));116 static DECLCALLBACK(int) drvCharDataAvailWrNotify(PPDMISERIALCONNECTOR pInterface) 117 { 118 LogFlowFunc(("pInterface=%#p\n", pInterface)); 117 119 PDRVCHAR pThis = RT_FROM_MEMBER(pInterface, DRVCHAR, ISerialConnector); 118 120 119 121 int rc = VINF_SUCCESS; 120 size_t cbAvailOld = ASMAtomicAddZ(&pThis->cbAvailWr, cbAvail);121 if (! cbAvailOld)122 bool fAvailOld = ASMAtomicXchgBool(&pThis->fAvailWrExt, true); 123 if (!fAvailOld) 122 124 rc = pThis->pDrvStream->pfnPollInterrupt(pThis->pDrvStream); 123 125 … … 219 221 uint32_t fEvts = 0; 220 222 223 if (!pThis->fAvailWrInt) 224 pThis->fAvailWrInt = ASMAtomicXchgBool(&pThis->fAvailWrExt, false); 225 221 226 if ( !pThis->cbRemaining 222 227 && pThis->pDrvStream->pfnRead) 223 228 fEvts |= RTPOLL_EVT_READ; 224 if ( pThis-> cbAvailWr229 if ( pThis->fAvailWrInt 225 230 || pThis->cbTxUsed) 226 231 fEvts |= RTPOLL_EVT_WRITE; … … 232 237 if (fEvtsRecv & RTPOLL_EVT_WRITE) 233 238 { 234 if (pThis-> cbAvailWr)239 if (pThis->fAvailWrInt) 235 240 { 236 241 /* Stuff as much data into the TX buffer as we can. */ 237 size_t cbToFetch = RT_ MIN(RT_ELEMENTS(pThis->abTxBuf) - pThis->cbTxUsed, pThis->cbAvailWr);242 size_t cbToFetch = RT_ELEMENTS(pThis->abTxBuf) - pThis->cbTxUsed; 238 243 size_t cbFetched = 0; 239 244 rc = pThis->pDrvSerialPort->pfnReadWr(pThis->pDrvSerialPort, &pThis->abTxBuf[pThis->cbTxUsed], cbToFetch, … … 242 247 243 248 if (cbFetched > 0) 244 {245 ASMAtomicSubZ(&pThis->cbAvailWr, cbFetched);246 249 pThis->cbTxUsed += cbFetched; 247 }248 250 else 249 251 { 250 /* The guest reset the send queue and there is no data available anymore. */251 pThis-> cbAvailWr = 0;252 /* There is no data available anymore. */ 253 pThis->fAvailWrInt = false; 252 254 } 253 255 } … … 331 333 332 334 /* Reset TX and RX buffers. */ 333 pThis->cbAvailWr = 0; 335 pThis->fAvailWrExt = false; 336 pThis->fAvailWrInt = false; 334 337 pThis->cbTxUsed = 0; 335 338 pThis->cbRemaining = 0; -
trunk/src/VBox/Devices/Serial/DrvHostSerialNew.cpp
r73331 r73712 63 63 char *pszDevicePath; 64 64 65 /** Amount of data available for sending from the device/driver above. */ 66 volatile size_t cbAvailWr; 65 /** Flag whether data is available from the device/driver above as notified by the driver. */ 66 volatile bool fAvailWrExt; 67 /** Internal copy of the flag which gets reset when there is no data anymore. */ 68 bool fAvailWrInt; 67 69 /** Small send buffer. */ 68 70 uint8_t abTxBuf[16]; … … 187 189 188 190 /** @interface_method_impl{PDMISERIALCONNECTOR,pfnDataAvailWrNotify} */ 189 static DECLCALLBACK(int) drvHostSerialDataAvailWrNotify(PPDMISERIALCONNECTOR pInterface , size_t cbAvail)191 static DECLCALLBACK(int) drvHostSerialDataAvailWrNotify(PPDMISERIALCONNECTOR pInterface) 190 192 { 191 193 PDRVHOSTSERIAL pThis = RT_FROM_MEMBER(pInterface, DRVHOSTSERIAL, ISerialConnector); 192 194 193 195 int rc = VINF_SUCCESS; 194 size_t cbAvailOld = ASMAtomicAddZ(&pThis->cbAvailWr, cbAvail);195 if (! cbAvailOld)196 bool fAvailOld = ASMAtomicXchgBool(&pThis->fAvailWrExt, true); 197 if (!fAvailOld) 196 198 rc = RTSerialPortEvtPollInterrupt(pThis->hSerialPort); 197 199 … … 376 378 uint32_t fEvtFlags = RTSERIALPORT_EVT_F_STATUS_LINE_CHANGED | RTSERIALPORT_EVT_F_BREAK_DETECTED; 377 379 380 if (!pThis->fAvailWrInt) 381 pThis->fAvailWrInt = ASMAtomicXchgBool(&pThis->fAvailWrExt, false); 382 378 383 /* Wait until there is room again if there is anyting to send. */ 379 if ( pThis-> cbAvailWr384 if ( pThis->fAvailWrInt 380 385 || pThis->cbTxUsed) 381 386 fEvtFlags |= RTSERIALPORT_EVT_F_DATA_TX; … … 391 396 if (fEvtsRecv & RTSERIALPORT_EVT_F_DATA_TX) 392 397 { 393 if (pThis-> cbAvailWr)398 if (pThis->fAvailWrInt) 394 399 { 395 400 /* Stuff as much data into the TX buffer as we can. */ 396 size_t cbToFetch = RT_ MIN(RT_ELEMENTS(pThis->abTxBuf) - pThis->cbTxUsed, pThis->cbAvailWr);401 size_t cbToFetch = RT_ELEMENTS(pThis->abTxBuf) - pThis->cbTxUsed; 397 402 size_t cbFetched = 0; 398 403 rc = pThis->pDrvSerialPort->pfnReadWr(pThis->pDrvSerialPort, &pThis->abTxBuf[pThis->cbTxUsed], cbToFetch, … … 401 406 402 407 if (cbFetched > 0) 403 { 404 ASMAtomicSubZ(&pThis->cbAvailWr, cbFetched); 405 pThis->cbTxUsed += cbFetched; 406 } 408 pThis->cbTxUsed += cbFetched; 407 409 else 408 410 { 409 /* The guest reset the send queue and there is no data available anymore. */410 pThis-> cbAvailWr = 0;411 /* There is no data available anymore. */ 412 pThis->fAvailWrInt = false; 411 413 } 412 414 } … … 565 567 pThis->pDrvIns = pDrvIns; 566 568 pThis->hSerialPort = NIL_RTSERIALPORT; 567 pThis->cbAvailWr = 0; 569 pThis->fAvailWrExt = false; 570 pThis->fAvailWrInt = false; 568 571 pThis->cbTxUsed = 0; 569 572 pThis->offWrite = 0; -
trunk/src/VBox/Devices/Serial/UartCore.cpp
r73636 r73712 70 70 # define UART_REG_IIR_ID_SET(a_Val) (((a_Val) << 1) & UART_REG_IIR_ID_MASK) 71 71 /** Gets the interrupt identification from the given IIR register value. */ 72 # define UART_REG_IIR_ID_GET(a_Val) (((a_Val) >> 1) & UART_REG_IIR_ID_MASK)72 # define UART_REG_IIR_ID_GET(a_Val) (((a_Val) & UART_REG_IIR_ID_MASK) >> 1) 73 73 /** Receiver Line Status interrupt. */ 74 74 # define UART_REG_IIR_ID_RCL 0x3 … … 337 337 338 338 339 /** 340 * Returns the amount of bytes stored in the given FIFO. 341 * 342 * @retrusn Amount of bytes stored in the FIFO. 343 * @param pFifo The FIFO. 344 */ 345 DECLINLINE(size_t) uartFifoUsedGet(PUARTFIFO pFifo) 346 { 347 return pFifo->cbUsed; 348 } 349 350 351 /** 352 * Puts a new character into the given FIFO. 353 * 354 * @returns Flag whether the FIFO overflowed. 355 * @param pFifo The FIFO to put the data into. 356 * @param fOvrWr Flag whether to overwrite data if the FIFO is full. 357 * @param bData The data to add. 358 */ 359 DECLINLINE(bool) uartFifoPut(PUARTFIFO pFifo, bool fOvrWr, uint8_t bData) 360 { 361 if (fOvrWr || pFifo->cbUsed < pFifo->cbMax) 362 { 363 pFifo->abBuf[pFifo->offWrite] = bData; 364 pFifo->offWrite = (pFifo->offWrite + 1) % pFifo->cbMax; 365 } 366 367 bool fOverFlow = false; 368 if (pFifo->cbUsed < pFifo->cbMax) 369 pFifo->cbUsed++; 370 else 371 { 372 fOverFlow = true; 373 if (fOvrWr) /* Advance the read position to account for the lost character. */ 374 pFifo->offRead = (pFifo->offRead + 1) % pFifo->cbMax; 375 } 376 377 return fOverFlow; 378 } 379 380 381 /** 382 * Returns the next character in the FIFO. 383 * 384 * @return Next byte in the FIFO. 385 * @param pFifo The FIFO to get data from. 386 */ 387 DECLINLINE(uint8_t) uartFifoGet(PUARTFIFO pFifo) 388 { 389 uint8_t bRet = 0; 390 391 if (pFifo->cbUsed) 392 { 393 bRet = pFifo->abBuf[pFifo->offRead]; 394 pFifo->offRead = (pFifo->offRead + 1) % pFifo->cbMax; 395 pFifo->cbUsed--; 396 } 397 398 return bRet; 399 } 400 401 339 402 #ifdef IN_RING3 340 403 /** … … 365 428 366 429 367 /**368 * Puts a new character into the given FIFO.369 *370 * @returns Flag whether the FIFO overflowed.371 * @param pFifo The FIFO to put the data into.372 * @param fOvrWr Flag whether to overwrite data if the FIFO is full.373 * @param bData The data to add.374 */375 DECLINLINE(bool) uartFifoPut(PUARTFIFO pFifo, bool fOvrWr, uint8_t bData)376 {377 if (fOvrWr || pFifo->cbUsed < pFifo->cbMax)378 {379 pFifo->abBuf[pFifo->offWrite] = bData;380 pFifo->offWrite = (pFifo->offWrite + 1) % pFifo->cbMax;381 }382 383 bool fOverFlow = false;384 if (pFifo->cbUsed < pFifo->cbMax)385 pFifo->cbUsed++;386 else387 {388 fOverFlow = true;389 if (fOvrWr) /* Advance the read position to account for the lost character. */390 pFifo->offRead = (pFifo->offRead + 1) % pFifo->cbMax;391 }392 393 return fOverFlow;394 }395 #endif396 397 398 /**399 * Returns the next character in the FIFO.400 *401 * @return Next byte in the FIFO.402 * @param pFifo The FIFO to get data from.403 */404 DECLINLINE(uint8_t) uartFifoGet(PUARTFIFO pFifo)405 {406 uint8_t bRet = 0;407 408 if (pFifo->cbUsed)409 {410 bRet = pFifo->abBuf[pFifo->offRead];411 pFifo->offRead = (pFifo->offRead + 1) % pFifo->cbMax;412 pFifo->cbUsed--;413 }414 415 return bRet;416 }417 418 419 #ifdef IN_RING3420 430 /** 421 431 * Tries to copy the requested amount of data from the given FIFO into the provided buffer. … … 748 758 { 749 759 #ifndef IN_RING3 750 rc = VINF_IOM_R3_IOPORT_WRITE; 760 if (!uartFifoUsedGet(&pThis->FifoXmit)) 761 rc = VINF_IOM_R3_IOPORT_WRITE; 762 else 763 { 764 uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, uVal); 765 UART_REG_CLR(pThis->uRegLsr, UART_REG_LSR_THRE | UART_REG_LSR_TEMT); 766 } 751 767 #else 752 768 uartFifoPut(&pThis->FifoXmit, true /*fOvrWr*/, uVal); … … 754 770 pThis->fThreEmptyPending = false; 755 771 uartIrqUpdate(pThis); 756 if (pThis->pDrvSerial) 772 if ( pThis->pDrvSerial 773 && uartFifoUsedGet(&pThis->FifoXmit) == 1) 757 774 { 758 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial , 1);775 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial); 759 776 if (RT_FAILURE(rc2)) 760 777 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); … … 776 793 if (pThis->pDrvSerial) 777 794 { 778 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial , 1);795 int rc2 = pThis->pDrvSerial->pfnDataAvailWrNotify(pThis->pDrvSerial); 779 796 if (RT_FAILURE(rc2)) 780 797 LogRelMax(10, ("Serial#%d: Failed to send data with %Rrc\n", pThis->pDevInsR3->iInstance, rc2)); … … 821 838 else 822 839 pThis->uRegIer = uVal & UART_REG_IER_MASK_WR_16750; 840 841 if (pThis->uRegLsr & UART_REG_LSR_THRE) 842 pThis->fThreEmptyPending = true; 843 823 844 uartIrqUpdate(pThis); 824 845 } … … 1657 1678 pThis->uRegScr = 0; 1658 1679 pThis->fIrqCtiPending = false; 1659 pThis->fThreEmptyPending = false;1680 pThis->fThreEmptyPending = true; 1660 1681 1661 1682 /* Standard FIFO size for 15550A. */
Note:
See TracChangeset
for help on using the changeset viewer.