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