install approved copyright notice
[unix-history] / usr / src / sys / tahoe / vba / vxm.c
/* vxm.c 1.3 86/01/12 */
#include "vx.h"
#if NVX > 0
/*
* VIOC-X Modem control
*/
#include "param.h"
#include "file.h"
#include "ioctl.h"
#include "tty.h"
#include "conf.h"
#include "../tahoevba/vioc.h"
#include "vbsc.h"
#if NVBSC > 0
#include "../tahoebsc/bscio.h"
#include "../tahoebsc/bsc.h"
extern char bscport[];
#endif
extern struct vcx vcx[] ;
extern struct tty vx_tty[];
extern struct vcmds v_cmds[] ;
extern int vxstart() ;
extern struct vxcmd *vobtain() ;
extern struct vxcmd *nextcmd() ;
vcmodem(dev,flag)
dev_t dev ;
{
struct tty *tp ;
register struct vxcmd *cp ;
register struct vcx *xp ;
register struct vblok *kp ;
register port ;
port = minor(dev) ;
tp = &vx_tty[port] ;
port &= 017 ;
xp = (struct vcx *)tp->t_addr ;
cp = vobtain(xp) ;
kp = VBAS(xp->v_nbr) ;
/*
* Issue MODEM command
*/
cp->cmd = MDMCTL ;
cp->par[0] = (flag == VMOD_ON) ? V_ENAB : V_DISAB ;
cp->par[1] = port;
vcmd(xp->v_nbr, (caddr_t)&cp->cmd) ;
port -= xp->v_loport ;
if((kp->v_dcd >> port) & 1) {
if(flag == VMOD_ON)
tp->t_state |= TS_CARR_ON ;
return(1) ;
}
return(0) ;
}
/*
* VCMINTR called when an unsolicited interrup occurs signaling
* some change of modem control state.
*/
vcmintr(n)
register n ; /* viocx number */
{
register struct vblok *kp ;
register struct tty *tp ;
register port ;
kp = VBAS( n ) ;
port = kp->v_usdata[0] & 017 ;
tp = &vx_tty[port+n*16] ;
#if NVBSC > 0
/*
* Check for change in DSR for BISYNC port.
*/
if ((kp->v_ustat & DSR_CHG) && (bscport[port+n*16] & BISYNC)) {
register struct vcx *xp ;
register struct bsc *bp ;
extern struct bsc bsc[] ;
xp = (struct vcx *)tp->t_addr ;
bp = &bsc[minor(tp->t_dev)] ;
bp->b_hlflgs &= ~BSC_DSR ;
if (kp->v_ustat & DSR_ON)
bp->b_hlflgs |= BSC_DSR ;
/*debug*/printf("BSC DSR Chg: %x\n", kp->v_ustat & DSR_CHG);
}
if (bscport[port+n*16] & BISYNC) return;
#endif
if((kp->v_ustat & DCD_ON) && ((tp->t_state & TS_CARR_ON) == 0) ) {
tp->t_state |= TS_CARR_ON ;
wakeup((caddr_t)&tp->t_canq) ;
return ;
}
if((kp->v_ustat & DCD_OFF) && (tp->t_state & TS_CARR_ON)) {
tp->t_state &= ~TS_CARR_ON ;
if(tp->t_state & TS_ISOPEN) {
register struct vcx *xp ;
register struct vcmds *cp ;
register struct vxcmd *cmdp ;
ttyflush(tp, FREAD|FWRITE);
/* clear all pending trnansmits */
xp = &vcx[n];
if(tp->t_state&(TS_BUSY|TS_FLUSH) && xp->v_vers==V_NEW) {
int i, cmdfound = 0;
cp = &v_cmds[n];
for(i = cp->v_empty; i!=cp->v_fill; ) {
cmdp = (struct vxcmd *)((long *)cp->cmdbuf[i]-1);
if((cmdp->cmd==XMITDTA || cmdp->cmd==XMITIMM)
&& ((struct vxmit *)cmdp->par)->line == port) {
cmdfound++;
cmdp->cmd = FDTATOX ;
cmdp->par[1] = port ;
}
if(++i >= VC_CMDBUFL)
i = 0;
}
if(cmdfound)
tp->t_state &= ~(TS_BUSY|TS_FLUSH);
/* cmd is already in vioc, have to flush it */
else {
cmdp = vobtain(xp);
cmdp->cmd = FDTATOX ;
cmdp->par[1] = port ;
vcmd(n, (caddr_t)&cmdp->cmd);
}
}
if((tp->t_flags&NOHANG)==0) {
gsignal(tp->t_pgrp, SIGHUP) ;
gsignal(tp->t_pgrp, SIGCONT);
}
}
return ;
}
if((kp->v_ustat & BRK_CHR) && (tp->t_state & TS_ISOPEN) ) {
(*linesw[tp->t_line].l_rint)(tp->t_intrc & 0377, tp) ;
return ;
}
}
#endif