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