xref: /csrg-svn/sys/tahoe/vba/vxm.c (revision 24002)
1*24002Ssam /*	vxm.c	1.1	85/07/21	*/
2*24002Ssam 
3*24002Ssam #include "vx.h"
4*24002Ssam #if NVX > 0
5*24002Ssam /*
6*24002Ssam  *	VIOC-X Modem control
7*24002Ssam  */
8*24002Ssam 
9*24002Ssam #include "../h/param.h"
10*24002Ssam #include "../h/file.h"
11*24002Ssam #include "../h/ioctl.h"
12*24002Ssam #include "../h/tty.h"
13*24002Ssam #include "../h/conf.h"
14*24002Ssam #include "../vba/vioc.h"
15*24002Ssam #include "vbsc.h"
16*24002Ssam #if NVBSC > 0
17*24002Ssam #include "../bsc/bscio.h"
18*24002Ssam #include "../bsc/bsc.h"
19*24002Ssam extern char bscport[];
20*24002Ssam #endif
21*24002Ssam 
22*24002Ssam 
23*24002Ssam extern	struct	vcx	vcx[] ;
24*24002Ssam extern	struct	tty	vx_tty[];
25*24002Ssam extern	struct	vcmds	v_cmds[] ;
26*24002Ssam 
27*24002Ssam extern	int	vxstart() ;
28*24002Ssam extern	struct	vxcmd	*vobtain() ;
29*24002Ssam extern	struct	vxcmd	*nextcmd() ;
30*24002Ssam 
31*24002Ssam 
32*24002Ssam vcmodem(dev,flag)
33*24002Ssam dev_t dev ;
34*24002Ssam {
35*24002Ssam 	struct tty *tp ;
36*24002Ssam 	register struct vxcmd *cp ;
37*24002Ssam 	register struct vcx *xp ;
38*24002Ssam 	register struct vblok *kp ;
39*24002Ssam 	register port ;
40*24002Ssam 
41*24002Ssam 	port = minor(dev) ;
42*24002Ssam 	tp = &vx_tty[port] ;
43*24002Ssam 	port &= 017 ;
44*24002Ssam 	xp = (struct vcx *)tp->t_addr ;
45*24002Ssam 	cp = vobtain(xp) ;
46*24002Ssam 	kp = VBAS(xp->v_nbr) ;
47*24002Ssam 
48*24002Ssam 	/*
49*24002Ssam 	 * Issue MODEM command
50*24002Ssam 	 */
51*24002Ssam 	cp->cmd = MDMCTL ;
52*24002Ssam 	cp->par[0] = (flag == VMOD_ON) ? V_ENAB : V_DISAB ;
53*24002Ssam 	cp->par[1] = port;
54*24002Ssam 	vcmd(xp->v_nbr, &cp->cmd) ;
55*24002Ssam 	port -= xp->v_loport ;
56*24002Ssam 	if((kp->v_dcd >> port) & 1) {
57*24002Ssam 		if(flag == VMOD_ON)
58*24002Ssam 			tp->t_state |= TS_CARR_ON ;
59*24002Ssam 		return(1) ;
60*24002Ssam 	}
61*24002Ssam 	return(0) ;
62*24002Ssam }
63*24002Ssam 
64*24002Ssam 
65*24002Ssam /*
66*24002Ssam  * VCMINTR called when an unsolicited interrup occurs signaling
67*24002Ssam  * some change of modem control state.
68*24002Ssam  */
69*24002Ssam vcmintr(n)
70*24002Ssam register n ;	/* viocx number */
71*24002Ssam {
72*24002Ssam 	register struct vblok *kp ;
73*24002Ssam 	register struct tty *tp ;
74*24002Ssam 	register port ;
75*24002Ssam 
76*24002Ssam 	kp = VBAS( n ) ;
77*24002Ssam 	port = kp->v_usdata[0] & 017 ;
78*24002Ssam 	tp = &vx_tty[port+n*16] ;
79*24002Ssam 
80*24002Ssam #if NVBSC > 0
81*24002Ssam 			/*
82*24002Ssam 			 * Check for change in DSR for BISYNC port.
83*24002Ssam 			 */
84*24002Ssam 	if ((kp->v_ustat & DSR_CHG) && (bscport[port+n*16] & BISYNC)) {
85*24002Ssam 		register struct	vcx *xp ;
86*24002Ssam 		register struct bsc *bp ;
87*24002Ssam 		extern	 struct	bsc bsc[] ;
88*24002Ssam 
89*24002Ssam 		xp = (struct vcx *)tp->t_addr ;
90*24002Ssam 		bp = &bsc[minor(tp->t_dev)] ;
91*24002Ssam 		bp->b_hlflgs &= ~BSC_DSR ;
92*24002Ssam 		if (kp->v_ustat & DSR_ON)
93*24002Ssam 			bp->b_hlflgs |= BSC_DSR ;
94*24002Ssam /*debug*/printf("BSC DSR Chg: %x\n", kp->v_ustat & DSR_CHG);
95*24002Ssam 	}
96*24002Ssam 	if (bscport[port+n*16] & BISYNC) return;
97*24002Ssam #endif
98*24002Ssam 	if((kp->v_ustat & DCD_ON) && ((tp->t_state & TS_CARR_ON) == 0) ) {
99*24002Ssam 		tp->t_state |= TS_CARR_ON ;
100*24002Ssam 		wakeup((caddr_t)&tp->t_canq) ;
101*24002Ssam 		return ;
102*24002Ssam 	}
103*24002Ssam 
104*24002Ssam 	if((kp->v_ustat & DCD_OFF) && (tp->t_state & TS_CARR_ON)) {
105*24002Ssam 		tp->t_state &= ~TS_CARR_ON ;
106*24002Ssam 		if(tp->t_state & TS_ISOPEN) {
107*24002Ssam 			register struct vcx *xp ;
108*24002Ssam 			register struct vcmds *cp ;
109*24002Ssam 			register struct vxcmd *cmdp ;
110*24002Ssam 
111*24002Ssam 			ttyflush(tp, FREAD|FWRITE);
112*24002Ssam 			/* clear all pending trnansmits */
113*24002Ssam 			xp = &vcx[n];
114*24002Ssam 			if(tp->t_state&(TS_BUSY|TS_FLUSH) && xp->v_vers==V_NEW) {
115*24002Ssam 				int i, cmdfound = 0;
116*24002Ssam 				cp = &v_cmds[n];
117*24002Ssam 				for(i = cp->v_empty; i!=cp->v_fill; ) {
118*24002Ssam 					cmdp = (struct vxcmd *)((long *)cp->cmdbuf[i]-1);
119*24002Ssam 					if((cmdp->cmd==XMITDTA || cmdp->cmd==XMITIMM)
120*24002Ssam 					 && ((struct vxmit *)cmdp->par)->line == port) {
121*24002Ssam 						cmdfound++;
122*24002Ssam 						cmdp->cmd = FDTATOX ;
123*24002Ssam 						cmdp->par[1] = port ;
124*24002Ssam 					}
125*24002Ssam 					if(++i >= VC_CMDBUFL)
126*24002Ssam 						i = 0;
127*24002Ssam 				}
128*24002Ssam 				if(cmdfound)
129*24002Ssam 					tp->t_state &= ~(TS_BUSY|TS_FLUSH);
130*24002Ssam 				/* cmd is already in vioc, have to flush it */
131*24002Ssam 				else {
132*24002Ssam 					cmdp = vobtain(xp);
133*24002Ssam 					cmdp->cmd = FDTATOX ;
134*24002Ssam 					cmdp->par[1] = port ;
135*24002Ssam 					vcmd(n, &cmdp->cmd);
136*24002Ssam 				}
137*24002Ssam 			}
138*24002Ssam 			if((tp->t_flags&NOHANG)==0) {
139*24002Ssam 				gsignal(tp->t_pgrp, SIGHUP) ;
140*24002Ssam 				gsignal(tp->t_pgrp, SIGCONT);
141*24002Ssam 			}
142*24002Ssam 		}
143*24002Ssam 		return ;
144*24002Ssam 	}
145*24002Ssam 
146*24002Ssam 	if((kp->v_ustat & BRK_CHR)  && (tp->t_state & TS_ISOPEN) ) {
147*24002Ssam 		(*linesw[tp->t_line].l_rint)(tp->t_intrc & 0377, tp) ;
148*24002Ssam 		return ;
149*24002Ssam 	}
150*24002Ssam }
151*24002Ssam #endif
152