|
|
1.1 root 1: #include "vx.h"
2: #if NVX > 0
3: /*
4: * VIOC-X Modem control
5: */
6:
7: #include "../h/param.h"
8: #include "../h/file.h"
9: #include "../h/ioctl.h"
10: #include "../h/tty.h"
11: #include "../h/conf.h"
1.1.1.2 ! root 12: #include "../h/dir.h"
! 13: #include "../h/user.h"
1.1 root 14: #include "../vba/vioc.h"
15: #include "../vba/vxdebug.h"
16:
17: #include "vbsc.h"
18: #if NVBSC > 0
19: #include "../bsc/bscio.h"
20: #include "../bsc/bsc.h"
21: extern char bscport[];
22: #endif
23:
1.1.1.2 ! root 24: extern struct vcx vcx[];
1.1 root 25: extern struct tty vx_tty[];
1.1.1.2 ! root 26: extern struct vcmds v_cmds[];
1.1 root 27:
1.1.1.2 ! root 28: extern int vxstart();
! 29: extern struct vxcmd *vobtain();
1.1 root 30:
1.1.1.2 ! root 31: unsigned char vcmanual[NVXPORTS];
1.1 root 32:
1.1.1.2 ! root 33: vcumodem(dev, cmd, arg, mode)
! 34: int dev, cmd;
! 35: register caddr_t arg;
! 36: int mode;
1.1 root 37: {
1.1.1.2 ! root 38: register int line = minor(dev)&0xff;
! 39: register struct tty *tp = &vx_tty[line];
! 40: register int port = line&0xf;
1.1 root 41: register struct vcx *xp ;
42: register struct vblok *kp ;
43:
1.1.1.2 ! root 44: xp = &vcx[line>>4];
! 45: kp = VBAS(xp->v_nbr);
! 46:
! 47: switch (cmd) {
! 48: case VCMANUAL:
! 49: if (*(int *)arg == VC_OFF) {
! 50: ttywait(tp);
! 51: vcmanual[line] &= ~VC_RTS; /* make sure RTS gets turned off */
! 52: vcmodem(line, -1);
! 53: vcmanual[line] &= ~VC_MANUAL;
! 54: if (vcmanual[line]&VC_DCD)
! 55: tp->t_state |= TS_CARR_ON;
! 56: else /* XXX.jds should hangup and flush */
! 57: tp->t_state &= ~TS_CARR_ON;
! 58: } else {
! 59: vcmanual[line] = VC_MANUAL;
! 60: if (tp->t_state&TS_CARR_ON)
! 61: vcmanual[line] |= VC_DCD;
! 62: if (tp->t_state&TS_ISOPEN)
! 63: vcmanual[line] |= VC_DTR;
! 64: }
! 65: vcmodem(dev, VMOD_ON);
! 66: break;
! 67:
! 68: case VCGRS232:
! 69: port -= xp->v_loport;
! 70: if (kp->v_dcd&1<<port)
! 71: vcmanual[line] |= VC_DCD;
! 72: else
! 73: vcmanual[line] &= ~VC_DCD;
! 74: if (kp->v_cts&1<<port)
! 75: vcmanual[line] |= VC_CTS;
! 76: else
! 77: vcmanual[line] &= ~VC_CTS;
! 78: u.u_r.r_val1 = vcmanual[line]&VC_MASK;
! 79: break;
! 80:
! 81: case VCSRS232:
! 82: if ((vcmanual[line]&VC_MANUAL) == 0)
! 83: /*
! 84: * Ok to look at the signals, but
! 85: * you can't set them unless you go
! 86: * into manual mode.
! 87: */
! 88: return(EINVAL);
! 89: vcmanual[line] &= ~(VC_DTR|VC_RTS);
! 90: vcmanual[line] |= *(int *)arg&(VC_DTR|VC_RTS);
! 91: vcmodem(dev, -1);
! 92: break;
! 93:
! 94: default:
! 95: return(EINVAL);
! 96: }
! 97: return(0);
! 98: }
! 99:
! 100: vcmodem(dev, flag)
! 101: register int dev;
! 102: int flag;
! 103: {
! 104: struct tty *tp;
! 105: register struct vxcmd *cp;
! 106: register struct vcx *xp;
! 107: register struct vblok *kp;
! 108: register int port, line, mode, carrier = 0;
! 109:
! 110: line = minor(dev)&0xff;
! 111: tp = &vx_tty[line];
! 112: xp = (struct vcx *)tp->t_addr;
! 113: port = line&0xf;
! 114: cp = vobtain(xp);
! 115: kp = VBAS(xp->v_nbr);
1.1 root 116:
117: /*
118: * Issue MODEM command
119: */
1.1.1.2 ! root 120: cp->cmd = MDMCTL;
! 121: if (vcmanual[line]&VC_MANUAL) {
! 122: /*
! 123: * We're in manual mode.
! 124: */
! 125: mode = V_MANUAL;
! 126: if (vcmanual[line]&VC_RTS)
! 127: mode |= V_RTS;
! 128: if (vcmanual[line]&VC_DTR)
! 129: mode |= V_DTR;
! 130: carrier++;
! 131: } else {
! 132: /*
! 133: * We're in "auto" mode.
! 134: */
! 135: mode = V_AUTO;
! 136: if (flag == VMOD_ON)
! 137: mode |= V_DTR;
1.1 root 138: }
1.1.1.2 ! root 139: cp->par[0] = mode;
! 140: cp->par[1] = port;
! 141: vcmd(xp->v_nbr, &cp->cmd);
! 142:
! 143: port -= xp->v_loport;
! 144: #ifdef VX_DEBUG
! 145: if (flag == VMOD_ON)
! 146: printf("\nvcmodem:ON, port%d, dcd(%lx)",
! 147: port, kp->v_dcd&0xffff);
! 148: else
! 149: printf("\nvcmodem:OFF, port%d, dcd(%lx)",
! 150: port, kp->v_dcd&0xffff);
! 151: #endif
! 152: if (kp->v_dcd>>port&1) {
! 153: tp->t_state |= TS_CARR_ON;
! 154: vcmanual[line] |= VC_DCD;
! 155: carrier++;
! 156: } else
! 157: vcmanual[line] &= ~VC_DCD;
! 158:
! 159: if (kp->v_cts>>port&1)
! 160: vcmanual[line] |= VC_CTS;
! 161: else
! 162: vcmanual[line] &= ~VC_CTS;
1.1 root 163:
1.1.1.2 ! root 164: return(carrier != 0);
! 165: }
1.1 root 166:
167: /*
168: * VCMINTR called when an unsolicited interrup occurs signaling
169: * some change of modem control state.
170: */
171: vcmintr(n)
1.1.1.2 ! root 172: register int n; /* viocx number */
1.1 root 173: {
1.1.1.2 ! root 174: register struct vblok *kp;
! 175: register struct tty *tp;
! 176: register int port, line;
! 177:
! 178: kp = VBAS(n);
! 179: port = kp->v_usdata[0]&017;
! 180: line = port + (n<<4);
! 181: tp = &vx_tty[line];
1.1 root 182:
183: #if NVBSC > 0
1.1.1.2 ! root 184: /*
! 185: * Check for change in DSR for BISYNC port.
! 186: */
! 187: if ((kp->v_ustat&DSR_CHG) && (bscport[line]&BISYNC)) {
! 188: register struct bsc *bp;
! 189: extern struct bsc bsc[];
! 190:
! 191: bp = &bsc[(minor(tp->t_dev) >> 4)&0xf];
! 192: bp->b_hlflgs &= ~BSC_DSR;
! 193: if (kp->v_ustat&DSR_ON)
! 194: bp->b_hlflgs |= BSC_DSR;
1.1 root 195: }
1.1.1.2 ! root 196: if (bscport[line]&BISYNC)
! 197: return;
1.1 root 198: #endif
199:
1.1.1.2 ! root 200: if (vcmanual[port]&VC_MANUAL) {
! 201: register int ustat = kp->v_ustat;
! 202: /*
! 203: * Update our modem status.
! 204: */
! 205: if (ustat&DCD_ON)
! 206: vcmanual[line] |= VC_DCD;
! 207: else
! 208: vcmanual[line] &= ~VC_DCD;
! 209: if (ustat&CTS_ON)
! 210: vcmanual[line] |= VC_CTS;
! 211: else
! 212: vcmanual[line] &= ~VC_CTS;
! 213: goto out;
! 214: }
! 215:
! 216: if (kp->v_ustat&DCD_ON) {
1.1 root 217: #ifdef VX_DEBUG
1.1.1.2 ! root 218: printf("\nvcmintr: CARR_ON, VIOC%d, port%d, state(%lx)",
! 219: n, port, tp->t_state);
1.1 root 220: #endif
221:
1.1.1.2 ! root 222: if ((tp->t_state&TS_CARR_ON) == 0 &&
! 223: tp->t_state&(TS_WOPEN|TS_ISOPEN)) {
! 224: /*
! 225: * Carrier transition from low to high.
! 226: */
! 227: tp->t_state |= TS_CARR_ON;
! 228: if (tp->t_state&TS_WOPEN)
! 229: wakeup((caddr_t)&tp->t_canq);
! 230: }
! 231: return;
1.1 root 232: }
233:
1.1.1.2 ! root 234: if (kp->v_ustat&DCD_OFF) {
! 235: if (tp->t_state&TS_CARR_ON &&
! 236: tp->t_state&(TS_WOPEN|TS_ISOPEN)) {
! 237: /*
! 238: * Carrier transition from high to low.
! 239: */
1.1 root 240: ttyflush(tp, FREAD|FWRITE);
1.1.1.2 ! root 241: vxflush(tp);
! 242: if ((tp->t_flags&NOHANG)==0) {
! 243: gsignal(tp->t_pgrp, SIGHUP);
1.1 root 244: gsignal(tp->t_pgrp, SIGCONT);
245: }
1.1.1.2 ! root 246: tp->t_state &= ~TS_CARR_ON;
1.1 root 247: }
1.1.1.2 ! root 248: return;
! 249: }
! 250: out:
! 251: if (kp->v_ustat&BRK_CHR && tp->t_state&TS_ISOPEN) {
! 252: (*linesw[tp->t_line].l_rint)(tp->t_intrc&0377, tp);
! 253: return;
1.1 root 254: }
1.1.1.2 ! root 255: }
1.1 root 256:
1.1.1.2 ! root 257: /*
! 258: * Stop further output on the line.
! 259: * Must be called from spltty or higher.
! 260: */
! 261: vxflush(tp)
! 262: register struct tty *tp;
! 263: {
! 264: register int n = minor(tp->t_dev)>>4;
! 265: register int port = minor(tp->t_dev)&0xf;
! 266: register struct vcx *xp;
! 267: register struct vcmds *cp = &v_cmds[n];
! 268: register struct vxcmd *cmdp;
! 269: register int i;
! 270:
! 271: xp = &vcx[n];
! 272: if (((tp->t_state&TS_BUSY) == 0 && (tp->t_state&TS_FLUSH) == 0) ||
! 273: xp->v_vers == V_OLD)
! 274: /*
! 275: * Output already stopped.
! 276: */
! 277: return;
! 278:
! 279: /*
! 280: * Either output is in progress for this port
! 281: * or an output command is queued up for it.
! 282: * Check the queue and see if it has gotten to
! 283: * the vioc yet.
! 284: */
! 285: for (i = cp->v_empty; i!=cp->v_fill;) {
! 286: cmdp = (struct vxcmd *)((long *)cp->cmdbuf[i]-1);
! 287: if ((cmdp->cmd==XMITDTA || cmdp->cmd==XMITIMM) &&
! 288: ((struct vxmit *)cmdp->par)->line == port) {
! 289: /*
! 290: * Found the command on the input queue --
! 291: * turn it into something harmless.
! 292: */
! 293: cmdp->cmd = FDTATOX;
! 294: cmdp->par[1] = port;
! 295: tp->t_state &= ~TS_BUSY;
! 296: return;
! 297: }
! 298: if (++i >= VC_CMDBUFL)
! 299: i = 0;
1.1 root 300: }
1.1.1.2 ! root 301:
! 302: /*
! 303: * Command has already gotten to the VIOC --
! 304: * tell the VIOC to get rid of it.
! 305: */
! 306: cmdp = vobtain(xp);
! 307: cmdp->cmd = FDTATOX;
! 308: cmdp->par[1] = port;
! 309: vcmd(n, &cmdp->cmd);
1.1 root 310: }
311: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.