Date: Sat, 4 Jun 2005 05:26:37 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 77951 for review Message-ID: <200506040526.j545Qb4H020145@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=77951 Change 77951 by marcel@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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506040526.j545Qb4H020145>