svn commit: r274215 - head/sys/dev/virtio/console
Bryan Venteicher
bryanv at FreeBSD.org
Fri Nov 7 03:36:29 UTC 2014
Author: bryanv
Date: Fri Nov 7 03:36:28 2014
New Revision: 274215
URL: https://svnweb.freebsd.org/changeset/base/274215
Log:
Several minor changes to hopefully complete the VirtIO console driver
- Support the KDB alt break sequence to enter the debugger,
panic, reboot, etc. [1]
- Provide emergency write feature description. Note that QEMU
does not implement this feature.
- Make the VTCON_FLAG_* defines sequential once again.
- When the multiple port feature is not negotiated, query the
rows and columns of the one console during the device attach
when the size feature is negotiated.
- Report failure to the device if hot plugging a port fails.
- Acknowledge the console port event with an open event. This
is required by the spec, but QEMU doesn't seem to care.
Submitted by: Juniper [1]
MFC after: 1 month
Modified:
head/sys/dev/virtio/console/virtio_console.c
Modified: head/sys/dev/virtio/console/virtio_console.c
==============================================================================
--- head/sys/dev/virtio/console/virtio_console.c Fri Nov 7 03:07:10 2014 (r274214)
+++ head/sys/dev/virtio/console/virtio_console.c Fri Nov 7 03:36:28 2014 (r274215)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/kdb.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sglist.h>
@@ -78,6 +79,11 @@ struct vtcon_port {
int vtcport_id;
int vtcport_flags;
#define VTCON_PORT_FLAG_GONE 0x01
+#define VTCON_PORT_FLAG_CONSOLE 0x02
+
+#if defined(KDB)
+ int vtcport_alt_break_state;
+#endif
};
#define VTCON_PORT_LOCK(_port) mtx_lock(&(_port)->vtcport_mtx)
@@ -94,17 +100,11 @@ struct vtcon_softc {
device_t vtcon_dev;
struct mtx vtcon_mtx;
uint64_t vtcon_features;
- uint32_t vtcon_flags;
-#define VTCON_FLAG_DETACHED 0x0001
-#define VTCON_FLAG_SIZE 0x0010
-#define VTCON_FLAG_MULTIPORT 0x0020
-
- struct task vtcon_ctrl_task;
- struct virtqueue *vtcon_ctrl_rxvq;
- struct virtqueue *vtcon_ctrl_txvq;
- struct mtx vtcon_ctrl_tx_mtx;
-
uint32_t vtcon_max_ports;
+ uint32_t vtcon_flags;
+#define VTCON_FLAG_DETACHED 0x01
+#define VTCON_FLAG_SIZE 0x02
+#define VTCON_FLAG_MULTIPORT 0x04
/*
* Ports can be added and removed during runtime, but we have
@@ -112,6 +112,11 @@ struct vtcon_softc {
* indexed by the port ID.
*/
struct vtcon_softc_port *vtcon_ports;
+
+ struct task vtcon_ctrl_task;
+ struct virtqueue *vtcon_ctrl_rxvq;
+ struct virtqueue *vtcon_ctrl_txvq;
+ struct mtx vtcon_ctrl_tx_mtx;
};
#define VTCON_LOCK(_sc) mtx_lock(&(_sc)->vtcon_mtx)
@@ -133,6 +138,7 @@ struct vtcon_softc {
static struct virtio_feature_desc vtcon_feature_desc[] = {
{ VIRTIO_CONSOLE_F_SIZE, "ConsoleSize" },
{ VIRTIO_CONSOLE_F_MULTIPORT, "MultiplePorts" },
+ { VIRTIO_CONSOLE_F_EMERG_WRITE, "EmergencyWrite" },
{ 0, NULL }
};
@@ -331,10 +337,15 @@ vtcon_attach(device_t dev)
if (sc->vtcon_flags & VTCON_FLAG_MULTIPORT) {
TASK_INIT(&sc->vtcon_ctrl_task, 0, vtcon_ctrl_task_cb, sc);
error = vtcon_ctrl_init(sc);
- } else
+ if (error)
+ goto fail;
+ } else {
error = vtcon_port_create(sc, 0);
- if (error)
- goto fail;
+ if (error)
+ goto fail;
+ if (sc->vtcon_flags & VTCON_FLAG_SIZE)
+ vtcon_port_update_console_size(sc);
+ }
error = virtio_setup_intr(dev, INTR_TYPE_TTY);
if (error) {
@@ -703,6 +714,7 @@ vtcon_ctrl_port_add_event(struct vtcon_s
if (error) {
device_printf(dev, "%s: cannot create port %d: %d\n",
__func__, id, error);
+ vtcon_ctrl_send_control(sc, id, VIRTIO_CONSOLE_PORT_READY, 0);
return;
}
}
@@ -735,9 +747,27 @@ vtcon_ctrl_port_remove_event(struct vtco
static void
vtcon_ctrl_port_console_event(struct vtcon_softc *sc, int id)
{
+ device_t dev;
+ struct vtcon_softc_port *scport;
+ struct vtcon_port *port;
+
+ dev = sc->vtcon_dev;
+ scport = &sc->vtcon_ports[id];
+
+ VTCON_LOCK(sc);
+ port = scport->vcsp_port;
+ if (port == NULL) {
+ VTCON_UNLOCK(sc);
+ device_printf(dev, "%s: console port %d, but does not exist\n",
+ __func__, id);
+ return;
+ }
- device_printf(sc->vtcon_dev, "%s: port %d console event\n",
- __func__, id);
+ VTCON_PORT_LOCK(port);
+ VTCON_UNLOCK(sc);
+ port->vtcport_flags |= VTCON_PORT_FLAG_CONSOLE;
+ vtcon_port_submit_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
+ VTCON_PORT_UNLOCK(port);
}
static void
@@ -1179,8 +1209,14 @@ again:
deq = 0;
while ((buf = virtqueue_dequeue(vq, &len)) != NULL) {
- for (i = 0; i < len; i++)
+ for (i = 0; i < len; i++) {
+#if defined(KDB)
+ if (port->vtcport_flags & VTCON_PORT_FLAG_CONSOLE)
+ kdb_alt_break(buf[i],
+ &port->vtcport_alt_break_state);
+#endif
ttydisc_rint(tp, buf[i], 0);
+ }
vtcon_port_requeue_buf(port, buf);
deq++;
}
More information about the svn-src-all
mailing list