summaryrefslogtreecommitdiff
path: root/src/VBox/Devices/Serial
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Serial')
-rw-r--r--src/VBox/Devices/Serial/DevSerial.cpp648
-rw-r--r--src/VBox/Devices/Serial/DrvChar.cpp3
-rw-r--r--src/VBox/Devices/Serial/DrvHostSerial.cpp22
-rw-r--r--src/VBox/Devices/Serial/DrvNamedPipe.cpp2
-rw-r--r--src/VBox/Devices/Serial/DrvRawFile.cpp9
5 files changed, 337 insertions, 347 deletions
diff --git a/src/VBox/Devices/Serial/DevSerial.cpp b/src/VBox/Devices/Serial/DevSerial.cpp
index f15312f0..debe4a4d 100644
--- a/src/VBox/Devices/Serial/DevSerial.cpp
+++ b/src/VBox/Devices/Serial/DevSerial.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -159,7 +159,7 @@ struct SerialFifo
* @implements PDMIBASE
* @implements PDMICHARPORT
*/
-struct SerialState
+typedef struct SerialState
{
/** Access critical section. */
PDMCRITSECT CritSect;
@@ -226,45 +226,31 @@ struct SerialState
uint64_t char_transmit_time;
#ifdef VBOX_SERIAL_PCI
- PCIDEVICE dev;
+ PCIDEVICE PciDev;
#endif /* VBOX_SERIAL_PCI */
-};
+} DEVSERIAL;
+/** Pointer to the serial device state. */
+typedef DEVSERIAL *PDEVSERIAL;
#ifndef VBOX_DEVICE_STRUCT_TESTCASE
-
-#ifdef VBOX_SERIAL_PCI
-#define PCIDEV_2_SERIALSTATE(pPciDev) ( (SerialState *)((uintptr_t)(pPciDev) - RT_OFFSETOF(SerialState, dev)) )
-#endif /* VBOX_SERIAL_PCI */
-#define PDMIBASE_2_SERIALSTATE(pInstance) ( (SerialState *)((uintptr_t)(pInterface) - RT_OFFSETOF(SerialState, IBase)) )
-#define PDMICHARPORT_2_SERIALSTATE(pInstance) ( (SerialState *)((uintptr_t)(pInterface) - RT_OFFSETOF(SerialState, ICharPort)) )
-
-
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
-RT_C_DECLS_BEGIN
-PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
-PDMBOTHCBDECL(int) serialIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
-RT_C_DECLS_END
-
#ifdef IN_RING3
-static int serial_can_receive(SerialState *s);
-static void serial_receive(void *opaque, const uint8_t *buf, int size);
+static int serial_can_receive(PDEVSERIAL pThis);
+static void serial_receive(PDEVSERIAL pThis, const uint8_t *buf, int size);
-static void fifo_clear(SerialState *s, int fifo)
+static void fifo_clear(PDEVSERIAL pThis, int fifo)
{
- SerialFifo *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
+ SerialFifo *f = (fifo) ? &pThis->recv_fifo : &pThis->xmit_fifo;
memset(f->data, 0, UART_FIFO_LENGTH);
f->count = 0;
f->head = 0;
f->tail = 0;
}
-static int fifo_put(SerialState *s, int fifo, uint8_t chr)
+static int fifo_put(PDEVSERIAL pThis, int fifo, uint8_t chr)
{
- SerialFifo *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
+ SerialFifo *f = (fifo) ? &pThis->recv_fifo : &pThis->xmit_fifo;
/* Receive overruns do not overwrite FIFO contents. */
if (fifo == XMIT_FIFO || f->count < UART_FIFO_LENGTH)
@@ -279,14 +265,14 @@ static int fifo_put(SerialState *s, int fifo, uint8_t chr)
else if (fifo == XMIT_FIFO) /* need to at least adjust tail to maintain pipe state consistency */
++f->tail;
else if (fifo == RECV_FIFO)
- s->lsr |= UART_LSR_OE;
+ pThis->lsr |= UART_LSR_OE;
return 1;
}
-static uint8_t fifo_get(SerialState *s, int fifo)
+static uint8_t fifo_get(PDEVSERIAL pThis, int fifo)
{
- SerialFifo *f = (fifo) ? &s->recv_fifo : &s->xmit_fifo;
+ SerialFifo *f = (fifo) ? &pThis->recv_fifo : &pThis->xmit_fifo;
uint8_t c;
if (f->count == 0)
@@ -300,272 +286,270 @@ static uint8_t fifo_get(SerialState *s, int fifo)
return c;
}
-static void serial_update_irq(SerialState *s)
+static void serial_update_irq(PDEVSERIAL pThis)
{
uint8_t tmp_iir = UART_IIR_NO_INT;
- if ( (s->ier & UART_IER_RLSI)
- && (s->lsr & UART_LSR_INT_ANY)) {
+ if ( (pThis->ier & UART_IER_RLSI)
+ && (pThis->lsr & UART_LSR_INT_ANY)) {
tmp_iir = UART_IIR_RLSI;
- } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) {
- /* Note that(s->ier & UART_IER_RDI) can mask this interrupt,
+ } else if ((pThis->ier & UART_IER_RDI) && pThis->timeout_ipending) {
+ /* Note that(pThis->ier & UART_IER_RDI) can mask this interrupt,
* this is not in the specification but is observed on existing
* hardware. */
tmp_iir = UART_IIR_CTI;
- } else if ( (s->ier & UART_IER_RDI)
- && (s->lsr & UART_LSR_DR)
- && ( !(s->fcr & UART_FCR_FE)
- || s->recv_fifo.count >= s->recv_fifo.itl)) {
+ } else if ( (pThis->ier & UART_IER_RDI)
+ && (pThis->lsr & UART_LSR_DR)
+ && ( !(pThis->fcr & UART_FCR_FE)
+ || pThis->recv_fifo.count >= pThis->recv_fifo.itl)) {
tmp_iir = UART_IIR_RDI;
- } else if ( (s->ier & UART_IER_THRI)
- && s->thr_ipending) {
+ } else if ( (pThis->ier & UART_IER_THRI)
+ && pThis->thr_ipending) {
tmp_iir = UART_IIR_THRI;
- } else if ( (s->ier & UART_IER_MSI)
- && (s->msr & UART_MSR_ANY_DELTA)) {
+ } else if ( (pThis->ier & UART_IER_MSI)
+ && (pThis->msr & UART_MSR_ANY_DELTA)) {
tmp_iir = UART_IIR_MSI;
}
- s->iir = tmp_iir | (s->iir & 0xF0);
+ pThis->iir = tmp_iir | (pThis->iir & 0xF0);
/** XXX only call the SetIrq function if the state really changes! */
if (tmp_iir != UART_IIR_NO_INT) {
- Log(("serial_update_irq %d 1\n", s->irq));
+ Log(("serial_update_irq %d 1\n", pThis->irq));
# ifdef VBOX_SERIAL_PCI
- PDMDevHlpPCISetIrqNoWait(s->CTX_SUFF(pDevIns), 0, 1);
+ PDMDevHlpPCISetIrqNoWait(pThis->CTX_SUFF(pDevIns), 0, 1);
# else /* !VBOX_SERIAL_PCI */
- PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 1);
+ PDMDevHlpISASetIrqNoWait(pThis->CTX_SUFF(pDevIns), pThis->irq, 1);
# endif /* !VBOX_SERIAL_PCI */
} else {
- Log(("serial_update_irq %d 0\n", s->irq));
+ Log(("serial_update_irq %d 0\n", pThis->irq));
# ifdef VBOX_SERIAL_PCI
- PDMDevHlpPCISetIrqNoWait(s->CTX_SUFF(pDevIns), 0, 0);
+ PDMDevHlpPCISetIrqNoWait(pThis->CTX_SUFF(pDevIns), 0, 0);
# else /* !VBOX_SERIAL_PCI */
- PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 0);
+ PDMDevHlpISASetIrqNoWait(pThis->CTX_SUFF(pDevIns), pThis->irq, 0);
# endif /* !VBOX_SERIAL_PCI */
}
}
-static void serial_tsr_retry_update_parameters(SerialState *s, uint64_t tf)
+static void serial_tsr_retry_update_parameters(PDEVSERIAL pThis, uint64_t tf)
{
- s->tsr_retry_bound_max = RT_MAX((tf * MAX_XMIT_RETRY_TIME) / s->char_transmit_time, MIN_XMIT_RETRY);
- s->tsr_retry_bound_min = RT_MAX(s->tsr_retry_bound_max / (1000 * MAX_XMIT_RETRY_TIME), MIN_XMIT_RETRY);
+ pThis->tsr_retry_bound_max = RT_MAX((tf * MAX_XMIT_RETRY_TIME) / pThis->char_transmit_time, MIN_XMIT_RETRY);
+ pThis->tsr_retry_bound_min = RT_MAX(pThis->tsr_retry_bound_max / (1000 * MAX_XMIT_RETRY_TIME), MIN_XMIT_RETRY);
/* for simplicity just reset to max retry count */
- s->tsr_retry_bound = s->tsr_retry_bound_max;
+ pThis->tsr_retry_bound = pThis->tsr_retry_bound_max;
}
-static void serial_tsr_retry_bound_reached(SerialState *s)
+static void serial_tsr_retry_bound_reached(PDEVSERIAL pThis)
{
/* this is most likely means we have some backend connection issues */
/* decrement the retry bound */
- s->tsr_retry_bound = RT_MAX(s->tsr_retry_bound / (10 * MAX_XMIT_RETRY_TIME), s->tsr_retry_bound_min);
+ pThis->tsr_retry_bound = RT_MAX(pThis->tsr_retry_bound / (10 * MAX_XMIT_RETRY_TIME), pThis->tsr_retry_bound_min);
}
-static void serial_tsr_retry_succeeded(SerialState *s)
+static void serial_tsr_retry_succeeded(PDEVSERIAL pThis)
{
/* success means we have a backend connection working OK,
* set retry bound to its maximum value */
- s->tsr_retry_bound = s->tsr_retry_bound_max;
+ pThis->tsr_retry_bound = pThis->tsr_retry_bound_max;
}
-static void serial_update_parameters(SerialState *s)
+static void serial_update_parameters(PDEVSERIAL pThis)
{
int speed, parity, data_bits, stop_bits, frame_size;
- if (s->divider == 0)
+ if (pThis->divider == 0)
return;
frame_size = 1;
- if (s->lcr & 0x08) {
+ if (pThis->lcr & 0x08) {
frame_size++;
- if (s->lcr & 0x10)
+ if (pThis->lcr & 0x10)
parity = 'E';
else
parity = 'O';
} else {
parity = 'N';
}
- if (s->lcr & 0x04)
+ if (pThis->lcr & 0x04)
stop_bits = 2;
else
stop_bits = 1;
- data_bits = (s->lcr & 0x03) + 5;
+ data_bits = (pThis->lcr & 0x03) + 5;
frame_size += data_bits + stop_bits;
- speed = 115200 / s->divider;
- uint64_t tf = TMTimerGetFreq(CTX_SUFF(s->transmit_timer));
- s->char_transmit_time = (tf / speed) * frame_size;
- serial_tsr_retry_update_parameters(s, tf);
+ speed = 115200 / pThis->divider;
+ uint64_t tf = TMTimerGetFreq(CTX_SUFF(pThis->transmit_timer));
+ pThis->char_transmit_time = (tf / speed) * frame_size;
+ serial_tsr_retry_update_parameters(pThis, tf);
Log(("speed=%d parity=%c data=%d stop=%d\n", speed, parity, data_bits, stop_bits));
- if (RT_LIKELY(s->pDrvChar))
- s->pDrvChar->pfnSetParameters(s->pDrvChar, speed, parity, data_bits, stop_bits);
+ if (RT_LIKELY(pThis->pDrvChar))
+ pThis->pDrvChar->pfnSetParameters(pThis->pDrvChar, speed, parity, data_bits, stop_bits);
}
-static void serial_xmit(void *opaque, bool bRetryXmit)
+static void serial_xmit(PDEVSERIAL pThis, bool bRetryXmit)
{
- SerialState *s = (SerialState*)opaque;
-
- if (s->tsr_retry <= 0) {
- if (s->fcr & UART_FCR_FE) {
- s->tsr = fifo_get(s, XMIT_FIFO);
- if (!s->xmit_fifo.count)
- s->lsr |= UART_LSR_THRE;
+ if (pThis->tsr_retry <= 0) {
+ if (pThis->fcr & UART_FCR_FE) {
+ pThis->tsr = fifo_get(pThis, XMIT_FIFO);
+ if (!pThis->xmit_fifo.count)
+ pThis->lsr |= UART_LSR_THRE;
} else {
- s->tsr = s->thr;
- s->lsr |= UART_LSR_THRE;
+ pThis->tsr = pThis->thr;
+ pThis->lsr |= UART_LSR_THRE;
}
}
- if (s->mcr & UART_MCR_LOOP) {
+ if (pThis->mcr & UART_MCR_LOOP) {
/* in loopback mode, say that we just received a char */
- serial_receive(s, &s->tsr, 1);
- } else if ( RT_LIKELY(s->pDrvChar)
- && RT_FAILURE(s->pDrvChar->pfnWrite(s->pDrvChar, &s->tsr, 1))) {
- if ((s->tsr_retry >= 0) && ((!bRetryXmit) || (s->tsr_retry <= s->tsr_retry_bound))) {
- if (!s->tsr_retry)
- s->tsr_retry = 1; /* make sure the retry state is always set */
+ serial_receive(pThis, &pThis->tsr, 1);
+ } else if ( RT_LIKELY(pThis->pDrvChar)
+ && RT_FAILURE(pThis->pDrvChar->pfnWrite(pThis->pDrvChar, &pThis->tsr, 1))) {
+ if ((pThis->tsr_retry >= 0) && ((!bRetryXmit) || (pThis->tsr_retry <= pThis->tsr_retry_bound))) {
+ if (!pThis->tsr_retry)
+ pThis->tsr_retry = 1; /* make sure the retry state is always set */
else if (bRetryXmit) /* do not increase the retry count if the retry is actually caused by next char write */
- s->tsr_retry++;
+ pThis->tsr_retry++;
- TMTimerSet(CTX_SUFF(s->transmit_timer), TMTimerGet(CTX_SUFF(s->transmit_timer)) + s->char_transmit_time * 4);
+ TMTimerSet(CTX_SUFF(pThis->transmit_timer), TMTimerGet(CTX_SUFF(pThis->transmit_timer)) + pThis->char_transmit_time * 4);
return;
} else {
/* drop this character. */
- s->tsr_retry = 0;
- serial_tsr_retry_bound_reached(s);
+ pThis->tsr_retry = 0;
+ serial_tsr_retry_bound_reached(pThis);
}
}
else {
- s->tsr_retry = 0;
- serial_tsr_retry_succeeded(s);
+ pThis->tsr_retry = 0;
+ serial_tsr_retry_succeeded(pThis);
}
- if (!(s->lsr & UART_LSR_THRE))
- TMTimerSet(CTX_SUFF(s->transmit_timer),
- TMTimerGet(CTX_SUFF(s->transmit_timer)) + s->char_transmit_time);
+ if (!(pThis->lsr & UART_LSR_THRE))
+ TMTimerSet(CTX_SUFF(pThis->transmit_timer),
+ TMTimerGet(CTX_SUFF(pThis->transmit_timer)) + pThis->char_transmit_time);
- if (s->lsr & UART_LSR_THRE) {
- s->lsr |= UART_LSR_TEMT;
- s->thr_ipending = 1;
- serial_update_irq(s);
+ if (pThis->lsr & UART_LSR_THRE) {
+ pThis->lsr |= UART_LSR_TEMT;
+ pThis->thr_ipending = 1;
+ serial_update_irq(pThis);
}
}
#endif /* IN_RING3 */
-static int serial_ioport_write(SerialState *s, uint32_t addr, uint32_t val)
+static int serial_ioport_write(PDEVSERIAL pThis, uint32_t addr, uint32_t val)
{
addr &= 7;
#ifndef IN_RING3
- NOREF(s);
+ NOREF(pThis);
return VINF_IOM_R3_IOPORT_WRITE;
#else
switch(addr) {
default:
case 0:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0xff00) | val;
- serial_update_parameters(s);
+ if (pThis->lcr & UART_LCR_DLAB) {
+ pThis->divider = (pThis->divider & 0xff00) | val;
+ serial_update_parameters(pThis);
} else {
- s->thr = (uint8_t) val;
- if (s->fcr & UART_FCR_FE) {
- fifo_put(s, XMIT_FIFO, s->thr);
- s->thr_ipending = 0;
- s->lsr &= ~UART_LSR_TEMT;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
+ pThis->thr = (uint8_t) val;
+ if (pThis->fcr & UART_FCR_FE) {
+ fifo_put(pThis, XMIT_FIFO, pThis->thr);
+ pThis->thr_ipending = 0;
+ pThis->lsr &= ~UART_LSR_TEMT;
+ pThis->lsr &= ~UART_LSR_THRE;
+ serial_update_irq(pThis);
} else {
- s->thr_ipending = 0;
- s->lsr &= ~UART_LSR_THRE;
- serial_update_irq(s);
+ pThis->thr_ipending = 0;
+ pThis->lsr &= ~UART_LSR_THRE;
+ serial_update_irq(pThis);
}
- serial_xmit(s, false);
+ serial_xmit(pThis, false);
}
break;
case 1:
- if (s->lcr & UART_LCR_DLAB) {
- s->divider = (s->divider & 0x00ff) | (val << 8);
- serial_update_parameters(s);
+ if (pThis->lcr & UART_LCR_DLAB) {
+ pThis->divider = (pThis->divider & 0x00ff) | (val << 8);
+ serial_update_parameters(pThis);
} else {
- s->ier = val & 0x0f;
- if (s->lsr & UART_LSR_THRE) {
- s->thr_ipending = 1;
- serial_update_irq(s);
+ pThis->ier = val & 0x0f;
+ if (pThis->lsr & UART_LSR_THRE) {
+ pThis->thr_ipending = 1;
+ serial_update_irq(pThis);
}
}
break;
case 2:
- if (!s->f16550AEnabled)
+ if (!pThis->f16550AEnabled)
break;
val = val & 0xFF;
- if (s->fcr == val)
+ if (pThis->fcr == val)
break;
/* Did the enable/disable flag change? If so, make sure FIFOs get flushed */
- if ((val ^ s->fcr) & UART_FCR_FE)
+ if ((val ^ pThis->fcr) & UART_FCR_FE)
val |= UART_FCR_XFR | UART_FCR_RFR;
/* FIFO clear */
if (val & UART_FCR_RFR) {
- TMTimerStop(s->fifo_timeout_timer);
- s->timeout_ipending = 0;
- fifo_clear(s, RECV_FIFO);
+ TMTimerStop(pThis->fifo_timeout_timer);
+ pThis->timeout_ipending = 0;
+ fifo_clear(pThis, RECV_FIFO);
}
if (val & UART_FCR_XFR) {
- fifo_clear(s, XMIT_FIFO);
+ fifo_clear(pThis, XMIT_FIFO);
}
if (val & UART_FCR_FE) {
- s->iir |= UART_IIR_FE;
+ pThis->iir |= UART_IIR_FE;
/* Set RECV_FIFO trigger Level */
switch (val & 0xC0) {
case UART_FCR_ITL_1:
- s->recv_fifo.itl = 1;
+ pThis->recv_fifo.itl = 1;
break;
case UART_FCR_ITL_2:
- s->recv_fifo.itl = 4;
+ pThis->recv_fifo.itl = 4;
break;
case UART_FCR_ITL_3:
- s->recv_fifo.itl = 8;
+ pThis->recv_fifo.itl = 8;
break;
case UART_FCR_ITL_4:
- s->recv_fifo.itl = 14;
+ pThis->recv_fifo.itl = 14;
break;
}
} else
- s->iir &= ~UART_IIR_FE;
+ pThis->iir &= ~UART_IIR_FE;
/* Set fcr - or at least the bits in it that are supposed to "stick" */
- s->fcr = val & 0xC9;
- serial_update_irq(s);
+ pThis->fcr = val & 0xC9;
+ serial_update_irq(pThis);
break;
case 3:
{
int break_enable;
- s->lcr = val;
- serial_update_parameters(s);
+ pThis->lcr = val;
+ serial_update_parameters(pThis);
break_enable = (val >> 6) & 1;
- if (break_enable != s->last_break_enable) {
- s->last_break_enable = break_enable;
- if (RT_LIKELY(s->pDrvChar))
+ if (break_enable != pThis->last_break_enable) {
+ pThis->last_break_enable = break_enable;
+ if (RT_LIKELY(pThis->pDrvChar))
{
Log(("serial_ioport_write: Set break %d\n", break_enable));
- int rc = s->pDrvChar->pfnSetBreak(s->pDrvChar, !!break_enable);
+ int rc = pThis->pDrvChar->pfnSetBreak(pThis->pDrvChar, !!break_enable);
AssertRC(rc);
}
}
}
break;
case 4:
- s->mcr = val & 0x1f;
- if (RT_LIKELY(s->pDrvChar))
+ pThis->mcr = val & 0x1f;
+ if (RT_LIKELY(pThis->pDrvChar))
{
- int rc = s->pDrvChar->pfnSetModemLines(s->pDrvChar,
- !!(s->mcr & UART_MCR_RTS),
- !!(s->mcr & UART_MCR_DTR));
+ int rc = pThis->pDrvChar->pfnSetModemLines(pThis->pDrvChar,
+ !!(pThis->mcr & UART_MCR_RTS),
+ !!(pThis->mcr & UART_MCR_DTR));
AssertRC(rc);
}
break;
@@ -574,16 +558,15 @@ static int serial_ioport_write(SerialState *s, uint32_t addr, uint32_t val)
case 6:
break;
case 7:
- s->scr = val;
+ pThis->scr = val;
break;
}
return VINF_SUCCESS;
#endif
}
-static uint32_t serial_ioport_read(void *opaque, uint32_t addr, int *pRC)
+static uint32_t serial_ioport_read(PDEVSERIAL pThis, uint32_t addr, int *pRC)
{
- SerialState *s = (SerialState *)opaque;
uint32_t ret = ~0U;
*pRC = VINF_SUCCESS;
@@ -592,65 +575,65 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr, int *pRC)
switch(addr) {
default:
case 0:
- if (s->lcr & UART_LCR_DLAB) {
+ if (pThis->lcr & UART_LCR_DLAB) {
/* DLAB == 1: divisor latch (LS) */
- ret = s->divider & 0xff;
+ ret = pThis->divider & 0xff;
} else {
#ifndef IN_RING3
*pRC = VINF_IOM_R3_IOPORT_READ;
#else
- if (s->fcr & UART_FCR_FE) {
- ret = fifo_get(s, RECV_FIFO);
- if (s->recv_fifo.count == 0)
- s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
+ if (pThis->fcr & UART_FCR_FE) {
+ ret = fifo_get(pThis, RECV_FIFO);
+ if (pThis->recv_fifo.count == 0)
+ pThis->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
else
- TMTimerSet(s->fifo_timeout_timer,
- TMTimerGet(s->fifo_timeout_timer) + s->char_transmit_time * 4);
- s->timeout_ipending = 0;
+ TMTimerSet(pThis->fifo_timeout_timer,
+ TMTimerGet(pThis->fifo_timeout_timer) + pThis->char_transmit_time * 4);
+ pThis->timeout_ipending = 0;
} else {
- Log(("serial_io_port_read: read 0x%X\n", s->rbr));
- ret = s->rbr;
- s->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
+ Log(("serial_io_port_read: read 0x%X\n", pThis->rbr));
+ ret = pThis->rbr;
+ pThis->lsr &= ~(UART_LSR_DR | UART_LSR_BI);
}
- serial_update_irq(s);
- if (s->fRecvWaiting)
+ serial_update_irq(pThis);
+ if (pThis->fRecvWaiting)
{
- s->fRecvWaiting = false;
- int rc = RTSemEventSignal(s->ReceiveSem);
+ pThis->fRecvWaiting = false;
+ int rc = RTSemEventSignal(pThis->ReceiveSem);
AssertRC(rc);
}
#endif
}
break;
case 1:
- if (s->lcr & UART_LCR_DLAB) {
+ if (pThis->lcr & UART_LCR_DLAB) {
/* DLAB == 1: divisor latch (MS) */
- ret = (s->divider >> 8) & 0xff;
+ ret = (pThis->divider >> 8) & 0xff;
} else {
- ret = s->ier;
+ ret = pThis->ier;
}
break;
case 2:
#ifndef IN_RING3
*pRC = VINF_IOM_R3_IOPORT_READ;
#else
- ret = s->iir;
+ ret = pThis->iir;
if ((ret & UART_IIR_ID) == UART_IIR_THRI) {
- s->thr_ipending = 0;
- serial_update_irq(s);
+ pThis->thr_ipending = 0;
+ serial_update_irq(pThis);
}
/* reset msr changed bit */
- s->msr_changed = false;
+ pThis->msr_changed = false;
#endif
break;
case 3:
- ret = s->lcr;
+ ret = pThis->lcr;
break;
case 4:
- ret = s->mcr;
+ ret = pThis->mcr;
break;
case 5:
- if ((s->lsr & UART_LSR_DR) == 0 && s->fYieldOnLSRRead)
+ if ((pThis->lsr & UART_LSR_DR) == 0 && pThis->fYieldOnLSRRead)
{
/* No data available and yielding is enabled, so yield in ring3. */
#ifndef IN_RING3
@@ -660,39 +643,39 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr, int *pRC)
RTThreadYield ();
#endif
}
- ret = s->lsr;
+ ret = pThis->lsr;
/* Clear break and overrun interrupts */
- if (s->lsr & (UART_LSR_BI|UART_LSR_OE)) {
+ if (pThis->lsr & (UART_LSR_BI|UART_LSR_OE)) {
#ifndef IN_RING3
*pRC = VINF_IOM_R3_IOPORT_READ;
#else
- s->lsr &= ~(UART_LSR_BI|UART_LSR_OE);
- serial_update_irq(s);
+ pThis->lsr &= ~(UART_LSR_BI|UART_LSR_OE);
+ serial_update_irq(pThis);
#endif
}
break;
case 6:
- if (s->mcr & UART_MCR_LOOP) {
+ if (pThis->mcr & UART_MCR_LOOP) {
/* in loopback, the modem output pins are connected to the
inputs */
- ret = (s->mcr & 0x0c) << 4;
- ret |= (s->mcr & 0x02) << 3;
- ret |= (s->mcr & 0x01) << 5;
+ ret = (pThis->mcr & 0x0c) << 4;
+ ret |= (pThis->mcr & 0x02) << 3;
+ ret |= (pThis->mcr & 0x01) << 5;
} else {
- ret = s->msr;
+ ret = pThis->msr;
/* Clear delta bits & msr int after read, if they were set */
- if (s->msr & UART_MSR_ANY_DELTA) {
+ if (pThis->msr & UART_MSR_ANY_DELTA) {
#ifndef IN_RING3
*pRC = VINF_IOM_R3_IOPORT_READ;
#else
- s->msr &= 0xF0;
- serial_update_irq(s);
+ pThis->msr &= 0xF0;
+ serial_update_irq(pThis);
#endif
}
}
break;
case 7:
- ret = s->scr;
+ ret = pThis->scr;
break;
}
return ret;
@@ -700,43 +683,45 @@ static uint32_t serial_ioport_read(void *opaque, uint32_t addr, int *pRC)
#ifdef IN_RING3
-static int serial_can_receive(SerialState *s)
+static int serial_can_receive(PDEVSERIAL pThis)
{
- if (s->fcr & UART_FCR_FE) {
- if (s->recv_fifo.count < UART_FIFO_LENGTH)
- return (s->recv_fifo.count <= s->recv_fifo.itl)
- ? s->recv_fifo.itl - s->recv_fifo.count : 1;
+ if (pThis->fcr & UART_FCR_FE) {
+ if (pThis->recv_fifo.count < UART_FIFO_LENGTH)
+ return (pThis->recv_fifo.count <= pThis->recv_fifo.itl)
+ ? pThis->recv_fifo.itl - pThis->recv_fifo.count : 1;
else
return 0;
} else {
- return !(s->lsr & UART_LSR_DR);
+ return !(pThis->lsr & UART_LSR_DR);
}
}
-static void serial_receive(void *opaque, const uint8_t *buf, int size)
+static void serial_receive(PDEVSERIAL pThis, const uint8_t *buf, int size)
{
- SerialState *s = (SerialState*)opaque;
- if (s->fcr & UART_FCR_FE) {
+ if (pThis->fcr & UART_FCR_FE) {
int i;
for (i = 0; i < size; i++) {
- fifo_put(s, RECV_FIFO, buf[i]);
+ fifo_put(pThis, RECV_FIFO, buf[i]);
}
- s->lsr |= UART_LSR_DR;
+ pThis->lsr |= UART_LSR_DR;
/* call the timeout receive callback in 4 char transmit time */
- TMTimerSet(s->fifo_timeout_timer, TMTimerGet(s->fifo_timeout_timer) + s->char_transmit_time * 4);
+ TMTimerSet(pThis->fifo_timeout_timer, TMTimerGet(pThis->fifo_timeout_timer) + pThis->char_transmit_time * 4);
} else {
- if (s->lsr & UART_LSR_DR)
- s->lsr |= UART_LSR_OE;
- s->rbr = buf[0];
- s->lsr |= UART_LSR_DR;
+ if (pThis->lsr & UART_LSR_DR)
+ pThis->lsr |= UART_LSR_OE;
+ pThis->rbr = buf[0];
+ pThis->lsr |= UART_LSR_DR;
}
- serial_update_irq(s);
+ serial_update_irq(pThis);
}
-/** @copydoc PDMICHARPORT::pfnNotifyRead */
+
+/**
+ * @interface_method_impl{PDMICHARPORT,pfnNotifyRead}
+ */
static DECLCALLBACK(int) serialNotifyRead(PPDMICHARPORT pInterface, const void *pvBuf, size_t *pcbRead)
{
- SerialState *pThis = PDMICHARPORT_2_SERIALSTATE(pInterface);
+ PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ICharPort);
const uint8_t *pu8Buf = (const uint8_t*)pvBuf;
size_t cbRead = *pcbRead;
@@ -759,10 +744,12 @@ static DECLCALLBACK(int) serialNotifyRead(PPDMICHARPORT pInterface, const void *
return VINF_SUCCESS;
}
-/** @copydoc PDMICHARPORT::pfnNotifyStatusLinesChanged */
+/**
+ * @@interface_method_impl{PDMICHARPORT,pfnNotifyStatusLinesChanged}
+ */
static DECLCALLBACK(int) serialNotifyStatusLinesChanged(PPDMICHARPORT pInterface, uint32_t newStatusLines)
{
- SerialState *pThis = PDMICHARPORT_2_SERIALSTATE(pInterface);
+ PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ICharPort);
uint8_t newMsr = 0;
Log(("%s: pInterface=%p newStatusLines=%u\n", __FUNCTION__, pInterface, newStatusLines));
@@ -798,16 +785,22 @@ static DECLCALLBACK(int) serialNotifyStatusLinesChanged(PPDMICHARPORT pInterface
return VINF_SUCCESS;
}
-/** @copydoc PDMICHARPORT::pfnNotifyBufferFull */
+
+/**
+ * @interface_method_impl{PDMICHARPORT,pfnNotifyBufferFull}
+ */
static DECLCALLBACK(int) serialNotifyBufferFull(PPDMICHARPORT pInterface, bool fFull)
{
return VINF_SUCCESS;
}
-/** @copydoc PDMICHARPORT::pfnNotifyBreak */
+
+/**
+ * @interface_method_impl{PDMICHARPORT,pfnNotifyBreak}
+ */
static DECLCALLBACK(int) serialNotifyBreak(PPDMICHARPORT pInterface)
{
- SerialState *pThis = PDMICHARPORT_2_SERIALSTATE(pInterface);
+ PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, ICharPort);
Log(("%s: pInterface=%p\n", __FUNCTION__, pInterface));
@@ -821,12 +814,15 @@ static DECLCALLBACK(int) serialNotifyBreak(PPDMICHARPORT pInterface)
return VINF_SUCCESS;
}
+
+/* -=-=-=-=-=-=-=-=- Timer callbacks -=-=-=-=-=-=-=-=- */
+
/**
- * Fifo timer functions.
+ * @callback_method_tmpl{FNTMTIMERDEV, Fifo timer function.}
*/
static DECLCALLBACK(void) serialFifoTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- SerialState *pThis = (SerialState *)pvUser;
+ PDEVSERIAL pThis = (PDEVSERIAL)pvUser;
Assert(PDMCritSectIsOwner(&pThis->CritSect));
if (pThis->recv_fifo.count)
{
@@ -836,73 +832,27 @@ static DECLCALLBACK(void) serialFifoTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, v
}
/**
- * Transmit timer function.
- * Just retry to transmit a character.
+ * @callback_method_tmpl{FNTMTIMERDEV, Transmit timer function.}
*
- * @param pTimer The timer handle.
- * @param pDevIns The device instance.
- * @param pvUser The user pointer.
+ * Just retry to transmit a character.
*/
static DECLCALLBACK(void) serialTransmitTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
{
- SerialState *pThis = (SerialState *)pvUser;
+ PDEVSERIAL pThis = (PDEVSERIAL)pvUser;
Assert(PDMCritSectIsOwner(&pThis->CritSect));
serial_xmit(pThis, true);
}
-/**
- * Reset the serial device.
- *
- * @param pDevIns The device instance.
- */
-static DECLCALLBACK(void) serialReset(PPDMDEVINS pDevIns)
-{
- SerialState *s = PDMINS_2_DATA(pDevIns, SerialState *);
-
- s->rbr = 0;
- s->ier = 0;
- s->iir = UART_IIR_NO_INT;
- s->lcr = 0;
- s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
- s->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
- /* Default to 9600 baud, 1 start bit, 8 data bits, 1 stop bit, no parity. */
- s->divider = 0x0C;
- s->mcr = UART_MCR_OUT2;
- s->scr = 0;
- s->tsr_retry = 0;
- uint64_t tf = TMTimerGetFreq(CTX_SUFF(s->transmit_timer));
- s->char_transmit_time = (tf / 9600) * 10;
- serial_tsr_retry_update_parameters(s, tf);
-
- fifo_clear(s, RECV_FIFO);
- fifo_clear(s, XMIT_FIFO);
-
- s->thr_ipending = 0;
- s->last_break_enable = 0;
-# ifdef VBOX_SERIAL_PCI
- PDMDevHlpPCISetIrqNoWait(s->CTX_SUFF(pDevIns), 0, 0);
-# else /* !VBOX_SERIAL_PCI */
- PDMDevHlpISASetIrqNoWait(s->CTX_SUFF(pDevIns), s->irq, 0);
-# endif /* !VBOX_SERIAL_PCI */
-}
-
#endif /* IN_RING3 */
+/* -=-=-=-=-=-=-=-=- I/O Port Access Handlers -=-=-=-=-=-=-=-=- */
+
/**
- * Port I/O Handler for OUT operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTOUT}
*/
-PDMBOTHCBDECL(int) serialIOPortWrite(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t u32, unsigned cb)
+PDMBOTHCBDECL(int) serialIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
int rc;
Assert(PDMCritSectIsOwner(&pThis->CritSect));
@@ -920,21 +870,13 @@ PDMBOTHCBDECL(int) serialIOPortWrite(PPDMDEVINS pDevIns, void *pvUser,
return rc;
}
+
/**
- * Port I/O Handler for IN operations.
- *
- * @returns VBox status code.
- *
- * @param pDevIns The device instance.
- * @param pvUser User argument.
- * @param Port Port number used for the IN operation.
- * @param u32 The value to output.
- * @param cb The value size in bytes.
+ * @callback_method_impl{FNIOMIOPORTIN}
*/
-PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser,
- RTIOPORT Port, uint32_t *pu32, unsigned cb)
+PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
int rc;
Assert(PDMCritSectIsOwner(&pThis->CritSect));
@@ -951,26 +893,26 @@ PDMBOTHCBDECL(int) serialIOPortRead(PPDMDEVINS pDevIns, void *pvUser,
#ifdef IN_RING3
+/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
+
/**
- * @copydoc FNSSMDEVLIVEEXEC
+ * @callback_method_tmpl{FNSSMDEVLIVEEXEC}
*/
-static DECLCALLBACK(int) serialLiveExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM,
- uint32_t uPass)
+static DECLCALLBACK(int) serialLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
SSMR3PutS32(pSSM, pThis->irq);
SSMR3PutU32(pSSM, pThis->base);
return VINF_SSM_DONT_CALL_AGAIN;
}
+
/**
- * @copydoc FNSSMDEVSAVEEXEC
+ * @callback_method_tmpl{FNSSMDEVSAVEEXEC}
*/
-static DECLCALLBACK(int) serialSaveExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM)
+static DECLCALLBACK(int) serialSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
SSMR3PutU16(pSSM, pThis->divider);
SSMR3PutU8(pSSM, pThis->rbr);
@@ -995,15 +937,13 @@ static DECLCALLBACK(int) serialSaveExec(PPDMDEVINS pDevIns,
return SSMR3PutU32(pSSM, ~0); /* sanity/terminator */
}
+
/**
- * @copydoc FNSSMDEVLOADEXEC
+ * @callback_method_tmpl{FNSSMDEVLOADEXEC}
*/
-static DECLCALLBACK(int) serialLoadExec(PPDMDEVINS pDevIns,
- PSSMHANDLE pSSM,
- uint32_t uVersion,
- uint32_t uPass)
+static DECLCALLBACK(int) serialLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
if (uVersion == SERIAL_SAVED_STATE_VERSION_16450)
{
@@ -1074,21 +1014,16 @@ static DECLCALLBACK(int) serialLoadExec(PPDMDEVINS pDevIns,
}
-/**
- * @copydoc FNPDMDEVRELOCATE
- */
-static DECLCALLBACK(void) serialRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
-{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
- pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
- pThis->transmit_timerRC = TMTimerRCPtr(pThis->transmit_timerR3);
-}
-
#ifdef VBOX_SERIAL_PCI
+/* -=-=-=-=-=-=-=-=- PCI Device Callback(s) -=-=-=-=-=-=-=-=- */
-static DECLCALLBACK(int) serialIOPortRegionMap(PPCIDEVICE pPciDev, /* unsigned */ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
+/**
+ * @callback_method_impl{FNPCIIOREGIONMAP}
+ */
+static DECLCALLBACK(int) serialIOPortRegionMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress,
+ uint32_t cb, PCIADDRESSSPACE enmType)
{
- SerialState *pThis = PCIDEV_2_SERIALSTATE(pPciDev);
+ PDEVSERIAL pThis = RT_FROM_MEMBER(pPciDev, DEVSERIAL, PciDev);
int rc = VINF_SUCCESS;
Assert(enmType == PCI_ADDRESS_SPACE_IO);
@@ -1110,29 +1045,75 @@ static DECLCALLBACK(int) serialIOPortRegionMap(PPCIDEVICE pPciDev, /* unsigned *
#endif /* VBOX_SERIAL_PCI */
+
+/* -=-=-=-=-=-=-=-=- PDMIBASE on LUN#1 -=-=-=-=-=-=-=-=- */
+
/**
* @interface_method_impl{PDMIBASE, pfnQueryInterface}
*/
static DECLCALLBACK(void *) serialQueryInterface(PPDMIBASE pInterface, const char *pszIID)
{
- SerialState *pThis = PDMIBASE_2_SERIALSTATE(pInterface);
+ PDEVSERIAL pThis = RT_FROM_MEMBER(pInterface, DEVSERIAL, IBase);
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IBase);
PDMIBASE_RETURN_INTERFACE(pszIID, PDMICHARPORT, &pThis->ICharPort);
return NULL;
}
+
+/* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */
+
/**
- * Destruct a device instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @returns VBox status.
- * @param pDevIns The device instance data.
+ * @interface_method_impl{PDMDEVREG, pfnRelocate}
+ */
+static DECLCALLBACK(void) serialRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
+ pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pThis->transmit_timerRC = TMTimerRCPtr(pThis->transmit_timerR3);
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG, pfnReset}
+ */
+static DECLCALLBACK(void) serialReset(PPDMDEVINS pDevIns)
+{
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
+
+ pThis->rbr = 0;
+ pThis->ier = 0;
+ pThis->iir = UART_IIR_NO_INT;
+ pThis->lcr = 0;
+ pThis->lsr = UART_LSR_TEMT | UART_LSR_THRE;
+ pThis->msr = UART_MSR_DCD | UART_MSR_DSR | UART_MSR_CTS;
+ /* Default to 9600 baud, 1 start bit, 8 data bits, 1 stop bit, no parity. */
+ pThis->divider = 0x0C;
+ pThis->mcr = UART_MCR_OUT2;
+ pThis->scr = 0;
+ pThis->tsr_retry = 0;
+ uint64_t tf = TMTimerGetFreq(CTX_SUFF(pThis->transmit_timer));
+ pThis->char_transmit_time = (tf / 9600) * 10;
+ serial_tsr_retry_update_parameters(pThis, tf);
+
+ fifo_clear(pThis, RECV_FIFO);
+ fifo_clear(pThis, XMIT_FIFO);
+
+ pThis->thr_ipending = 0;
+ pThis->last_break_enable = 0;
+# ifdef VBOX_SERIAL_PCI
+ PDMDevHlpPCISetIrqNoWait(pThis->CTX_SUFF(pDevIns), 0, 0);
+# else /* !VBOX_SERIAL_PCI */
+ PDMDevHlpISASetIrqNoWait(pThis->CTX_SUFF(pDevIns), pThis->irq, 0);
+# endif /* !VBOX_SERIAL_PCI */
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG, pfnDestruct}
*/
static DECLCALLBACK(int) serialDestruct(PPDMDEVINS pDevIns)
{
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
RTSemEventDestroy(pThis->ReceiveSem);
@@ -1148,8 +1129,8 @@ static DECLCALLBACK(int) serialDestruct(PPDMDEVINS pDevIns)
*/
static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
{
+ PDEVSERIAL pThis = PDMINS_2_DATA(pDevIns, PDEVSERIAL);
int rc;
- SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState*);
uint16_t io_base;
uint8_t irq_lvl;
@@ -1163,6 +1144,7 @@ static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG
pThis->pDevInsR3 = pDevIns;
pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+ pThis->ReceiveSem = NIL_RTSEMEVENT;
/* IBase */
pThis->IBase.pfnQueryInterface = serialQueryInterface;
@@ -1175,17 +1157,17 @@ static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG
#ifdef VBOX_SERIAL_PCI
/* the PCI device */
- pThis->dev.config[0x00] = 0xee; /* Vendor: ??? */
- pThis->dev.config[0x01] = 0x80;
- pThis->dev.config[0x02] = 0x01; /* Device: ??? */
- pThis->dev.config[0x03] = 0x01;
- pThis->dev.config[0x04] = PCI_COMMAND_IOACCESS;
- pThis->dev.config[0x09] = 0x01; /* Programming interface: 16450 */
- pThis->dev.config[0x0a] = 0x00; /* Subclass: Serial controller */
- pThis->dev.config[0x0b] = 0x07; /* Class: Communication controller */
- pThis->dev.config[0x0e] = 0x00; /* Header type: standard */
- pThis->dev.config[0x3c] = irq_lvl; /* preconfigure IRQ number (0 = autoconfig)*/
- pThis->dev.config[0x3d] = 1; /* interrupt pin 0 */
+ pThis->PciDev.config[0x00] = 0xee; /* Vendor: ??? */
+ pThis->PciDev.config[0x01] = 0x80;
+ pThis->PciDev.config[0x02] = 0x01; /* Device: ??? */
+ pThis->PciDev.config[0x03] = 0x01;
+ pThis->PciDev.config[0x04] = PCI_COMMAND_IOACCESS;
+ pThis->PciDev.config[0x09] = 0x01; /* Programming interface: 16450 */
+ pThis->PciDev.config[0x0a] = 0x00; /* Subclass: Serial controller */
+ pThis->PciDev.config[0x0b] = 0x07; /* Class: Communication controller */
+ pThis->PciDev.config[0x0e] = 0x00; /* Header type: standard */
+ pThis->PciDev.config[0x3c] = irq_lvl; /* preconfigure IRQ number (0 = autoconfig)*/
+ pThis->PciDev.config[0x3d] = 1; /* interrupt pin 0 */
#endif /* VBOX_SERIAL_PCI */
/*
@@ -1302,7 +1284,7 @@ static DECLCALLBACK(int) serialConstruct(PPDMDEVINS pDevIns, int iInstance, PCFG
/*
* Register the PCI Device and region.
*/
- rc = PDMDevHlpPCIRegister(pDevIns, &pThis->dev);
+ rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
if (RT_FAILURE(rc))
return rc;
rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, 8, PCI_ADDRESS_SPACE_IO, serialIOPortRegionMap);
@@ -1399,14 +1381,14 @@ const PDMDEVREG g_DeviceSerialPort =
/* cMaxInstances */
UINT32_MAX,
/* cbInstance */
- sizeof(SerialState),
+ sizeof(DEVSERIAL),
/* pfnConstruct */
serialConstruct,
/* pfnDestruct */
serialDestruct,
/* pfnRelocate */
serialRelocate,
- /* pfnIOCtl */
+ /* pfnMemSetup */
NULL,
/* pfnPowerOn */
NULL,
diff --git a/src/VBox/Devices/Serial/DrvChar.cpp b/src/VBox/Devices/Serial/DrvChar.cpp
index f0b60afb..a0d1b797 100644
--- a/src/VBox/Devices/Serial/DrvChar.cpp
+++ b/src/VBox/Devices/Serial/DrvChar.cpp
@@ -10,7 +10,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -304,6 +304,7 @@ static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
if (pThis->SendSem != NIL_RTSEMEVENT)
{
RTSemEventSignal(pThis->SendSem);
+ pThis->SendSem = NIL_RTSEMEVENT;
}
/*
diff --git a/src/VBox/Devices/Serial/DrvHostSerial.cpp b/src/VBox/Devices/Serial/DrvHostSerial.cpp
index 09f6b05b..0c44fad0 100644
--- a/src/VBox/Devices/Serial/DrvHostSerial.cpp
+++ b/src/VBox/Devices/Serial/DrvHostSerial.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -1069,13 +1069,15 @@ static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
/* Empty the send queue */
- RTSemEventDestroy(pThis->SendSem);
- pThis->SendSem = NIL_RTSEMEVENT;
+ if (pThis->SendSem != NIL_RTSEMEVENT)
+ {
+ RTSemEventDestroy(pThis->SendSem);
+ pThis->SendSem = NIL_RTSEMEVENT;
+ }
- int rc;
#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
- rc = RTPipeClose(pThis->hWakeupPipeW); AssertRC(rc);
+ int rc = RTPipeClose(pThis->hWakeupPipeW); AssertRC(rc);
pThis->hWakeupPipeW = NIL_RTPIPE;
rc = RTPipeClose(pThis->hWakeupPipeR); AssertRC(rc);
pThis->hWakeupPipeR = NIL_RTPIPE;
@@ -1091,8 +1093,11 @@ static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
pThis->hDeviceFileR = NIL_RTFILE;
}
# endif
- rc = RTFileClose(pThis->hDeviceFile); AssertRC(rc);
- pThis->hDeviceFile = NIL_RTFILE;
+ if (pThis->hDeviceFile != NIL_RTFILE)
+ {
+ rc = RTFileClose(pThis->hDeviceFile); AssertRC(rc);
+ pThis->hDeviceFile = NIL_RTFILE;
+ }
#elif defined(RT_OS_WINDOWS)
CloseHandle(pThis->hEventRecv);
@@ -1135,6 +1140,7 @@ static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
pThis->hEventSend = INVALID_HANDLE_VALUE;
pThis->hDeviceFile = INVALID_HANDLE_VALUE;
#endif
+ pThis->SendSem = NIL_RTSEMEVENT;
/* IBase. */
pDrvIns->IBase.pfnQueryInterface = drvHostSerialQueryInterface;
/* ICharConnector. */
@@ -1143,8 +1149,6 @@ static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pC
pThis->ICharConnector.pfnSetModemLines = drvHostSerialSetModemLines;
pThis->ICharConnector.pfnSetBreak = drvHostSerialSetBreak;
-/** @todo Initialize all members with NIL values!! The destructor is ALWAYS called. */
-
/*
* Query configuration.
*/
diff --git a/src/VBox/Devices/Serial/DrvNamedPipe.cpp b/src/VBox/Devices/Serial/DrvNamedPipe.cpp
index 4145d99d..be9bebe2 100644
--- a/src/VBox/Devices/Serial/DrvNamedPipe.cpp
+++ b/src/VBox/Devices/Serial/DrvNamedPipe.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Devices/Serial/DrvRawFile.cpp b/src/VBox/Devices/Serial/DrvRawFile.cpp
index 92d28408..0a9de209 100644
--- a/src/VBox/Devices/Serial/DrvRawFile.cpp
+++ b/src/VBox/Devices/Serial/DrvRawFile.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -139,8 +139,11 @@ static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
if (pThis->pszLocation)
MMR3HeapFree(pThis->pszLocation);
- RTFileClose(pThis->hOutputFile);
- pThis->hOutputFile = NIL_RTFILE;
+ if (pThis->hOutputFile != NIL_RTFILE)
+ {
+ RTFileClose(pThis->hOutputFile);
+ pThis->hOutputFile = NIL_RTFILE;
+ }
}