Patchwork virtio-serial: Send per-console port resize notifications to guest

login
register
mail settings
Submitter Amit Shah
Date May 5, 2010, 8:48 p.m.
Message ID <1273092505-22783-1-git-send-email-amit.shah@redhat.com>
Download mbox | patch
Permalink /patch/51766/
State New
Headers show

Comments

Amit Shah - May 5, 2010, 8:48 p.m.
From: Kusanagi Kouichi <slash@ac.auone-net.jp>

Add a new API, virtio_serial_resize_console(port, rows, cols), to notify
the guest of console size updates.

This works for both, !MULTIPORT and MULTIPORT cases. For the former
case, we send updates via virtio config changes, whereas in the latter,
the config changes are deprecated and the VIRTIO_CONSOLE_RESIZE control
message is used instead.

[Amit: Add per-port row,col notification to the guest via control
       message, split off virtio-console.c patch]

Signed-off-by: Kusanagi Kouichi <slash@ac.auone-net.jp>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
---
 hw/virtio-serial-bus.c |   36 ++++++++++++++++++++++++++++++++++++
 hw/virtio-serial.h     |   13 +++++++++++--
 2 files changed, 47 insertions(+), 2 deletions(-)

Patch

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 3ce95e8..52649b4 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -205,6 +205,41 @@  int virtio_serial_close(VirtIOSerialPort *port)
     return 0;
 }
 
+void virtio_serial_resize_console(VirtIOSerialPort *port, int rows, int cols)
+{
+    struct virtio_console_control cpkt;
+    struct {
+        uint16_t rows;
+        uint16_t cols;
+    } size;
+    uint8_t *buffer;
+    size_t buffer_len;
+
+    if (!use_multiport(port->vser)) {
+        port->vser->config.rows = rows;
+        port->vser->config.cols = cols;
+
+        virtio_notify_config(&port->vser->vdev);
+        return;
+    }
+
+    /* For MULTIPORT case, each port can have a different size */
+    stw_p(&cpkt.event, VIRTIO_CONSOLE_RESIZE);
+    stw_p(&cpkt.value, 1);
+
+    stw_p(&size.rows, rows);
+    stw_p(&size.cols, cols);
+
+    buffer_len = sizeof(cpkt) + sizeof(size);
+    buffer = qemu_malloc(buffer_len);
+
+    memcpy(buffer, &cpkt, sizeof(cpkt));
+    memcpy(buffer + sizeof(cpkt), &size, sizeof(size));
+
+    send_control_msg(port, buffer, buffer_len);
+    qemu_free(buffer);
+}
+
 /* Individual ports/apps call this function to write to the guest. */
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
                             size_t size)
@@ -425,6 +460,7 @@  static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
 
     vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
 
+    features |= (1 << VIRTIO_CONSOLE_F_SIZE);
     if (vser->bus->max_nr_ports > 1) {
         features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
     }
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index a93b545..912287c 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -25,14 +25,18 @@ 
 #define VIRTIO_ID_CONSOLE		3
 
 /* Features supported */
+#define VIRTIO_CONSOLE_F_SIZE		0
 #define VIRTIO_CONSOLE_F_MULTIPORT	1
 
 #define VIRTIO_CONSOLE_BAD_ID           (~(uint32_t)0)
 
 struct virtio_console_config {
     /*
-     * These two fields are used by VIRTIO_CONSOLE_F_SIZE which
-     * isn't implemented here yet
+     * These two fields are unused if multiport is enabled.  When
+     * multiport is disabled, they hold the size of the underlying
+     * chardev.  When a chardev is resized, the guest is notified by a
+     * config space update.  When multiport is enabled, a control
+     * message is sent instead.
      */
     uint16_t cols;
     uint16_t rows;
@@ -165,6 +169,11 @@  int virtio_serial_open(VirtIOSerialPort *port);
 int virtio_serial_close(VirtIOSerialPort *port);
 
 /*
+ * Notify resize to the guest
+ */
+void virtio_serial_resize_console(VirtIOSerialPort *port, int rows, int cols);
+
+/*
  * Send data to Guest
  */
 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,