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