Introduce ttygone() which indicates that the hardware is detached.

Move dtrwait logic to the generic TTY level.
This commit is contained in:
Poul-Henning Kamp 2004-07-11 15:18:39 +00:00
parent cd2890d712
commit 911dbd84c7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=131981
16 changed files with 117 additions and 375 deletions

View File

@ -160,14 +160,11 @@ typedef struct _drv_t {
cx_dma_mem_t dmamem;
struct tty *tty;
struct callout_handle dcd_timeout_handle;
unsigned dtrwait;
unsigned dtroff;
unsigned callout;
unsigned lock;
int open_dev;
int cd;
int running;
struct callout_handle dtr_timeout_handle;
#ifdef NETGRAPH
char nodename [NG_NODELEN+1];
hook_p hook;
@ -217,7 +214,6 @@ extern const u_char csigma_fw_data[];
static void cx_oproc (struct tty *tp);
static int cx_param (struct tty *tp, struct termios *t);
static void cx_stop (struct tty *tp, int flag);
static void cx_dtrwakeup (void *a);
static void cx_receive (cx_chan_t *c, char *data, int len);
static void cx_transmit (cx_chan_t *c, void *attachment, int len);
static void cx_error (cx_chan_t *c, int data);
@ -817,7 +813,6 @@ static int cx_attach (device_t dev)
sprintf (d->name, "cx%d.%d", b->num, c->num);
d->board = b;
d->chan = c;
d->dtrwait = 3 * hz; /* Default DTR off timeout is 3 seconds. */
d->open_dev = 0;
c->sys = d;
@ -940,8 +935,6 @@ static int cx_detach (device_t dev)
if (!d || d->chan->type == T_NONE)
continue;
if (d->dtr_timeout_handle.callout)
untimeout (cx_dtrwakeup, d, d->dtr_timeout_handle);
if (d->dcd_timeout_handle.callout)
untimeout (cx_carrier, c, d->dcd_timeout_handle);
}
@ -1518,12 +1511,9 @@ static int cx_open (struct cdev *dev, int flag, int mode, struct thread *td)
dev->si_tty = d->tty;
d->tty->t_dev = dev;
again:
if (d->dtroff) {
error = tsleep (&d->dtrwait, TTIPRI | PCATCH, "cxdtr", 0);
if (error)
return error;
goto again;
}
error = ttydtrwaitsleep(d->tty);
if (error)
return error;
if ((d->tty->t_state & TS_ISOPEN) && (d->tty->t_state & TS_XCLUDE) &&
#if __FreeBSD_version >= 500000
@ -1608,11 +1598,7 @@ failed: if (! (d->tty->t_state & TS_ISOPEN)) {
splhigh ();
cx_set_dtr (d->chan, 0);
cx_set_rts (d->chan, 0);
if (d->dtrwait) {
d->dtr_timeout_handle =
timeout (cx_dtrwakeup, d, d->dtrwait);
d->dtroff = 1;
}
ttydtrwaitstart(d->tty);
spl0 ();
}
return error;
@ -1652,11 +1638,7 @@ static int cx_close (struct cdev *dev, int flag, int mode, struct thread *td)
if ((d->tty->t_cflag & HUPCL) || ! (d->tty->t_state & TS_ISOPEN)) {
cx_set_dtr (d->chan, 0);
cx_set_rts (d->chan, 0);
if (d->dtrwait) {
d->dtr_timeout_handle =
timeout (cx_dtrwakeup, d, d->dtrwait);
d->dtroff = 1;
}
ttydtrwaitstart(d->tty);
}
ttyclose (d->tty);
splx (s);
@ -2139,48 +2121,11 @@ static int cx_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int flag, struc
*(int*)data = cx_modem_status (d);
return 0;
#ifdef TIOCMSDTRWAIT
case TIOCMSDTRWAIT:
CX_DEBUG2 (d, ("ioctl: tiocmsdtrwait\n"));
/* Only for superuser! */
#if __FreeBSD_version < 500000
error = suser (p);
#else /* __FreeBSD_version >= 500000 */
error = suser (td);
#endif /* __FreeBSD_version >= 500000 */
if (error)
return error;
s = splhigh ();
d->dtrwait = *(int*)data * hz / 100;
splx (s);
return 0;
#endif
#ifdef TIOCMGDTRWAIT
case TIOCMGDTRWAIT:
CX_DEBUG2 (d, ("ioctl: tiocmgdtrwait\n"));
s = splhigh ();
*(int*)data = d->dtrwait * 100 / hz;
splx (s);
return 0;
#endif
}
CX_DEBUG2 (d, ("ioctl: 0x%lx\n", cmd));
return ENOTTY;
}
/*
* Wake up opens() waiting for DTR ready.
*/
static void cx_dtrwakeup (void *arg)
{
drv_t *d = arg;
d->dtroff = 0;
wakeup (&d->dtrwait);
}
#if __FreeBSD_version < 502113
static void
ttyldoptim(tp)

