diff options
Diffstat (limited to 'src/VBox/Devices/Serial/DevSerial.cpp')
-rw-r--r-- | src/VBox/Devices/Serial/DevSerial.cpp | 79 |
1 files changed, 41 insertions, 38 deletions
diff --git a/src/VBox/Devices/Serial/DevSerial.cpp b/src/VBox/Devices/Serial/DevSerial.cpp index 5f577f740..d9fa695e3 100644 --- a/src/VBox/Devices/Serial/DevSerial.cpp +++ b/src/VBox/Devices/Serial/DevSerial.cpp @@ -1,4 +1,4 @@ -/* $Id: DevSerial.cpp $ */ +/* $Id: DevSerial.cpp 37466 2011-06-15 12:44:16Z vboxsync $ */ /** @file * DevSerial - 16550A UART emulation. * (taken from hw/serial.c 2010/05/15 with modifications) @@ -277,7 +277,7 @@ static int fifo_put(SerialState *s, int fifo, uint8_t chr) if (f->count < UART_FIFO_LENGTH) f->count++; else if (fifo == XMIT_FIFO) /* need to at least adjust tail to maintain pipe state consistency */ - ++f->tail; + ++f->tail; else if (fifo == RECV_FIFO) s->lsr |= UART_LSR_OE; @@ -826,14 +826,13 @@ static DECLCALLBACK(int) serialNotifyBreak(PPDMICHARPORT pInterface) */ static DECLCALLBACK(void) serialFifoTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) { - SerialState *s = (SerialState*)pvUser; - PDMCritSectEnter(&s->CritSect, VERR_PERMISSION_DENIED); - if (s->recv_fifo.count) + SerialState *pThis = (SerialState *)pvUser; + Assert(PDMCritSectIsOwner(&pThis->CritSect)); + if (pThis->recv_fifo.count) { - s->timeout_ipending = 1; - serial_update_irq(s); + pThis->timeout_ipending = 1; + serial_update_irq(pThis); } - PDMCritSectLeave(&s->CritSect); } /** @@ -846,10 +845,9 @@ static DECLCALLBACK(void) serialFifoTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, v */ static DECLCALLBACK(void) serialTransmitTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) { - SerialState *s = (SerialState*)pvUser; - PDMCritSectEnter(&s->CritSect, VERR_PERMISSION_DENIED); - serial_xmit(s, true); - PDMCritSectLeave(&s->CritSect); + SerialState *pThis = (SerialState *)pvUser; + Assert(PDMCritSectIsOwner(&pThis->CritSect)); + serial_xmit(pThis, true); } /** @@ -905,20 +903,19 @@ PDMBOTHCBDECL(int) serialIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb) { SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *); - int rc = VINF_SUCCESS; + int rc; + Assert(PDMCritSectIsOwner(&pThis->CritSect)); if (cb == 1) { - rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_WRITE); - if (rc == VINF_SUCCESS) - { - Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, u32)); - rc = serial_ioport_write(pThis, Port, u32); - PDMCritSectLeave(&pThis->CritSect); - } + Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, u32)); + rc = serial_ioport_write(pThis, Port, u32); } else + { AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32)); + rc = VINF_SUCCESS; + } return rc; } @@ -938,17 +935,13 @@ PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb) { SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *); - int rc = VINF_SUCCESS; + int rc; + Assert(PDMCritSectIsOwner(&pThis->CritSect)); if (cb == 1) { - rc = PDMCritSectEnter(&pThis->CritSect, VINF_IOM_HC_IOPORT_READ); - if (rc == VINF_SUCCESS) - { - *pu32 = serial_ioport_read(pThis, Port, &rc); - Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, *pu32)); - PDMCritSectLeave(&pThis->CritSect); - } + *pu32 = serial_ioport_read(pThis, Port, &rc); + Log2(("%s: port %#06x val %#04x\n", __FUNCTION__, Port, *pu32)); } else rc = VERR_IOM_IOPORT_UNUSED; @@ -1271,25 +1264,35 @@ static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG LogRel(("Serial#%d: emulating %s\n", pDevIns->iInstance, pThis->f16550AEnabled ? "16550A" : "16450")); /* - * Initialize critical section and the semaphore. - * This must of course be done before attaching drivers or anything else which can call us back.. + * Initialize critical section and the semaphore. Change the default + * critical section to ours so that TM and IOM will enter it before + * calling us. + * + * Note! This must of be done BEFORE creating timers, registering I/O ports + * and other things which might pick up the default CS or end up + * calling back into the device. */ - rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Serial#%d", iInstance); - if (RT_FAILURE(rc)) - return rc; + rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "Serial#%u", iInstance); + AssertRCReturn(rc, rc); + + rc = PDMDevHlpSetDeviceCritSect(pDevIns, &pThis->CritSect); + AssertRCReturn(rc, rc); rc = RTSemEventCreate(&pThis->ReceiveSem); - AssertRC(rc); + AssertRCReturn(rc, rc); + /* + * Create the timers. + */ rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, serialFifoTimer, pThis, - TMTIMER_FLAGS_NO_CRIT_SECT, "Serial Fifo Timer", + TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "Serial Fifo Timer", &pThis->fifo_timeout_timer); - AssertRC(rc); + AssertRCReturn(rc, rc); rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, serialTransmitTimer, pThis, - TMTIMER_FLAGS_NO_CRIT_SECT, "Serial Transmit Timer", + TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "Serial Transmit Timer", &pThis->transmit_timerR3); - AssertRC(rc); + AssertRCReturn(rc, rc); pThis->transmit_timerR0 = TMTimerR0Ptr(pThis->transmit_timerR3); pThis->transmit_timerRC = TMTimerRCPtr(pThis->transmit_timerR3); |