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