Patchwork [01/12] char: rename qemu_chr_write() to qemu_chr_fe_write()

login
register
mail settings
Submitter Anthony Liguori
Date Aug. 1, 2011, 2:22 p.m.
Message ID <1312208590-25502-2-git-send-email-aliguori@us.ibm.com>
Download mbox | patch
Permalink /patch/107754/
State New
Headers show

Comments

Anthony Liguori - Aug. 1, 2011, 2:22 p.m.
The char layer is confusing.  There is a front-end, typically a device, that
can send and receive data.  The front-end sends data by calling
qemu_chr_write().

The back-end, typically created via -chardev, can also send and receive data.
Oddly, it sends data by calling qemu_chr_read().

Let's be explicit about which function is for which party.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
---
 gdbstub.c               |    2 +-
 hw/ccid-card-passthru.c |    4 ++--
 hw/debugcon.c           |    2 +-
 hw/escc.c               |    2 +-
 hw/etraxfs_ser.c        |    2 +-
 hw/grlib_apbuart.c      |    2 +-
 hw/lm32_juart.c         |    2 +-
 hw/lm32_uart.c          |    2 +-
 hw/mcf_uart.c           |    2 +-
 hw/milkymist-uart.c     |    2 +-
 hw/omap2.c              |    6 +++---
 hw/parallel.c           |    2 +-
 hw/pl011.c              |    2 +-
 hw/pxa2xx.c             |    2 +-
 hw/serial.c             |    2 +-
 hw/sh_serial.c          |    2 +-
 hw/spapr_vty.c          |    4 ++--
 hw/strongarm.c          |    2 +-
 hw/syborg_serial.c      |    4 ++--
 hw/usb-serial.c         |    2 +-
 hw/virtio-console.c     |    2 +-
 hw/xen_console.c        |    2 +-
 hw/xilinx_uartlite.c    |    2 +-
 monitor.c               |    2 +-
 qemu-char.c             |    4 ++--
 qemu-char.h             |    3 ++-
 slirp/slirp.c           |    2 +-
 usb-redir.c             |    2 +-
 28 files changed, 35 insertions(+), 34 deletions(-)
Avi Kivity - Aug. 4, 2011, 4 p.m.
On 08/01/2011 05:22 PM, Anthony Liguori wrote:
> The char layer is confusing.  There is a front-end, typically a device, that
> can send and receive data.  The front-end sends data by calling
> qemu_chr_write().
>
> The back-end, typically created via -chardev, can also send and receive data.
> Oddly, it sends data by calling qemu_chr_read().
>
> Let's be explicit about which function is for which party.

A different way to accomplish this would be to have each pipe expose two 
interfaces (a front end and a back end), and use the same functions for 
both.  Just like a unix pipe.

The back end interface would typically be an internal object.
Anthony Liguori - Aug. 4, 2011, 4:11 p.m.
On 08/04/2011 11:00 AM, Avi Kivity wrote:
> On 08/01/2011 05:22 PM, Anthony Liguori wrote:
>> The char layer is confusing. There is a front-end, typically a device,
>> that
>> can send and receive data. The front-end sends data by calling
>> qemu_chr_write().
>>
>> The back-end, typically created via -chardev, can also send and
>> receive data.
>> Oddly, it sends data by calling qemu_chr_read().
>>
>> Let's be explicit about which function is for which party.
>
> A different way to accomplish this would be to have each pipe expose two
> interfaces (a front end and a back end), and use the same functions for
> both. Just like a unix pipe.

This is exactly what I'm trying to do.  This is why I decided to do this 
before QOM, because this will change the relationships between objects 
dramatically since you no longer need to subclass CharDriverState since 
it's just being used as a pipe.

Regards,

Anthony Liguori

