3aa12267a5
(except in netccitt, netiso and netns) that I didn't notice when I fixed "all" such warnings before.
359 lines
7.6 KiB
C
359 lines
7.6 KiB
C
static char _ittyid[] = "@(#)$Id: iitty.c,v 1.4 1995/02/28 00:20:30 pst Exp $";
|
|
/*******************************************************************************
|
|
* II - Version 0.1 $Revision: 1.4 $ $State: Exp $
|
|
*
|
|
* Copyright 1994 Dietmar Friede
|
|
*******************************************************************************
|
|
* Bug reports, patches, comments, suggestions should be sent to:
|
|
*
|
|
* jkr@saarlink.de or jkrause@guug.de
|
|
*
|
|
*******************************************************************************
|
|
* $Log: iitty.c,v $
|
|
* Revision 1.4 1995/02/28 00:20:30 pst
|
|
* Incorporate bde's code-review comments.
|
|
*
|
|
* (a) bring back ttselect, now that we have xxxdevtotty() it isn't dangerous.
|
|
* (b) remove all of the wrappers that have been replaced by ttselect
|
|
* (c) fix formatting in syscons.c and definition in syscons.h
|
|
* (d) add cxdevtotty
|
|
*
|
|
* NOT DONE:
|
|
* (e) make pcvt work... it was already broken...when someone fixes pcvt to
|
|
* link properly, just rename get_pccons to xxxdevtotty and we're done
|
|
*
|
|
* Revision 1.3 1995/02/25 20:08:52 pst
|
|
* (a) remove the pointer to each driver's tty structure array from cdevsw
|
|
* (b) add a function callback vector to tty drivers that will return a pointer
|
|
* to a valid tty structure based upon a dev_t
|
|
* (c) make syscons structures the same size whether or not APM is enabled so
|
|
* utilities don't crash if NAPM changes (and make the damn kernel compile!)
|
|
* (d) rewrite /dev/snp ioctl interface so that it is device driver and i386
|
|
* independant
|
|
*
|
|
* Revision 1.2 1995/02/15 06:28:28 jkh
|
|
* Fix up include paths, nuke some warnings.
|
|
*
|
|
* Revision 1.1 1995/02/14 15:00:32 jkh
|
|
* An ISDN driver that supports the EDSS1 and the 1TR6 ISDN interfaces.
|
|
* EDSS1 is the "Euro-ISDN", 1TR6 is the soon obsolete german ISDN Interface.
|
|
* Obtained from: Dietmar Friede <dfriede@drnhh.neuhaus.de> and
|
|
* Juergen Krause <jkr@saarlink.de>
|
|
*
|
|
* This is only one part - the rest to follow in a couple of hours.
|
|
* This part is a benign import, since it doesn't affect anything else.
|
|
*
|
|
*
|
|
******************************************************************************/
|
|
|
|
#include "ity.h"
|
|
#if NITY > 0
|
|
|
|
#include "param.h"
|
|
#include "systm.h"
|
|
#include "ioctl.h"
|
|
#include "select.h"
|
|
#include "tty.h"
|
|
#include "proc.h"
|
|
#include "user.h"
|
|
#include "conf.h"
|
|
#include "file.h"
|
|
#include "uio.h"
|
|
#include "kernel.h"
|
|
#include "syslog.h"
|
|
#include "types.h"
|
|
|
|
#include "gnu/isdn/isdn_ioctl.h"
|
|
|
|
int ityparam();
|
|
void itystart();
|
|
|
|
int nity = NITY;
|
|
int itydefaultrate = 64000;
|
|
short ity_addr[NITY];
|
|
struct tty ity_tty[NITY];
|
|
static int applnr[NITY];
|
|
static int next_if= 0;
|
|
|
|
#define UNIT(x) (minor(x)&0x3f)
|
|
#define OUTBOUND(x) ((minor(x)&0x80)==0x80)
|
|
|
|
int
|
|
ityattach(int ap)
|
|
{
|
|
if(next_if >= NITY)
|
|
return(-1);
|
|
|
|
applnr[next_if]= ap;
|
|
return(next_if++);
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
int
|
|
ityopen(dev_t dev, int flag, int mode, struct proc * p)
|
|
{
|
|
register struct tty *tp;
|
|
register int unit;
|
|
int error = 0;
|
|
|
|
unit = UNIT(dev);
|
|
if (unit >= next_if)
|
|
return (ENXIO);
|
|
|
|
tp = &ity_tty[unit];
|
|
tp->t_oproc = itystart;
|
|
tp->t_param = ityparam;
|
|
tp->t_dev = dev;
|
|
if ((tp->t_state & TS_ISOPEN) == 0)
|
|
{
|
|
tp->t_state |= TS_WOPEN;
|
|
ttychars(tp);
|
|
if (tp->t_ispeed == 0)
|
|
{
|
|
tp->t_iflag = TTYDEF_IFLAG;
|
|
tp->t_oflag = TTYDEF_OFLAG;
|
|
tp->t_cflag = TTYDEF_CFLAG;
|
|
tp->t_lflag = TTYDEF_LFLAG;
|
|
tp->t_ispeed = tp->t_ospeed = itydefaultrate;
|
|
}
|
|
ityparam(tp, &tp->t_termios);
|
|
ttsetwater(tp);
|
|
} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
|
|
return (EBUSY);
|
|
(void) spltty();
|
|
|
|
if(OUTBOUND(dev)) tp->t_cflag |= CLOCAL;
|
|
|
|
while ((flag & O_NONBLOCK) == 0 && (tp->t_cflag & CLOCAL) == 0 &&
|
|
(tp->t_state & TS_CARR_ON) == 0)
|
|
{
|
|
tp->t_state |= TS_WOPEN;
|
|
if (error = ttysleep(tp, (caddr_t) & tp->t_rawq, TTIPRI | PCATCH,
|
|
ttopen, 0))
|
|
break;
|
|
}
|
|
(void) spl0();
|
|
if (error == 0)
|
|
error = (*linesw[tp->t_line].l_open) (dev, tp);
|
|
return (error);
|
|
}
|
|
|
|
/* ARGSUSED */
|
|
int
|
|
ityclose(dev, flag, mode, p)
|
|
dev_t dev;
|
|
int flag, mode;
|
|
struct proc *p;
|
|
{
|
|
register struct tty *tp;
|
|
register ity;
|
|
register int unit;
|
|
|
|
unit = UNIT(dev);
|
|
ity = ity_addr[unit];
|
|
if(tp = &ity_tty[unit])
|
|
(*linesw[tp->t_line].l_close) (tp, flag);
|
|
ttyclose(tp);
|
|
isdn_disconnect(applnr[unit],0);
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
ityread(dev, uio, flag)
|
|
dev_t dev;
|
|
struct uio *uio;
|
|
int flag;
|
|
{
|
|
register struct tty *tp = &ity_tty[UNIT(dev)];
|
|
|
|
return ((*linesw[tp->t_line].l_read) (tp, uio, flag));
|
|
}
|
|
|
|
int
|
|
itywrite(dev, uio, flag)
|
|
dev_t dev;
|
|
struct uio *uio;
|
|
int flag;
|
|
{
|
|
int unit = UNIT(dev);
|
|
register struct tty *tp = &ity_tty[unit];
|
|
|
|
return ((*linesw[tp->t_line].l_write) (tp, uio, flag));
|
|
}
|
|
|
|
int
|
|
ity_input(int no, int len, char *buf)
|
|
{
|
|
register struct tty *tp = &ity_tty[no];
|
|
int i;
|
|
|
|
if (tp->t_state & TS_ISOPEN)
|
|
for(i= 0; i<len; i++)
|
|
(*linesw[tp->t_line].l_rint)(buf[i], tp);
|
|
else len= 0;
|
|
return(len);
|
|
}
|
|
|
|
void
|
|
itystart(struct tty *tp)
|
|
{
|
|
int s, unit;
|
|
|
|
unit = UNIT(tp->t_dev);
|
|
|
|
s = splhigh();
|
|
if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP))
|
|
{
|
|
splx(s);
|
|
return;
|
|
}
|
|
if (tp->t_outq.c_cc <= tp->t_lowat)
|
|
{
|
|
if (tp->t_state & TS_ASLEEP)
|
|
{
|
|
tp->t_state &= ~TS_ASLEEP;
|
|
wakeup((caddr_t) & tp->t_outq);
|
|
}
|
|
selwakeup(&tp->t_wsel);
|
|
}
|
|
if (tp->t_outq.c_cc)
|
|
{
|
|
if(OUTBOUND(tp->t_dev) && (tp->t_cflag & CLOCAL) &&
|
|
((tp->t_state & TS_CARR_ON) == 0))
|
|
isdn_msg(applnr[unit]);
|
|
else isdn_output(applnr[unit]);
|
|
tp->t_state |= TS_BUSY;
|
|
}
|
|
splx(s);
|
|
}
|
|
|
|
int
|
|
ity_out(int no, char *buf, int len)
|
|
{
|
|
struct tty *tp = &ity_tty[no];
|
|
int i;
|
|
|
|
if(tp == NULL)
|
|
return(0);
|
|
if(tp->t_outq.c_cc)
|
|
{
|
|
for (i = 0; i < len && tp->t_outq.c_cc; ++i)
|
|
buf[i]= getc(&tp->t_outq);
|
|
return(i);
|
|
}
|
|
tp->t_state &=~ (TS_BUSY|TS_FLUSH);
|
|
if (tp->t_line)
|
|
(*linesw[tp->t_line].l_start)(tp);
|
|
else
|
|
itystart(tp);
|
|
return(0);
|
|
}
|
|
|
|
void
|
|
ity_connect(int no)
|
|
{
|
|
struct tty *tp = &ity_tty[no];
|
|
|
|
if(tp == NULL)
|
|
return;
|
|
if(OUTBOUND(tp->t_dev)) tp->t_cflag &= ~CLOCAL;
|
|
(*linesw[tp->t_line].l_modem) (tp, 1);
|
|
tp->t_state |= TS_CARR_ON;
|
|
tp->t_state &=~ (TS_BUSY|TS_FLUSH);
|
|
if (tp->t_line)
|
|
(*linesw[tp->t_line].l_start)(tp);
|
|
else
|
|
itystart(tp);
|
|
}
|
|
|
|
void
|
|
ity_disconnect(int no)
|
|
{
|
|
struct tty *tp = &ity_tty[no];
|
|
if(tp) (*linesw[tp->t_line].l_modem) (tp, 0);
|
|
}
|
|
|
|
int
|
|
ityioctl(dev, cmd, data, flag,p)
|
|
dev_t dev;
|
|
int cmd;
|
|
caddr_t data;
|
|
int flag;
|
|
struct proc *p;
|
|
{
|
|
register struct tty *tp;
|
|
register int unit = UNIT(dev);
|
|
register int error;
|
|
|
|
tp = &ity_tty[unit];
|
|
error = (*linesw[tp->t_line].l_ioctl) (tp, cmd, data, flag,p);
|
|
if (error >= 0)
|
|
return (error);
|
|
error = ttioctl(tp, cmd, data, flag);
|
|
if (error >= 0)
|
|
return (error);
|
|
|
|
switch (cmd)
|
|
{
|
|
default:
|
|
return (ENOTTY);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
ityparam(tp, t)
|
|
register struct tty *tp;
|
|
register struct termios *t;
|
|
{
|
|
register ity;
|
|
register int cfcr, cflag = t->c_cflag;
|
|
int unit = UNIT(tp->t_dev);
|
|
int ospeed = t->c_ospeed;
|
|
|
|
/* check requested parameters */
|
|
if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
|
|
return (EINVAL);
|
|
/* and copy to tty */
|
|
tp->t_ispeed = t->c_ispeed;
|
|
tp->t_ospeed = t->c_ospeed;
|
|
tp->t_cflag = cflag;
|
|
|
|
if (ospeed == 0)
|
|
{
|
|
isdn_disconnect(applnr[unit],0);
|
|
return (0);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
/*
|
|
* Stop output on a line.
|
|
*/
|
|
/* ARGSUSED */
|
|
void
|
|
itystop(struct tty *tp, int flag)
|
|
{
|
|
register int s;
|
|
|
|
s = splhigh();
|
|
if (tp->t_state & TS_BUSY)
|
|
{
|
|
if ((tp->t_state & TS_TTSTOP) == 0)
|
|
tp->t_state |= TS_FLUSH;
|
|
}
|
|
splx(s);
|
|
}
|
|
|
|
struct tty *
|
|
itydevtotty(dev_t dev)
|
|
{
|
|
register int unit = UNIT(dev);
|
|
if (unit >= next_if)
|
|
return (NULL);
|
|
|
|
return (&ity_tty[unit]);
|
|
}
|
|
|
|
#endif
|