Ticket #1548: uart_buffer.patch
| File uart_buffer.patch, 4.8 KB (added by , 14 years ago) |
|---|
-
include/VBox/pdmifs.h
1456 1456 * @thread Any thread. 1457 1457 */ 1458 1458 DECLR3CALLBACKMEMBER(int, pfnNotifyStatusLinesChanged,(PPDMICHARPORT pInterface, uint32_t fNewStatusLines)); 1459 1460 /** 1461 * Notify the device when the driver buffer is full. 1462 * 1463 * @returns VBox status code. 1464 * @param pInterface Pointer to the interface structure containing the called function pointer. 1465 * @param fFull Buffer full. 1466 * @thread Any thread. 1467 */ 1468 DECLR3CALLBACKMEMBER(int, pfnNotifyBufferFull,(PPDMICHARPORT pInterface, bool fFull)); 1459 1469 1460 1470 /** 1461 1471 * Notify the device/driver that a break occurred. -
src/VBox/Devices/Serial/DevSerial.cpp
267 267 if (s->lcr & UART_LCR_DLAB) { 268 268 s->divider = (s->divider & 0xff00) | val; 269 269 serial_update_parameters(s); 270 } else {270 } else if (s->lsr & UART_LSR_THRE) { 271 271 s->thr_ipending = 0; 272 s->lsr &= ~UART_LSR_THRE;273 serial_update_irq(s);274 272 ch = val; 275 273 if (RT_LIKELY(s->pDrvChar)) 276 274 { … … 279 277 AssertRC(rc); 280 278 } 281 279 s->thr_ipending = 1; 282 s->lsr |= UART_LSR_THRE;283 s->lsr |= UART_LSR_TEMT;284 280 serial_update_irq(s); 285 } 281 } else 282 Log(("serial: THR not EMPTY!\n")); 286 283 break; 287 284 case 1: 288 285 if (s->lcr & UART_LCR_DLAB) { … … 501 498 return VINF_SUCCESS; 502 499 } 503 500 501 static DECLCALLBACK(int) serialNotifyBufferFull(PPDMICHARPORT pInterface, bool fFull) 502 { 503 SerialState *pThis = PDMICHARPORT_2_SERIALSTATE(pInterface); 504 PDMCritSectEnter(&pThis->CritSect, VERR_PERMISSION_DENIED); 505 if (fFull) 506 { 507 pThis->lsr &= ~UART_LSR_THRE; 508 } 509 else 510 { 511 pThis->thr_ipending = 1; 512 pThis->lsr |= UART_LSR_THRE; 513 pThis->lsr |= UART_LSR_TEMT; 514 } 515 serial_update_irq(pThis); 516 PDMCritSectLeave(&pThis->CritSect); 517 return VINF_SUCCESS; 518 } 519 504 520 static DECLCALLBACK(int) serialNotifyBreak(PPDMICHARPORT pInterface) 505 521 { 506 522 SerialState *pThis = PDMICHARPORT_2_SERIALSTATE(pInterface); … … 804 820 /* ICharPort */ 805 821 pThis->ICharPort.pfnNotifyRead = serialNotifyRead; 806 822 pThis->ICharPort.pfnNotifyStatusLinesChanged = serialNotifyStatusLinesChanged; 823 pThis->ICharPort.pfnNotifyBufferFull = serialNotifyBufferFull; 807 824 pThis->ICharPort.pfnNotifyBreak = serialNotifyBreak; 808 825 809 826 #ifdef VBOX_SERIAL_PCI -
src/VBox/Devices/Serial/DrvChar.cpp
71 71 uint8_t aSendQueue[CHAR_MAX_SEND_QUEUE]; 72 72 uint32_t volatile iSendQueueHead; 73 73 uint32_t iSendQueueTail; 74 uint32_t cEntries; 74 75 75 76 uintptr_t AlignmentPadding; 76 77 /** Read/write statistics */ … … 120 121 121 122 LogFlow(("%s: pvBuf=%#p cbWrite=%d\n", __FUNCTION__, pvBuf, cbWrite)); 122 123 123 for (uint32_t i=0; i<cbWrite;i++)124 for (uint32_t i=0; i<cbWrite; i++) 124 125 { 125 uint32_t idx = pThis->iSendQueueHead; 126 uint32_t iOld = pThis->iSendQueueHead; 127 uint32_t iNew = (iOld + 1) & CHAR_MAX_SEND_QUEUE_MASK; 126 128 127 pThis->aSendQueue[idx] = pBuffer[i]; 128 idx = (idx + 1) & CHAR_MAX_SEND_QUEUE_MASK; 129 pThis->aSendQueue[iOld] = pBuffer[i]; 129 130 130 131 STAM_COUNTER_INC(&pThis->StatBytesWritten); 131 ASMAtomicXchgU32(&pThis->iSendQueueHead, idx); 132 ASMAtomicXchgU32(&pThis->iSendQueueHead, iNew); 133 ASMAtomicIncU32(&pThis->cEntries); 134 if (pThis->cEntries > CHAR_MAX_SEND_QUEUE_MASK / 2) 135 pThis->pDrvCharPort->pfnNotifyBufferFull(pThis->pDrvCharPort, true); 132 136 } 133 137 RTSemEventSignal(pThis->SendSem); 134 138 return VINF_SUCCESS; … … 176 180 size_t cbProcessed = 1; 177 181 178 182 rc = pThis->pDrvStream->pfnWrite(pThis->pDrvStream, &pThis->aSendQueue[pThis->iSendQueueTail], &cbProcessed); 183 pThis->pDrvCharPort->pfnNotifyBufferFull(pThis->pDrvCharPort, false); 179 184 if (RT_SUCCESS(rc)) 180 185 { 181 186 Assert(cbProcessed); 182 187 pThis->iSendQueueTail++; 183 188 pThis->iSendQueueTail &= CHAR_MAX_SEND_QUEUE_MASK; 189 ASMAtomicDecU32(&pThis->cEntries); 184 190 } 185 191 else if (rc == VERR_TIMEOUT) 186 192 {