>
> The back end interface would typically be an internal object.
>
Avi Kivity - Aug. 4, 2011, 4:14 p.m.
On 08/04/2011 07:11 PM, Anthony Liguori wrote:
> On 08/04/2011 11:00 AM, Avi Kivity wrote:
>> On 08/01/2011 05:22 PM, Anthony Liguori wrote:
>>> The char layer is confusing. There is a front-end, typically a device,
>>> that
>>> can send and receive data. The front-end sends data by calling
>>> qemu_chr_write().
>>>
>>> The back-end, typically created via -chardev, can also send and
>>> receive data.
>>> Oddly, it sends data by calling qemu_chr_read().
>>>
>>> Let's be explicit about which function is for which party.
>>
>> A different way to accomplish this would be to have each pipe expose two
>> interfaces (a front end and a back end), and use the same functions for
>> both. Just like a unix pipe.
>
> This is exactly what I'm trying to do.  This is why I decided to do 
> this before QOM, because this will change the relationships between 
> objects dramatically since you no longer need to subclass 
> CharDriverState since it's just being used as a pipe.

Yes, I'm just talking about the function names, not about the 
implementation.

   qemu_chr_fe_write(chr,...) -> qemu_chr_write(chr, ...)
   qemu_chr_be_write(chr, ...) -> qemu_chr_write(&chr->backend, ...)
Avi Kivity - Aug. 4, 2011, 4:17 p.m.
On 08/04/2011 07:14 PM, Avi Kivity wrote:
>
> Yes, I'm just talking about the function names, not about the 
> implementation.
>
>   qemu_chr_fe_write(chr,...) -> qemu_chr_write(chr, ...)
>   qemu_chr_be_write(chr, ...) -> qemu_chr_write(&chr->backend, ...)
>

And, if you want an internal pipe:

    QemuPipeEndpoint pipe1, pipe2;

    qemu_chr_pipe_init(&pipe0, &pipe1);

so clients don't have to choose between frontend and backend.  Finally 
you can connect COM1: to COM2: with a qemu-provided null modem cable!
Anthony Liguori - Aug. 4, 2011, 4:21 p.m.
On 08/04/2011 11:14 AM, Avi Kivity wrote:
> On 08/04/2011 07:11 PM, Anthony Liguori wrote:
>> On 08/04/2011 11:00 AM, Avi Kivity wrote:
>>> On 08/01/2011 05:22 PM, Anthony Liguori wrote:
>>>> The char layer is confusing. There is a front-end, typically a device,
>>>> that
>>>> can send and receive data. The front-end sends data by calling
>>>> qemu_chr_write().
>>>>
>>>> The back-end, typically created via -chardev, can also send and
>>>> receive data.
>>>> Oddly, it sends data by calling qemu_chr_read().
>>>>
>>>> Let's be explicit about which function is for which party.
>>>
>>> A different way to accomplish this would be to have each pipe expose two
>>> interfaces (a front end and a back end), and use the same functions for
>>> both. Just like a unix pipe.
>>
>> This is exactly what I'm trying to do. This is why I decided to do
>> this before QOM, because this will change the relationships between
>> objects dramatically since you no longer need to subclass
>> CharDriverState since it's just being used as a pipe.
>
> Yes, I'm just talking about the function names, not about the
> implementation.
>
> qemu_chr_fe_write(chr,...) -> qemu_chr_write(chr, ...)
> qemu_chr_be_write(chr, ...) -> qemu_chr_write(&chr->backend, ...)

These are just the incremental patches to get us there.  Some more 
refactoring is needed to get to a single function.

Regards,

Anthony Liguori
Anthony Liguori - Aug. 4, 2011, 4:22 p.m.
On 08/04/2011 11:17 AM, Avi Kivity wrote:
> On 08/04/2011 07:14 PM, Avi Kivity wrote:
>>
>> Yes, I'm just talking about the function names, not about the
>> implementation.
>>
>> qemu_chr_fe_write(chr,...) -> qemu_chr_write(chr, ...)
>> qemu_chr_be_write(chr, ...) -> qemu_chr_write(&chr->backend, ...)
>>
>
> And, if you want an internal pipe:
>
> QemuPipeEndpoint pipe1, pipe2;
>
> qemu_chr_pipe_init(&pipe0, &pipe1);
>
> so clients don't have to choose between frontend and backend. Finally
> you can connect COM1: to COM2: with a qemu-provided null modem cable!