View File

@ -117,7 +117,6 @@ __FBSDID("$FreeBSD$");
#define p_com_addr p_cy_addr
#define sioclose cyclose
#define siodriver cydriver
#define siodtrwakeup cydtrwakeup
#define sioinput cyinput
#define siointr1 cyintr
#define sioioctl cyioctl
@ -191,7 +190,6 @@ __FBSDID("$FreeBSD$");
#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
#define CS_CHECKMSR 1 /* check of MSR scheduled */
#define CS_CTS_OFLOW 2 /* use CTS output flow control */
#define CS_DTR_OFF 0x10 /* DTR held off */
#define CS_ODONE 4 /* output completed */
#define CS_RTS_IFLOW 8 /* use RTS input flow control */
#define CSE_ODONE 1 /* output transmitted */
@ -256,7 +254,6 @@ struct com_s {
bool_t poll_output; /* nonzero if polling for output is required */
#endif
int unit; /* unit number */
int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
#if 0
u_int tx_fifo_size;
#endif
@ -332,7 +329,6 @@ static void cd1400_channel_cmd_wait(struct com_s *com);
static void cd_etc(struct com_s *com, int etc);
static int cd_getreg(struct com_s *com, int reg);
static void cd_setreg(struct com_s *com, int reg, int val);
static timeout_t siodtrwakeup;
static void comhardclose(struct com_s *com);
static void sioinput(struct com_s *com);
static int commctl(struct com_s *com, int bits, int how);
@ -515,7 +511,6 @@ cyattach_common(cy_iobase, cy_align)
com->mcr_rts = MCR_RTS;
com->mcr_rts_reg = CD1400_MSVR1;
}
com->dtr_wait = 3 * hz;
com->obufs[0].l_head = com->obuf1;
com->obufs[1].l_head = com->obuf2;
@ -614,11 +609,9 @@ sioopen(dev, flag, mode, td)
* up any changes of the device state.
*/
open_top:
while (com->state & CS_DTR_OFF) {
error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "cydtr", 0);
if (error != 0)
goto out;
}
error = ttydtrwaitsleep(tp);
if (error != 0)
goto out;
if (tp->t_state & TS_ISOPEN) {
/*
* The device is open, so everything has been initialized.
@ -864,10 +857,7 @@ comhardclose(com)
| CD1400_CCR_RCVDIS;
cd1400_channel_cmd(com, com->channel_control);
if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
timeout(siodtrwakeup, com, com->dtr_wait);
com->state |= CS_DTR_OFF;
}
ttydtrwaitstart(tp);
}
}
#if 0
@ -920,17 +910,6 @@ siowrite(dev, uio, flag)
#endif
}
static void
siodtrwakeup(chan)
void *chan;
{
struct com_s *com;
com = (struct com_s *)chan;
com->state &= ~CS_DTR_OFF;
wakeup(&com->dtr_wait);
}
/*
* This function:
* a) needs to be called with COM_LOCK() held, and
@ -1649,18 +1628,6 @@ sioioctl(dev, cmd, data, flag, td)
case TIOCMGET:
*(int *)data = commctl(com, 0, DMGET);
break;
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
error = suser(td);
if (error != 0) {
splx(s);
return (error);
}
com->dtr_wait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = com->dtr_wait * 100 / hz;
break;
case TIOCTIMESTAMP:
com->do_timestamp = TRUE;
*(struct timeval *)data = com->timestamp;

View File

@ -603,7 +603,6 @@ digi_init(struct digi_softc *sc)
fepcmd_w(port, SRXHWATER, (3 * port->rxbufsize) >> 2, 10);
bc->edelay = 100;
port->dtr_wait = 3 * hz;
/*
* We don't use all the flags from <sys/ttydefaults.h> since
@ -738,7 +737,7 @@ digiopen(struct cdev *dev, int flag, int mode, struct thread *td)
open_top:
while (port->status & DIGI_DTR_OFF) {
port->wopeners++;
error = tsleep(&port->dtr_wait, TTIPRI | PCATCH, "digidtr", 0);
error = tsleep(&tp->t_dtr_wait, TTIPRI | PCATCH, "digidtr", 0);
port->wopeners--;
if (error)
goto out;
@ -906,7 +905,7 @@ digidtrwakeup(void *chan)
struct digi_p *port = chan;
port->status &= ~DIGI_DTR_OFF;
wakeup(&port->dtr_wait);
wakeup(&port->tp->t_dtr_wait);
port->wopeners--;
}
@ -929,10 +928,10 @@ digihardclose(struct digi_p *port)
!(port->it_in.c_cflag & CLOCAL)) ||
!(port->tp->t_state & TS_ISOPEN)) {
digimodem(port->tp, 0, SER_DTR | SER_RTS);
if (port->dtr_wait != 0) {
if (port->tp->t_dtr_wait != 0) {
/* Schedule a wakeup of any callin devices */
port->wopeners++;
timeout(&digidtrwakeup, port, port->dtr_wait);
timeout(&digidtrwakeup, port, port->tp->t_dtr_wait);
port->status |= DIGI_DTR_OFF;
}
}
@ -1282,18 +1281,6 @@ digiioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *t
case DIGIIO_RING:
port->send_ring = *(u_char *)data;
break;
case TIOCMSDTRWAIT:
error = suser(td);
if (error != 0) {
splx(s);
return (error);
}
port->dtr_wait = *(int *)data *hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = port->dtr_wait * 100 / hz;
break;
#ifdef DIGI_INTERRUPT
case TIOCTIMESTAMP:
*(struct timeval *)data = sc->intr_timestamp;

