diff mbox series

[9/9] dev-serial: store flow control and xon/xoff characters

Message ID 20201026083401.13231-10-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series dev-serial: minor fixes and improvements | expand

Commit Message

Mark Cave-Ayland Oct. 26, 2020, 8:34 a.m. UTC
Note that whilst the device does not do anything with these values, they are
logged with trace events and stored to allow future implementation.

The default flow control is set to none at reset as documented in the Linux
ftdi_sio.h header file.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 hw/usb/dev-serial.c | 38 +++++++++++++++++++++++++++++++++++---
 hw/usb/trace-events |  2 ++
 2 files changed, 37 insertions(+), 3 deletions(-)

Comments

Samuel Thibault Oct. 26, 2020, 9:58 a.m. UTC | #1
Mark Cave-Ayland, le lun. 26 oct. 2020 08:34:01 +0000, a ecrit:
> Note that whilst the device does not do anything with these values, they are
> logged with trace events and stored to allow future implementation.
> 
> The default flow control is set to none at reset as documented in the Linux
> ftdi_sio.h header file.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

> ---
>  hw/usb/dev-serial.c | 38 +++++++++++++++++++++++++++++++++++---
>  hw/usb/trace-events |  2 ++
>  2 files changed, 37 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
> index fa734bcf54..3dbc56d77a 100644
> --- a/hw/usb/dev-serial.c
> +++ b/hw/usb/dev-serial.c
> @@ -52,6 +52,7 @@
>  
>  /* SET_FLOW_CTRL */
>  
> +#define FTDI_NO_HS         0
>  #define FTDI_RTS_CTS_HS    1
>  #define FTDI_DTR_DSR_HS    2
>  #define FTDI_XON_XOFF_HS   4
> @@ -98,6 +99,9 @@ struct USBSerialState {
>      uint8_t error_chr;
>      uint8_t event_trigger;
>      bool always_plugged;
> +    uint8_t flow_control;
> +    uint8_t xon;
> +    uint8_t xoff;
>      QEMUSerialSetParams params;
>      int latency;        /* ms */
>      CharBackend cs;
> @@ -181,14 +185,36 @@ static const USBDesc desc_braille = {
>      .str  = desc_strings,
>  };
>  
> +static void usb_serial_set_flow_control(USBSerialState *s,
> +                                        uint8_t flow_control)
> +{
> +    USBDevice *dev = USB_DEVICE(s);
> +    USBBus *bus = usb_bus_from_device(dev);
> +
> +    /* TODO: ioctl */
> +    s->flow_control = flow_control;
> +    trace_usb_serial_set_flow_control(bus->busnr, dev->addr, flow_control);
> +}
> +
> +static void usb_serial_set_xonxoff(USBSerialState *s, int xonxoff)
> +{
> +    USBDevice *dev = USB_DEVICE(s);
> +    USBBus *bus = usb_bus_from_device(dev);
> +
> +    s->xon = xonxoff & 0xff;
> +    s->xoff = (xonxoff >> 8) & 0xff;
> +
> +    trace_usb_serial_set_xonxoff(bus->busnr, dev->addr, s->xon, s->xoff);
> +}
> +
>  static void usb_serial_reset(USBSerialState *s)
>  {
> -    /* TODO: Set flow control to none */
>      s->event_chr = 0x0d;
>      s->event_trigger = 0;
>      s->recv_ptr = 0;
>      s->recv_used = 0;
>      /* TODO: purge in char driver */
> +    usb_serial_set_flow_control(s, FTDI_NO_HS);
>  }
>  
>  static void usb_serial_handle_reset(USBDevice *dev)
> @@ -285,9 +311,15 @@ static void usb_serial_handle_control(USBDevice *dev, USBPacket *p,
>          qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
>          break;
>      }
> -    case VendorDeviceOutRequest | FTDI_SET_FLOW_CTRL:
> -        /* TODO: ioctl */
> +    case VendorDeviceOutRequest | FTDI_SET_FLOW_CTRL: {
> +        uint8_t flow_control = index >> 8;
> +
> +        usb_serial_set_flow_control(s, flow_control);
> +        if (flow_control & FTDI_XON_XOFF_HS) {
> +            usb_serial_set_xonxoff(s, value);
> +        }
>          break;
> +    }
>      case VendorDeviceOutRequest | FTDI_SET_BAUD: {
>          static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 };
>          int subdivisor8 = subdivisors8[((value & 0xc000) >> 14)
> diff --git a/hw/usb/trace-events b/hw/usb/trace-events
> index 0d0a3e5f2a..725b7077ad 100644
> --- a/hw/usb/trace-events
> +++ b/hw/usb/trace-events
> @@ -331,3 +331,5 @@ usb_serial_unsupported_data_bits(int bus, int addr, int value) "dev %d:%d unsupp
>  usb_serial_bad_token(int bus, int addr) "dev %d:%d bad token"
>  usb_serial_set_baud(int bus, int addr, int baud) "dev %d:%d baud rate %d"
>  usb_serial_set_data(int bus, int addr, int parity, int data, int stop) "dev %d:%d parity %c, data bits %d, stop bits %d"
> +usb_serial_set_flow_control(int bus, int addr, int index) "dev %d:%d flow control %d"
> +usb_serial_set_xonxoff(int bus, int addr, uint8_t xon, uint8_t xoff) "dev %d:%d xon 0x%x xoff 0x%x"
> -- 
> 2.20.1
>
diff mbox series

Patch

diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
index fa734bcf54..3dbc56d77a 100644
--- a/hw/usb/dev-serial.c
+++ b/hw/usb/dev-serial.c
@@ -52,6 +52,7 @@ 
 
 /* SET_FLOW_CTRL */
 
+#define FTDI_NO_HS         0
 #define FTDI_RTS_CTS_HS    1
 #define FTDI_DTR_DSR_HS    2
 #define FTDI_XON_XOFF_HS   4
@@ -98,6 +99,9 @@  struct USBSerialState {
     uint8_t error_chr;
     uint8_t event_trigger;
     bool always_plugged;
+    uint8_t flow_control;
+    uint8_t xon;
+    uint8_t xoff;
     QEMUSerialSetParams params;
     int latency;        /* ms */
     CharBackend cs;
@@ -181,14 +185,36 @@  static const USBDesc desc_braille = {
     .str  = desc_strings,
 };
 
+static void usb_serial_set_flow_control(USBSerialState *s,
+                                        uint8_t flow_control)
+{
+    USBDevice *dev = USB_DEVICE(s);
+    USBBus *bus = usb_bus_from_device(dev);
+
+    /* TODO: ioctl */
+    s->flow_control = flow_control;
+    trace_usb_serial_set_flow_control(bus->busnr, dev->addr, flow_control);
+}
+
+static void usb_serial_set_xonxoff(USBSerialState *s, int xonxoff)
+{
+    USBDevice *dev = USB_DEVICE(s);
+    USBBus *bus = usb_bus_from_device(dev);
+
+    s->xon = xonxoff & 0xff;
+    s->xoff = (xonxoff >> 8) & 0xff;
+
+    trace_usb_serial_set_xonxoff(bus->busnr, dev->addr, s->xon, s->xoff);
+}
+
 static void usb_serial_reset(USBSerialState *s)
 {
-    /* TODO: Set flow control to none */
     s->event_chr = 0x0d;
     s->event_trigger = 0;
     s->recv_ptr = 0;
     s->recv_used = 0;
     /* TODO: purge in char driver */
+    usb_serial_set_flow_control(s, FTDI_NO_HS);
 }
 
 static void usb_serial_handle_reset(USBDevice *dev)
@@ -285,9 +311,15 @@  static void usb_serial_handle_control(USBDevice *dev, USBPacket *p,
         qemu_chr_fe_ioctl(&s->cs, CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
         break;
     }
-    case VendorDeviceOutRequest | FTDI_SET_FLOW_CTRL:
-        /* TODO: ioctl */
+    case VendorDeviceOutRequest | FTDI_SET_FLOW_CTRL: {
+        uint8_t flow_control = index >> 8;
+
+        usb_serial_set_flow_control(s, flow_control);
+        if (flow_control & FTDI_XON_XOFF_HS) {
+            usb_serial_set_xonxoff(s, value);
+        }
         break;
+    }
     case VendorDeviceOutRequest | FTDI_SET_BAUD: {
         static const int subdivisors8[8] = { 0, 4, 2, 1, 3, 5, 6, 7 };
         int subdivisor8 = subdivisors8[((value & 0xc000) >> 14)
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
index 0d0a3e5f2a..725b7077ad 100644
--- a/hw/usb/trace-events
+++ b/hw/usb/trace-events
@@ -331,3 +331,5 @@  usb_serial_unsupported_data_bits(int bus, int addr, int value) "dev %d:%d unsupp
 usb_serial_bad_token(int bus, int addr) "dev %d:%d bad token"
 usb_serial_set_baud(int bus, int addr, int baud) "dev %d:%d baud rate %d"
 usb_serial_set_data(int bus, int addr, int parity, int data, int stop) "dev %d:%d parity %c, data bits %d, stop bits %d"
+usb_serial_set_flow_control(int bus, int addr, int index) "dev %d:%d flow control %d"
+usb_serial_set_xonxoff(int bus, int addr, uint8_t xon, uint8_t xoff) "dev %d:%d xon 0x%x xoff 0x%x"