Page MenuHomeFreeBSD

D8680.diff
No OneTemporary

D8680.diff

Index: sys/dev/virtio/console/virtio_console.c
===================================================================
--- sys/dev/virtio/console/virtio_console.c
+++ sys/dev/virtio/console/virtio_console.c
@@ -74,6 +74,11 @@
struct vtcon_softc *vtcport_sc;
struct vtcon_softc_port *vtcport_scport;
struct tty *vtcport_tty;
+ struct consdev *vtcport_consdev;
+ char *vtcport_name;
+ char *vtcport_buf;
+ uint32_t vtcport_buf_len;
+ uint32_t vtcport_buf_pos;
struct virtqueue *vtcport_invq;
struct virtqueue *vtcport_outvq;
int vtcport_id;
@@ -228,6 +233,24 @@
.tsw_free = vtcon_tty_free,
};
+static cn_probe_t vtcon_cnprobe;
+static cn_init_t vtcon_cninit;
+static cn_term_t vtcon_cnterm;
+static cn_getc_t vtcon_cngetc;
+static cn_putc_t vtcon_cnputc;
+static cn_grab_t vtcon_cngrab;
+static cn_ungrab_t vtcon_cnungrab;
+
+const struct consdev_ops vtcon_cnops = {
+ .cn_probe = vtcon_cnprobe,
+ .cn_init = vtcon_cninit,
+ .cn_term = vtcon_cnterm,
+ .cn_getc = vtcon_cngetc,
+ .cn_putc = vtcon_cnputc,
+ .cn_grab = vtcon_cngrab,
+ .cn_ungrab = vtcon_cnungrab,
+};
+
static device_method_t vtcon_methods[] = {
/* Device methods. */
DEVMETHOD(device_probe, vtcon_probe),
@@ -252,6 +275,99 @@
MODULE_VERSION(virtio_console, 1);
MODULE_DEPEND(virtio_console, virtio, 1, 1, 1);
+static void
+vtcon_cnregister(struct vtcon_port *port)
+{
+ struct consdev *cp;
+
+ cp = port->vtcport_consdev;
+ if (cp == NULL) {
+ cp = malloc(sizeof(struct consdev), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ cp->cn_ops = &vtcon_cnops;
+ cp->cn_arg = port;
+ cp->cn_pri = CN_REMOTE;
+ if (port->vtcport_name != NULL) {
+ strlcpy(cp->cn_name, port->vtcport_name,
+ sizeof(cp->cn_name));
+ } else {
+ snprintf(cp->cn_name, sizeof(cp->cn_name), "%s%r.%r",
+ VTCON_TTY_PREFIX,
+ device_get_unit(port->vtcport_sc->vtcon_dev),
+ port->vtcport_id);
+ }
+ port->vtcport_consdev = cp;
+ }
+
+ /* Attach the port as console. */
+ cnadd(cp);
+}
+
+static void
+vtcon_cngrab(struct consdev *cp)
+{
+}
+
+static void
+vtcon_cnungrab(struct consdev *cp)
+{
+}
+
+static void
+vtcon_cnprobe(struct consdev *cp)
+{
+}
+
+static void
+vtcon_cninit(struct consdev *cp)
+{
+}
+
+static void
+vtcon_cnterm(struct consdev *cp)
+{
+}
+
+static int
+vtcon_cngetc(struct consdev *cp)
+{
+ struct vtcon_port *port;
+ struct virtqueue *vq;
+ uint32_t len;
+ int ret;
+
+ port = cp->cn_arg;
+ vq = port->vtcport_invq;
+ if (port->vtcport_buf == NULL) {
+ port->vtcport_buf = virtqueue_dequeue(vq, &len);
+ if (port->vtcport_buf == NULL)
+ return (-1);
+ port->vtcport_buf_len = len;
+ port->vtcport_buf_pos = 0;
+ }
+
+ ret = port->vtcport_buf[port->vtcport_buf_pos];
+ port->vtcport_buf_pos++;
+ if (port->vtcport_buf_pos == port->vtcport_buf_len) {
+ vtcon_port_requeue_buf(port, port->vtcport_buf);
+ virtqueue_notify(vq);
+ port->vtcport_buf = NULL;
+ }
+ return (ret);
+}
+
+static void
+vtcon_cnputc(struct consdev *cp, int c)
+{
+ struct vtcon_port *port = cp->cn_arg;
+ char cv = c;
+
+ /*VTCON_PORT_LOCK(port);*/
+ if ((port->vtcport_flags & VTCON_PORT_FLAG_GONE) == 0)
+ vtcon_port_out(port, &cv, 1);
+ /*VTCON_PORT_UNLOCK(port);*/
+}
+
static int
vtcon_modevent(module_t mod, int type, void *unused)
{
@@ -773,6 +889,7 @@
port->vtcport_flags |= VTCON_PORT_FLAG_CONSOLE;
vtcon_port_submit_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
VTCON_PORT_UNLOCK(port);
+ vtcon_cnregister(port);
}
static void
@@ -818,6 +935,7 @@
return;
}
+ port->vtcport_name = strndup(name, len, M_DEVBUF);
tty_makealias(port->vtcport_tty, "vtcon/%*s", (int)len, name);
}
@@ -1160,6 +1278,10 @@
port->vtcport_flags |= VTCON_PORT_FLAG_GONE;
+ if (port->vtcport_consdev != NULL)
+ cnremove(port->vtcport_consdev);
+ free(port->vtcport_name, M_DEVBUF);
+
if (tp != NULL) {
atomic_add_int(&vtcon_pending_free, 1);
tty_rel_gone(tp);

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 10, 6:56 AM (17 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31207746
Default Alt Text
D8680.diff (3 KB)

Event Timeline