View File

@ -86,7 +86,6 @@ struct digi_p {
u_char modem; /* Force values */
int active_out; /* nonzero if the callout device is open */
int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
u_int wopeners; /* # processes waiting for DCD in open() */
/*

View File

@ -93,7 +93,6 @@ struct rc_chans {
u_char rc_msvr; /* modem sig. status */
u_char rc_cor2; /* options reg */
u_char rc_pendcmd; /* special cmd pending */
u_int rc_dtrwait; /* dtr timeout */
u_int rc_dcdwaits; /* how many waits DCD in open */
struct tty rc_tp; /* tty struct */
u_char *rc_iptr; /* Chars input buffer */
@ -140,18 +139,15 @@ static void rc_reinit(struct rc_softc *);
#ifdef RCDEBUG
static void printrcflags();
#endif
static void rc_dtrwakeup(void *);
static void rc_wait0(struct rc_softc *sc, int chan, int line);
static d_open_t rcopen;
static d_close_t rcclose;
static d_ioctl_t rcioctl;
static struct cdevsw rc_cdevsw = {
.d_version = D_VERSION,
.d_open = rcopen,
.d_close = rcclose,
.d_ioctl = rcioctl,
.d_name = "rc",
.d_flags = D_TTY | D_NEEDGIANT,
};
@ -316,7 +312,6 @@ rc_attach(device_t dev)
rc->rc_bufend = &rc->rc_ibuf[RC_IBUFSIZE];
rc->rc_hiwat = &rc->rc_ibuf[RC_IHIGHWATER];
rc->rc_optr = rc->rc_obufend = rc->rc_obuf;
rc->rc_dtrwait = 3 * hz;
callout_init(&rc->rc_dtrcallout, 0);
tp = &rc->rc_tp;
ttychars(tp);
@ -358,7 +353,7 @@ rc_detach(device_t dev)
{
struct rc_softc *sc;
struct rc_chans *rc;
int error, i, s;
int error, i;
sc = device_get_softc(dev);
if (sc->sc_opencount > 0)
@ -367,18 +362,11 @@ rc_detach(device_t dev)
rc = sc->sc_channels;
for (i = 0; i < CD180_NCHAN; i++, rc++) {
ttygone(&rc->rc_tp);
destroy_dev(rc->rc_dev);
destroy_dev(rc->rc_cdev);
}
rc = sc->sc_channels;
s = splsoftclock();
for (i = 0; i < CD180_NCHAN; i++) {
if ((rc->rc_flags & RC_DTR_OFF) &&
!callout_stop(&rc->rc_dtrcallout))
tsleep(&rc->rc_dtrwait, TTIPRI, "rcdtrdet", 0);
}
error = bus_teardown_intr(dev, sc->sc_irq, sc->sc_hwicookie);
if (error)
device_printf(dev, "failed to deregister interrupt handler\n");
@ -874,11 +862,9 @@ rcopen(struct cdev *dev, int flag, int mode, d_thread_t *td)
s = spltty();
again:
while (rc->rc_flags & RC_DTR_OFF) {
error = tsleep(&(rc->rc_dtrwait), TTIPRI | PCATCH, "rcdtr", 0);
if (error != 0)
goto out;
}
error = ttydtrwaitsleep(tp);
if (error != 0)
goto out;
if (tp->t_state & TS_ISOPEN) {
if (CALLOUT(dev)) {
if (!(rc->rc_flags & RC_ACTOUT)) {
@ -995,11 +981,7 @@ rc_hardclose(struct rc_chans *rc)
CCRCMD(sc, rc->rc_chan, CCR_ResetChan);
WAITFORCCR(sc, rc->rc_chan);
(void) rc_modem(tp, SER_RTS, 0);
if (rc->rc_dtrwait) {
callout_reset(&rc->rc_dtrcallout, rc->rc_dtrwait,
rc_dtrwakeup, rc);
rc->rc_flags |= RC_DTR_OFF;
}
ttydtrwaitstart(tp);
}
rc->rc_flags &= ~RC_ACTOUT;
wakeup( &rc->rc_rcb); /* wake bi */
@ -1200,44 +1182,6 @@ rc_reinit(struct rc_softc *sc)
(void) rc_param(&rc->rc_tp, &rc->rc_tp.t_termios);
}
static int
rcioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, d_thread_t *td)
{
struct rc_chans *rc;
struct tty *tp;
int s, error;
rc = DEV_TO_RC(dev);
tp = &rc->rc_tp;
error = ttyioctl(dev, cmd, data, flag, td);
ttyldoptim(tp);
if (error != ENOTTY)
return (error);
s = spltty();
switch (cmd) {
case TIOCMSDTRWAIT:
error = suser(td);
if (error != 0) {
splx(s);
return (error);
}
rc->rc_dtrwait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = rc->rc_dtrwait * 100 / hz;
break;
default:
(void) splx(s);
return ENOTTY;
}
(void) splx(s);
return 0;
}
/* Modem control routines */
static int
@ -1477,16 +1421,6 @@ printrcflags(struct rc_chans *rc, char *comment)
}
#endif /* RCDEBUG */
static void
rc_dtrwakeup(void *arg)
{
struct rc_chans *rc;
rc = (struct rc_chans *)arg;
rc->rc_flags &= ~RC_DTR_OFF;
wakeup(&rc->rc_dtrwait);
}
static void
rc_discard_output(struct rc_chans *rc)
{

View File

@ -871,7 +871,6 @@ rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports)
rp->rp_tty->t_line = 0;
/* tty->t_termios = deftermios;
*/
rp->dtr_wait = 3 * hz;
rp->it_in.c_iflag = 0;
rp->it_in.c_oflag = 0;
rp->it_in.c_cflag = TTYDEF_CFLAG;
@ -983,7 +982,7 @@ rpopen(dev, flag, mode, td)
open_top:
while(rp->state & ~SET_DTR) {
error = tsleep(&rp->dtr_wait, TTIPRI | PCATCH, "rpdtr", 0);
error = tsleep(&tp->t_dtr_wait, TTIPRI | PCATCH, "rpdtr", 0);
if(error != 0)
goto out;
}
@ -1174,8 +1173,8 @@ rphardclose(struct rp_port *rp)
if(IS_CALLOUT(tp->t_dev)) {
sClrDTR(cp);
}
if(rp->dtr_wait != 0) {
timeout(rpdtrwakeup, rp, rp->dtr_wait);
if(tp->t_dtr_wait != 0) {
timeout(rpdtrwakeup, rp, tp->t_dtr_wait);
rp->state |= ~SET_DTR;
}
@ -1222,7 +1221,7 @@ rpdtrwakeup(void *chan)
rp = (struct rp_port *)chan;
rp->state &= SET_DTR;
wakeup(&rp->dtr_wait);
wakeup(&rp->rp_tty->t_dtr_wait);
}
static int
@ -1408,17 +1407,6 @@ rpioctl(dev, cmd, data, flag, td)
*(int *)data = result;
break;
case TIOCMSDTRWAIT:
error = suser(td);
if(error != 0) {
splx(oldspl);
return(error);
}
rp->dtr_wait = *(int *)data * hz/100;
break;
case TIOCMGDTRWAIT:
*(int *)data = rp->dtr_wait * 100/hz;
break;
default:
splx(oldspl);
return ENOTTY;

View File

@ -57,7 +57,6 @@ struct rp_port {
unsigned char state; /* state of dtr */
/* Time to hold DTR down on close */
int dtr_wait;
int wopeners; /* processes waiting for DCD */
int rp_port;

View File

@ -102,7 +102,6 @@ static void si_start(struct tty *);
static void si_stop(struct tty *, int);
static timeout_t si_lstart;
static void sihardclose(struct si_port *pp);
static void sidtrwakeup(void *chan);
#ifdef SI_DEBUG
static char *si_mctl2str(enum si_mctl cmd);
@ -543,7 +542,6 @@ siattach(device_t dev)
pp->sp_tty = ttymalloc(NULL);
pp->sp_pend = IDLE_CLOSE;
pp->sp_state = 0; /* internal flag */
pp->sp_dtr_wait = 3 * hz;
pp->sp_iin.c_iflag = TTYDEF_IFLAG;
pp->sp_iin.c_oflag = TTYDEF_OFLAG;
pp->sp_iin.c_cflag = TTYDEF_CFLAG;
@ -652,11 +650,9 @@ siopen(struct cdev *dev, int flag, int mode, struct thread *td)
error = 0;
open_top:
while (pp->sp_state & SS_DTR_OFF) {
error = tsleep(&pp->sp_dtr_wait, TTIPRI|PCATCH, "sidtr", 0);
if (error != 0)
goto out;
}
error = ttydtrwaitsleep(tp);
if (error != 0)
goto out;
if (tp->t_state & TS_ISOPEN) {
/*
@ -837,11 +833,7 @@ sihardclose(struct si_port *pp)
(void) si_modem(pp, BIC, TIOCM_DTR|TIOCM_RTS);
(void) si_command(pp, FCLOSE, SI_NOWAIT);
if (pp->sp_dtr_wait != 0) {
timeout(sidtrwakeup, pp, pp->sp_dtr_wait);
pp->sp_state |= SS_DTR_OFF;
}
ttydtrwaitstart(tp);
}
pp->sp_active_out = FALSE;
wakeup(&pp->sp_active_out);
@ -850,25 +842,6 @@ sihardclose(struct si_port *pp)
splx(oldspl);
}
/*
* called at splsoftclock()...
*/
static void
sidtrwakeup(void *chan)
{
struct si_port *pp;
int oldspl;
oldspl = spltty();
pp = (struct si_port *)chan;
pp->sp_state &= ~SS_DTR_OFF;
wakeup(&pp->sp_dtr_wait);
splx(oldspl);
}
static int
siwrite(struct cdev *dev, struct uio *uio, int flag)
{
@ -1056,15 +1029,6 @@ siioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
case TIOCMGET:
*(int *)data = si_modem(pp, GET, 0);
break;
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
error = suser(td);
if (error == 0)
pp->sp_dtr_wait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = pp->sp_dtr_wait * 100 / hz;
break;
default:
error = ENOTTY;
}

View File

@ -331,7 +331,6 @@ struct si_port {
int sp_last_hi_ip; /* cached DCD */
int sp_state;
int sp_active_out; /* callout is open */
int sp_dtr_wait; /* DTR holddown in hz */
int sp_delta_overflows;
u_int sp_wopeners; /* # procs waiting DCD */
/* Initial state. */
@ -362,7 +361,6 @@ struct si_port {
/* 0x0800 -- */
#define SS_WAITWRITE 0x1000
#define SS_BLOCKWRITE 0x2000
#define SS_DTR_OFF 0x4000 /* DTR held off */
/*
* Command post flags

View File

@ -150,7 +150,6 @@ __FBSDID("$FreeBSD$");
#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
#define CS_CHECKMSR 1 /* check of MSR scheduled */
#define CS_CTS_OFLOW 2 /* use CTS output flow control */
#define CS_DTR_OFF 0x10 /* DTR held off */
#define CS_ODONE 4 /* output completed */
#define CS_RTS_IFLOW 8 /* use RTS input flow control */
#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */
@ -201,7 +200,6 @@ struct com_s {
bool_t poll_output; /* nonzero if polling for output is required */
bool_t st16650a; /* nonzero if Startech 16650A compatible */
int unit; /* unit number */
int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
u_int flags; /* copy of device flags */
u_int tx_fifo_size;
u_int wopeners; /* # processes waiting for DCD in open() */
@ -285,7 +283,6 @@ static int espattach(struct com_s *com, Port_t esp_port);
static void combreak(struct tty *tp, int sig);
static timeout_t siobusycheck;
static u_int siodivisor(u_long rclk, speed_t speed);
static timeout_t siodtrwakeup;
static void comhardclose(struct com_s *com);
static void sioinput(struct com_s *com);
static void siointr1(struct com_s *com);
@ -457,6 +454,7 @@ siodetach(dev)
return (0);
}
com->gone = TRUE;
ttygone(com->tp);
for (i = 0 ; i < 6; i++)
destroy_dev(com->devs[i]);
if (com->irqres) {
@ -961,7 +959,6 @@ sioattach(dev, xrid, rclk)
com->bst = rman_get_bustag(port);
com->bsh = rman_get_bushandle(port);
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
com->tx_fifo_size = 1;
@ -1239,13 +1236,9 @@ sioopen(dev, flag, mode, td)
* up any changes of the device state.
*/
open_top:
while (com->state & CS_DTR_OFF) {
error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "siodtr", 0);
if (com_addr(unit) == NULL)
return (ENXIO);
if (error != 0 || com->gone)
goto out;
}
error = ttydtrwaitsleep(tp);
if (error != 0)
goto out;
if (tp->t_state & TS_ISOPEN) {
/*
* The device is open, so everything has been initialized.
@ -1479,10 +1472,7 @@ comhardclose(com)
&& !(com->it_in.c_cflag & CLOCAL))
|| !(tp->t_state & TS_ISOPEN)) {
(void)commodem(tp, 0, SER_DTR);
if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
timeout(siodtrwakeup, com, com->dtr_wait);
com->state |= CS_DTR_OFF;
}
ttydtrwaitstart(tp);
}
}
if (com->hasfifo) {
@ -1610,17 +1600,6 @@ siodivisor(rclk, speed)
return (divisor);
}
static void
siodtrwakeup(chan)
void *chan;
{
struct com_s *com;
com = (struct com_s *)chan;
com->state &= ~CS_DTR_OFF;
wakeup(&com->dtr_wait);
}
/*
* Call this function with the sio_lock mutex held. It will return with the
* lock still held.
@ -2113,18 +2092,6 @@ sioioctl(dev, cmd, data, flag, td)
return (error);
s = spltty();
switch (cmd) {
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
error = suser(td);
if (error != 0) {
splx(s);
return (error);
}
com->dtr_wait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = com->dtr_wait * 100 / hz;
break;
case TIOCTIMESTAMP:
com->do_timestamp = TRUE;
*(struct timeval *)data = com->timestamp;

View File

@ -281,7 +281,6 @@ sxattach(
sc->sc_ports[x].sp_chan = x;
sc->sc_ports[x].sp_tty = tp++;
sc->sc_ports[x].sp_state = 0; /* internal flag */
sc->sc_ports[x].sp_dtr_wait = 3 * hz;
sc->sc_ports[x].sp_iin.c_iflag = TTYDEF_IFLAG;
sc->sc_ports[x].sp_iin.c_oflag = TTYDEF_OFLAG;
sc->sc_ports[x].sp_iin.c_cflag = TTYDEF_CFLAG;
@ -391,7 +390,7 @@ sxopen(
* it to assert.
*/
while (pp->sp_state & SX_SS_DTR_OFF && SX_DTRPIN(pp)) {
error = tsleep(&pp->sp_dtr_wait, TTIPRI|PCATCH, "sxdtr", 0);
error = tsleep(&tp->t_dtr_wait, TTIPRI|PCATCH, "sxdtr", 0);
if (error != 0)
goto out;
}
@ -603,8 +602,8 @@ sxhardclose(
* If we should hold DTR off for a bit and we actually have a
* DTR pin to hold down, schedule sxdtrwakeup().
*/
if (pp->sp_dtr_wait != 0 && SX_DTRPIN(pp)) {
timeout(sxdtrwakeup, pp, pp->sp_dtr_wait);
if (tp->t_dtr_wait != 0 && SX_DTRPIN(pp)) {
timeout(sxdtrwakeup, pp, tp->t_dtr_wait);
pp->sp_state |= SX_SS_DTR_OFF;
}
@ -630,7 +629,7 @@ sxdtrwakeup(void *chan)
oldspl = spltty();
pp = (struct sx_port *)chan;
pp->sp_state &= ~SX_SS_DTR_OFF;
wakeup(&pp->sp_dtr_wait);
wakeup(&pp->sp_tty->t_dtr_wait);
splx(oldspl);
}
@ -884,15 +883,6 @@ sxioctl(
DPRINT((pp, DBG_IOCTL, "sxioctl(%s) got signals 0x%x\n",
devtoname(dev), *(int *)data));
break;
case TIOCMSDTRWAIT: /* Set "wait on close" delay. */
/* must be root since the wait applies to following logins */
error = suser(p);
if (error == 0)
pp->sp_dtr_wait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT: /* Get "wait on close" delay. */
*(int *)data = pp->sp_dtr_wait * 100 / hz;
break;
default:
error = ENOTTY;
}

View File

@ -39,7 +39,6 @@ struct sx_port {
struct tty *sp_tty;
int sp_state;
int sp_active_out; /* callout is open */
int sp_dtr_wait; /* DTR holddown in hz */
int sp_delta_overflows;
u_int sp_wopeners; /* Processes waiting for DCD. */
struct termios sp_iin; /* Initial state. */

View File

@ -963,6 +963,16 @@ ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
splx(s);
break;
#endif
case TIOCMGDTRWAIT:
*(int *)data = tp->t_dtr_wait * 100 / hz;
break;
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
error = suser(td);
if (error)
return (error);
tp->t_dtr_wait = *(int *)data * hz / 100;
break;
case TIOCNXCL: /* reset exclusive use of tty */
s = spltty();
CLR(tp->t_state, TS_XCLUDE);
@ -2773,6 +2783,7 @@ ttymalloc(struct tty *tp)
}
tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO);
tp->t_timeout = -1;
tp->t_dtr_wait = 3 * hz;
mtx_init(&tp->t_mtx, "tty", NULL, MTX_DEF);
tp->t_refcnt = 1;
mtx_lock(&tty_list_mutex);
@ -2894,6 +2905,7 @@ ttyioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td
error = ttyld_ioctl(tp, cmd, data, flag, td);
if (error == ENOIOCTL)
error = ttioctl(tp, cmd, data, flag);
ttyldoptim(tp);
if (error != ENOIOCTL)
return (error);
return (ENOTTY);
@ -2916,6 +2928,58 @@ ttyldoptim(struct tty *tp)
tp->t_state &= ~TS_CAN_BYPASS_L_RINT;
}
static void
ttydtrwaitwakeup(void *arg)
{
struct tty *tp;
tp = arg;
tp->t_state &= ~TS_DTR_WAIT;
wakeup(&tp->t_dtr_wait);
}
void
ttydtrwaitstart(struct tty *tp)
{
if (tp->t_dtr_wait == 0)
return;
if (tp->t_state & TS_DTR_WAIT)
return;
timeout(ttydtrwaitwakeup, tp, tp->t_dtr_wait);
tp->t_state |= TS_DTR_WAIT;
}
int
ttydtrwaitsleep(struct tty *tp)
{
int error;
error = 0;
while (error == 0) {
if (tp->t_state & TS_GONE)
error = ENXIO;
else if (!(tp->t_state & TS_DTR_WAIT))
break;
else
error = tsleep(&tp->t_dtr_wait, TTIPRI | PCATCH,
"dtrwait", 0);
}
return (error);
}
/*
* This function is called when the hardware disappears. We set a flag
* and wake up stuff so all sleeping threads will notice.
*/
void
ttygone(struct tty *tp)
{
tp->t_state |= TS_GONE;
wakeup(&tp->t_dtr_wait);
}
/*
* Record the relationship between the serial ports notion of modem control

View File

@ -212,7 +212,6 @@
#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
#define CS_CHECKMSR 1 /* check of MSR scheduled */
#define CS_CTS_OFLOW 2 /* use CTS output flow control */
#define CS_DTR_OFF 0x10 /* DTR held off */
#define CS_ODONE 4 /* output completed */
#define CS_RTS_IFLOW 8 /* use RTS input flow control */
#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */
@ -263,7 +262,6 @@ struct com_s {
bool_t poll_output; /* nonzero if polling for output is required */
bool_t st16650a; /* nonzero if Startech 16650A compatible */
int unit; /* unit number */
int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
u_int flags; /* copy of device flags */
u_int tx_fifo_size;
u_int wopeners; /* # processes waiting for DCD in open() */
@ -371,7 +369,6 @@ static int espattach(struct com_s *com, Port_t esp_port);
static void combreak(struct tty *tp, int sig);
static timeout_t siobusycheck;
static u_int siodivisor(u_long rclk, speed_t speed);
static timeout_t siodtrwakeup;
static void comhardclose(struct com_s *com);
static void sioinput(struct com_s *com);
static void siointr1(struct com_s *com);
@ -788,6 +785,7 @@ siodetach(dev)
return (0);
}
com->gone = TRUE;
ttygone(com->tp);
for (i = 0 ; i < 6; i++)
destroy_dev(com->devs[i]);
if (com->irqres) {
@ -1512,7 +1510,6 @@ sioattach(dev, xrid, rclk)
com->bst = rman_get_bustag(port);
com->bsh = rman_get_bushandle(port);
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
com->tx_fifo_size = 1;
@ -1909,13 +1906,9 @@ sioopen(dev, flag, mode, td)
* up any changes of the device state.
*/
open_top:
while (com->state & CS_DTR_OFF) {
error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "siodtr", 0);
if (com_addr(unit) == NULL)
return (ENXIO);
if (error != 0 || com->gone)
goto out;
}
error = ttydtrwaitsleep(tp);
if (error)
goto out;
if (tp->t_state & TS_ISOPEN) {
/*
* The device is open, so everything has been initialized.
@ -2229,10 +2222,7 @@ comhardclose(com)
else
#endif
(void)commodem(tp, 0, SER_DTR);
if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
timeout(siodtrwakeup, com, com->dtr_wait);
com->state |= CS_DTR_OFF;
}
ttydtrwaitstart(tp);
}
#ifdef PC98
else {
@ -2385,17 +2375,6 @@ siodivisor(rclk, speed)
return (divisor);
}
static void
siodtrwakeup(chan)
void *chan;
{
struct com_s *com;
com = (struct com_s *)chan;
com->state &= ~CS_DTR_OFF;
wakeup(&com->dtr_wait);
}
/*
* Call this function with the sio_lock mutex held. It will return with the
* lock still held.
@ -3088,18 +3067,6 @@ sioioctl(dev, cmd, data, flag, td)
return (error);
s = spltty();
switch (cmd) {
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
error = suser(td);
if (error != 0) {
splx(s);
return (error);
}
com->dtr_wait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = com->dtr_wait * 100 / hz;
break;
case TIOCTIMESTAMP:
com->do_timestamp = TRUE;
*(struct timeval *)data = com->timestamp;

View File

@ -212,7 +212,6 @@
#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */
#define CS_CHECKMSR 1 /* check of MSR scheduled */
#define CS_CTS_OFLOW 2 /* use CTS output flow control */
#define CS_DTR_OFF 0x10 /* DTR held off */
#define CS_ODONE 4 /* output completed */
#define CS_RTS_IFLOW 8 /* use RTS input flow control */
#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */
@ -263,7 +262,6 @@ struct com_s {
bool_t poll_output; /* nonzero if polling for output is required */
bool_t st16650a; /* nonzero if Startech 16650A compatible */
int unit; /* unit number */
int dtr_wait; /* time to hold DTR down on close (* 1/hz) */
u_int flags; /* copy of device flags */
u_int tx_fifo_size;
u_int wopeners; /* # processes waiting for DCD in open() */
@ -371,7 +369,6 @@ static int espattach(struct com_s *com, Port_t esp_port);
static void combreak(struct tty *tp, int sig);
static timeout_t siobusycheck;
static u_int siodivisor(u_long rclk, speed_t speed);
static timeout_t siodtrwakeup;
static void comhardclose(struct com_s *com);
static void sioinput(struct com_s *com);
static void siointr1(struct com_s *com);
@ -788,6 +785,7 @@ siodetach(dev)
return (0);
}
com->gone = TRUE;
ttygone(com->tp);
for (i = 0 ; i < 6; i++)
destroy_dev(com->devs[i]);
if (com->irqres) {
@ -1512,7 +1510,6 @@ sioattach(dev, xrid, rclk)
com->bst = rman_get_bustag(port);
com->bsh = rman_get_bushandle(port);
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0;
com->tx_fifo_size = 1;
@ -1909,13 +1906,9 @@ sioopen(dev, flag, mode, td)
* up any changes of the device state.
*/
open_top:
while (com->state & CS_DTR_OFF) {
error = tsleep(&com->dtr_wait, TTIPRI | PCATCH, "siodtr", 0);
if (com_addr(unit) == NULL)
return (ENXIO);
if (error != 0 || com->gone)
goto out;
}
error = ttydtrwaitsleep(tp);
if (error)
goto out;
if (tp->t_state & TS_ISOPEN) {
/*
* The device is open, so everything has been initialized.
@ -2229,10 +2222,7 @@ comhardclose(com)
else
#endif
(void)commodem(tp, 0, SER_DTR);
if (com->dtr_wait != 0 && !(com->state & CS_DTR_OFF)) {
timeout(siodtrwakeup, com, com->dtr_wait);
com->state |= CS_DTR_OFF;
}
ttydtrwaitstart(tp);
}
#ifdef PC98
else {
@ -2385,17 +2375,6 @@ siodivisor(rclk, speed)
return (divisor);
}
static void
siodtrwakeup(chan)
void *chan;
{
struct com_s *com;
com = (struct com_s *)chan;
com->state &= ~CS_DTR_OFF;
wakeup(&com->dtr_wait);
}
/*
* Call this function with the sio_lock mutex held. It will return with the
* lock still held.
@ -3088,18 +3067,6 @@ sioioctl(dev, cmd, data, flag, td)
return (error);
s = spltty();
switch (cmd) {
case TIOCMSDTRWAIT:
/* must be root since the wait applies to following logins */
error = suser(td);
if (error != 0) {
splx(s);
return (error);
}
com->dtr_wait = *(int *)data * hz / 100;
break;
case TIOCMGDTRWAIT:
*(int *)data = com->dtr_wait * 100 / hz;
break;
case TIOCTIMESTAMP:
com->do_timestamp = TRUE;
*(struct timeval *)data = com->timestamp;

View File

@ -117,6 +117,7 @@ struct tty {
struct mtx t_mtx;
int t_refcnt;
int t_hotchar; /* linedisc preferred hot char */
int t_dtr_wait; /* Inter-session DTR holddown [hz] */
/* Driver supplied methods */
t_oproc_t *t_oproc; /* Start output. */
@ -224,6 +225,9 @@ struct xtty {
#define TS_DSR_OFLOW 0x800000 /* For CDSR_OFLOW. */
#endif
#define TS_DTR_WAIT 0x1000000 /* DTR hold-down between sessions */
#define TS_GONE 0x2000000 /* Hardware detached */
/* Character type information. */
#define ORDINARY 0
#define CONTROL 1
@ -308,7 +312,10 @@ void ttyblock(struct tty *tp);
void ttychars(struct tty *tp);
int ttycheckoutq(struct tty *tp, int wait);
int ttyclose(struct tty *tp);
int ttydtrwaitsleep(struct tty *tp);
void ttydtrwaitstart(struct tty *tp);
void ttyflush(struct tty *tp, int rw);
void ttygone(struct tty *tp);
void ttyinfo(struct tty *tp);
int ttyinput(int c, struct tty *tp);
int ttylclose(struct tty *tp, int flag);