Yes, that's exactly the goal :-)

The only problem left to be resolved is how to handle ioctl(). 
qemu_chr_ioctl() forces asymmetry today.

I think if we merge ioctl into qemu_chr_event() by adding a return and 
data payload, it'll make the semantics be synchronous messaging and 
it'll be easy to make ioctl work.

Regards,

Anthony Liguori

>

Patch

diff --git a/gdbstub.c b/gdbstub.c
index 27b0cfa..d6c362e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -382,7 +382,7 @@  static void put_buffer(GDBState *s, const uint8_t *buf, int len)
         }
     }
 #else
-    qemu_chr_write(s->chr, buf, len);
+    qemu_chr_fe_write(s->chr, buf, len);
 #endif
 }
 
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 28eb9d1..082fd82 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -72,8 +72,8 @@  static void ccid_card_vscard_send_msg(PassthruState *s,
     scr_msg_header.type = htonl(type);
     scr_msg_header.reader_id = htonl(reader_id);
     scr_msg_header.length = htonl(length);
-    qemu_chr_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
-    qemu_chr_write(s->cs, payload, length);
+    qemu_chr_fe_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
+    qemu_chr_fe_write(s->cs, payload, length);
 }
 
 static void ccid_card_vscard_send_apdu(PassthruState *s,
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 5ee6821..c9ee6d9 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -51,7 +51,7 @@  static void debugcon_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val);
 #endif
 
-    qemu_chr_write(s->chr, &ch, 1);
+    qemu_chr_fe_write(s->chr, &ch, 1);
 }
 
 
diff --git a/hw/escc.c b/hw/escc.c
index f6fd919..c1460b7 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -578,7 +578,7 @@  static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
         s->tx = val;
         if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
             if (s->chr)
-                qemu_chr_write(s->chr, &s->tx, 1);
+                qemu_chr_fe_write(s->chr, &s->tx, 1);
             else if (s->type == kbd && !s->disabled) {
                 handle_kbd_command(s, val);
             }
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index b917d4d..35f8325 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -118,7 +118,7 @@  ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr)
     {
         case RW_DOUT:
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
             s->regs[R_INTR] |= 3;
             s->pending_tx = 1;
             s->regs[addr] = value;
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 169a56e..c90b810 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -114,7 +114,7 @@  grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr) {
     case DATA_OFFSET:
         c = value & 0xFF;
-        qemu_chr_write(uart->chr, &c, 1);
+        qemu_chr_fe_write(uart->chr, &c, 1);
         return;
 
     case STATUS_OFFSET:
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index fddcf7e..5454aa4 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -72,7 +72,7 @@  void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
 
     s->jtx = jtx;
     if (s->chr) {
-        qemu_chr_write(s->chr, &ch, 1);
+        qemu_chr_fe_write(s->chr, &ch, 1);
     }
 }
 
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index 09090e9..3678545 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -169,7 +169,7 @@  static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr) {
     case R_RXTX:
         if (s->chr) {
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         }
         break;
     case R_IER:
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index 905e116..747bc36 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -110,7 +110,7 @@  static void mcf_uart_do_tx(mcf_uart_state *s)
 {
     if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) {
         if (s->chr)
-            qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
+            qemu_chr_fe_write(s->chr, (unsigned char *)&s->tb, 1);
         s->sr |= MCF_UART_TxEMP;
     }
     if (s->tx_enabled) {
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index 56c90da..e8e309d 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -77,7 +77,7 @@  static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr) {
     case R_RXTX:
         if (s->chr) {
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         }
         trace_milkymist_uart_pulse_irq_tx();
         qemu_irq_pulse(s->tx_irq);
diff --git a/hw/omap2.c b/hw/omap2.c
index c9b3540..919318f 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -748,14 +748,14 @@  static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
 
     if (ch == STI_TRACE_CONTROL_CHANNEL) {
         /* Flush channel <i>value</i>.  */
-        qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
+        qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1);
     } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
         if (value == 0xc0 || value == 0xc3) {
             /* Open channel <i>ch</i>.  */
         } else if (value == 0x00)
-            qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
+            qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1);
         else
