PERFORCE change 77951 for review
Marcel Moolenaar
marcel at FreeBSD.org
Fri Jun 3 22:26:39 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=77951
Change 77951 by marcel at marcel_nfs on 2005/06/04 05:26:03
Submit some large changes before something happens:
o Add logic to handle device preemption. If the VGA driver is
the low-level console, we need to tell the accelerated driver
for the hardware about it. Otherwise it'll initialize the
hardware and render the low-level console useless. If the
accel driver knows that the hardware is used for the low-
level console, it can delay initializing the hardware until
the virtual consoles are ready for use.
o Have the GMCH driver save the device_t of the DRAM controller
so that it can figure out the refresh rate of the local
memory. This is needed to properly program the hardware.
o If the VGA driver attaches during bus enumeration, register
it with VTC. This will trigger the creation of a virtual
terminal with terminal emulator.
o Prevent the VGA driver from probing the ISA bus when we have
found PCI based hardware.
o Express the display depth in bits, not colors.
o Implement the bulk of the VTC TTY layer. Needs a more work.
o Implement TE support functions. A single TE can drive more
than one graphics card and they don't have to have the same
resolution. To deal with this, TEs operate with a character-
based resolution (80x24 for VT100). Based on this and the
resolution of the graphics device, a matching font is found
by the TE support layer. To support double-width and double-
height modes, a scaling factor is passed down to the support
functions so that a bigger font can be selected.
Note: The initial configuration of VTC maps all graphics cards
and keyboards (not yet dealt with) to a single virtual terminal.
Once in multi-user mode, this should be reconfigurable so that
there's a TE per graphics card.
Affected files ...
.. //depot/projects/tty/sys/dev/vtc/hw/gmch/gmch.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/hw/gmch/gmch_bus_pci.c#4 edit
.. //depot/projects/tty/sys/dev/vtc/hw/vga/vga.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/hw/vga/vga.h#3 edit
.. //depot/projects/tty/sys/dev/vtc/hw/vga/vga_bus_isa.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/hw/vga/vga_bus_pci.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/hw/vga/vga_con.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_con.c#9 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_con.h#3 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_core.c#5 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_font.c#5 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_logo.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_te.c#2 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_te.h#3 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_te_if.m#3 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_te_vt102.c#3 edit
.. //depot/projects/tty/sys/dev/vtc/vtc_tty.c#2 edit
Differences ...
==== //depot/projects/tty/sys/dev/vtc/hw/gmch/gmch.c#3 (text+ko) ====
@@ -34,6 +34,7 @@
#include <sys/bus.h>
#include <sys/rman.h>
+#include <dev/vtc/vtc_vtout.h>
#include <dev/vtc/hw/gmch/gmch.h>
devclass_t gmch_devclass;
@@ -44,6 +45,9 @@
{
struct gmch_softc *sc;
+ if (vtc_vtout_console(dev))
+ device_printf(dev, "console!\n");
+
sc = device_get_softc(dev);
sc->gmch_dev = dev;
return (0);
==== //depot/projects/tty/sys/dev/vtc/hw/gmch/gmch_bus_pci.c#4 (text+ko) ====
@@ -42,9 +42,12 @@
#include <dev/vtc/hw/gmch/gmch.h>
#define PCI_VENDOR_INTEL 0x8086
-#define PCI_DEVICE_I815 0x1132
+#define PCI_DEVICE_I815_DRAM 0x1130
+#define PCI_DEVICE_I815_GUI 0x1132
#define PCI_DEVICE_I830M 0x3577
+static device_t gmch_dram_controller;
+
static int gmch_pci_attach(device_t dev);
static int gmch_pci_probe(device_t dev);
@@ -91,13 +94,23 @@
gmch_pci_probe(device_t dev)
{
+ if (pci_get_vendor(dev) != PCI_VENDOR_INTEL)
+ return (ENXIO);
+
+ /*
+ * Save the device_t of the DRAM controller of the i815 chipset.
+ * We need it in case we do get to attach to the GUI accel.
+ */
+ if (pci_get_device(dev) == PCI_DEVICE_I815_DRAM) {
+ gmch_dram_controller = dev;
+ return (ENXIO);
+ }
+
if (pci_get_class(dev) != PCIC_DISPLAY)
return (ENXIO);
- if (pci_get_vendor(dev) != PCI_VENDOR_INTEL)
- return (ENXIO);
switch (pci_get_device(dev)) {
- case PCI_DEVICE_I815:
+ case PCI_DEVICE_I815_GUI:
device_set_desc(dev, "82815/EM/EP/P Internal GUI Accelerator");
break;
case PCI_DEVICE_I830M:
==== //depot/projects/tty/sys/dev/vtc/hw/vga/vga.c#3 (text+ko) ====
@@ -34,9 +34,11 @@
#include <sys/bus.h>
#include <sys/rman.h>
+#include <dev/vtc/vtc.h>
+#include <dev/vtc/vtc_vtout.h>
+
#include <dev/ic/vga.h>
#include <dev/vtc/hw/vga/vga.h>
-#include <dev/vtc/vtc.h>
/* Convenience macros. */
#define MEM_READ(sc, ofs) \
@@ -441,6 +443,20 @@
return (error);
}
+static int
+vga_bitblt(void *cookie, int op, uintptr_t src, uintptr_t dst, int width,
+ int height, ...)
+{
+ struct vga_softc *sc = (struct vga_softc *)cookie;
+ va_list ap;
+ int error;
+
+ va_start(ap, height);
+ error = vga_vbitblt(sc, op, src, dst, width, height, ap);
+ va_end(ap);
+ return (error);
+}
+
int
vga_attach(device_t dev)
{
@@ -460,5 +476,5 @@
640 * (480 - vtc_logo4_height) / 2 + (640 - vtc_logo4_width) / 2,
vtc_logo4_width, vtc_logo4_height);
- return (0);
+ return (vtc_vtout_attach(sc, vga_bitblt, 640, 480));
}
==== //depot/projects/tty/sys/dev/vtc/hw/vga/vga.h#3 (text+ko) ====
@@ -41,6 +41,7 @@
{
device_t vga_dev;
dev_t vga_node;
+ struct vtc_conout *vga_conout;
/* Device flags and state. */
int vga_bustype:2;
==== //depot/projects/tty/sys/dev/vtc/hw/vga/vga_bus_isa.c#3 (text+ko) ====
@@ -39,6 +39,8 @@
#include <isa/isareg.h>
#include <isa/isavar.h>
+#include <dev/vtc/vtc_con.h>
+
#include <dev/ic/vga.h>
#include <dev/vtc/hw/vga/vga.h>
@@ -69,6 +71,14 @@
vga_isa_probe(device_t dev)
{
+ /*
+ * We can get called even when there's a PCI VGA device. It happens
+ * when an accelerated driver for the hardware exists that preempts
+ * the VGA driver. We check for this and bail out right away.
+ */
+ if (vga_console.vga_conout->vtc_busdev != NULL)
+ return (ENXIO);
+
printf("ISA VGA is being probed!\n");
return (ENXIO);
}
==== //depot/projects/tty/sys/dev/vtc/hw/vga/vga_bus_pci.c#3 (text+ko) ====
@@ -39,6 +39,8 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#include <dev/vtc/vtc_con.h>
+
#include <dev/ic/vga.h>
#include <dev/vtc/hw/vga/vga.h>
@@ -132,6 +134,20 @@
if ((cfg & PCIM_CMD_PORTEN) == 0)
return (ENXIO);
+ /*
+ * Handle preemption in case we're the VTC console. We typically
+ * don't get to attach when there's an accelerated driver for the
+ * hardware. The problem is that we like to continue to use the
+ * hardware for the low-level console until we're ready to switch
+ * to the virtual terminal, at which time the accelerated driver
+ * can take control. We handshake by letting VTC know what the
+ * device_t for the hardware is so that accelerated drivers can
+ * check whether they're attaching to the low-level console device
+ * or not and take appropriate action.
+ */
+ if (vga_console.vga_console)
+ vga_console.vga_conout->vtc_busdev = dev;
+
return (BUS_PROBE_GENERIC);
}
==== //depot/projects/tty/sys/dev/vtc/hw/vga/vga_con.c#3 (text+ko) ====
@@ -65,7 +65,7 @@
co->vtc_con_cookie = &vga_console;
co->vtc_con_width = 640;
co->vtc_con_height = 480;
- co->vtc_con_depth = 16;
+ co->vtc_con_depth = 4;
return (0);
}
@@ -74,8 +74,10 @@
{
struct vga_softc *sc = co->vtc_con_cookie;
- if (vga_init(sc) == 0)
+ if (vga_init(sc) == 0) {
+ sc->vga_conout = co;
sc->vga_console = 1;
+ }
}
static void
==== //depot/projects/tty/sys/dev/vtc/vtc_con.c#9 (text+ko) ====
@@ -52,8 +52,6 @@
CONS_DRIVER(vtc, vtc_cnprobe, vtc_cninit, vtc_cnterm, vtc_cngetc, vtc_cncheckc,
vtc_cnputc, NULL);
-SET_DECLARE(vtc_conout_set, struct vtc_conout);
-
static void
vtc_cnprobe(struct consdev *cp)
{
@@ -80,6 +78,7 @@
{
struct vtc_conout *vc = cp->cn_arg;
+ vc->vtc_consdev = cp;
vc->vtc_con_init(vc);
}
==== //depot/projects/tty/sys/dev/vtc/vtc_con.h#3 (text+ko) ====
@@ -37,11 +37,13 @@
typedef int vtc_con_probe_f(struct vtc_conout *);
struct vtc_conout {
+ struct consdev *vtc_consdev;
+ device_t vtc_busdev;
const char *vtc_con_name;
vtc_con_probe_f *vtc_con_probe;
vtc_con_init_f *vtc_con_init;
vtc_con_bitblt_f *vtc_con_bitblt;
- void * vtc_con_cookie;
+ void *vtc_con_cookie;
int vtc_con_width;
int vtc_con_height;
int vtc_con_depth;
@@ -53,11 +55,9 @@
.vtc_con_probe = probe, \
.vtc_con_init = init, \
.vtc_con_bitblt = bitblt, \
- .vtc_con_cookie = NULL, \
- .vtc_con_width = -1, \
- .vtc_con_height = -1, \
- .vtc_con_depth = -1 \
}; \
DATA_SET(vtc_conout_set, name##_vtc_conout)
+SET_DECLARE(vtc_conout_set, struct vtc_conout);
+
#endif /* !_DEV_VTC_CON_H_ */
==== //depot/projects/tty/sys/dev/vtc/vtc_core.c#5 (text+ko) ====
@@ -1,4 +1,4 @@
-/*
+/*-
* Copyright (c) 2003-2005 Marcel Moolenaar
* All rights reserved.
*
@@ -29,14 +29,161 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
+#include <sys/kobj.h>
+#include <sys/malloc.h>
#include <sys/module.h>
+#include <sys/tty.h>
#include <dev/vtc/vtc.h>
+#include <dev/vtc/vtc_con.h>
+#include <dev/vtc/vtc_te.h>
+#include <dev/vtc/vtc_vtout.h>
+#include "vtc_te_if.h"
+
char vtc_device_name[] = "vtc";
+TAILQ_HEAD(, vtc_te_softc) vtc_te_devs =
+ TAILQ_HEAD_INITIALIZER(vtc_te_devs);
+TAILQ_HEAD(, vtc_vtout_softc) vtc_vtout_devs =
+ TAILQ_HEAD_INITIALIZER(vtc_vtout_devs);
+
+MALLOC_DEFINE(M_VTC, "VTC", "VTC driver");
+
+extern struct vtc_te_class vt102_class;
+
+static int
+vtc_tty_open(struct tty *tp, struct cdev *dev)
+{
+ struct vtc_te_softc *te;
+
+ te = tp->t_sc;
+ /* XXX notify the TE that we're opened? */
+ return (0);
+}
+
+static void
+vtc_tty_close(struct tty *tp)
+{
+ struct vtc_te_softc *te;
+
+ te = tp->t_sc;
+ if (te == NULL)
+ return;
+
+ wakeup(te);
+}
+
+static void
+vtc_tty_oproc(struct tty *tp)
+{
+ struct vtc_te_softc *te;
+
+ te = tp->t_sc;
+ if (te == NULL)
+ return;
+
+ if (tp->t_state & (TS_TTSTOP | TS_BUSY))
+ return;
+
+ if (tp->t_outq.c_cc > 0) {
+ tp->t_state |= TS_BUSY;
+ /* XXX loop to display all characters in the buffer. */
+ tp->t_state &= ~TS_BUSY;
+ }
+
+ ttwwakeup(tp);
+}
+
+static int
+vtc_tty_param(struct tty *tp, struct termios *t)
+{
+ struct vtc_te_softc *te;
+
+ te = tp->t_sc;
+ if (te == NULL)
+ return (ENODEV);
+
+ ttsetwater(tp);
+ return (0);
+}
+
+static int
+vtc_tty_modem(struct tty *tp, int biton, int bitoff)
+{
+
+ return (0);
+}
+
+static void
+vtc_tty_break(struct tty *tp, int state)
+{
+}
+
+static void
+vtc_tty_stop(struct tty *tp, int rw)
+{
+}
+
+int
+vtc_vtout_attach(void *cookie, vtout_bitblt_f bitblt, int width, int height)
+{
+ struct vtc_te_softc *te;
+ struct tty *tp;
+ struct vtc_vtout_softc *vo;
+
+ vo = malloc(sizeof(*vo), M_VTC, M_WAITOK|M_ZERO);
+ TAILQ_INSERT_TAIL(&vtc_vtout_devs, vo, vo_alldevs);
+ vo->vo_cookie = cookie;
+ vo->vo_bitblt = bitblt;
+ vo->vo_width = width;
+ vo->vo_height = height;
+
+ te = malloc(vt102_class.size, M_VTC, M_WAITOK|M_ZERO);
+ TAILQ_INSERT_TAIL(&vtc_te_devs, te, te_alldevs);
+ TAILQ_INIT(&te->te_vodevs);
+ TAILQ_INSERT_TAIL(&te->te_vodevs, vo, vo_tedevs);
+
+ VTC_TE_RESET(te);
+
+ tp = ttyalloc();
+ te->te_tty = tp;
+ tp->t_sc = te;
+
+ tp->t_oproc = vtc_tty_oproc;
+ tp->t_param = vtc_tty_param;
+ tp->t_stop = vtc_tty_stop;
+ tp->t_modem = vtc_tty_modem;
+ tp->t_break = vtc_tty_break;
+ tp->t_open = vtc_tty_open;
+ tp->t_close = vtc_tty_close;
+
+/*
+ sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name, "ttyv%r",
+ unit);
+*/
+ ttyconsolemode(tp, 0);
+
+ ttycreate(tp, NULL, 0, MINOR_CALLOUT, "v%r", 0);
+ return (0);
+}
+
+int
+vtc_vtout_console(device_t dev)
+{
+ struct vtc_conout *vc, **iter;
+
+ SET_FOREACH(iter, vtc_conout_set) {
+ vc = *iter;
+ if (vc->vtc_busdev == dev)
+ return (1);
+ }
+ return (0);
+}
+
static int
vtc_modevent(module_t mod, int type, void *data)
{
==== //depot/projects/tty/sys/dev/vtc/vtc_font.c#5 (text+ko) ====
@@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+
#include <dev/vtc/vtc.h>
unsigned char vtc_font_8x16[95 * 16] = {
==== //depot/projects/tty/sys/dev/vtc/vtc_logo.c#3 (text+ko) ====
@@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+
#include <dev/vtc/vtc.h>
#define __ 0
==== //depot/projects/tty/sys/dev/vtc/vtc_te.c#2 (text+ko) ====
@@ -31,11 +31,70 @@
#include <sys/systm.h>
#include <sys/kobj.h>
+#include <dev/vtc/vtc.h>
#include <dev/vtc/vtc_te.h>
+#include <dev/vtc/vtc_vtout.h>
+
+int
+vtc_te_bell(struct vtc_te_softc *te)
+{
+
+ return (ENXIO);
+}
int
-vtc_te_bell(struct vtc_te_softc *sc)
+vtc_te_putc(struct vtc_te_softc *te, int row, int col, int ws, int hs, int fl,
+ __wchar_t wc)
+{
+ struct vtc_vtout_softc *vo;
+ uint8_t *glyph;
+
+ KASSERT(wc >= 0x20, ("Unexpected control character"));
+
+ TAILQ_FOREACH(vo, &te->te_vodevs, vo_tedevs) {
+ if (vo->vo_ws != ws || vo->vo_hs != hs) {
+ vo->vo_cw = (vo->vo_width / te->te_maxcol) * ws;
+ vo->vo_ch = (vo->vo_height / te->te_maxrow) * hs;
+ /*
+ * Lookup matching font, with glyphs no wider than
+ * vtout->vo_cw and no higher than vtout->vo_ch.
+ */
+ vo->vo_font = vtc_font_8x16;
+ }
+
+ glyph = vo->vo_font + (wc - 0x20) * 16;
+ vo->vo_bitblt(vo->vo_cookie, BITBLT_H1TOFB, (uintptr_t)glyph,
+ vo->vo_width * row * vo->vo_ch + col * vo->vo_cw,
+ 8, 16, 0, 7);
+ }
+ return (0);
+}
+
+int
+vtc_te_repos(struct vtc_te_softc *te, int row, int col)
{
return (ENXIO);
}
+
+int
+vtc_te_scroll(struct vtc_te_softc *te, int ulr, int ulc, int lrr, int lrc,
+ int hs)
+{
+ struct vtc_vtout_softc *vo;
+ int ch, cw;
+
+ TAILQ_FOREACH(vo, &te->te_vodevs, vo_tedevs) {
+ ch = vo->vo_height / te->te_maxrow;
+ cw = vo->vo_width / te->te_maxcol;
+
+ vo->vo_bitblt(vo->vo_cookie, BITBLT_FBTOFB,
+ vo->vo_width * (ulr + hs) * ch + ulc * cw,
+ vo->vo_width * ulr * ch + ulc * cw,
+ (lrc - ulc) * cw, (lrr - ulr - hs) * ch);
+
+ vo->vo_bitblt(vo->vo_cookie, BITBLT_CTOFB, 0,
+ (lrr - hs) * ch, (lrc - ulc) * cw, hs * ch);
+ }
+ return (0);
+}
==== //depot/projects/tty/sys/dev/vtc/vtc_te.h#3 (text+ko) ====
@@ -38,12 +38,20 @@
struct vtc_te_softc {
KOBJ_FIELDS;
- struct vtc_te_class *sc_class;
+ struct vtc_te_class *te_class;
+ TAILQ_ENTRY(vtc_te_softc) te_alldevs;
+ TAILQ_HEAD(, vtc_vtout_softc) te_vodevs;
+ struct tty *te_tty;
+ int te_maxcol;
+ int te_maxrow;
};
/*
* TE support functions.
*/
int vtc_te_bell(struct vtc_te_softc *);
+int vtc_te_putc(struct vtc_te_softc *, int, int, int, int, int, __wchar_t);
+int vtc_te_repos(struct vtc_te_softc *, int, int);
+int vtc_te_scroll(struct vtc_te_softc *, int, int, int, int, int);
#endif /* !_DEV_VTC_TE_H_ */
==== //depot/projects/tty/sys/dev/vtc/vtc_te_if.m#3 (text+ko) ====
@@ -35,6 +35,11 @@
INTERFACE vtc_te;
+# reset() - initialize/reset
+METHOD int reset {
+ struct vtc_te_softc *this;
+};
+
# write() - write to the terminal
METHOD int write {
struct vtc_te_softc *this;
==== //depot/projects/tty/sys/dev/vtc/vtc_te_vt102.c#3 (text+ko) ====
@@ -45,11 +45,22 @@
int state;
int count;
char cbuf[16];
+ int col, row;
+ int maxcol, maxrow;
+
+ int autowrap:1;
+ int dh:1;
+ int dw:1;
+ int underline:1;
+
+ int wrap:1;
};
+static int vt102_reset(struct vtc_te_softc *);
static int vt102_write(struct vtc_te_softc *, __wchar_t);
static kobj_method_t vt102_methods[] = {
+ KOBJMETHOD(vtc_te_reset, vt102_reset),
KOBJMETHOD(vtc_te_write, vt102_write),
{ 0, 0 }
};
@@ -60,15 +71,58 @@
sizeof(struct vt102_softc),
};
+static __inline int
+vt102_putc(struct vt102_softc *vt102, __wchar_t wc)
+{
+
+ return (vtc_te_putc(&vt102->base, vt102->row << vt102->dh,
+ vt102->col << vt102->dw, 1 << vt102->dw, 1 << vt102->dh,
+ vt102->underline, wc));
+}
+
+static __inline int
+vt102_repos(struct vt102_softc *vt102)
+{
+
+ vt102->wrap = 0;
+ return (vtc_te_repos(&vt102->base, vt102->row << vt102->dh,
+ vt102->col << vt102->dw));
+}
+
+static __inline int
+vt102_newline(struct vt102_softc *vt102)
+{
+
+ if (vt102->row == vt102->maxrow)
+ return (vtc_te_scroll(&vt102->base, 0, 0,
+ vt102->maxrow << vt102->dh, vt102->maxcol << vt102->dw,
+ 1 << vt102->dh));
+ vt102->row++;
+ return (vt102_repos(vt102));
+}
+
static int
vt102_answerback(struct vt102_softc *vt102)
{
return (0);
}
-static int
+static __inline int
vt102_print(struct vt102_softc *vt102, __wchar_t wc)
{
+
+ if (vt102->autowrap && vt102->wrap) {
+ vt102->col = 0;
+ vt102_newline(vt102);
+ }
+ vt102_putc(vt102, wc);
+ vt102->col++;
+ if (vt102->col > vt102->maxcol) {
+ vt102->col = vt102->maxcol;
+ if (vt102->autowrap)
+ vt102->wrap = 1;
+ } else
+ vt102_repos(vt102);
return (0);
}
@@ -85,18 +139,42 @@
error = vtc_te_bell(&vt102->base);
break;
case 0x08: /* BS */
+ if (vt102->col > 0) {
+ vt102->col--;
+ vt102_putc(vt102, ' ');
+ vt102_repos(vt102);
+ }
break;
case 0x09: /* HT */
+ if (vt102->col < vt102->maxcol) {
+ vt102->col = (vt102->col + 8) & ~7;
+ if (vt102->col > vt102->maxcol)
+ vt102->col = vt102->maxcol;
+ vt102_repos(vt102);
+ }
break;
case 0x0A: /* LF */
case 0x0B: /* VT (processed as LF) */
case 0x0C: /* FF (processed as LF) */
+ vt102_newline(vt102);
break;
case 0x0D: /* CR */
+ if (vt102->col > 0) {
+ vt102->col = 0;
+ vt102_repos(vt102);
+ }
break;
case 0x0E: /* SO */
+ /*
+ * Select G1 character set. We're Unicode, hence no character
+ * set switching.
+ */
break;
case 0x0F: /* SI */
+ /*
+ * Select G0 character set. We're Unicode, hence no character
+ * set switching.
+ */
break;
case 0x18: /* CAN */
case 0x1A: /* SUB (processed as CAN) */
@@ -127,9 +205,24 @@
}
static int
-vt102_write(struct vtc_te_softc *sc, __wchar_t wc)
+vt102_reset(struct vtc_te_softc *te)
+{
+ struct vt102_softc *vt102 = (struct vt102_softc *)te;
+
+ te->te_maxcol = 80;
+ te->te_maxrow = 24;
+
+ vt102->maxcol = 80;
+ vt102->maxrow = 24;
+
+ vt102->autowrap = 1;
+ return (0);
+}
+
+static int
+vt102_write(struct vtc_te_softc *te, __wchar_t wc)
{
- struct vt102_softc *vt102 = (struct vt102_softc *)sc;
+ struct vt102_softc *vt102 = (struct vt102_softc *)te;
int error;
KASSERT(wc >= 0, ("Negative UTF-32 characters don't exist!"));
==== //depot/projects/tty/sys/dev/vtc/vtc_tty.c#2 (text+ko) ====
@@ -27,6 +27,122 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-vtc_tty_write(struct vtc_tty_softc *sc, wchar_t wc)
+#include <dev/vtc/vtc_te.h>
+
+static int
+vtc_tty_open(struct tty *tp, struct cdev *dev)
+{
+ struct vtc_te_softc *sc;
+
+ sc = tp->t_sc;
+ /* XXX notify the TE that we're opened? */
+ return (0);
+}
+
+static void
+vtc_tty_close(struct tty *tp)
+{
+ struct vtc_te_softc *sc;
+
+ sc = tp->t_sc;
+ if (sc == NULL)
+ return;
+
+ wakeup(sc);
+ return;
+}
+
+static void
+vtc_tty_oproc(struct tty *tp)
+{
+ struct vtc_te_softc *sc;
+
+ sc = tp->t_sc;
+ if (sc == NULL)
+ return;
+
+ if (tp->t_state & (TS_TTSTOP | TS_BUSY))
+ return;
+
+ if (tp->t_outq.c_cc > 0) {
+ tp->t_state |= TS_BUSY;
+ /* XXX loop to display all characters in the buffer. */
+ tp->t_state &= ~TS_BUSY;
+ }
+
+ ttwwakeup(tp);
+}
+
+static int
+vtc_tty_param(struct tty *tp, struct termios *t)
+{
+ struct vtc_te_softc *sc;
+
+ sc = tp->t_sc;
+ if (sc == NULL)
+ return (ENODEV);
+
+ ttsetwater(tp);
+ return (0);
+}
+
+static int
+vtc_tty_modem(struct tty *tp, int biton, int bitoff)
+{
+
+ return (0);
+}
+
+static void
+vtc_tty_break(struct tty *tp, int state)
+{
+}
+
+static void
+vtc_tty_stop(struct tty *tp, int rw)
+{
+}
+
+int
+vtc_tty_attach(struct vtc_te_softc *sc)
+{
+ struct tty *tp;
+ int unit;
+
+ tp = ttyalloc();
+ sc->sc_u.u_tty.tp = tp;
+ tp->t_sc = sc;
+
+ unit = device_get_unit(sc->sc_dev);
+
+ tp->t_oproc = uart_tty_oproc;
+ tp->t_param = uart_tty_param;
+ tp->t_stop = uart_tty_stop;
+ tp->t_modem = uart_tty_modem;
+ tp->t_break = uart_tty_break;
+ tp->t_open = uart_tty_open;
+ tp->t_close = uart_tty_close;
+
+ tp->t_pps = &sc->sc_pps;
+
+ if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+ sprintf(((struct consdev *)sc->sc_sysdev->cookie)->cn_name,
+ "ttyu%r", unit);
+ ttyconsolemode(tp, 0);
+ }
+
+ ttycreate(tp, NULL, 0, MINOR_CALLOUT, "v%r", unit);
+
+ return (0);
+}
+
+int vtc_tty_detach(struct vtc_te_softc *sc)
{
+ struct tty *tp;
+
+ tp = sc->sc_u.u_tty.tp;
+ ttygone(tp);
+ ttyfree(tp);
+
+ return (0);
}
More information about the p4-projects
mailing list