diff options
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/dcons/dcons.h | 2 | ||||
| -rw-r--r-- | sys/dev/dcons/dcons_os.c | 393 | ||||
| -rw-r--r-- | sys/dev/nmdm/nmdm.c | 412 | ||||
| -rw-r--r-- | sys/dev/ofw/ofw_console.c | 143 | ||||
| -rw-r--r-- | sys/dev/syscons/schistory.c | 7 | ||||
| -rw-r--r-- | sys/dev/syscons/scmouse.c | 5 | ||||
| -rw-r--r-- | sys/dev/syscons/scterm-sc.c | 2 | ||||
| -rw-r--r-- | sys/dev/syscons/scvesactl.c | 12 | ||||
| -rw-r--r-- | sys/dev/syscons/scvidctl.c | 18 | ||||
| -rw-r--r-- | sys/dev/syscons/syscons.c | 327 | ||||
| -rw-r--r-- | sys/dev/syscons/syscons.h | 24 | ||||
| -rw-r--r-- | sys/dev/syscons/sysmouse.c | 135 | ||||
| -rw-r--r-- | sys/dev/uart/uart_core.c | 3 | ||||
| -rw-r--r-- | sys/dev/uart/uart_tty.c | 165 | ||||
| -rw-r--r-- | sys/dev/usb/ucom.c | 334 | ||||
| -rw-r--r-- | sys/dev/usb/ucomvar.h | 8 | ||||
| -rw-r--r-- | sys/dev/usb/uftdi.c | 27 | ||||
| -rw-r--r-- | sys/dev/usb/umodem.c | 4 |
18 files changed, 686 insertions, 1335 deletions
diff --git a/sys/dev/dcons/dcons.h b/sys/dev/dcons/dcons.h index 49ef869cecc1..e613f5bbe51d 100644 --- a/sys/dev/dcons/dcons.h +++ b/sys/dev/dcons/dcons.h @@ -98,7 +98,7 @@ struct dcons_softc { int brk_state; #define DC_GDB 1 int flags; - void *dev; + void *tty; }; int dcons_checkc(struct dcons_softc *); diff --git a/sys/dev/dcons/dcons_os.c b/sys/dev/dcons/dcons_os.c index a43cd28d3527..aad963750ba3 100644 --- a/sys/dev/dcons/dcons_os.c +++ b/sys/dev/dcons/dcons_os.c @@ -1,7 +1,7 @@ /*- * Copyright (C) 2003,2004 * Hidetoshi Shimokawa. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -18,7 +18,7 @@ * 4. Neither the name of the author nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -30,15 +30,13 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * $FreeBSD$ */ #include <sys/param.h> -#if __FreeBSD_version >= 502122 #include <sys/kdb.h> #include <gdb/gdb.h> -#endif #include <sys/kernel.h> #include <sys/module.h> #include <sys/systm.h> @@ -54,13 +52,8 @@ #include <machine/bus.h> -#ifdef __DragonFly__ -#include "dcons.h" -#include "dcons_os.h" -#else #include <dev/dcons/dcons.h> #include <dev/dcons/dcons_os.h> -#endif #include <ddb/ddb.h> #include <sys/reboot.h> @@ -90,53 +83,6 @@ #define DCONS_FORCE_CONSOLE 0 /* Mostly for FreeBSD-4/DragonFly */ #endif -#ifndef DCONS_FORCE_GDB -#define DCONS_FORCE_GDB 1 -#endif - -#if __FreeBSD_version >= 500101 -#define CONS_NODEV 1 -#if __FreeBSD_version < 502122 -static struct consdev gdbconsdev; -#endif -#endif - -static d_open_t dcons_open; -static d_close_t dcons_close; -#if defined(__DragonFly__) || __FreeBSD_version < 500104 -static d_ioctl_t dcons_ioctl; -#endif - -static struct cdevsw dcons_cdevsw = { -#ifdef __DragonFly__ -#define CDEV_MAJOR 184 - "dcons", CDEV_MAJOR, D_TTY, NULL, 0, - dcons_open, dcons_close, ttyread, ttywrite, dcons_ioctl, - ttypoll, nommap, nostrategy, nodump, nopsize, -#elif __FreeBSD_version >= 500104 - .d_version = D_VERSION, - .d_open = dcons_open, - .d_close = dcons_close, - .d_name = "dcons", - .d_flags = D_TTY | D_NEEDGIANT, -#else -#define CDEV_MAJOR 184 - /* open */ dcons_open, - /* close */ dcons_close, - /* read */ ttyread, - /* write */ ttywrite, - /* ioctl */ dcons_ioctl, - /* poll */ ttypoll, - /* mmap */ nommap, - /* strategy */ nostrategy, - /* name */ "dcons", - /* major */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ D_TTY, -#endif -}; - #ifndef KLD_MODULE static char bssbuf[DCONS_BUF_SIZE]; /* buf in bss */ #endif @@ -156,20 +102,6 @@ static int drv_init = 0; static struct callout dcons_callout; struct dcons_buf *dcons_buf; /* for local dconschat */ -#ifdef __DragonFly__ -#define DEV dev_t -#define THREAD d_thread_t -#elif __FreeBSD_version < 500000 -#define DEV dev_t -#define THREAD struct proc -#else -#define DEV struct cdev * -#define THREAD struct thread -#endif - - -static void dcons_tty_start(struct tty *); -static int dcons_tty_param(struct tty *, struct termios *); static void dcons_timeout(void *); static int dcons_drv_init(int); @@ -181,12 +113,12 @@ static cn_putc_t dcons_cnputc; CONSOLE_DRIVER(dcons); -#if defined(GDB) && (__FreeBSD_version >= 502122) -static gdb_probe_f dcons_dbg_probe; -static gdb_init_f dcons_dbg_init; -static gdb_term_f dcons_dbg_term; -static gdb_getc_f dcons_dbg_getc; -static gdb_putc_f dcons_dbg_putc; +#if defined(GDB) +static gdb_probe_f dcons_dbg_probe; +static gdb_init_f dcons_dbg_init; +static gdb_term_f dcons_dbg_term; +static gdb_getc_f dcons_dbg_getc; +static gdb_putc_f dcons_dbg_putc; GDB_DBGPORT(dcons, dcons_dbg_probe, dcons_dbg_init, dcons_dbg_term, dcons_dbg_getc, dcons_dbg_putc); @@ -194,21 +126,25 @@ GDB_DBGPORT(dcons, dcons_dbg_probe, dcons_dbg_init, dcons_dbg_term, extern struct gdb_dbgport *gdb_cur; #endif +static tsw_outwakeup_t dcons_outwakeup; + +static struct ttydevsw dcons_ttydevsw = { + .tsw_flags = TF_NOPREFIX, + .tsw_outwakeup = dcons_outwakeup, +}; + #if (defined(GDB) || defined(DDB)) && defined(ALT_BREAK_TO_DEBUGGER) static int dcons_check_break(struct dcons_softc *dc, int c) { -#if __FreeBSD_version >= 502122 int kdb_brk; -#endif + if (c < 0) return (c); -#if __FreeBSD_version >= 502122 if ((kdb_brk = kdb_alt_break(c, &dc->brk_state)) != 0) { switch (kdb_brk) { case KDB_REQ_DEBUGGER: - if ((dc->flags & DC_GDB) != 0) { #ifdef GDB if (gdb_cur == &dcons_gdb_dbgport) { @@ -229,27 +165,6 @@ dcons_check_break(struct dcons_softc *dc, int c) break; } } -#else - switch (dc->brk_state) { - case STATE1: - if (c == KEY_TILDE) - dc->brk_state = STATE2; - else - dc->brk_state = STATE0; - break; - case STATE2: - dc->brk_state = STATE0; - if (c == KEY_CTRLB) { -#if DCONS_FORCE_GDB - if (dc->flags & DC_GDB) - boothowto |= RB_GDB; -#endif - breakpoint(); - } - } - if (c == KEY_CR) - dc->brk_state = STATE1; -#endif return (c); } #else @@ -263,7 +178,7 @@ dcons_os_checkc_nopoll(struct dcons_softc *dc) if (dg.dma_tag != NULL) bus_dmamap_sync(dg.dma_tag, dg.dma_map, BUS_DMASYNC_POSTREAD); - + c = dcons_check_break(dc, dcons_checkc(dc)); if (dg.dma_tag != NULL) @@ -279,18 +194,6 @@ dcons_os_checkc(struct dcons_softc *dc) return (dcons_os_checkc_nopoll(dc)); } -#if defined(GDB) || !defined(CONS_NODEV) -static int -dcons_os_getc(struct dcons_softc *dc) -{ - int c; - - while ((c = dcons_os_checkc(dc)) == -1); - - return (c & 0xff); -} -#endif - static void dcons_os_putc(struct dcons_softc *dc, int c) { @@ -302,122 +205,17 @@ dcons_os_putc(struct dcons_softc *dc, int c) if (dg.dma_tag != NULL) bus_dmamap_sync(dg.dma_tag, dg.dma_map, BUS_DMASYNC_PREWRITE); } -static int -dcons_open(DEV dev, int flag, int mode, THREAD *td) -{ - struct tty *tp; - int unit, error, s; - - unit = minor(dev); - if (unit != 0) - return (ENXIO); - - tp = dev->si_tty; - tp->t_oproc = dcons_tty_start; - tp->t_param = dcons_tty_param; - tp->t_stop = nottystop; - tp->t_dev = dev; - - error = 0; - - s = spltty(); - if ((tp->t_state & TS_ISOPEN) == 0) { - tp->t_state |= TS_CARR_ON; - ttyconsolemode(tp, 0); - } else if ((tp->t_state & TS_XCLUDE) && - priv_check(td, PRIV_TTY_EXCLUSIVE)) { - splx(s); - return (EBUSY); - } - splx(s); - -#if __FreeBSD_version < 502113 - error = (*linesw[tp->t_line].l_open)(dev, tp); -#else - error = ttyld_open(tp, dev); -#endif - - return (error); -} - -static int -dcons_close(DEV dev, int flag, int mode, THREAD *td) -{ - int unit; - struct tty *tp; - - unit = minor(dev); - if (unit != 0) - return (ENXIO); - - tp = dev->si_tty; - if (tp->t_state & TS_ISOPEN) { -#if __FreeBSD_version < 502113 - (*linesw[tp->t_line].l_close)(tp, flag); - ttyclose(tp); -#else - ttyld_close(tp, flag); - tty_close(tp); -#endif - } - - return (0); -} - -#if defined(__DragonFly__) || __FreeBSD_version < 500104 -static int -dcons_ioctl(DEV dev, u_long cmd, caddr_t data, int flag, THREAD *td) -{ - int unit; - struct tty *tp; - int error; - - unit = minor(dev); - if (unit != 0) - return (ENXIO); - - tp = dev->si_tty; - error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, td); - if (error != ENOIOCTL) - return (error); - - error = ttioctl(tp, cmd, data, flag); - if (error != ENOIOCTL) - return (error); - - return (ENOTTY); -} -#endif - -static int -dcons_tty_param(struct tty *tp, struct termios *t) -{ - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; - return 0; -} static void -dcons_tty_start(struct tty *tp) +dcons_outwakeup(struct tty *tp) { struct dcons_softc *dc; - int s; - - dc = (struct dcons_softc *)tp->t_dev->si_drv1; - s = spltty(); - if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { - ttwwakeup(tp); - return; - } + char ch; - tp->t_state |= TS_BUSY; - while (tp->t_outq.c_cc != 0) - dcons_os_putc(dc, getc(&tp->t_outq)); - tp->t_state &= ~TS_BUSY; + dc = tty_softc(tp); - ttwwakeup(tp); - splx(s); + while (ttydisc_getc(tp, &ch, sizeof ch) != 0) + dcons_os_putc(dc, ch); } static void @@ -429,14 +227,13 @@ dcons_timeout(void *v) for (i = 0; i < DCONS_NPORT; i ++) { dc = &sc[i]; - tp = ((DEV)dc->dev)->si_tty; + tp = dc->tty; + + tty_lock(tp); while ((c = dcons_os_checkc_nopoll(dc)) != -1) - if (tp->t_state & TS_ISOPEN) -#if __FreeBSD_version < 502113 - (*linesw[tp->t_line].l_rint)(c, tp); -#else - ttyld_rint(tp, c); -#endif + ttydisc_rint(tp, c, 0); + ttydisc_rint_done(tp); + tty_unlock(tp); } polltime = hz / poll_hz; if (polltime < 1) @@ -447,14 +244,7 @@ dcons_timeout(void *v) static void dcons_cnprobe(struct consdev *cp) { -#ifdef __DragonFly__ - cp->cn_dev = make_dev(&dcons_cdevsw, DCONS_CON, - UID_ROOT, GID_WHEEL, 0600, "dcons"); -#elif __FreeBSD_version >= 501109 sprintf(cp->cn_name, "dcons"); -#else - cp->cn_dev = makedev(CDEV_MAJOR, DCONS_CON); -#endif #if DCONS_FORCE_CONSOLE cp->cn_pri = CN_REMOTE; #else @@ -466,12 +256,7 @@ static void dcons_cninit(struct consdev *cp) { dcons_drv_init(0); -#if CONS_NODEV - cp->cn_arg -#else - cp->cn_dev->si_drv1 -#endif - = (void *)&sc[DCONS_CON]; /* share port0 with unit0 */ + cp->cn_arg = (void *)&sc[DCONS_CON]; /* share port0 with unit0 */ } static void @@ -479,39 +264,19 @@ dcons_cnterm(struct consdev *cp) { } -#if CONS_NODEV static int dcons_cngetc(struct consdev *cp) { struct dcons_softc *dc = (struct dcons_softc *)cp->cn_arg; return (dcons_os_checkc(dc)); } + static void dcons_cnputc(struct consdev *cp, int c) { struct dcons_softc *dc = (struct dcons_softc *)cp->cn_arg; dcons_os_putc(dc, c); } -#else -static int -dcons_cngetc(DEV dev) -{ - struct dcons_softc *dc = (struct dcons_softc *)dev->si_drv1; - return (dcons_os_getc(dc)); -} -static int -dcons_cncheckc(DEV dev) -{ - struct dcons_softc *dc = (struct dcons_softc *)dev->si_drv1; - return (dcons_os_checkc(dc)); -} -static void -dcons_cnputc(DEV dev, int c) -{ - struct dcons_softc *dc = (struct dcons_softc *)dev->si_drv1; - dcons_os_putc(dc, c); -} -#endif static int dcons_drv_init(int stage) @@ -577,24 +342,6 @@ dcons_drv_init(int stage) ok: dcons_buf = dg.buf; -#if __FreeBSD_version < 502122 -#if defined(DDB) && DCONS_FORCE_GDB -#if CONS_NODEV - gdbconsdev.cn_arg = (void *)&sc[DCONS_GDB]; -#if __FreeBSD_version >= 501109 - sprintf(gdbconsdev.cn_name, "dgdb"); -#endif - gdb_arg = &gdbconsdev; -#elif defined(__DragonFly__) - gdbdev = make_dev(&dcons_cdevsw, DCONS_GDB, - UID_ROOT, GID_WHEEL, 0600, "dgdb"); -#else - gdbdev = makedev(CDEV_MAJOR, DCONS_GDB); -#endif - gdb_getc = dcons_cngetc; - gdb_putc = dcons_cnputc; -#endif -#endif drv_init = 1; return 0; @@ -606,23 +353,12 @@ dcons_attach_port(int port, char *name, int flags) { struct dcons_softc *dc; struct tty *tp; - DEV dev; dc = &sc[port]; + tp = tty_alloc(&dcons_ttydevsw, dc, NULL); dc->flags = flags; - dev = make_dev(&dcons_cdevsw, port, - UID_ROOT, GID_WHEEL, 0600, name); - dc->dev = (void *)dev; - tp = ttyalloc(); - - dev->si_drv1 = (void *)dc; - dev->si_tty = tp; - - tp->t_oproc = dcons_tty_start; - tp->t_param = dcons_tty_param; - tp->t_stop = nottystop; - tp->t_dev = dc->dev; - + dc->tty = tp; + tty_makedev(tp, NULL, "%s", name); return(0); } @@ -631,16 +367,9 @@ dcons_attach(void) { int polltime; -#ifdef __DragonFly__ - cdevsw_add(&dcons_cdevsw, -1, 0); -#endif dcons_attach_port(DCONS_CON, "dcons", 0); dcons_attach_port(DCONS_GDB, "dgdb", DC_GDB); -#if __FreeBSD_version < 500000 - callout_init(&dcons_callout); -#else callout_init(&dcons_callout, 0); -#endif polltime = hz / poll_hz; if (polltime < 1) polltime = 1; @@ -655,37 +384,14 @@ dcons_detach(int port) struct dcons_softc *dc; dc = &sc[port]; + tp = dc->tty; - tp = ((DEV)dc->dev)->si_tty; - - if (tp->t_state & TS_ISOPEN) { - printf("dcons: still opened\n"); -#if __FreeBSD_version < 502113 - (*linesw[tp->t_line].l_close)(tp, 0); - tp->t_gen++; - ttyclose(tp); - ttwakeup(tp); - ttwwakeup(tp); -#else - ttyld_close(tp, 0); - tty_close(tp); -#endif - } - /* XXX - * must wait until all device are closed. - */ -#ifdef __DragonFly__ - tsleep((void *)dc, 0, "dcodtc", hz/4); -#else - tsleep((void *)dc, PWAIT, "dcodtc", hz/4); -#endif - destroy_dev(dc->dev); + tty_lock(tp); + tty_rel_gone(tp); return(0); } - -/* cnXXX works only for FreeBSD-5 */ static int dcons_modevent(module_t mode, int type, void *data) { @@ -695,29 +401,16 @@ dcons_modevent(module_t mode, int type, void *data) case MOD_LOAD: ret = dcons_drv_init(1); dcons_attach(); -#if __FreeBSD_version >= 500000 if (ret == 0) { dcons_cnprobe(&dcons_consdev); dcons_cninit(&dcons_consdev); cnadd(&dcons_consdev); } -#endif break; case MOD_UNLOAD: printf("dcons: unload\n"); callout_stop(&dcons_callout); -#if __FreeBSD_version < 502122 -#if defined(DDB) && DCONS_FORCE_GDB -#if CONS_NODEV - gdb_arg = NULL; -#else - gdbdev = NULL; -#endif -#endif -#endif -#if __FreeBSD_version >= 500000 cnremove(&dcons_consdev); -#endif dcons_detach(DCONS_CON); dcons_detach(DCONS_GDB); dg.buf->magic = 0; @@ -737,10 +430,20 @@ dcons_modevent(module_t mode, int type, void *data) return(err); } -#if defined(GDB) && (__FreeBSD_version >= 502122) +#if defined(GDB) /* Debugger interface */ static int +dcons_os_getc(struct dcons_softc *dc) +{ + int c; + + while ((c = dcons_os_checkc(dc)) == -1); + + return (c & 0xff); +} + +static int dcons_dbg_probe(void) { int dcons_gdb; diff --git a/sys/dev/nmdm/nmdm.c b/sys/dev/nmdm/nmdm.c index 8536c181cd58..706d416e662b 100644 --- a/sys/dev/nmdm/nmdm.c +++ b/sys/dev/nmdm/nmdm.c @@ -36,9 +36,6 @@ __FBSDID("$FreeBSD$"); * Mighty handy for use with serial console in Vmware */ -#include "opt_compat.h" -#include "opt_tty.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/priv.h> @@ -48,252 +45,176 @@ __FBSDID("$FreeBSD$"); #include <sys/fcntl.h> #include <sys/poll.h> #include <sys/kernel.h> +#include <sys/limits.h> #include <sys/module.h> #include <sys/serial.h> #include <sys/signalvar.h> #include <sys/malloc.h> #include <sys/taskqueue.h> -MALLOC_DEFINE(M_NLMDM, "nullmodem", "nullmodem data structures"); - -static d_close_t nmdmclose; -static t_modem_t nmdmmodem; -static d_open_t nmdmopen; -static t_oproc_t nmdmoproc; -static t_param_t nmdmparam; -static t_stop_t nmdmstop; - -static struct cdevsw nmdm_cdevsw = { - .d_version = D_VERSION, - .d_open = nmdmopen, - .d_close = nmdmclose, - .d_name = "nmdn", - .d_flags = D_TTY | D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR, +MALLOC_DEFINE(M_NMDM, "nullmodem", "nullmodem data structures"); + +static tsw_inwakeup_t nmdm_outwakeup; +static tsw_outwakeup_t nmdm_inwakeup; +static tsw_param_t nmdm_param; +static tsw_modem_t nmdm_modem; + +static struct ttydevsw nmdm_class = { + .tsw_flags = TF_NOPREFIX, + .tsw_inwakeup = nmdm_inwakeup, + .tsw_outwakeup = nmdm_outwakeup, + .tsw_param = nmdm_param, + .tsw_modem = nmdm_modem, }; -#define BUFSIZ 100 /* Chunk size iomoved to/from user */ -#define NMDM_MAX_NUM 128 /* Artificially limit # devices. */ -#define PF_STOPPED 0x10 /* user told stopped */ -#define BFLAG CLONE_FLAG0 - -struct softpart { - struct tty *nm_tty; - struct cdev *dev; - int nm_dcd; - struct task pt_task; - struct softpart *other; - struct callout co; - u_long quota; - u_long accumulator; - int rate; - int credits; +static void nmdm_task_tty(void *, int); + +struct nmdmsoftc; + +struct nmdmpart { + struct tty *np_tty; + int np_dcd; + struct task np_task; + struct nmdmpart *np_other; + struct nmdmsoftc *np_pair; + struct callout np_callout; + u_long np_quota; + u_long np_accumulator; + int np_rate; + int np_credits; #define QS 8 /* Quota shift */ }; -struct nm_softc { - TAILQ_ENTRY(nm_softc) pt_list; - int pt_flags; - struct softpart part1, part2; - struct prison *pt_prison; +struct nmdmsoftc { + struct nmdmpart ns_part1; + struct nmdmpart ns_part2; + struct mtx ns_mtx; }; -static struct clonedevs *nmdmclones; -static TAILQ_HEAD(,nm_softc) nmdmhead = TAILQ_HEAD_INITIALIZER(nmdmhead); +static int nmdm_count = 0; + +static struct nmdmsoftc * +nmdm_alloc(unsigned long unit) +{ + struct nmdmsoftc *ns; + struct tty *tp; + + atomic_add_acq_int(&nmdm_count, 1); + + ns = malloc(sizeof(*ns), M_NMDM, M_WAITOK|M_ZERO); + mtx_init(&ns->ns_mtx, "nmdm", NULL, MTX_DEF); + + /* Hook the pairs together. */ + ns->ns_part1.np_pair = ns; + ns->ns_part1.np_other = &ns->ns_part2; + TASK_INIT(&ns->ns_part1.np_task, 0, nmdm_task_tty, &ns->ns_part1); + callout_init(&ns->ns_part1.np_callout, 0); + + ns->ns_part2.np_pair = ns; + ns->ns_part2.np_other = &ns->ns_part1; + TASK_INIT(&ns->ns_part2.np_task, 0, nmdm_task_tty, &ns->ns_part2); + callout_init(&ns->ns_part2.np_callout, 0); + + /* Create device nodes. */ + tp = ns->ns_part1.np_tty = tty_alloc(&nmdm_class, &ns->ns_part1, + &ns->ns_mtx); + tty_makedev(tp, NULL, "nmdm%luA", unit); + + tp = ns->ns_part2.np_tty = tty_alloc(&nmdm_class, &ns->ns_part2, + &ns->ns_mtx); + tty_makedev(tp, NULL, "nmdm%luB", unit); + + return (ns); +} static void nmdm_clone(void *arg, struct ucred *cred, char *name, int nameen, struct cdev **dev) { - int i, unit; - char *p; - struct cdev *d1, *d2; + unsigned long unit; + char *end; + struct nmdmsoftc *ns; if (*dev != NULL) return; - if (strcmp(name, "nmdm") == 0) { - p = NULL; - unit = -1; - } else { - i = dev_stdclone(name, &p, "nmdm", &unit); - if (i == 0) - return; - if (p[0] != '\0' && p[0] != 'A' && p[0] != 'B') - return; - else if (p[0] != '\0' && p[1] != '\0') - return; - } - i = clone_create(&nmdmclones, &nmdm_cdevsw, &unit, &d1, 0); - if (i) { - d1 = make_dev(&nmdm_cdevsw, unit2minor(unit), - 0, 0, 0666, "nmdm%dA", unit); - if (d1 == NULL) - return; - d2 = make_dev(&nmdm_cdevsw, unit2minor(unit) | BFLAG, - 0, 0, 0666, "nmdm%dB", unit); - if (d2 == NULL) { - destroy_dev(d1); - return; - } - d2->si_drv2 = d1; - d1->si_drv2 = d2; - dev_depends(d1, d2); - dev_depends(d2, d1); - d1->si_flags |= SI_CHEAPCLONE; - d2->si_flags |= SI_CHEAPCLONE; - } - if (p != NULL && p[0] == 'B') - *dev = d1->si_drv2; + if (strncmp(name, "nmdm", 4) != 0) + return; + + /* Device name must be "nmdm%lu%c", where %c is 'A' or 'B'. */ + name += 4; + unit = strtoul(name, &end, 10); + if (unit == ULONG_MAX || name == end) + return; + if ((end[0] != 'A' && end[0] != 'B') || end[1] != '\0') + return; + + /* XXX: pass privileges? */ + ns = nmdm_alloc(unit); + + if (end[0] == 'A') + *dev = ns->ns_part1.np_tty->t_dev; else - *dev = d1; - dev_ref(*dev); + *dev = ns->ns_part2.np_tty->t_dev; } static void nmdm_timeout(void *arg) { - struct softpart *sp; - - sp = arg; + struct nmdmpart *np = arg; - if (sp->rate == 0) + if (np->np_rate == 0) return; /* * Do a simple Floyd-Steinberg dither here to avoid FP math. * Wipe out unused quota from last tick. */ - sp->accumulator += sp->credits; - sp->quota = sp->accumulator >> QS; - sp->accumulator &= ((1 << QS) - 1); + np->np_accumulator += np->np_credits; + np->np_quota = np->np_accumulator >> QS; + np->np_accumulator &= ((1 << QS) - 1); - taskqueue_enqueue(taskqueue_swi_giant, &sp->pt_task); - callout_reset(&sp->co, sp->rate, nmdm_timeout, arg); + taskqueue_enqueue(taskqueue_swi, &np->np_task); + callout_reset(&np->np_callout, np->np_rate, nmdm_timeout, np); } static void nmdm_task_tty(void *arg, int pending __unused) { struct tty *tp, *otp; - struct softpart *sp; - int c; + struct nmdmpart *np = arg; + char c; - tp = arg; - sp = tp->t_sc; - otp = sp->other->nm_tty; + tp = np->np_tty; + tty_lock(tp); + + otp = np->np_other->np_tty; KASSERT(otp != NULL, ("NULL otp in nmdmstart")); KASSERT(otp != tp, ("NULL otp == tp nmdmstart")); - if (sp->other->nm_dcd) { - if (!(tp->t_state & TS_ISOPEN)) { - sp->other->nm_dcd = 0; - (void)ttyld_modem(otp, 0); + if (np->np_other->np_dcd) { + if (!tty_opened(tp)) { + np->np_other->np_dcd = 0; + ttydisc_modem(otp, 0); } } else { - if (tp->t_state & TS_ISOPEN) { - sp->other->nm_dcd = 1; - (void)ttyld_modem(otp, 1); + if (tty_opened(tp)) { + np->np_other->np_dcd = 1; + ttydisc_modem(otp, 1); } } - if (tp->t_state & TS_TTSTOP) - return; - while (tp->t_outq.c_cc != 0) { - if (sp->rate && !sp->quota) - return; - if (otp->t_state & TS_TBLOCK) - return; - sp->quota--; - c = getc(&tp->t_outq); - if (otp->t_state & TS_ISOPEN) - ttyld_rint(otp, c); - } - if (tp->t_outq.c_cc == 0) - ttwwakeup(tp); -} - -/* - * This function creates and initializes a pair of ttys. - */ -static void -nmdminit(struct cdev *dev1) -{ - struct cdev *dev2; - struct nm_softc *pt; - - dev2 = dev1->si_drv2; - - dev1->si_flags &= ~SI_CHEAPCLONE; - dev2->si_flags &= ~SI_CHEAPCLONE; - - pt = malloc(sizeof(*pt), M_NLMDM, M_WAITOK | M_ZERO); - TAILQ_INSERT_TAIL(&nmdmhead, pt, pt_list); - - dev1->si_drv1 = dev2->si_drv1 = pt; - - pt->part1.dev = dev1; - pt->part2.dev = dev2; - - pt->part1.nm_tty = ttyalloc(); - pt->part1.nm_tty->t_oproc = nmdmoproc; - pt->part1.nm_tty->t_stop = nmdmstop; - pt->part1.nm_tty->t_modem = nmdmmodem; - pt->part1.nm_tty->t_param = nmdmparam; - pt->part1.nm_tty->t_dev = dev1; - pt->part1.nm_tty->t_sc = &pt->part1; - TASK_INIT(&pt->part1.pt_task, 0, nmdm_task_tty, pt->part1.nm_tty); - callout_init(&pt->part1.co, 0); - - pt->part2.nm_tty = ttyalloc(); - pt->part2.nm_tty->t_oproc = nmdmoproc; - pt->part2.nm_tty->t_stop = nmdmstop; - pt->part2.nm_tty->t_modem = nmdmmodem; - pt->part2.nm_tty->t_param = nmdmparam; - pt->part2.nm_tty->t_dev = dev2; - pt->part2.nm_tty->t_sc = &pt->part2; - TASK_INIT(&pt->part2.pt_task, 0, nmdm_task_tty, pt->part2.nm_tty); - callout_init(&pt->part2.co, 0); - - pt->part1.other = &pt->part2; - pt->part2.other = &pt->part1; - - dev1->si_tty = pt->part1.nm_tty; - dev1->si_drv1 = pt; - - dev2->si_tty = pt->part2.nm_tty; - dev2->si_drv1 = pt; -} - -/* - * Device opened from userland - */ -static int -nmdmopen(struct cdev *dev, int flag, int devtype, struct thread *td) -{ - struct tty *tp, *tp2; - int error; - struct nm_softc *pti; - struct softpart *sp; - - if (dev->si_drv1 == NULL) - nmdminit(dev); - pti = dev->si_drv1; - if (pti->pt_prison != td->td_ucred->cr_prison) - return (EBUSY); - - tp = dev->si_tty; - sp = tp->t_sc; - tp2 = sp->other->nm_tty; - - if ((tp->t_state & TS_ISOPEN) == 0) { - ttyinitmode(tp, 0, 0); - ttsetwater(tp); /* XXX ? */ - } else if (tp->t_state & TS_XCLUDE && - priv_check(td, PRIV_TTY_EXCLUSIVE)) { - return (EBUSY); + while (ttydisc_rint_poll(otp) > 0) { + if (np->np_rate && !np->np_quota) + break; + if (ttydisc_getc(tp, &c, 1) != 1) + break; + np->np_quota--; + ttydisc_rint(otp, c, 0); } - error = ttyld_open(tp, dev); - return (error); + ttydisc_rint_done(otp); + + tty_unlock(tp); } static int @@ -317,18 +238,17 @@ bits_per_char(struct termios *t) } static int -nmdmparam(struct tty *tp, struct termios *t) +nmdm_param(struct tty *tp, struct termios *t) { - struct softpart *sp; + struct nmdmpart *np = tty_softc(tp); struct tty *tp2; int bpc, rate, speed, i; - sp = tp->t_sc; - tp2 = sp->other->nm_tty; + tp2 = np->np_other->np_tty; - if (!((t->c_cflag | tp2->t_cflag) & CDSR_OFLOW)) { - sp->rate = 0; - sp->other->rate = 0; + if (!((t->c_cflag | tp2->t_termios.c_cflag) & CDSR_OFLOW)) { + np->np_rate = 0; + np->np_other->np_rate = 0; return (0); } @@ -343,10 +263,10 @@ nmdmparam(struct tty *tp, struct termios *t) for (i = 0; i < 2; i++) { /* Use the slower of our receive and their transmit rate */ - speed = imin(tp2->t_ospeed, t->c_ispeed); + speed = imin(tp2->t_termios.c_ospeed, t->c_ispeed); if (speed == 0) { - sp->rate = 0; - sp->other->rate = 0; + np->np_rate = 0; + np->np_other->np_rate = 0; return (0); } @@ -359,73 +279,63 @@ nmdmparam(struct tty *tp, struct termios *t) speed *= rate; speed /= hz; /* [(char/sec)/tick, scaled */ - sp->credits = speed; - sp->rate = rate; - callout_reset(&sp->co, rate, nmdm_timeout, sp); + np->np_credits = speed; + np->np_rate = rate; + callout_reset(&np->np_callout, rate, nmdm_timeout, np); /* * swap pointers for second pass so the other end gets * updated as well. */ - sp = sp->other; + np = np->np_other; t = &tp2->t_termios; tp2 = tp; } + return (0); } static int -nmdmmodem(struct tty *tp, int sigon, int sigoff) +nmdm_modem(struct tty *tp, int sigon, int sigoff) { - struct softpart *sp; - int i; + struct nmdmpart *np = tty_softc(tp); + int i = 0; - sp = tp->t_sc; if (sigon || sigoff) { if (sigon & SER_DTR) - sp->other->nm_dcd = 1; + np->np_other->np_dcd = 1; if (sigoff & SER_DTR) - sp->other->nm_dcd = 0; - ttyld_modem(sp->other->nm_tty, sp->other->nm_dcd); + np->np_other->np_dcd = 0; + + ttydisc_modem(np->np_other->np_tty, np->np_other->np_dcd); + return (0); } else { - i = 0; - if (sp->nm_dcd) + if (np->np_dcd) i |= SER_DCD; - if (sp->other->nm_dcd) + if (np->np_other->np_dcd) i |= SER_DTR; + return (i); } } -static int -nmdmclose(struct cdev *dev, int flag, int mode, struct thread *td) -{ - struct tty *tp = dev->si_tty; - int error; - - error = ttyld_close(tp, flag); - (void) tty_close(dev->si_tty); - - return (error); -} - static void -nmdmoproc(struct tty *tp) +nmdm_inwakeup(struct tty *tp) { - struct softpart *pt; + struct nmdmpart *np = tty_softc(tp); - pt = tp->t_sc; - taskqueue_enqueue(taskqueue_swi_giant, &pt->pt_task); + /* We can receive again, so wake up the other side. */ + taskqueue_enqueue(taskqueue_swi, &np->np_other->np_task); } static void -nmdmstop(struct tty *tp, int flush) +nmdm_outwakeup(struct tty *tp) { - struct softpart *pt; + struct nmdmpart *np = tty_softc(tp); - pt = tp->t_sc; - taskqueue_enqueue(taskqueue_swi_giant, &pt->pt_task); + /* We can transmit again, so wake up our side. */ + taskqueue_enqueue(taskqueue_swi, &np->np_task); } /* @@ -435,32 +345,28 @@ static int nmdm_modevent(module_t mod, int type, void *data) { static eventhandler_tag tag; - struct nm_softc *pt, *tpt; - int error = 0; switch(type) { case MOD_LOAD: - clone_setup(&nmdmclones); tag = EVENTHANDLER_REGISTER(dev_clone, nmdm_clone, 0, 1000); if (tag == NULL) return (ENOMEM); break; case MOD_SHUTDOWN: - /* FALLTHROUGH */ + break; + case MOD_UNLOAD: + if (nmdm_count != 0) + return (EBUSY); EVENTHANDLER_DEREGISTER(dev_clone, tag); - TAILQ_FOREACH_SAFE(pt, &nmdmhead, pt_list, tpt) { - destroy_dev(pt->part1.dev); - TAILQ_REMOVE(&nmdmhead, pt, pt_list); - free(pt, M_NLMDM); - } - clone_cleanup(&nmdmclones); break; + default: - error = EOPNOTSUPP; + return (EOPNOTSUPP); } - return (error); + + return (0); } DEV_MODULE(nmdm, nmdm_modevent, NULL); diff --git a/sys/dev/ofw/ofw_console.c b/sys/dev/ofw/ofw_console.c index 156f1211ec54..bec52d670e56 100644 --- a/sys/dev/ofw/ofw_console.c +++ b/sys/dev/ofw/ofw_console.c @@ -49,15 +49,15 @@ __FBSDID("$FreeBSD$"); #endif #define OFBURSTLEN 128 /* max number of bytes to write in one chunk */ -static d_open_t ofw_dev_open; -static d_close_t ofw_dev_close; - -static struct cdevsw ofw_cdevsw = { - .d_version = D_VERSION, - .d_open = ofw_dev_open, - .d_close = ofw_dev_close, - .d_name = "ofw", - .d_flags = D_TTY | D_NEEDGIANT, +static tsw_open_t ofwtty_open; +static tsw_close_t ofwtty_close; +static tsw_outwakeup_t ofwtty_outwakeup; + +static struct ttydevsw ofw_ttydevsw = { + .tsw_flags = TF_NOPREFIX, + .tsw_open = ofwtty_open, + .tsw_close = ofwtty_close, + .tsw_outwakeup = ofwtty_outwakeup, }; static struct tty *ofw_tp = NULL; @@ -69,9 +69,6 @@ static struct callout_handle ofw_timeouthandle static int alt_break_state; #endif -static void ofw_tty_start(struct tty *); -static int ofw_tty_param(struct tty *, struct termios *); -static void ofw_tty_stop(struct tty *, int); static void ofw_timeout(void *); static cn_probe_t ofw_cnprobe; @@ -87,7 +84,7 @@ cn_drvinit(void *unused) { phandle_t options; char output[32]; - struct cdev *dev; + struct tty *tp; if (ofw_consdev.cn_pri != CN_DEAD && ofw_consdev.cn_name[0] != '\0') { @@ -99,9 +96,9 @@ cn_drvinit(void *unused) * XXX: This is a hack and it may result in two /dev/ttya * XXX: devices on platforms where the sab driver works. */ - dev = make_dev(&ofw_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "%s", - output); - make_dev_alias(dev, "ofwcons"); + tp = tty_alloc(&ofw_ttydevsw, NULL, NULL); + tty_makedev(tp, NULL, "%s", output); + tty_makealias(tp, "ofwcons"); } } @@ -111,112 +108,36 @@ static int stdin; static int stdout; static int -ofw_dev_open(struct cdev *dev, int flag, int mode, struct thread *td) +ofwtty_open(struct tty *tp) { - struct tty *tp; - int unit; - int error, setuptimeout; - - error = 0; - setuptimeout = 0; - unit = minor(dev); - - /* - * XXX: BAD, should happen at attach time - */ - if (dev->si_tty == NULL) { - ofw_tp = ttyalloc(); - dev->si_tty = ofw_tp; - ofw_tp->t_dev = dev; - } - tp = dev->si_tty; - - tp->t_oproc = ofw_tty_start; - tp->t_param = ofw_tty_param; - tp->t_stop = ofw_tty_stop; - tp->t_dev = dev; - - if ((tp->t_state & TS_ISOPEN) == 0) { - tp->t_state |= TS_CARR_ON; - ttyconsolemode(tp, 0); - - setuptimeout = 1; - } else if ((tp->t_state & TS_XCLUDE) && - priv_check(td, PRIV_TTY_EXCLUSIVE)) { - return (EBUSY); - } - - error = ttyld_open(tp, dev); + polltime = hz / OFWCONS_POLL_HZ; + if (polltime < 1) + polltime = 1; - if (error == 0 && setuptimeout) { - polltime = hz / OFWCONS_POLL_HZ; - if (polltime < 1) { - polltime = 1; - } - - ofw_timeouthandle = timeout(ofw_timeout, tp, polltime); - } + ofw_timeouthandle = timeout(ofw_timeout, tp, polltime); - return (error); + return (0); } -static int -ofw_dev_close(struct cdev *dev, int flag, int mode, struct thread *td) +static void +ofwtty_close(struct tty *tp) { - int unit; - struct tty *tp; - - unit = minor(dev); - tp = dev->si_tty; - - if (unit != 0) { - return (ENXIO); - } /* XXX Should be replaced with callout_stop(9) */ untimeout(ofw_timeout, tp, ofw_timeouthandle); - ttyld_close(tp, flag); - tty_close(tp); - - return (0); -} - - -static int -ofw_tty_param(struct tty *tp, struct termios *t) -{ - - return (0); } static void -ofw_tty_start(struct tty *tp) +ofwtty_outwakeup(struct tty *tp) { - struct clist *cl; int len; u_char buf[OFBURSTLEN]; - - if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) - return; - - tp->t_state |= TS_BUSY; - cl = &tp->t_outq; - len = q_to_b(cl, buf, OFBURSTLEN); - OF_write(stdout, buf, len); - tp->t_state &= ~TS_BUSY; - - ttwwakeup(tp); -} - -static void -ofw_tty_stop(struct tty *tp, int flag) -{ - - if (tp->t_state & TS_BUSY) { - if ((tp->t_state & TS_TTSTOP) == 0) { - tp->t_state |= TS_FLUSH; - } + for (;;) { + len = ttydisc_getc(tp, buf, sizeof buf); + if (len == 0) + break; + OF_write(stdout, buf, len); } } @@ -228,11 +149,11 @@ ofw_timeout(void *v) tp = (struct tty *)v; - while ((c = ofw_cngetc(NULL)) != -1) { - if (tp->t_state & TS_ISOPEN) { - ttyld_rint(tp, c); - } - } + tty_lock(tp); + while ((c = ofw_cngetc(NULL)) != -1) + ttydisc_rint(tp, c, 0); + ttydisc_rint_done(tp); + tty_unlock(tp); ofw_timeouthandle = timeout(ofw_timeout, tp, polltime); } diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c index 860e8f95b85b..860367b28102 100644 --- a/sys/dev/syscons/schistory.c +++ b/sys/dev/syscons/schistory.c @@ -291,8 +291,7 @@ sc_hist_down_line(scr_stat *scp) } int -sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, - struct thread *td) +sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { scr_stat *scp; int error; @@ -300,7 +299,7 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, switch (cmd) { case CONS_HISTORY: /* set history size */ - scp = SC_STAT(tp->t_dev); + scp = SC_STAT(tp); if (*(int *)data <= 0) return EINVAL; if (scp->status & BUFFER_SAVED) @@ -315,7 +314,7 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, return error; case CONS_CLRHIST: - scp = SC_STAT(tp->t_dev); + scp = SC_STAT(tp); sc_vtb_clear(scp->history, scp->sc->scr_map[0x20], SC_NORM_ATTR << 8); return 0; diff --git a/sys/dev/syscons/scmouse.c b/sys/dev/syscons/scmouse.c index 25a2da0c2a93..2d998d403993 100644 --- a/sys/dev/syscons/scmouse.c +++ b/sys/dev/syscons/scmouse.c @@ -605,8 +605,7 @@ sc_mouse_paste(scr_stat *scp) #endif /* SC_NO_CUTPASTE */ int -sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, - struct thread *td) +sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { mouse_info_t *mouse; mouse_info_t buf; @@ -616,7 +615,7 @@ sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, int s; int f; - scp = SC_STAT(tp->t_dev); + scp = SC_STAT(tp); switch (cmd) { diff --git a/sys/dev/syscons/scterm-sc.c b/sys/dev/syscons/scterm-sc.c index e89debbe403a..b52bea8c7e40 100644 --- a/sys/dev/syscons/scterm-sc.c +++ b/sys/dev/syscons/scterm-sc.c @@ -705,7 +705,7 @@ outloop: static int scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, - int flag, struct thread *td) + struct thread *td) { term_stat *tcp = scp->ts; vid_info_t *vi; diff --git a/sys/dev/syscons/scvesactl.c b/sys/dev/syscons/scvesactl.c index c68d46a7d9d6..9a2c253869c8 100644 --- a/sys/dev/syscons/scvesactl.c +++ b/sys/dev/syscons/scvesactl.c @@ -48,19 +48,15 @@ __FBSDID("$FreeBSD$"); #include <dev/fb/fbreg.h> #include <dev/syscons/syscons.h> -static d_ioctl_t *prev_user_ioctl; +static tsw_ioctl_t *prev_user_ioctl; static int -vesa_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) +vesa_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { scr_stat *scp; - struct tty *tp; int mode; - tp = dev->si_tty; - if (!tp) - return ENXIO; - scp = SC_STAT(tp->t_dev); + scp = SC_STAT(tp); switch (cmd) { @@ -123,7 +119,7 @@ vesa_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread * } if (prev_user_ioctl) - return (*prev_user_ioctl)(dev, cmd, data, flag, td); + return (*prev_user_ioctl)(tp, cmd, data, td); else return ENOIOCTL; } diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index 5e1d91098f30..045f79f25e75 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -241,11 +241,8 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, || tp->t_winsize.ws_row != scp->ysize) { tp->t_winsize.ws_col = scp->xsize; tp->t_winsize.ws_row = scp->ysize; - if (tp->t_pgrp != NULL) { - PGRP_LOCK(tp->t_pgrp); - pgsignal(tp->t_pgrp, SIGWINCH, 1); - PGRP_UNLOCK(tp->t_pgrp); - } + + tty_signal_pgrp(tp, SIGWINCH); } return 0; @@ -308,11 +305,8 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) || tp->t_winsize.ws_ypixel != scp->ypixel) { tp->t_winsize.ws_xpixel = scp->xpixel; tp->t_winsize.ws_ypixel = scp->ypixel; - if (tp->t_pgrp != NULL) { - PGRP_LOCK(tp->t_pgrp); - pgsignal(tp->t_pgrp, SIGWINCH, 1); - PGRP_UNLOCK(tp->t_pgrp); - } + + tty_signal_pgrp(tp, SIGWINCH); } return 0; @@ -475,7 +469,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, vidd_ioctl((a), (c), (caddr_t)(d))) int -sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread *td) +sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { scr_stat *scp; video_adapter_t *adp; @@ -488,7 +482,7 @@ sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct thread * int ival; #endif - scp = SC_STAT(tp->t_dev); + scp = SC_STAT(tp); if (scp == NULL) /* tp == SC_MOUSE */ return ENOIOCTL; adp = scp->sc->adp; diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 96ca0b7b0943..ed5e45959c20 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/random.h> #include <sys/reboot.h> +#include <sys/serial.h> #include <sys/signalvar.h> #include <sys/sysctl.h> #include <sys/tty.h> @@ -69,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include <machine/psl.h> #include <machine/frame.h> #endif +#include <machine/stdarg.h> #include <dev/kbd/kbdreg.h> #include <dev/fb/fbreg.h> @@ -105,7 +107,7 @@ static struct tty *sc_console_tty; static struct consdev *sc_consptr; static void *kernel_console_ts; static scr_stat main_console; -static struct cdev *main_devs[MAXCONS]; +static struct tty *main_devs[MAXCONS]; static char init_done = COLD; static char shutdown_in_progress = FALSE; @@ -150,7 +152,7 @@ SYSCTL_INT(_hw_syscons, OID_AUTO, kbd_debug, CTLFLAG_RW|CTLFLAG_SECURE, &enable_ #include "font.h" #endif - d_ioctl_t *sc_user_ioctl; + tsw_ioctl_t *sc_user_ioctl; static bios_values_t bios_value; @@ -161,24 +163,18 @@ SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key, #define SC_CONSOLECTL 255 #define VTY_WCHAN(sc, vty) (&SC_DEV(sc, vty)) -#define VIRTUAL_TTY(sc, x) (SC_DEV((sc), (x)) != NULL ? \ - SC_DEV((sc), (x))->si_tty : NULL) -#define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN)) static int debugger; /* prototypes */ static int sc_allocate_keyboard(sc_softc_t *sc, int unit); -static struct tty *sc_alloc_tty(struct cdev *dev); static int scvidprobe(int unit, int flags, int cons); static int sckbdprobe(int unit, int flags, int cons); static void scmeminit(void *arg); -static int scdevtounit(struct cdev *dev); +static int scdevtounit(struct tty *tp); static kbd_callback_func_t sckbdevent; -static int scparam(struct tty *tp, struct termios *t); -static void scstart(struct tty *tp); static void scinit(int unit, int flags); -static scr_stat *sc_get_stat(struct cdev *devptr); +static scr_stat *sc_get_stat(struct tty *tp); static void scterm(int unit, int flags); static void scshutdown(void *arg, int howto); static u_int scgetc(sc_softc_t *sc, u_int flags); @@ -219,6 +215,7 @@ static int save_kbd_state(scr_stat *scp); static int update_kbd_state(scr_stat *scp, int state, int mask); static int update_kbd_leds(scr_stat *scp, int which); static timeout_t blink_screen; +static struct tty *sc_alloc_tty(int, const char *, ...) __printflike(2, 3); static cn_probe_t sc_cnprobe; static cn_init_t sc_cninit; @@ -228,21 +225,23 @@ static cn_putc_t sc_cnputc; CONSOLE_DRIVER(sc); -static d_open_t scopen; -static d_close_t scclose; -static d_read_t scread; -static d_ioctl_t scioctl; -static d_mmap_t scmmap; - -static struct cdevsw sc_cdevsw = { - .d_version = D_VERSION, - .d_open = scopen, - .d_close = scclose, - .d_read = scread, - .d_ioctl = scioctl, - .d_mmap = scmmap, - .d_name = "sc", - .d_flags = D_TTY | D_NEEDGIANT, +static tsw_open_t sctty_open; +static tsw_close_t sctty_close; +static tsw_outwakeup_t sctty_outwakeup; +static tsw_ioctl_t sctty_ioctl; +static tsw_mmap_t sctty_mmap; + +static struct ttydevsw sc_ttydevsw = { + /* + * XXX: we should use the prefix, but this doesn't work for + * consolectl. + */ + .tsw_flags = TF_NOPREFIX, + .tsw_open = sctty_open, + .tsw_close = sctty_close, + .tsw_outwakeup = sctty_outwakeup, + .tsw_ioctl = sctty_ioctl, + .tsw_mmap = sctty_mmap, }; int @@ -310,17 +309,47 @@ static char return names[i].name[(adp->va_flags & V_ADP_COLOR) ? 0 : 1]; } +static void +sctty_outwakeup(struct tty *tp) +{ + size_t len; + u_char buf[PCBURST]; + scr_stat *scp = sc_get_stat(tp); + + if (scp->status & SLKED || + (scp == scp->sc->cur_scp && scp->sc->blink_in_progress)) + return; + + for (;;) { + len = ttydisc_getc(tp, buf, sizeof buf); + if (len == 0) + break; + sc_puts(scp, buf, len); + } +} + static struct tty * -sc_alloc_tty(struct cdev *dev) +sc_alloc_tty(int index, const char *fmt, ...) { + va_list ap; + struct sc_ttysoftc *stc; struct tty *tp; + char name[11]; /* "consolectl" */ + + va_start(ap, fmt); + + /* Allocate TTY object and softc to store unit number. */ + stc = malloc(sizeof(struct sc_ttysoftc), M_DEVBUF, M_WAITOK); + stc->st_index = index; + stc->st_stat = NULL; + tp = tty_alloc(&sc_ttydevsw, stc, &Giant); + + /* Create device node. */ + va_start(ap, fmt); + vsnrprintf(name, sizeof name, 32, fmt, ap); + va_end(ap); + tty_makedev(tp, NULL, "%s", name); - tp = dev->si_tty = ttyalloc(); - ttyinitmode(tp, 1, 0); - tp->t_oproc = scstart; - tp->t_param = scparam; - tp->t_stop = nottystop; - tp->t_dev = dev; return (tp); } @@ -333,7 +362,6 @@ sc_attach_unit(int unit, int flags) video_info_t info; #endif int vc; - struct cdev *dev; flags &= ~SC_KERNEL_CONSOLE; @@ -418,9 +446,7 @@ sc_attach_unit(int unit, int flags) for (vc = 0; vc < sc->vtys; vc++) { if (sc->dev[vc] == NULL) { - sc->dev[vc] = make_dev(&sc_cdevsw, vc + unit * MAXCONS, - UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS); - sc_alloc_tty(sc->dev[vc]); + sc->dev[vc] = sc_alloc_tty(vc, "ttyv%r", vc + unit * MAXCONS); if (vc == 0 && sc->dev == main_devs) SC_STAT(sc->dev[0]) = &main_console; } @@ -431,11 +457,8 @@ sc_attach_unit(int unit, int flags) */ } - dev = make_dev(&sc_cdevsw, SC_CONSOLECTL, - UID_ROOT, GID_WHEEL, 0600, "consolectl"); - sc_console_tty = sc_alloc_tty(dev); - ttyconsolemode(sc_console_tty, 0); - SC_STAT(dev) = sc_console; + sc_console_tty = sc_alloc_tty(0, "consolectl"); + SC_STAT(sc_console_tty) = sc_console; return 0; } @@ -472,9 +495,9 @@ scmeminit(void *arg) SYSINIT(sc_mem, SI_SUB_KMEM, SI_ORDER_ANY, scmeminit, NULL); static int -scdevtounit(struct cdev *dev) +scdevtounit(struct tty *tp) { - int vty = SC_VTY(dev); + int vty = SC_VTY(tp); if (vty == SC_CONSOLECTL) return ((sc_console != NULL) ? sc_console->sc->unit : -1); @@ -485,48 +508,37 @@ scdevtounit(struct cdev *dev) } static int -scopen(struct cdev *dev, int flag, int mode, struct thread *td) +sctty_open(struct tty *tp) { - int unit = scdevtounit(dev); + int unit = scdevtounit(tp); sc_softc_t *sc; - struct tty *tp; scr_stat *scp; #ifndef __sparc64__ keyarg_t key; #endif - int error; DPRINTF(5, ("scopen: dev:%s, unit:%d, vty:%d\n", - devtoname(dev), unit, SC_VTY(dev))); + devtoname(tp->t_dev), unit, SC_VTY(tp))); - tp = dev->si_tty; sc = sc_get_softc(unit, (sc_console_unit == unit) ? SC_KERNEL_CONSOLE : 0); if (sc == NULL) return ENXIO; - if (!ISTTYOPEN(tp)) { - tp->t_termios = tp->t_init_in; + if (!tty_opened(tp)) { /* Use the current setting of the <-- key as default VERASE. */ /* If the Delete key is preferable, an stty is necessary */ #ifndef __sparc64__ if (sc->kbd != NULL) { key.keynum = KEYCODE_BS; kbdd_ioctl(sc->kbd, GIO_KEYMAPENT, (caddr_t)&key); - tp->t_cc[VERASE] = key.key.map[0]; + tp->t_termios.c_cc[VERASE] = key.key.map[0]; } #endif - scparam(tp, &tp->t_termios); - ttyld_modem(tp, 1); } - else - if (tp->t_state & TS_XCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE)) - return(EBUSY); - error = ttyld_open(tp, dev); - - scp = sc_get_stat(dev); + scp = sc_get_stat(tp); if (scp == NULL) { - scp = SC_STAT(dev) = alloc_scp(sc, SC_VTY(dev)); + scp = SC_STAT(tp) = alloc_scp(sc, SC_VTY(tp)); if (ISGRAPHSC(scp)) sc_set_pixel_mode(scp, NULL, COL, ROW, 16, 8); } @@ -535,18 +547,17 @@ scopen(struct cdev *dev, int flag, int mode, struct thread *td) tp->t_winsize.ws_row = scp->ysize; } - return error; + return (0); } -static int -scclose(struct cdev *dev, int flag, int mode, struct thread *td) +static void +sctty_close(struct tty *tp) { - struct tty *tp = dev->si_tty; scr_stat *scp; int s; - if (SC_VTY(dev) != SC_CONSOLECTL) { - scp = sc_get_stat(tp->t_dev); + if (SC_VTY(tp) != SC_CONSOLECTL) { + scp = sc_get_stat(tp); /* were we in the middle of the VT switching process? */ DPRINTF(5, ("sc%d: scclose(), ", scp->sc->unit)); s = spltty(); @@ -568,7 +579,7 @@ scclose(struct cdev *dev, int flag, int mode, struct thread *td) sc_vtb_destroy(&scp->scr); #endif sc_free_history_buffer(scp, scp->ysize); - SC_STAT(dev) = NULL; + SC_STAT(tp) = NULL; free(scp, M_DEVBUF); } #else @@ -581,13 +592,9 @@ scclose(struct cdev *dev, int flag, int mode, struct thread *td) kbdd_ioctl(scp->sc->kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode); DPRINTF(5, ("done.\n")); } - spltty(); - ttyld_close(tp, flag); - tty_close(tp); - spl0(); - return(0); } +#if 0 /* XXX mpsafetty: fix screensaver. What about outwakeup? */ static int scread(struct cdev *dev, struct uio *uio, int flag) { @@ -595,19 +602,22 @@ scread(struct cdev *dev, struct uio *uio, int flag) sc_touch_scrn_saver(); return ttyread(dev, uio, flag); } +#endif static int sckbdevent(keyboard_t *thiskbd, int event, void *arg) { sc_softc_t *sc; struct tty *cur_tty; - int c; + int c, error = 0; size_t len; u_char *cp; sc = (sc_softc_t *)arg; /* assert(thiskbd == sc->kbd) */ + mtx_lock(&Giant); + switch (event) { case KBDIO_KEYINPUT: break; @@ -615,9 +625,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg) sc->kbd = NULL; sc->keyboard = -1; kbd_release(thiskbd, (void *)&sc->keyboard); - return 0; + goto done; default: - return EINVAL; + error = EINVAL; + goto done; } /* @@ -627,10 +638,12 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg) */ while ((c = scgetc(sc, SCGETC_NONBLOCK)) != NOKEY) { - cur_tty = VIRTUAL_TTY(sc, sc->cur_scp->index); - if (!ISTTYOPEN(cur_tty)) { + cur_tty = SC_DEV(sc, sc->cur_scp->index); + if (!tty_opened(cur_tty)) { cur_tty = sc_console_tty; - if (!ISTTYOPEN(cur_tty)) + if (cur_tty == NULL) + continue; + if (!tty_opened(cur_tty)) continue; } @@ -639,47 +652,45 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg) switch (KEYFLAGS(c)) { case 0x0000: /* normal key */ - ttyld_rint(cur_tty, KEYCHAR(c)); + ttydisc_rint(cur_tty, KEYCHAR(c), 0); break; case FKEY: /* function key, return string */ cp = kbdd_get_fkeystr(thiskbd, KEYCHAR(c), &len); if (cp != NULL) { - while (len-- > 0) - ttyld_rint(cur_tty, *cp++); + if (ttydisc_can_bypass(cur_tty)) { + ttydisc_rint_bypass(cur_tty, cp, len); + } else { + while (len-- > 0) + ttydisc_rint(cur_tty, *cp++, 0); + } } break; case MKEY: /* meta is active, prepend ESC */ - ttyld_rint(cur_tty, 0x1b); - ttyld_rint(cur_tty, KEYCHAR(c)); + ttydisc_rint(cur_tty, 0x1b, 0); + ttydisc_rint(cur_tty, KEYCHAR(c), 0); break; case BKEY: /* backtab fixed sequence (esc [ Z) */ - ttyld_rint(cur_tty, 0x1b); - ttyld_rint(cur_tty, '['); - ttyld_rint(cur_tty, 'Z'); + ttydisc_rint(cur_tty, 0x1b, 0); + ttydisc_rint(cur_tty, '[', 0); + ttydisc_rint(cur_tty, 'Z', 0); break; } + + ttydisc_rint_done(cur_tty); } sc->cur_scp->status |= MOUSE_HIDDEN; - return 0; +done: + mtx_unlock(&Giant); + return (error); } static int -scparam(struct tty *tp, struct termios *t) -{ - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; - return 0; -} - -static int -scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) +sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { int error; int i; - struct tty *tp; sc_softc_t *sc; scr_stat *scp; int s; @@ -688,38 +699,36 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) int ival; #endif - tp = dev->si_tty; - /* If there is a user_ioctl function call that first */ if (sc_user_ioctl) { - error = (*sc_user_ioctl)(dev, cmd, data, flag, td); + error = (*sc_user_ioctl)(tp, cmd, data, td); if (error != ENOIOCTL) return error; } - error = sc_vid_ioctl(tp, cmd, data, flag, td); + error = sc_vid_ioctl(tp, cmd, data, td); if (error != ENOIOCTL) return error; #ifndef SC_NO_HISTORY - error = sc_hist_ioctl(tp, cmd, data, flag, td); + error = sc_hist_ioctl(tp, cmd, data, td); if (error != ENOIOCTL) return error; #endif #ifndef SC_NO_SYSMOUSE - error = sc_mouse_ioctl(tp, cmd, data, flag, td); + error = sc_mouse_ioctl(tp, cmd, data, td); if (error != ENOIOCTL) return error; #endif - scp = sc_get_stat(tp->t_dev); + scp = sc_get_stat(tp); /* assert(scp != NULL) */ /* scp is sc_console, if SC_VTY(dev) == SC_CONSOLECTL. */ sc = scp->sc; if (scp->tsw) { - error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, flag, td); + error = (*scp->tsw->te_ioctl)(scp, tp, cmd, data, td); if (error != ENOIOCTL) return error; } @@ -1031,8 +1040,8 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) case VT_OPENQRY: /* return free virtual console */ for (i = sc->first_vty; i < sc->first_vty + sc->vtys; i++) { - tp = VIRTUAL_TTY(sc, i); - if (!ISTTYOPEN(tp)) { + tp = SC_DEV(sc, i); + if (!tty_opened(tp)) { *(int *)data = i + 1; return 0; } @@ -1053,7 +1062,8 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) splx(s); if (error) return error; - return sc_switch_scr(sc, i); + error = sc_switch_scr(sc, i); + return (error); #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ defined(COMPAT_FREEBSD4) || defined(COMPAT_43) @@ -1441,34 +1451,7 @@ scioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) break; } - return (ttyioctl(dev, cmd, data, flag, td)); -} - -static void -scstart(struct tty *tp) -{ - struct clist *rbp; - int s, len; - u_char buf[PCBURST]; - scr_stat *scp = sc_get_stat(tp->t_dev); - - if (scp->status & SLKED || - (scp == scp->sc->cur_scp && scp->sc->blink_in_progress)) - return; - s = spltty(); - if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) { - tp->t_state |= TS_BUSY; - rbp = &tp->t_outq; - while (rbp->c_cc) { - len = q_to_b(rbp, buf, PCBURST); - splx(s); - sc_puts(scp, buf, len); - s = spltty(); - } - tp->t_state &= ~TS_BUSY; - ttwwakeup(tp); - } - splx(s); + return (ENOIOCTL); } static void @@ -1548,9 +1531,11 @@ sc_cnputc(struct consdev *cd, int c) scp->status |= CURSOR_ENABLED; sc_draw_cursor_image(scp); } - tp = VIRTUAL_TTY(scp->sc, scp->index); - if (ISTTYOPEN(tp)) - scstart(tp); + tp = SC_DEV(scp->sc, scp->index); + tty_lock(tp); + if (tty_opened(tp)) + sctty_outwakeup(tp); + tty_unlock(tp); } #endif /* !SC_NO_HISTORY */ @@ -2281,9 +2266,9 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) * if the switch mode is VT_AUTO, unless the next vty is the same * as the current or the current vty has been closed (but showing). */ - tp = VIRTUAL_TTY(sc, cur_scp->index); + tp = SC_DEV(sc, cur_scp->index); if ((cur_scp->index != next_scr) - && ISTTYOPEN(tp) + && tty_opened(tp) && (cur_scp->smode.mode == VT_AUTO) && ISGRAPHSC(cur_scp)) { splx(s); @@ -2299,14 +2284,14 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr) * console even if it is closed. */ if ((sc_console == NULL) || (next_scr != sc_console->index)) { - tp = VIRTUAL_TTY(sc, next_scr); - if (!ISTTYOPEN(tp)) { + tp = SC_DEV(sc, next_scr); + if (!tty_opened(tp)) { splx(s); sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION); DPRINTF(5, ("error 2, requested vty isn't open!\n")); return EINVAL; } - if ((debugger > 0) && (SC_STAT(tp->t_dev)->smode.mode == VT_PROCESS)) { + if ((debugger > 0) && (SC_STAT(tp)->smode.mode == VT_PROCESS)) { splx(s); DPRINTF(5, ("error 3, requested vty is in the VT_PROCESS mode\n")); return EINVAL; @@ -2609,7 +2594,7 @@ void sc_change_cursor_shape(scr_stat *scp, int flags, int base, int height) { sc_softc_t *sc; - struct cdev *dev; + struct tty *tp; int s; int i; @@ -2635,9 +2620,9 @@ sc_change_cursor_shape(scr_stat *scp, int flags, int base, int height) } for (i = sc->first_vty; i < sc->first_vty + sc->vtys; ++i) { - if ((dev = SC_DEV(sc, i)) == NULL) + if ((tp = SC_DEV(sc, i)) == NULL) continue; - if ((scp = sc_get_stat(dev)) == NULL) + if ((scp = sc_get_stat(tp)) == NULL) continue; scp->dflt_curs_attr = sc->curs_attr; change_cursor_shape(scp, CONS_RESET_CURSOR, -1, -1); @@ -2759,10 +2744,9 @@ scinit(int unit, int flags) kernel_default.rev_color); } else { /* assert(sc_malloc) */ - sc->dev = malloc(sizeof(struct cdev *)*sc->vtys, M_DEVBUF, M_WAITOK|M_ZERO); - sc->dev[0] = make_dev(&sc_cdevsw, unit * MAXCONS, - UID_ROOT, GID_WHEEL, 0600, "ttyv%r", unit * MAXCONS); - sc_alloc_tty(sc->dev[0]); + sc->dev = malloc(sizeof(struct tty *)*sc->vtys, M_DEVBUF, + M_WAITOK|M_ZERO); + sc->dev[0] = sc_alloc_tty(0, "ttyv%r", unit * MAXCONS); scp = alloc_scp(sc, sc->first_vty); SC_STAT(sc->dev[0]) = scp; } @@ -3287,9 +3271,9 @@ next_code: scp->status |= CURSOR_ENABLED; sc_draw_cursor_image(scp); } - tp = VIRTUAL_TTY(sc, scp->index); - if (ISTTYOPEN(tp)) - scstart(tp); + tp = SC_DEV(sc, scp->index); + if (tty_opened(tp)) + sctty_outwakeup(tp); #endif } } @@ -3382,8 +3366,8 @@ next_code: for (i = (this_scr - sc->first_vty + 1)%sc->vtys; sc->first_vty + i != this_scr; i = (i + 1)%sc->vtys) { - struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i); - if (ISTTYOPEN(tp)) { + struct tty *tp = SC_DEV(sc, sc->first_vty + i); + if (tty_opened(tp)) { sc_switch_scr(scp->sc, sc->first_vty + i); break; } @@ -3395,8 +3379,8 @@ next_code: for (i = (this_scr - sc->first_vty + sc->vtys - 1)%sc->vtys; sc->first_vty + i != this_scr; i = (i + sc->vtys - 1)%sc->vtys) { - struct tty *tp = VIRTUAL_TTY(sc, sc->first_vty + i); - if (ISTTYOPEN(tp)) { + struct tty *tp = SC_DEV(sc, sc->first_vty + i); + if (tty_opened(tp)) { sc_switch_scr(scp->sc, sc->first_vty + i); break; } @@ -3425,11 +3409,11 @@ next_code: } static int -scmmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot) +sctty_mmap(struct tty *tp, vm_offset_t offset, vm_paddr_t *paddr, int nprot) { scr_stat *scp; - scp = sc_get_stat(dev); + scp = sc_get_stat(tp); if (scp != scp->sc->cur_scp) return -1; return vidd_mmap(scp->sc->adp, offset, paddr, nprot); @@ -3586,12 +3570,13 @@ sc_paste(scr_stat *scp, u_char *p, int count) struct tty *tp; u_char *rmap; - tp = VIRTUAL_TTY(scp->sc, scp->sc->cur_scp->index); - if (!ISTTYOPEN(tp)) + tp = SC_DEV(scp->sc, scp->sc->cur_scp->index); + if (!tty_opened(tp)) return; rmap = scp->sc->scr_rmap; for (; count > 0; --count) - ttyld_rint(tp, rmap[*p++]); + ttydisc_rint(tp, rmap[*p++], 0); + ttydisc_rint_done(tp); } void @@ -3626,9 +3611,9 @@ blink_screen(void *arg) if (ISGRAPHSC(scp) || (scp->sc->blink_in_progress <= 1)) { scp->sc->blink_in_progress = 0; mark_all(scp); - tp = VIRTUAL_TTY(scp->sc, scp->index); - if (ISTTYOPEN(tp)) - scstart(tp); + tp = SC_DEV(scp->sc, scp->index); + if (tty_opened(tp)) + sctty_outwakeup(tp); if (scp->sc->delayed_next_scr) sc_switch_scr(scp->sc, scp->sc->delayed_next_scr - 1); } @@ -3650,11 +3635,11 @@ blink_screen(void *arg) */ static scr_stat * -sc_get_stat(struct cdev *devptr) +sc_get_stat(struct tty *tp) { - if (devptr == NULL) + if (tp == NULL) return (&main_console); - return (SC_STAT(devptr)); + return (SC_STAT(tp)); } /* diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index f17b294d51a3..548cec61d975 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -102,9 +102,9 @@ */ #define SC_DRIVER_NAME "syscons" #endif -#define SC_VTY(dev) minor(dev) +#define SC_VTY(dev) (((sc_ttysoftc *)tty_softc(tp))->st_index) #define SC_DEV(sc, vty) ((sc)->dev[(vty) - (sc)->first_vty]) -#define SC_STAT(dev) (*((scr_stat **)&(dev)->si_drv1)) +#define SC_STAT(tp) (*((scr_stat **)&((sc_ttysoftc *)tty_softc(tp))->st_stat)) /* printable chars */ #ifndef PRINTABLE @@ -220,7 +220,7 @@ typedef struct sc_softc { int first_vty; int vtys; - struct cdev **dev; + struct tty **dev; struct scr_stat *cur_scp; struct scr_stat *new_scp; struct scr_stat *old_scp; @@ -339,6 +339,12 @@ typedef struct scr_stat { #endif } scr_stat; +/* TTY softc. */ +typedef struct sc_ttysoftc { + int st_index; + scr_stat *st_stat; +} sc_ttysoftc; + #ifndef SC_NORM_ATTR #define SC_NORM_ATTR (FG_LIGHTGREY | BG_BLACK) #endif @@ -364,7 +370,7 @@ typedef int sc_term_init_t(scr_stat *scp, void **tcp, int code); typedef int sc_term_term_t(scr_stat *scp, void **tcp); typedef void sc_term_puts_t(scr_stat *scp, u_char *buf, int len); typedef int sc_term_ioctl_t(scr_stat *scp, struct tty *tp, u_long cmd, - caddr_t data, int flag, struct thread *td); + caddr_t data, struct thread *td); typedef int sc_term_reset_t(scr_stat *scp, int code); #define SC_TE_HARD_RESET 0 #define SC_TE_SOFT_RESET 1 @@ -531,8 +537,8 @@ typedef struct { } while(0) /* syscons.c */ -extern int (*sc_user_ioctl)(struct cdev *dev, u_long cmd, caddr_t data, - int flag, struct thread *td); +extern int (*sc_user_ioctl)(struct tty *tp, u_long cmd, caddr_t data, + struct thread *td); int sc_probe_unit(int unit, int flags); int sc_attach_unit(int unit, int flags); @@ -574,7 +580,7 @@ void sc_hist_end(scr_stat *scp); int sc_hist_up_line(scr_stat *scp); int sc_hist_down_line(scr_stat *scp); int sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct thread *td); + struct thread *td); #endif /* SC_NO_HISTORY */ /* scmouse.c */ @@ -599,7 +605,7 @@ void sc_mouse_paste(scr_stat *scp); #ifndef SC_NO_SYSMOUSE void sc_mouse_move(scr_stat *scp, int x, int y); int sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, - int flag, struct thread *td); + struct thread *td); #endif /* SC_NO_SYSMOUSE */ /* scvidctl.c */ @@ -609,7 +615,7 @@ int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode); int sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, int fontsize, int font_width); -int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, +int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td); int sc_render_add(sc_renderer_t *rndr); diff --git a/sys/dev/syscons/sysmouse.c b/sys/dev/syscons/sysmouse.c index 35d761b2bd6b..9d926b88924b 100644 --- a/sys/dev/syscons/sysmouse.c +++ b/sys/dev/syscons/sysmouse.c @@ -32,8 +32,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> -#include <sys/conf.h> #include <sys/priv.h> +#include <sys/serial.h> #include <sys/tty.h> #include <sys/kernel.h> #include <sys/consio.h> @@ -45,106 +45,24 @@ __FBSDID("$FreeBSD$"); #define SC_MOUSE 128 /* minor number */ -static d_open_t smopen; -static d_close_t smclose; -static d_ioctl_t smioctl; - -static struct cdevsw sm_cdevsw = { - .d_version = D_VERSION, - .d_open = smopen, - .d_close = smclose, - .d_ioctl = smioctl, - .d_name = "sysmouse", - .d_flags = D_TTY | D_NEEDGIANT, -}; - /* local variables */ static struct tty *sysmouse_tty; static int mouse_level; /* sysmouse protocol level */ static mousestatus_t mouse_status; -static void smstart(struct tty *tp); -static int smparam(struct tty *tp, struct termios *t); - -static int -smopen(struct cdev *dev, int flag, int mode, struct thread *td) -{ - struct tty *tp; - - DPRINTF(5, ("smopen: dev:%s, vty:%d\n", - devtoname(dev), SC_VTY(dev))); - -#if 0 - if (SC_VTY(dev) != SC_MOUSE) - return ENXIO; -#endif - - tp = dev->si_tty; - if (!(tp->t_state & TS_ISOPEN)) { - ttyinitmode(tp, 0, 0); - smparam(tp, &tp->t_termios); - ttyld_modem(tp, 1); - } else if (tp->t_state & TS_XCLUDE && - priv_check(td, PRIV_TTY_EXCLUSIVE)) { - return EBUSY; - } - - return ttyld_open(tp, dev); -} - -static int -smclose(struct cdev *dev, int flag, int mode, struct thread *td) -{ - struct tty *tp; - int s; - - tp = dev->si_tty; - s = spltty(); - mouse_level = 0; - ttyld_close(tp, flag); - tty_close(tp); - splx(s); - - return 0; -} - static void -smstart(struct tty *tp) -{ - struct clist *rbp; - u_char buf[PCBURST]; - int s; - - s = spltty(); - if (!(tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))) { - tp->t_state |= TS_BUSY; - rbp = &tp->t_outq; - while (rbp->c_cc) - q_to_b(rbp, buf, PCBURST); - tp->t_state &= ~TS_BUSY; - ttwwakeup(tp); - } - splx(s); -} - -static int -smparam(struct tty *tp, struct termios *t) +smdev_close(struct tty *tp) { - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; - return 0; + mouse_level = 0; } static int -smioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) +smdev_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) { - struct tty *tp; mousehw_t *hw; mousemode_t *mode; int s; - tp = dev->si_tty; switch (cmd) { case MOUSE_GETHWINFO: /* get device information */ @@ -224,25 +142,35 @@ smioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) return ENODEV; } - return(ttyioctl(dev, cmd, data, flag, td)); + return (ENOIOCTL); } +static int +smdev_param(struct tty *tp, struct termios *t) +{ + + /* + * Set the output baud rate to zero. The mouse device supports + * no output, so we don't want to waste buffers. + */ + t->c_ispeed = TTYDEF_SPEED_PSEUDO; + t->c_ospeed = B0; + + return (0); +} + +static struct ttydevsw smdev_ttydevsw = { + .tsw_flags = TF_NOPREFIX, + .tsw_close = smdev_close, + .tsw_ioctl = smdev_ioctl, + .tsw_param = smdev_param, +}; + static void sm_attach_mouse(void *unused) { - struct cdev *dev; - struct tty *tp; - - dev = make_dev(&sm_cdevsw, SC_MOUSE, UID_ROOT, GID_WHEEL, 0600, - "sysmouse"); - dev->si_tty = tp = ttyalloc(); - tp->t_oproc = smstart; - tp->t_param = smparam; - tp->t_stop = nottystop; - tp->t_dev = dev; - - sysmouse_tty = tp; - /* sysmouse doesn't have scr_stat */ + sysmouse_tty = tty_alloc(&smdev_ttydevsw, NULL, &Giant); + tty_makedev(sysmouse_tty, NULL, "sysmouse"); } SYSINIT(sysmouse, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sm_attach_mouse, NULL); @@ -293,7 +221,7 @@ sysmouse_event(mouse_info_t *info) if (mouse_status.flags == 0) return 0; - if ((sysmouse_tty == NULL) || !(sysmouse_tty->t_state & TS_ISOPEN)) + if ((sysmouse_tty == NULL) || !tty_opened(sysmouse_tty)) return mouse_status.flags; /* the first five bytes are compatible with MouseSystems' */ @@ -306,7 +234,7 @@ sysmouse_event(mouse_info_t *info) buf[2] = y >> 1; buf[4] = y - buf[2]; for (i = 0; i < MOUSE_MSC_PACKETSIZE; ++i) - ttyld_rint(sysmouse_tty, buf[i]); + ttydisc_rint(sysmouse_tty, buf[i], 0); if (mouse_level >= 1) { /* extended part */ z = imax(imin(z, 127), -128); @@ -315,8 +243,9 @@ sysmouse_event(mouse_info_t *info) /* buttons 4-10 */ buf[7] = (~mouse_status.button >> 3) & 0x7f; for (i = MOUSE_MSC_PACKETSIZE; i < MOUSE_SYS_PACKETSIZE; ++i) - ttyld_rint(sysmouse_tty, buf[i]); + ttydisc_rint(sysmouse_tty, buf[i], 0); } + ttydisc_rint_done(sysmouse_tty); return mouse_status.flags; } diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c index 3b0d64c90ae7..932c08ab4638 100644 --- a/sys/dev/uart/uart_core.c +++ b/sys/dev/uart/uart_core.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <sys/rman.h> #include <sys/termios.h> -#include <sys/tty.h> #include <machine/resource.h> #include <machine/stdarg.h> @@ -466,7 +465,7 @@ uart_bus_attach(device_t dev) sc->sc_polled = 1; } - sc->sc_rxbufsz = IBUFSIZ; + sc->sc_rxbufsz = 384; sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf), M_UART, M_WAITOK); sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf), diff --git a/sys/dev/uart/uart_tty.c b/sys/dev/uart/uart_tty.c index 1971049ce43a..9b37bb340bf5 100644 --- a/sys/dev/uart/uart_tty.c +++ b/sys/dev/uart/uart_tty.c @@ -123,11 +123,11 @@ uart_cngetc(struct consdev *cp) } static int -uart_tty_open(struct tty *tp, struct cdev *dev) +uart_tty_open(struct tty *tp) { struct uart_softc *sc; - sc = tp->t_sc; + sc = tty_softc(tp); if (sc == NULL || sc->sc_leaving) return (ENXIO); @@ -141,7 +141,7 @@ uart_tty_close(struct tty *tp) { struct uart_softc *sc; - sc = tp->t_sc; + sc = tty_softc(tp); if (sc == NULL || sc->sc_leaving || !sc->sc_opened) return; @@ -158,11 +158,11 @@ uart_tty_close(struct tty *tp) } static void -uart_tty_oproc(struct tty *tp) +uart_tty_outwakeup(struct tty *tp) { struct uart_softc *sc; - sc = tp->t_sc; + sc = tty_softc(tp); if (sc == NULL || sc->sc_leaving) return; @@ -173,30 +173,45 @@ uart_tty_oproc(struct tty *tp) * de-assert RTS for us. In that situation we're completely stuffed. * Without hardware support, we need to toggle RTS ourselves. */ - if ((tp->t_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) { - if ((tp->t_state & TS_TBLOCK) && + if ((tp->t_termios.c_cflag & CRTS_IFLOW) && !sc->sc_hwiflow) { +#if 0 + /*if ((tp->t_state & TS_TBLOCK) && (sc->sc_hwsig & SER_RTS)) UART_SETSIG(sc, SER_DRTS); - else if (!(tp->t_state & TS_TBLOCK) && + else */ if (/*!(tp->t_state & TS_TBLOCK) &&*/ !(sc->sc_hwsig & SER_RTS)) UART_SETSIG(sc, SER_DRTS|SER_RTS); +#endif + /* XXX: we should use inwakeup to implement this! */ + if (!(sc->sc_hwsig & SER_RTS)) + UART_SETSIG(sc, SER_DRTS|SER_RTS); } - if (tp->t_state & TS_TTSTOP) + if (sc->sc_txbusy) return; - if ((tp->t_state & TS_BUSY) || sc->sc_txbusy) - return; + sc->sc_txdatasz = ttydisc_getc(tp, sc->sc_txbuf, sc->sc_txfifosz); + if (sc->sc_txdatasz != 0) + UART_TRANSMIT(sc); +} - if (tp->t_outq.c_cc == 0) { - ttwwakeup(tp); - return; - } +static int +uart_tty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) +{ + struct uart_softc *sc; + + sc = tty_softc(tp); - sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf, sc->sc_txfifosz); - tp->t_state |= TS_BUSY; - UART_TRANSMIT(sc); - ttwwakeup(tp); + switch (cmd) { + case TIOCSBRK: + UART_IOCTL(sc, UART_IOCTL_BREAK, 1); + return (0); + case TIOCCBRK: + UART_IOCTL(sc, UART_IOCTL_BREAK, 0); + return (0); + default: + return pps_ioctl(cmd, data, &sc->sc_pps); + } } static int @@ -205,7 +220,7 @@ uart_tty_param(struct tty *tp, struct termios *t) struct uart_softc *sc; int databits, parity, stopbits; - sc = tp->t_sc; + sc = tty_softc(tp); if (sc == NULL || sc->sc_leaving) return (ENODEV); if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0) @@ -237,16 +252,16 @@ uart_tty_param(struct tty *tp, struct termios *t) UART_SETSIG(sc, SER_DDTR | SER_DTR); /* Set input flow control state. */ if (!sc->sc_hwiflow) { - if ((t->c_cflag & CRTS_IFLOW) && (tp->t_state & TS_TBLOCK)) + /* if ((t->c_cflag & CRTS_IFLOW) && (tp->t_state & TS_TBLOCK)) UART_SETSIG(sc, SER_DRTS); - else + else */ UART_SETSIG(sc, SER_DRTS | SER_RTS); } else UART_IOCTL(sc, UART_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW)); /* Set output flow control state. */ if (sc->sc_hwoflow) UART_IOCTL(sc, UART_IOCTL_OFLOW, (t->c_cflag & CCTS_OFLOW)); - ttsetwater(tp); + return (0); } @@ -255,48 +270,18 @@ uart_tty_modem(struct tty *tp, int biton, int bitoff) { struct uart_softc *sc; - sc = tp->t_sc; + sc = tty_softc(tp); if (biton != 0 || bitoff != 0) UART_SETSIG(sc, SER_DELTA(bitoff|biton) | biton); return (sc->sc_hwsig); } -static void -uart_tty_break(struct tty *tp, int state) -{ - struct uart_softc *sc; - - sc = tp->t_sc; - UART_IOCTL(sc, UART_IOCTL_BREAK, state); -} - -static void -uart_tty_stop(struct tty *tp, int rw) -{ - struct uart_softc *sc; - - sc = tp->t_sc; - if (sc == NULL || sc->sc_leaving) - return; - if (rw & FWRITE) { - if (sc->sc_txbusy) { - sc->sc_txbusy = 0; - UART_FLUSH(sc, UART_FLUSH_TRANSMITTER); - } - tp->t_state &= ~TS_BUSY; - } - if (rw & FREAD) { - UART_FLUSH(sc, UART_FLUSH_RECEIVER); - sc->sc_rxget = sc->sc_rxput = 0; - } -} - void uart_tty_intr(void *arg) { struct uart_softc *sc = arg; struct tty *tp; - int c, pend, sig, xc; + int c, err = 0, pend, sig, xc; if (sc->sc_leaving) return; @@ -306,78 +291,72 @@ uart_tty_intr(void *arg) return; tp = sc->sc_u.u_tty.tp; + tty_lock(tp); if (pend & SER_INT_RXREADY) { - while (!uart_rx_empty(sc) && !(tp->t_state & TS_TBLOCK)) { + while (!uart_rx_empty(sc) /* && !(tp->t_state & TS_TBLOCK)*/) { xc = uart_rx_get(sc); c = xc & 0xff; if (xc & UART_STAT_FRAMERR) - c |= TTY_FE; + err |= TRE_FRAMING; if (xc & UART_STAT_OVERRUN) - c |= TTY_OE; + err |= TRE_OVERRUN; if (xc & UART_STAT_PARERR) - c |= TTY_PE; - ttyld_rint(tp, c); + err |= TRE_PARITY; + ttydisc_rint(tp, c, err); } } - if (pend & SER_INT_BREAK) { - if (tp != NULL && !(tp->t_iflag & IGNBRK)) - ttyld_rint(tp, 0); - } + if (pend & SER_INT_BREAK) + ttydisc_rint(tp, 0, TRE_BREAK); if (pend & SER_INT_SIGCHG) { sig = pend & SER_INT_SIGMASK; if (sig & SER_DDCD) - ttyld_modem(tp, sig & SER_DCD); - if ((sig & SER_DCTS) && (tp->t_cflag & CCTS_OFLOW) && + ttydisc_modem(tp, sig & SER_DCD); + if ((sig & SER_DCTS) && (tp->t_termios.c_cflag & CCTS_OFLOW) && !sc->sc_hwoflow) { - if (sig & SER_CTS) { - tp->t_state &= ~TS_TTSTOP; - ttyld_start(tp); - } else - tp->t_state |= TS_TTSTOP; + if (sig & SER_CTS) + uart_tty_outwakeup(tp); } } - if (pend & SER_INT_TXIDLE) { - tp->t_state &= ~TS_BUSY; - ttyld_start(tp); - } + if (pend & SER_INT_TXIDLE) + uart_tty_outwakeup(tp); + ttydisc_rint_done(tp); + tty_unlock(tp); } +static struct ttydevsw uart_tty_class = { + .tsw_flags = TF_INITLOCK|TF_CALLOUT, + .tsw_open = uart_tty_open, + .tsw_close = uart_tty_close, + .tsw_outwakeup = uart_tty_outwakeup, + .tsw_ioctl = uart_tty_ioctl, + .tsw_param = uart_tty_param, + .tsw_modem = uart_tty_modem, +}; + int uart_tty_attach(struct uart_softc *sc) { struct tty *tp; int unit; - tp = ttyalloc(); - sc->sc_u.u_tty.tp = tp; - tp->t_sc = sc; + sc->sc_u.u_tty.tp = tp = tty_alloc(&uart_tty_class, sc, NULL); 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); + tty_init_console(tp, 0); } swi_add(&tty_intr_event, uart_driver_name, uart_tty_intr, sc, SWI_TTY, INTR_TYPE_TTY, &sc->sc_softih); - ttycreate(tp, TS_CALLOUT, "u%r", unit); + tty_makedev(tp, NULL, "u%r", unit); return (0); } @@ -387,10 +366,10 @@ int uart_tty_detach(struct uart_softc *sc) struct tty *tp; tp = sc->sc_u.u_tty.tp; - tp->t_pps = NULL; - ttygone(tp); + + tty_lock(tp); swi_remove(sc->sc_softih); - ttyfree(tp); + tty_rel_gone(tp); return (0); } diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c index f99a73ab4ad7..29c11ec88781 100644 --- a/sys/dev/usb/ucom.c +++ b/sys/dev/usb/ucom.c @@ -116,22 +116,33 @@ SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW, static int ucom_modevent(module_t, int, void *); static void ucom_cleanup(struct ucom_softc *); -static int ucomparam(struct tty *, struct termios *); -static void ucomstart(struct tty *); -static void ucomstop(struct tty *, int); static void ucom_shutdown(struct ucom_softc *); static void ucom_dtr(struct ucom_softc *, int); static void ucom_rts(struct ucom_softc *, int); -static void ucombreak(struct tty *, int); +static void ucombreak(struct ucom_softc *, int); static usbd_status ucomstartread(struct ucom_softc *); static void ucomreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status); static void ucomwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status); static void ucomstopread(struct ucom_softc *); -static t_open_t ucomopen; -static t_close_t ucomclose; -static t_modem_t ucommodem; -static t_ioctl_t ucomioctl; +static tsw_open_t ucomtty_open; +static tsw_close_t ucomtty_close; +static tsw_outwakeup_t ucomtty_outwakeup; +static tsw_ioctl_t ucomtty_ioctl; +static tsw_param_t ucomtty_param; +static tsw_modem_t ucomtty_modem; +static tsw_free_t ucomtty_free; + +static struct ttydevsw ucomtty_class = { + .tsw_flags = TF_INITLOCK|TF_CALLOUT, + .tsw_open = ucomtty_open, + .tsw_close = ucomtty_close, + .tsw_outwakeup = ucomtty_outwakeup, + .tsw_ioctl = ucomtty_ioctl, + .tsw_param = ucomtty_param, + .tsw_modem = ucomtty_modem, + .tsw_free = ucomtty_free, +}; devclass_t ucom_devclass; @@ -160,31 +171,20 @@ ucom_modevent(module_t mod, int type, void *data) return (0); } -int -ucom_attach_tty(struct ucom_softc *sc, int flags, char* fmt, int unit) +void +ucom_attach_tty(struct ucom_softc *sc, char* fmt, int unit) { struct tty *tp; - sc->sc_tty = tp = ttyalloc(); - tp->t_sc = sc; - tp->t_oproc = ucomstart; - tp->t_param = ucomparam; - tp->t_stop = ucomstop; - tp->t_break = ucombreak; - tp->t_open = ucomopen; - tp->t_close = ucomclose; - tp->t_modem = ucommodem; - tp->t_ioctl = ucomioctl; - - return ttycreate(tp, flags, fmt, unit); + sc->sc_tty = tp = tty_alloc(&ucomtty_class, sc, &Giant); + tty_makedev(tp, NULL, fmt, unit); } int ucom_attach(struct ucom_softc *sc) { - ucom_attach_tty(sc, TS_CALLOUT, - "U%d", device_get_unit(sc->sc_dev)); + ucom_attach_tty(sc, "U%d", device_get_unit(sc->sc_dev)); DPRINTF(("ucom_attach: ttycreate: tp = %p, %s\n", sc->sc_tty, sc->sc_tty->t_dev->si_name)); @@ -195,24 +195,17 @@ ucom_attach(struct ucom_softc *sc) int ucom_detach(struct ucom_softc *sc) { - int s; - DPRINTF(("ucom_detach: sc = %p, tp = %p\n", sc, sc->sc_tty)); + tty_lock(sc->sc_tty); sc->sc_dying = 1; - ttygone(sc->sc_tty); - if (sc->sc_tty->t_state & TS_ISOPEN) - ucomclose(sc->sc_tty); if (sc->sc_bulkin_pipe != NULL) usbd_abort_pipe(sc->sc_bulkin_pipe); if (sc->sc_bulkout_pipe != NULL) usbd_abort_pipe(sc->sc_bulkout_pipe); - ttyfree(sc->sc_tty); - - s = splusb(); - splx(s); + tty_rel_gone(sc->sc_tty); return (0); } @@ -227,30 +220,30 @@ ucom_shutdown(struct ucom_softc *sc) * Hang up if necessary. Wait a bit, so the other side has time to * notice even if we immediately open the port again. */ - if (ISSET(tp->t_cflag, HUPCL)) { - (void)ucommodem(tp, 0, SER_DTR); + if (tp->t_termios.c_cflag & HUPCL) { + (void)ucomtty_modem(tp, 0, SER_DTR); +#if 0 (void)tsleep(sc, TTIPRI, "ucomsd", hz); +#endif } } static int -ucomopen(struct tty *tp, struct cdev *dev) +ucomtty_open(struct tty *tp) { - struct ucom_softc *sc; + struct ucom_softc *sc = tty_softc(tp); usbd_status err; int error; - sc = tp->t_sc; - if (sc->sc_dying) return (ENXIO); - DPRINTF(("%s: ucomopen: tp = %p\n", device_get_nameunit(sc->sc_dev), tp)); + DPRINTF(("%s: ucomtty_open: tp = %p\n", device_get_nameunit(sc->sc_dev), tp)); sc->sc_poll = 0; sc->sc_lsr = sc->sc_msr = sc->sc_mcr = 0; - (void)ucommodem(tp, SER_DTR | SER_RTS, 0); + (void)ucomtty_modem(tp, SER_DTR | SER_RTS, 0); /* Device specific open */ if (sc->sc_callback->ucom_open != NULL) { @@ -262,7 +255,7 @@ ucomopen(struct tty *tp, struct cdev *dev) } } - DPRINTF(("ucomopen: open pipes in = %d out = %d\n", + DPRINTF(("ucomtty_open: open pipes in = %d out = %d\n", sc->sc_bulkin_no, sc->sc_bulkout_no)); /* Open the bulk pipes */ @@ -328,13 +321,11 @@ fail: } static void -ucomclose(struct tty *tp) +ucomtty_close(struct tty *tp) { - struct ucom_softc *sc; - - sc = tp->t_sc; + struct ucom_softc *sc = tty_softc(tp); - DPRINTF(("%s: ucomclose \n", device_get_nameunit(sc->sc_dev))); + DPRINTF(("%s: ucomtty_close \n", device_get_nameunit(sc->sc_dev))); ucom_cleanup(sc); @@ -343,35 +334,41 @@ ucomclose(struct tty *tp) } static int -ucomioctl(struct tty *tp, u_long cmd, void *data, int flag, struct thread *p) +ucomtty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *p) { - struct ucom_softc *sc; + struct ucom_softc *sc = tty_softc(tp); int error; - sc = tp->t_sc;; if (sc->sc_dying) return (EIO); DPRINTF(("ucomioctl: cmd = 0x%08lx\n", cmd)); - error = ENOTTY; + switch (cmd) { + case TIOCSBRK: + ucombreak(sc, 1); + return (0); + case TIOCCBRK: + ucombreak(sc, 0); + return (0); + } + + error = ENOIOCTL; if (sc->sc_callback->ucom_ioctl != NULL) error = sc->sc_callback->ucom_ioctl(sc->sc_parent, sc->sc_portno, - cmd, data, flag, p); + cmd, data, p); return (error); } static int -ucommodem(struct tty *tp, int sigon, int sigoff) +ucomtty_modem(struct tty *tp, int sigon, int sigoff) { - struct ucom_softc *sc; + struct ucom_softc *sc = tty_softc(tp); int mcr; int msr; int onoff; - sc = tp->t_sc; - if (sigon == 0 && sigoff == 0) { mcr = sc->sc_mcr; if (ISSET(mcr, SER_DTR)) @@ -412,12 +409,10 @@ ucommodem(struct tty *tp, int sigon, int sigoff) } static void -ucombreak(struct tty *tp, int onoff) +ucombreak(struct ucom_softc *sc, int onoff) { - struct ucom_softc *sc; - - sc = tp->t_sc; DPRINTF(("ucombreak: onoff = %d\n", onoff)); + if (sc->sc_callback->ucom_set == NULL) return; sc->sc_callback->ucom_set(sc->sc_parent, sc->sc_portno, @@ -467,47 +462,32 @@ ucom_status_change(struct ucom_softc *sc) return; onoff = ISSET(sc->sc_msr, SER_DCD) ? 1 : 0; DPRINTF(("ucom_status_change: DCD changed to %d\n", onoff)); - ttyld_modem(tp, onoff); + ttydisc_modem(tp, onoff); } } static int -ucomparam(struct tty *tp, struct termios *t) +ucomtty_param(struct tty *tp, struct termios *t) { - struct ucom_softc *sc; + struct ucom_softc *sc = tty_softc(tp); int error; usbd_status uerr; - sc = tp->t_sc; - if (sc->sc_dying) return (EIO); - DPRINTF(("ucomparam: sc = %p\n", sc)); + DPRINTF(("ucomtty_param: sc = %p\n", sc)); /* Check requested parameters. */ if (t->c_ospeed < 0) { - DPRINTF(("ucomparam: negative ospeed\n")); + DPRINTF(("ucomtty_param: negative ospeed\n")); return (EINVAL); } if (t->c_ispeed && t->c_ispeed != t->c_ospeed) { - DPRINTF(("ucomparam: mismatch ispeed and ospeed\n")); + DPRINTF(("ucomtty_param: mismatch ispeed and ospeed\n")); return (EINVAL); } - - /* - * If there were no changes, don't do anything. This avoids dropping - * input and improves performance when all we did was frob things like - * VMIN and VTIME. - */ - if (tp->t_ospeed == t->c_ospeed && - tp->t_cflag == t->c_cflag) - return (0); - - /* And copy to tty. */ - tp->t_ispeed = 0; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; + t->c_ispeed = t->c_ospeed; if (sc->sc_callback->ucom_param == NULL) return (0); @@ -516,20 +496,24 @@ ucomparam(struct tty *tp, struct termios *t) error = sc->sc_callback->ucom_param(sc->sc_parent, sc->sc_portno, t); if (error) { - DPRINTF(("ucomparam: callback: error = %d\n", error)); + DPRINTF(("ucomtty_param: callback: error = %d\n", error)); return (error); } +#if 0 ttsetwater(tp); +#endif if (t->c_cflag & CRTS_IFLOW) { sc->sc_state |= UCS_RTS_IFLOW; } else if (sc->sc_state & UCS_RTS_IFLOW) { sc->sc_state &= ~UCS_RTS_IFLOW; - (void)ucommodem(tp, SER_RTS, 0); + (void)ucomtty_modem(tp, SER_RTS, 0); } +#if 0 ttyldoptim(tp); +#endif uerr = ucomstartread(sc); if (uerr != USBD_NORMAL_COMPLETION) @@ -539,17 +523,23 @@ ucomparam(struct tty *tp, struct termios *t) } static void -ucomstart(struct tty *tp) +ucomtty_free(void *sc) +{ + /* + * Our softc gets deallocated earlier on. + * XXX: we should make sure the TTY device name doesn't get + * recycled before we end up here! + */ +} + +static void +ucomtty_outwakeup(struct tty *tp) { - struct ucom_softc *sc; - struct cblock *cbp; + struct ucom_softc *sc = tty_softc(tp); usbd_status err; - int s; - u_char *data; - int cnt; + size_t cnt; - sc = tp->t_sc; - DPRINTF(("ucomstart: sc = %p\n", sc)); + DPRINTF(("ucomtty_outwakeup: sc = %p\n", sc)); if (sc->sc_dying) return; @@ -564,90 +554,59 @@ ucomstart(struct tty *tp) if (sc->sc_oxfer == NULL) return; - s = spltty(); - + /* XXX: hardware flow control. We should use inwakeup here. */ +#if 0 if (tp->t_state & TS_TBLOCK) { if (ISSET(sc->sc_mcr, SER_RTS) && ISSET(sc->sc_state, UCS_RTS_IFLOW)) { - DPRINTF(("ucomstart: clear RTS\n")); - (void)ucommodem(tp, 0, SER_RTS); + DPRINTF(("ucomtty_outwakeup: clear RTS\n")); + (void)ucomtty_modem(tp, 0, SER_RTS); } } else { if (!ISSET(sc->sc_mcr, SER_RTS) && tp->t_rawq.c_cc <= tp->t_ilowat && ISSET(sc->sc_state, UCS_RTS_IFLOW)) { - DPRINTF(("ucomstart: set RTS\n")); - (void)ucommodem(tp, SER_RTS, 0); + DPRINTF(("ucomtty_outwakeup: set RTS\n")); + (void)ucomtty_modem(tp, SER_RTS, 0); } } +#endif - if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) { - ttwwakeup(tp); - DPRINTF(("ucomstart: stopped\n")); - goto out; - } - - if (tp->t_outq.c_cc <= tp->t_olowat) { - if (ISSET(tp->t_state, TS_SO_OLOWAT)) { - CLR(tp->t_state, TS_SO_OLOWAT); - wakeup(TSA_OLOWAT(tp)); - } - selwakeuppri(&tp->t_wsel, TTIPRI); - if (tp->t_outq.c_cc == 0) { - if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) == - TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) { - CLR(tp->t_state, TS_SO_OCOMPLETE); - wakeup(TSA_OCOMPLETE(tp)); - } - goto out; - } - } + if (sc->sc_state & UCS_TXBUSY) + return; - /* Grab the first contiguous region of buffer space. */ - data = tp->t_outq.c_cf; - cbp = (struct cblock *) ((intptr_t) tp->t_outq.c_cf & ~CROUND); - cnt = min((char *) (cbp+1) - tp->t_outq.c_cf, tp->t_outq.c_cc); + sc->sc_state |= UCS_TXBUSY; + if (sc->sc_callback->ucom_write != NULL) + cnt = sc->sc_callback->ucom_write(sc->sc_parent, + sc->sc_portno, tp, sc->sc_obuf, sc->sc_obufsize); + else + cnt = ttydisc_getc(tp, sc->sc_obuf, sc->sc_obufsize); if (cnt == 0) { - DPRINTF(("ucomstart: cnt == 0\n")); - goto out; - } - - SET(tp->t_state, TS_BUSY); - - if (cnt > sc->sc_obufsize) { - DPRINTF(("ucomstart: big buffer %d chars\n", cnt)); - cnt = sc->sc_obufsize; + DPRINTF(("ucomtty_outwakeup: cnt == 0\n")); + sc->sc_state &= ~UCS_TXBUSY; + return; } - if (sc->sc_callback->ucom_write != NULL) - sc->sc_callback->ucom_write(sc->sc_parent, sc->sc_portno, - sc->sc_obuf, data, &cnt); - else - memcpy(sc->sc_obuf, data, cnt); - DPRINTF(("ucomstart: %d chars\n", cnt)); + DPRINTF(("ucomtty_outwakeup: %zu chars\n", cnt)); usbd_setup_xfer(sc->sc_oxfer, sc->sc_bulkout_pipe, (usbd_private_handle)sc, sc->sc_obuf, cnt, USBD_NO_COPY, USBD_NO_TIMEOUT, ucomwritecb); /* What can we do on error? */ err = usbd_transfer(sc->sc_oxfer); - if (err != USBD_IN_PROGRESS) - printf("ucomstart: err=%s\n", usbd_errstr(err)); - - ttwwakeup(tp); - - out: - splx(s); + if (err != USBD_IN_PROGRESS) { + printf("ucomtty_outwakeup: err=%s\n", usbd_errstr(err)); + sc->sc_state &= ~UCS_TXBUSY; + } } +#if 0 static void ucomstop(struct tty *tp, int flag) { - struct ucom_softc *sc; + struct ucom_softc *sc = tty_softc(tp); int s; - sc = tp->t_sc; - DPRINTF(("ucomstop: %d\n", flag)); if ((flag & FREAD) && (sc->sc_state & UCS_RXSTOP) == 0) { @@ -658,19 +617,18 @@ ucomstop(struct tty *tp, int flag) if (flag & FWRITE) { DPRINTF(("ucomstop: write\n")); - s = spltty(); if (ISSET(tp->t_state, TS_BUSY)) { /* XXX do what? */ if (!ISSET(tp->t_state, TS_TTSTOP)) SET(tp->t_state, TS_FLUSH); } - splx(s); } - ucomstart(tp); + ucomtty_outwakeup(tp); DPRINTF(("ucomstop: done\n")); } +#endif static void ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) @@ -678,12 +636,11 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) struct ucom_softc *sc = (struct ucom_softc *)p; struct tty *tp = sc->sc_tty; u_int32_t cc; - int s; DPRINTF(("ucomwritecb: status = %d\n", status)); if (status == USBD_CANCELLED || sc->sc_dying) - goto error; + return; if (status != USBD_NORMAL_COMPLETION) { printf("%s: ucomwritecb: %s\n", @@ -691,7 +648,7 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); /* XXX we should restart after some delay. */ - goto error; + return; } usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL); @@ -699,28 +656,21 @@ ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) if (cc <= sc->sc_opkthdrlen) { printf("%s: sent size too small, cc = %d\n", device_get_nameunit(sc->sc_dev), cc); - goto error; + return; } /* convert from USB bytes to tty bytes */ cc -= sc->sc_opkthdrlen; - s = spltty(); + sc->sc_state &= ~UCS_TXBUSY; +#if 0 CLR(tp->t_state, TS_BUSY); if (ISSET(tp->t_state, TS_FLUSH)) CLR(tp->t_state, TS_FLUSH); else ndflush(&tp->t_outq, cc); - ttyld_start(tp); - splx(s); - - return; - - error: - s = spltty(); - CLR(tp->t_state, TS_BUSY); - splx(s); - return; +#endif + ucomtty_outwakeup(tp); } static usbd_status @@ -758,8 +708,6 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) usbd_status err; u_int32_t cc; u_char *cp; - int lostcc; - int s; DPRINTF(("ucomreadcb: status = %d\n", status)); @@ -791,42 +739,20 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) } if (cc < 1) goto resubmit; - - s = spltty(); - if (tp->t_state & TS_CAN_BYPASS_L_RINT) { - if (tp->t_rawq.c_cc + cc > tp->t_ihiwat - && (sc->sc_state & UCS_RTS_IFLOW - || tp->t_iflag & IXOFF) - && !(tp->t_state & TS_TBLOCK)) - ttyblock(tp); - lostcc = b_to_q((char *)cp, cc, &tp->t_rawq); - tp->t_rawcc += cc; - ttwakeup(tp); - if (tp->t_state & TS_TTSTOP - && (tp->t_iflag & IXANY - || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { - tp->t_state &= ~TS_TTSTOP; - tp->t_lflag &= ~FLUSHO; - ucomstart(tp); - } - if (lostcc > 0) - printf("%s: lost %d chars\n", device_get_nameunit(sc->sc_dev), - lostcc); - } else { - /* Give characters to tty layer. */ - while (cc > 0) { - DPRINTFN(7, ("ucomreadcb: char = 0x%02x\n", *cp)); - if (ttyld_rint(tp, *cp) == -1) { - /* XXX what should we do? */ - printf("%s: lost %d chars\n", - device_get_nameunit(sc->sc_dev), cc); - break; - } - cc--; - cp++; + + /* Give characters to tty layer. */ + while (cc > 0) { + DPRINTFN(7, ("ucomreadcb: char = 0x%02x\n", *cp)); + if (ttydisc_rint(tp, *cp, 0) == -1) { + /* XXX what should we do? */ + printf("%s: lost %d chars\n", + device_get_nameunit(sc->sc_dev), cc); + break; } + cc--; + cp++; } - splx(s); + ttydisc_rint_done(tp); resubmit: err = ucomstartread(sc); @@ -835,9 +761,11 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) /* XXX what should we dow now? */ } +#if 0 if ((sc->sc_state & UCS_RTS_IFLOW) && !ISSET(sc->sc_mcr, SER_RTS) && !(tp->t_state & TS_TBLOCK)) - ucommodem(tp, SER_RTS, 0); + ucomtty_modem(tp, SER_RTS, 0); +#endif } static void diff --git a/sys/dev/usb/ucomvar.h b/sys/dev/usb/ucomvar.h index 4a5ddd211902..7a35a0ace760 100644 --- a/sys/dev/usb/ucomvar.h +++ b/sys/dev/usb/ucomvar.h @@ -88,6 +88,7 @@ #define UCOM_UNK_PORTNO -1 /* XXX */ +struct tty; struct ucom_softc; struct ucom_callback { @@ -97,11 +98,11 @@ struct ucom_callback { #define UCOM_SET_RTS 2 #define UCOM_SET_BREAK 3 int (*ucom_param)(void *, int, struct termios *); - int (*ucom_ioctl)(void *, int, u_long, caddr_t, int, struct thread *); + int (*ucom_ioctl)(void *, int, u_long, caddr_t, struct thread *); int (*ucom_open)(void *, int); void (*ucom_close)(void *, int); void (*ucom_read)(void *, int, u_char **, u_int32_t *); - void (*ucom_write)(void *, int, u_char *, u_char *, u_int32_t *); + size_t (*ucom_write)(void *, int, struct tty *, u_char *, u_int32_t); }; /* line status register */ @@ -117,6 +118,7 @@ struct ucom_callback { /* ucom state declarations */ #define UCS_RXSTOP 0x0001 /* Rx stopped */ +#define UCS_TXBUSY 0x0002 /* Tx busy */ #define UCS_RTS_IFLOW 0x0008 /* use RTS input flow control */ struct ucom_softc { @@ -159,7 +161,7 @@ struct ucom_softc { extern devclass_t ucom_devclass; -int ucom_attach_tty(struct ucom_softc *, int, char*, int); +void ucom_attach_tty(struct ucom_softc *, char*, int); int ucom_attach(struct ucom_softc *); int ucom_detach(struct ucom_softc *); void ucom_status_change(struct ucom_softc *); diff --git a/sys/dev/usb/uftdi.c b/sys/dev/usb/uftdi.c index 22036e48ffcc..5a9921be7f4b 100644 --- a/sys/dev/usb/uftdi.c +++ b/sys/dev/usb/uftdi.c @@ -118,8 +118,8 @@ static void uftdi_set(void *, int, int, int); static int uftdi_param(void *, int, struct termios *); static int uftdi_open(void *sc, int portno); static void uftdi_read(void *sc, int portno, u_char **ptr,u_int32_t *count); -static void uftdi_write(void *sc, int portno, u_char *to, u_char *from, - u_int32_t *count); +static size_t uftdi_write(void *sc, int portno, struct tty *, + u_char *to, u_int32_t count); static void uftdi_break(void *sc, int portno, int onoff); static int uftdi_8u232am_getrate(speed_t speed, int *rate); @@ -486,20 +486,25 @@ uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count) *count -= 2; } -static void -uftdi_write(void *vsc, int portno, u_char *to, u_char *from, u_int32_t *count) +static size_t +uftdi_write(void *vsc, int portno, struct tty *tp, u_char *to, u_int32_t count) { struct uftdi_softc *sc = vsc; + size_t l; - DPRINTFN(10,("uftdi_write: sc=%p, port=%d count=%u data[0]=0x%02x\n", - vsc, portno, *count, from[0])); + DPRINTFN(10,("uftdi_write: sc=%p, port=%d tp=%p, count=%u\n", + vsc, portno, tp, count)); - /* Make length tag and copy data */ - if (sc->sc_hdrlen > 0) - *to = FTDI_OUT_TAG(*count, portno); + /* Leave space for the length tag. */ + l = ttydisc_getc(tp, to + sc->sc_hdrlen, count - sc->sc_hdrlen); + if (l == 0) + return (0); - memcpy(to + sc->sc_hdrlen, from, *count); - *count += sc->sc_hdrlen; + /* Make length tag. */ + if (sc->sc_hdrlen > 0) + *to = FTDI_OUT_TAG(l, portno); + + return (l + sc->sc_hdrlen); } static void diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c index 6424496d7f19..89b3e0506386 100644 --- a/sys/dev/usb/umodem.c +++ b/sys/dev/usb/umodem.c @@ -187,7 +187,7 @@ static void umodem_rts(struct umodem_softc *, int); static void umodem_break(struct umodem_softc *, int); static void umodem_set_line_state(struct umodem_softc *); static int umodem_param(void *, int, struct termios *); -static int umodem_ioctl(void *, int, u_long, caddr_t, int, struct thread *); +static int umodem_ioctl(void *, int, u_long, caddr_t, struct thread *); static int umodem_open(void *, int portno); static void umodem_close(void *, int portno); static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); @@ -611,7 +611,7 @@ umodem_param(void *addr, int portno, struct termios *t) } int -umodem_ioctl(void *addr, int portno, u_long cmd, caddr_t data, int flag, +umodem_ioctl(void *addr, int portno, u_long cmd, caddr_t data, struct thread *p) { struct umodem_softc *sc = addr; |