-            qemu_chr_write(s->chr, &byte, 1);
+            qemu_chr_fe_write(s->chr, &byte, 1);
     }
 }
 
diff --git a/hw/parallel.c b/hw/parallel.c
index cc853a5..f3e8219 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -120,7 +120,7 @@  parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
             if (val & PARA_CTR_STROBE) {
                 s->status &= ~PARA_STS_BUSY;
                 if ((s->control & PARA_CTR_STROBE) == 0)
-                    qemu_chr_write(s->chr, &s->dataw, 1);
+                    qemu_chr_fe_write(s->chr, &s->dataw, 1);
             } else {
                 if (s->control & PARA_CTR_INTEN) {
                     s->irq_pending = 1;
diff --git a/hw/pl011.c b/hw/pl011.c
index 997ce84..707a161 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -133,7 +133,7 @@  static void pl011_write(void *opaque, target_phys_addr_t offset,
         /* ??? Check if transmitter is enabled.  */
         ch = value;
         if (s->chr)
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         s->int_level |= PL011_INT_TX;
         pl011_update(s);
         break;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index cf93110..7516454 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1923,7 +1923,7 @@  static void pxa2xx_fir_write(void *opaque, target_phys_addr_t addr,
         else
             ch = ~value;
         if (s->chr && s->enable && (s->control[0] & (1 << 3)))	/* TXE */
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         break;
     case ICSR0:
         s->status[0] &= ~(value & 0x66);
diff --git a/hw/serial.c b/hw/serial.c
index 0ee61dd..dc6d1f8 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -334,7 +334,7 @@  static void serial_xmit(void *opaque)
     if (s->mcr & UART_MCR_LOOP) {
         /* in loopback mode, say that we just received a char */
         serial_receive1(s, &s->tsr, 1);
-    } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
+    } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
         if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
             s->tsr_retry++;
             qemu_mod_timer(s->transmit_timer,  new_xmit_ts + s->char_transmit_time);
diff --git a/hw/sh_serial.c b/hw/sh_serial.c
index 191f4a6..eabd726 100644
--- a/hw/sh_serial.c
+++ b/hw/sh_serial.c
@@ -105,7 +105,7 @@  static void sh_serial_write(void *opaque, uint32_t offs, uint32_t val)
     case 0x0c: /* FTDR / TDR */
         if (s->chr) {
             ch = val;
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
 	}
 	s->dr = val;
 	s->flags &= ~SH_SERIAL_FLAG_TDE;
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 6fc0105..f5046d9 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -50,8 +50,8 @@  void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
 {
     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
 
-    /* FIXME: should check the qemu_chr_write() return value */
-    qemu_chr_write(dev->chardev, buf, len);
+    /* FIXME: should check the qemu_chr_fe_write() return value */
+    qemu_chr_fe_write(dev->chardev, buf, len);
 }
 
 static int spapr_vty_init(VIOsPAPRDevice *sdev)
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 0e03d61..50fe0c0 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1067,7 +1067,7 @@  static void strongarm_uart_tx(void *opaque)
     if (s->utcr3 & UTCR3_LBM) /* loopback */ {
         strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
     } else if (s->chr) {
-        qemu_chr_write(s->chr, &s->tx_fifo[s->tx_start], 1);
+        qemu_chr_fe_write(s->chr, &s->tx_fifo[s->tx_start], 1);
     }
 
     s->tx_start = (s->tx_start + 1) % 8;
diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
index 2ef7175..25c6c9d 100644
--- a/hw/syborg_serial.c
+++ b/hw/syborg_serial.c
@@ -119,7 +119,7 @@  static void do_dma_tx(SyborgSerialState *s, uint32_t count)
         /* optimize later. Now, 1 byte per iteration */
         while (count--) {
             cpu_physical_memory_read(s->dma_tx_ptr, &ch, 1);
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
             s->dma_tx_ptr++;
         }
     } else {
@@ -203,7 +203,7 @@  static void syborg_serial_write(void *opaque, target_phys_addr_t offset,
     case SERIAL_DATA:
         ch = value;
         if (s->chr)
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         break;
     case SERIAL_INT_ENABLE:
         s->int_enable = value;
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 298c1e9..f093d18 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -369,7 +369,7 @@  static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
     case USB_TOKEN_OUT:
         if (devep != 2)
             goto fail;
-        qemu_chr_write(s->cs, data, len);
+        qemu_chr_fe_write(s->cs, data, len);
         break;
 
     case USB_TOKEN_IN:
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index fe5e188..6c386fa 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -27,7 +27,7 @@  static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
     ssize_t ret;
 
-    ret = qemu_chr_write(vcon->chr, buf, len);
+    ret = qemu_chr_fe_write(vcon->chr, buf, len);
     trace_virtio_console_flush_buf(port->id, len, ret);
 
     if (ret < 0) {
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 8ef104c..e218bb8 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -156,7 +156,7 @@  static void xencons_send(struct XenConsole *con)
 
     size = con->buffer.size - con->buffer.consumed;
     if (con->chr)
-        len = qemu_chr_write(con->chr, con->buffer.data + con->buffer.consumed,
+        len = qemu_chr_fe_write(con->chr, con->buffer.data + con->buffer.consumed,
                              size);
     else
         len = size;
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 9b94e98..467a26c 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -129,7 +129,7 @@  uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
 
         case R_TX:
             if (s->chr)
-                qemu_chr_write(s->chr, &ch, 1);
+                qemu_chr_fe_write(s->chr, &ch, 1);
 
             s->regs[addr] = value;
 
diff --git a/monitor.c b/monitor.c
index 1b8ba2c..38d4544 100644
--- a/monitor.c
+++ b/monitor.c
@@ -247,7 +247,7 @@  static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
 void monitor_flush(Monitor *mon)
 {
     if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
-        qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
+        qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index);
         mon->outbuf_index = 0;
     }
 }
diff --git a/qemu-char.c b/qemu-char.c
index 8e8cf31..fe5b28e 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -139,7 +139,7 @@  void qemu_chr_generic_open(CharDriverState *s)
     }
 }
 
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
+int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
 {
     return s->chr_write(s, buf, len);
 }
@@ -185,7 +185,7 @@  void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
     va_list ap;
     va_start(ap, fmt);
     vsnprintf(buf, sizeof(buf), fmt, ap);
-    qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
+    qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
     va_end(ap);
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index f361c6d..90f0c41 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -74,6 +74,7 @@  struct CharDriverState {
     char *filename;
     int opened;
     int avail_connections;
+
     QTAILQ_ENTRY(CharDriverState) next;
 };
 
@@ -87,7 +88,7 @@  void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
+int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
 void qemu_chr_add_handlers(CharDriverState *s,
                            IOCanReadHandler *fd_can_read,
diff --git a/slirp/slirp.c b/slirp/slirp.c
index df787ea..b2b04fd 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -838,7 +838,7 @@  int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
 {
 	if (so->s == -1 && so->extra) {
-		qemu_chr_write(so->extra, buf, len);
+		qemu_chr_fe_write(so->extra, buf, len);
 		return len;
 	}
 
diff --git a/usb-redir.c b/usb-redir.c
index e212993..606bc98 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -225,7 +225,7 @@  static int usbredir_write(void *priv, uint8_t *data, int count)
 {
     USBRedirDevice *dev = priv;
 
-    return qemu_chr_write(dev->cs, data, count);
+    return qemu_chr_fe_write(dev->cs, data, count);
 }
 
 /*