xref: /csrg-svn/sys/tahoe/vba/vxm.c (revision 25675)
1*25675Ssam /*	vxm.c	1.2	86/01/05	*/
224002Ssam 
324002Ssam #include "vx.h"
424002Ssam #if NVX > 0
524002Ssam /*
624002Ssam  *	VIOC-X Modem control
724002Ssam  */
824002Ssam 
924002Ssam #include "../h/param.h"
1024002Ssam #include "../h/file.h"
1124002Ssam #include "../h/ioctl.h"
1224002Ssam #include "../h/tty.h"
1324002Ssam #include "../h/conf.h"
14*25675Ssam #include "../tahoevba/vioc.h"
1524002Ssam #include "vbsc.h"
1624002Ssam #if NVBSC > 0
1724002Ssam #include "../bsc/bscio.h"
1824002Ssam #include "../bsc/bsc.h"
1924002Ssam extern char bscport[];
2024002Ssam #endif
2124002Ssam 
2224002Ssam 
2324002Ssam extern	struct	vcx	vcx[] ;
2424002Ssam extern	struct	tty	vx_tty[];
2524002Ssam extern	struct	vcmds	v_cmds[] ;
2624002Ssam 
2724002Ssam extern	int	vxstart() ;
2824002Ssam extern	struct	vxcmd	*vobtain() ;
2924002Ssam extern	struct	vxcmd	*nextcmd() ;
3024002Ssam 
3124002Ssam 
3224002Ssam vcmodem(dev,flag)
3324002Ssam dev_t dev ;
3424002Ssam {
3524002Ssam 	struct tty *tp ;
3624002Ssam 	register struct vxcmd *cp ;
3724002Ssam 	register struct vcx *xp ;
3824002Ssam 	register struct vblok *kp ;
3924002Ssam 	register port ;
4024002Ssam 
4124002Ssam 	port = minor(dev) ;
4224002Ssam 	tp = &vx_tty[port] ;
4324002Ssam 	port &= 017 ;
4424002Ssam 	xp = (struct vcx *)tp->t_addr ;
4524002Ssam 	cp = vobtain(xp) ;
4624002Ssam 	kp = VBAS(xp->v_nbr) ;
4724002Ssam 
4824002Ssam 	/*
4924002Ssam 	 * Issue MODEM command
5024002Ssam 	 */
5124002Ssam 	cp->cmd = MDMCTL ;
5224002Ssam 	cp->par[0] = (flag == VMOD_ON) ? V_ENAB : V_DISAB ;
5324002Ssam 	cp->par[1] = port;
54*25675Ssam 	vcmd(xp->v_nbr, (caddr_t)&cp->cmd) ;
5524002Ssam 	port -= xp->v_loport ;
5624002Ssam 	if((kp->v_dcd >> port) & 1) {
5724002Ssam 		if(flag == VMOD_ON)
5824002Ssam 			tp->t_state |= TS_CARR_ON ;
5924002Ssam 		return(1) ;
6024002Ssam 	}
6124002Ssam 	return(0) ;
6224002Ssam }
6324002Ssam 
6424002Ssam 
6524002Ssam /*
6624002Ssam  * VCMINTR called when an unsolicited interrup occurs signaling
6724002Ssam  * some change of modem control state.
6824002Ssam  */
6924002Ssam vcmintr(n)
7024002Ssam register n ;	/* viocx number */
7124002Ssam {
7224002Ssam 	register struct vblok *kp ;
7324002Ssam 	register struct tty *tp ;
7424002Ssam 	register port ;
7524002Ssam 
7624002Ssam 	kp = VBAS( n ) ;
7724002Ssam 	port = kp->v_usdata[0] & 017 ;
7824002Ssam 	tp = &vx_tty[port+n*16] ;
7924002Ssam 
8024002Ssam #if NVBSC > 0
8124002Ssam 			/*
8224002Ssam 			 * Check for change in DSR for BISYNC port.
8324002Ssam 			 */
8424002Ssam 	if ((kp->v_ustat & DSR_CHG) && (bscport[port+n*16] & BISYNC)) {
8524002Ssam 		register struct	vcx *xp ;
8624002Ssam 		register struct bsc *bp ;
8724002Ssam 		extern	 struct	bsc bsc[] ;
8824002Ssam 
8924002Ssam 		xp = (struct vcx *)tp->t_addr ;
9024002Ssam 		bp = &bsc[minor(tp->t_dev)] ;
9124002Ssam 		bp->b_hlflgs &= ~BSC_DSR ;
9224002Ssam 		if (kp->v_ustat & DSR_ON)
9324002Ssam 			bp->b_hlflgs |= BSC_DSR ;
9424002Ssam /*debug*/printf("BSC DSR Chg: %x\n", kp->v_ustat & DSR_CHG);
9524002Ssam 	}
9624002Ssam 	if (bscport[port+n*16] & BISYNC) return;
9724002Ssam #endif
9824002Ssam 	if((kp->v_ustat & DCD_ON) && ((tp->t_state & TS_CARR_ON) == 0) ) {
9924002Ssam 		tp->t_state |= TS_CARR_ON ;
10024002Ssam 		wakeup((caddr_t)&tp->t_canq) ;
10124002Ssam 		return ;
10224002Ssam 	}
10324002Ssam 
10424002Ssam 	if((kp->v_ustat & DCD_OFF) && (tp->t_state & TS_CARR_ON)) {
10524002Ssam 		tp->t_state &= ~TS_CARR_ON ;
10624002Ssam 		if(tp->t_state & TS_ISOPEN) {
10724002Ssam 			register struct vcx *xp ;
10824002Ssam 			register struct vcmds *cp ;
10924002Ssam 			register struct vxcmd *cmdp ;
11024002Ssam 
11124002Ssam 			ttyflush(tp, FREAD|FWRITE);
11224002Ssam 			/* clear all pending trnansmits */
11324002Ssam 			xp = &vcx[n];
11424002Ssam 			if(tp->t_state&(TS_BUSY|TS_FLUSH) && xp->v_vers==V_NEW) {
11524002Ssam 				int i, cmdfound = 0;
11624002Ssam 				cp = &v_cmds[n];
11724002Ssam 				for(i = cp->v_empty; i!=cp->v_fill; ) {
11824002Ssam 					cmdp = (struct vxcmd *)((long *)cp->cmdbuf[i]-1);
11924002Ssam 					if((cmdp->cmd==XMITDTA || cmdp->cmd==XMITIMM)
12024002Ssam 					 && ((struct vxmit *)cmdp->par)->line == port) {
12124002Ssam 						cmdfound++;
12224002Ssam 						cmdp->cmd = FDTATOX ;
12324002Ssam 						cmdp->par[1] = port ;
12424002Ssam 					}
12524002Ssam 					if(++i >= VC_CMDBUFL)
12624002Ssam 						i = 0;
12724002Ssam 				}
12824002Ssam 				if(cmdfound)
12924002Ssam 					tp->t_state &= ~(TS_BUSY|TS_FLUSH);
13024002Ssam 				/* cmd is already in vioc, have to flush it */
13124002Ssam 				else {
13224002Ssam 					cmdp = vobtain(xp);
13324002Ssam 					cmdp->cmd = FDTATOX ;
13424002Ssam 					cmdp->par[1] = port ;
135*25675Ssam 					vcmd(n, (caddr_t)&cmdp->cmd);
13624002Ssam 				}
13724002Ssam 			}
13824002Ssam 			if((tp->t_flags&NOHANG)==0) {
13924002Ssam 				gsignal(tp->t_pgrp, SIGHUP) ;
14024002Ssam 				gsignal(tp->t_pgrp, SIGCONT);
14124002Ssam 			}
14224002Ssam 		}
14324002Ssam 		return ;
14424002Ssam 	}
14524002Ssam 
14624002Ssam 	if((kp->v_ustat & BRK_CHR)  && (tp->t_state & TS_ISOPEN) ) {
14724002Ssam 		(*linesw[tp->t_line].l_rint)(tp->t_intrc & 0377, tp) ;
14824002Ssam 		return ;
14924002Ssam 	}
15024002Ssam }
15124002Ssam #endif
152