summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2008-08-20 08:31:58 +0000
committerEd Schouten <ed@FreeBSD.org>2008-08-20 08:31:58 +0000
commitbc093719ca478fe10b938cef32c30b528042cbcd (patch)
treebd0c08a66997254385160ce71ea32029b99f99f9 /sys/dev
parentb14f19cf9742655c453d9c1dd672393c31080af4 (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/dcons/dcons.h2
-rw-r--r--sys/dev/dcons/dcons_os.c393
-rw-r--r--sys/dev/nmdm/nmdm.c412
-rw-r--r--sys/dev/ofw/ofw_console.c143
-rw-r--r--sys/dev/syscons/schistory.c7
-rw-r--r--sys/dev/syscons/scmouse.c5
-rw-r--r--sys/dev/syscons/scterm-sc.c2
-rw-r--r--sys/dev/syscons/scvesactl.c12
-rw-r--r--sys/dev/syscons/scvidctl.c18
-rw-r--r--sys/dev/syscons/syscons.c327
-rw-r--r--sys/dev/syscons/syscons.h24
-rw-r--r--sys/dev/syscons/sysmouse.c135
-rw-r--r--sys/dev/uart/uart_core.c3
-rw-r--r--sys/dev/uart/uart_tty.c165
-rw-r--r--sys/dev/usb/ucom.c334
-rw-r--r--sys/dev/usb/ucomvar.h8
-rw-r--r--sys/dev/usb/uftdi.c27
-rw-r--r--sys/dev/usb/umodem.c4
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;