|
|
1.1 ! root 1: #include "../bsc/local.h" ! 2: #include "../bsc/bscio.h" ! 3: #include "../bsc/bsc.h" ! 4: ! 5: #ifdef BSC_DEBUG ! 6: #include "../bsc/bscdebug.h" ! 7: long bscdebug = 0; ! 8: long bscPC = 0; ! 9: #endif ! 10: ! 11: /* D.L.Buck and Associates, Inc. - %H% ! 12: * ! 13: * COPYRIGHT NOTICE: ! 14: * Copyright c %H% - An unpublished work by ! 15: * D.L.Buck and Associates, Inc. ! 16: * ! 17: * PROPRIETARY RIGHTS NOTICE: ! 18: * All rights reserved. This document and program contains ! 19: * proprietary information of D.L.Buck and Associates,Inc. ! 20: * of San Jose, California, U.S.A., embodying confidential ! 21: * information, ideas, and expressions, no part of which ! 22: * may be reproduced, or transmitted in any form or by any ! 23: * means, electronic, mechanical, or otherwise, without ! 24: * the written permission of D.L.Buck and Associates, Inc. ! 25: */ ! 26: ! 27: /* ! 28: * NAME ! 29: * bscll - CCI VIOCX' Communications Controller Interface ! 30: * and low-level hardware-dependent logic. ! 31: * DESCRIPTION ! 32: * This file contains the CCI VIOCX' Communications Controller ! 33: * Interface routines prepared for the Computer Consoles, Inc. ! 34: * Power 5/20 ("Oneida") computer system. ! 35: * Included in this module are local initialization and termination ! 36: * routines (bsclopn, bsclcls: local open and close), ! 37: * local DSR checking logic (bsckdsr), ! 38: * local transmit start (bscxmit) and receiver reset (brxres) routines, ! 39: * and the interrupt handlers. ! 40: * Interrupts are actually fielded by other CCI-written routines, and ! 41: * routed to software here. ! 42: * These routines are meant to be hardware-dependent. ! 43: */ ! 44: ! 45: #ifndef lint ! 46: char bscll_id[] = "%W% %Q% CCI"; ! 47: #endif ! 48: ! 49: #define t_dstat t_col /* Since 4.2 tty struct doesnot have dstat */ ! 50: /* we use t_col instead. */ ! 51: ! 52: /* External variables: */ ! 53: extern struct bsc bsc[]; /* BSC Device structures: see bsc.c */ ! 54: extern struct state states[]; /* BSC PSM State table: see bscpsm.c */ ! 55: extern struct tty vx_tty[]; ! 56: extern struct vcx vcx[]; ! 57: char * strlchr(); ! 58: struct vxcmd * vobtain(); /* Routine to obtain command buffer */ ! 59: int bscxbsy; /* Tx busy flags */ ! 60: ! 61: /* ! 62: * Bisync Low-Level Routines. ! 63: * ! 64: * bsclopn - Local open routine ! 65: * bsclcls - Local close routine ! 66: * bscparam - Set up BSC device ! 67: * bscxmit - Prepare xmit list and start BSC device ! 68: * bsctxd - Transmission complete - awaken PSM ! 69: * bscrxc - Receive single character ! 70: */ ! 71: ! 72: /* ! 73: * NAME ! 74: * bsclopn -- local line open routine ! 75: * SYNOPSIS ! 76: * bsclopn (dev,bp) ! 77: * dev_t dev; ! 78: * struct bsc *bp; ! 79: * DESCRIPTION ! 80: * Local open routine for CCI's VIOCX'. ! 81: * 1. Find VIOCX and associated `vcx' structure. ! 82: * 2. Initialize I/O port. ! 83: * RETURNS ! 84: * 0 for successful open, ! 85: * error number for failure (e.g., busy) ! 86: */ ! 87: /*VARARGS*/ ! 88: bsclopn(dev, bp) ! 89: dev_t dev; ! 90: register struct bsc *bp; ! 91: { ! 92: register struct vcx *xp; /* Ptr to viocx control struct */ ! 93: struct tty *tp; /* Ptr to associated tty */ ! 94: extern short vx_use; ! 95: register int s; ! 96: int port; ! 97: ! 98: dev = minor(dev); ! 99: /* 1. Find VIOCX and associated `vcx' structure. */ ! 100: if ((xp = (struct vcx *) bp->b_devregs) == (struct vcx *)0) ! 101: return ENXIO; ! 102: #ifdef BSC_DEBUG ! 103: bp->b_hlflgs |= BSC_DSR; /* Force DSR on */ ! 104: #endif ! 105: ! 106: /* 2. Initialize I/O Port. */ ! 107: port = dev; ! 108: /* dev += (xp->v_nbr*16); */ ! 109: dev = (xp->v_nbr*16) + (dev%NBSC); ! 110: tp = &vx_tty[dev]; /* tp -> tty control struct */ ! 111: tp->t_dev &= 0xf; /* Clear bscport no; upper nible*/ ! 112: tp->t_dev |= (port << 4); /* Set bscport no */ ! 113: tp->t_state = TS_ISOPEN; /* Mark as open */ ! 114: tp->t_line = LDISP; /* MARK LINE SWITCH # */ ! 115: tp->t_dstat = (char)port; /* save bscport no. */ ! 116: bscparam(port); /* Go program the device */ ! 117: /*brxres(port);*/ /* Done in bscparam().dn 2/2/85 */ ! 118: return 0; ! 119: } ! 120: ! 121: /* ! 122: * NAME ! 123: * bsclcls -- local bsc close ! 124: * SYNOPSIS ! 125: * bsclcls (dev,bp) ! 126: * dev_t dev; ! 127: * struct bsc *bp; ! 128: * DESCRIPTION ! 129: * Local close routine for CCI's VIOCX. ! 130: */ ! 131: /*ARGSUSED*/ ! 132: bsclcls (dev,bp) ! 133: dev_t dev; ! 134: register struct bsc *bp; ! 135: { ! 136: register struct vcx *xp; ! 137: register struct vxcmd *cp; ! 138: register struct tty *tp; ! 139: int s; ! 140: ! 141: xp = (struct vcx *) bp->b_devregs; ! 142: /* s = spl8(); */ ! 143: cp = vobtain (xp); /* Obtain command buffer */ ! 144: cp->cmd = MDMCTL; /* Modem control operation */ ! 145: cp->par[0] = 0; /* Turn DTR off */ ! 146: cp->par[1] = (dev%NBSC) + xp->v_loport; /* Specify the device */ ! 147: /* cp->par[1] = dev + xp->v_loport; */ /* Specify the device */ ! 148: vcmd (xp->v_nbr, &cp->cmd); /* Send the command */ ! 149: sleep ((caddr_t)cp, BSCPRI); /* Wait for completion */ ! 150: /*vrelease (xp, cp);*/ /* Done in compl. intr. handler */ ! 151: bscxbsy &= ~(1<<dev); /* Ensure transmit not busy */ ! 152: /* splx(s); */ ! 153: ! 154: /* tp = &vx_tty[dev+xp->v_nbr*16];*//* Close tty */ ! 155: tp = &vx_tty[(dev%NBSC)+xp->v_nbr*16];/* Close tty */ ! 156: tp->t_state = 0; /* Initial state */ ! 157: tp->t_line = 0; /* Reset line switch */ ! 158: } ! 159: ! 160: /* ! 161: * bscparam -- set up user-controlled BSC device parameters ! 162: * if ASCII, set up length=7, odd parity, ASCII SYN ! 163: * if EBCDIC, length=8, no parity, EBCDIC SYN ! 164: */ ! 165: bscparam(dev) /* set up user-controlled BSC device params */ ! 166: dev_t dev; ! 167: { ! 168: extern char ebccls[], asccls[];/* character class ptr, tbls */ ! 169: register struct bsc *bp = &bsc[dev]; ! 170: register struct vxcmd *cp; ! 171: register struct vcx *xp; ! 172: register struct tty *tp; ! 173: int s; ! 174: ! 175: xp = (struct vcx *) bp->b_devregs; ! 176: s = spl8(); ! 177: cp = vobtain(xp); /* Obtain command buffer */ ! 178: cp->cmd = LPARAX; /* Load Port Parameters */ ! 179: cp->par[0] = (bp->b_hlflgs & BSCFDX) ? 1 : 0; ! 180: cp->par[1] = (dev%NBSC) + xp->v_loport; /* Port # */ ! 181: cp->par[2] = 0; /* Not used */ ! 182: cp->par[3] = 10; /* XMITDTA TimeOut (seconds) */ ! 183: if (bp->b_hlflgs & BSCASCII) /* ASCII code in use */ ! 184: { ! 185: cp->par[4] = 0x40; /* 7 bits */ ! 186: cp->par[5] = ASCSYN; /* ASCII SYN char */ ! 187: cp->par[6] = 0; /* Not used */ ! 188: cp->par[7] = 1; /* Odd Parity */ ! 189: bp->b_rxcls = asccls; /* Use ascii char class tbl */ ! 190: } else { /* EBCDIC code in use */ ! 191: cp->par[4] = 0xc0; /* 8 bits */ ! 192: cp->par[5] = EBCSYN; /* EBCDIC SYN char */ ! 193: cp->par[6] = 0; /* Not used */ ! 194: cp->par[7] = 0; /* No Parity */ ! 195: bp->b_rxcls = ebccls; /* Use ebcdic char class tbl */ ! 196: } ! 197: vcmd(xp->v_nbr, &cp->cmd); /* Do LPARAX command */ ! 198: sleep ((caddr_t)cp, BSCPRI); /* Wait on Completion */ ! 199: ! 200: cp = vobtain(xp); /* Obtain command buffer */ ! 201: cp->cmd = MDMCTL; /* Set Modem Control */ ! 202: cp->par[1] = (dev%NBSC) + xp->v_loport; /* Port # */ ! 203: cp->par[0] = MDM_DTR; /* Turn on DTR */ ! 204: vcmd(xp->v_nbr, &cp->cmd); /* Do MDMCTL command */ ! 205: sleep ((caddr_t)cp, BSCPRI); /* Wait on Completion */ ! 206: ! 207: /*vrelease (xp, cp);*/ /* Done in compl. intr. handler */ ! 208: splx(s); ! 209: brxres(dev); /* Reset receiver */ ! 210: } ! 211: ! 212: /* ! 213: * NAME/SYNOPSIS ! 214: * bsckdsr(dev,bp) ! 215: * dev_t dev; struct bsc *bp; ! 216: * DESCRIPTION ! 217: * Check DSR status, post result to b_hlflgs ! 218: * ALGORITHM ! 219: * Currently ineffective; CCI fixing firmware problem. ! 220: */ ! 221: /*ARGSUSED*/ ! 222: bsckdsr(dev,bp) /* Check for current DSR status */ ! 223: register dev_t dev; ! 224: register struct bsc *bp; ! 225: { } /* Completely ineffective */ ! 226: ! 227: #define SIZEMASK 0x03ff /* Lower portion of word is transmit length */ ! 228: #define X_HUNT 0x0200 /* Hunting for synch */ ! 229: #define X_CNT 0x0003 /* Mask for g/p counter */ ! 230: ! 231: /* NAME ! 232: * bscxmit - Start transmission on given device ! 233: * SYNOPSIS ! 234: * bscxmit (dev, newstate) ! 235: * dev_t dev; ! 236: * int newstate; ! 237: * ALGORITHM ! 238: * 1. Save 'newstate' as psm state to follow completion of ! 239: * transmission. Initialize b_cntl control flags. ! 240: * 2. Prepare for transmission. Build VIOCX XMITDTA command ! 241: * block, giving pointers and counts for each transmit data ! 242: * element. CRC must be calculated before transmission as ! 243: * VIOCX' controller emulates simple DMA operation. ! 244: * 3. Start transmission by giving XMITDTA command to VIOCX'. ! 245: * VALUE RETURNED ! 246: * None. ! 247: * ERRORS ! 248: * None. ! 249: */ ! 250: bscxmit (dev, newstate) ! 251: dev_t dev; ! 252: int newstate; ! 253: { ! 254: register struct bsc *bp = &bsc[dev]; ! 255: int s, i, j; ! 256: struct vxcmd *vobtain(); ! 257: register struct vcx *xp; ! 258: register struct vxcmd *cp; ! 259: register char *mp; ! 260: char * addr, *phaddr, *p; ! 261: caddr_t vtoph(); ! 262: ! 263: /* Make sure we don't try to double transmit */ ! 264: xp = (struct vcx *)bp->b_devregs; ! 265: s = spl8(); ! 266: if (bscxbsy & (1<<dev)) { /* Tx already busy */ ! 267: splx(s); ! 268: return; ! 269: } ! 270: bscxbsy |= 1<<dev; /* Mark tx busy */ ! 271: /* 1. Save 'newstate' as psm state to follow completion of ! 272: * transmission. Initialize b_cntl control flags. ! 273: */ ! 274: bp->b_nstate = newstate; /* Next state for PSM when tx done */ ! 275: ! 276: /* 2. Prepare for transmission. Build VIOCX XMITDTA command ! 277: * block, giving pointers and counts for each transmit data ! 278: * element. CRC must be calculated before transmission as ! 279: * VIOCX' controller emulates simple DMA operation. ! 280: */ ! 281: cp = vobtain(xp); /* Obtain XMITDTA Cmd. Buffer */ ! 282: /* splx(s); */ /* Should be done after vcmd().dn 2/2/85 */ ! 283: cp->cmd = XMITDTA-1; /* Initially, zero items in tx list */ ! 284: mp = cp->par; /* First xmit subcommand area */ ! 285: bp->b_crc[0] = bp->b_crc[1] = 0;/* Reset lrc (we compute) */ ! 286: ! 287: for (bp->b_txlptr = &bp->b_txlst[1];/* For each xmit list element,*/ ! 288: bp->b_txlptr->xptr; /* until end of list, */ ! 289: ++bp->b_txlptr) { /* stepping one list element, */ ! 290: /* Compute the CRC */ ! 291: i = bp->b_txlptr->xnum & SIZEMASK; /* Length */ ! 292: if (!i) ! 293: continue; /* zero-length element */ ! 294: addr = bp->b_txlptr->xptr; /* Address */ ! 295: addr[i] = '\0'; ! 296: if (bp->b_txlptr->xnum & X_CRC) /* Needs crc accumulation */ ! 297: { ! 298: register char *next; ! 299: if(!(bp->b_hlflgs & BSC_XTRN)){ ! 300: /* Append CRC after each IUS */ ! 301: while (next = strlchr(addr,0x1f, ! 302: (int)(&bp->b_txlptr->xptr[i]-addr))) { ! 303: ++next; ! 304: crccalc((int)(next-addr),addr,bp); ! 305: if (!(bp->b_hlflgs & BSCASCII)) ! 306: *next++ = bp->b_crc[0]; ! 307: *next++ = bp->b_crc[1]; ! 308: bp->b_crc[0] = bp->b_crc[1] = 0; ! 309: addr = next; ! 310: } ! 311: } else { ! 312: /* Transparent: skip DLE in DLE-xxx sequence */ ! 313: while(next = strlchr(addr,0x10, ! 314: (int)(&bp->b_txlptr->xptr[i]-addr))) { ! 315: ++next; ! 316: crccalc((int)(next-addr),addr,bp); ! 317: addr = ++next; ! 318: } ! 319: } ! 320: /* Compute CRC for last segment */ ! 321: crccalc((int)(&bp->b_txlptr->xptr[i] - addr), addr, bp); ! 322: } ! 323: addr = bp->b_txlptr->xptr; ! 324: if (i > 254) { /* Max of 254 bytes per VIOC list element */ ! 325: /* Divide into two transmit segments for DMA */ ! 326: mp[1] = 254-1; /* Set count */ ! 327: mp[0] = (dev%NBSC)+xp->v_loport;/* Set device */ ! 328: phaddr = vtoph(0, addr); ! 329: p = (char *)&phaddr; ! 330: for (j=0; j < sizeof phaddr; j++) ! 331: mp[j+2] = *p++; ! 332: i -= 254; ! 333: addr += 254; ! 334: mp += 6; ! 335: ++cp->cmd; /* Count # elements*/ ! 336: } ! 337: mp[1] = i-1; /* Set count */ ! 338: mp[0] = (dev%NBSC)+xp->v_loport; /* Set device */ ! 339: #if BSC_DEBUG ! 340: if (bscdebug & BSCLLX) { ! 341: register long ic; ! 342: register char *d_addr = addr; ! 343: ! 344: printf("bscxmit: "); ! 345: for (ic=0;ic<i;ic++) { ! 346: printf("(%lx)",d_addr[ic] & 0xff); ! 347: if (!(ic % 15)) printf("\n"); ! 348: } ! 349: } ! 350: #endif ! 351: phaddr = vtoph(0, addr); ! 352: p = (char *)&phaddr; ! 353: for (j=0; j < sizeof phaddr; j++) ! 354: mp[j+2] = *p++; ! 355: mp += 6; /* Advance cmd list element ptr */ ! 356: ++cp->cmd; /* Keep count on # elements */ ! 357: } ! 358: ! 359: /* 3. Start transmission by giving XMITDTA command to VIOCX'. */ ! 360: vcmd (xp->v_nbr, &cp->cmd); /* Give XMITDTA cmd. to VIOCX' */ ! 361: splx(s); ! 362: } ! 363: ! 364: /* ! 365: * NAME/SYNOPSIS ! 366: * bsctxd(dev) ! 367: * int dev ! 368: * DESCRIPTION ! 369: * Called from CCI's interrupt fielder for VIOCX command completion. ! 370: * (vxxint, in vcx.c) ! 371: * If the command was for a device having tp->t_line == LDISP ! 372: * (marked as BSC device in vxreset), ! 373: * this routine is called with the port number. ! 374: * ALGORITHM ! 375: * Turn off Tx Busy flag, set PSM state to previously given newstate ! 376: * (see bscxmit), and call PSM. ! 377: */ ! 378: bsctxd(dev) /* Transmission Done */ ! 379: int dev; ! 380: { ! 381: register struct bsc *bp = &bsc[dev]; ! 382: ! 383: bscxbsy &= ~(1<<dev); /* Tx done - turn off busy flag */ ! 384: if (states[bp->b_state].s_type != 's') ! 385: return; ! 386: bp->b_state = bp->b_nstate; /* New state */ ! 387: bscpsm((dev_t)dev); /* Restart PSM */ ! 388: } ! 389: ! 390: /* ! 391: * Receive Processing Data and Tables ! 392: */ ! 393: char adlelst[] = { '0', '1', ';', '<', 0x04 }; ! 394: char edlelst[] = { 0x70, 0x61, 0x6b, 0x7c, 0x37 }; ! 395: char dlexxx[] = {C_AK0, C_AK1, C_WAK, C_RVI, C_EOT }; ! 396: ! 397: /* Level 0 data classes: */ ! 398: #define C0_DATA 0 /* Data character */ ! 399: #define C0_SOH 1 /* Start of Heading */ ! 400: #define C0_STX 2 /* Start of Text */ ! 401: #define C0_ETX 3 /* End of Text and Last Block */ ! 402: #define C0_ETB 4 /* End of Text, not Last Block */ ! 403: #define C0_IUS 5 /* Unit Separator (2780 only) */ ! 404: #define C0_SYN 6 /* Synchronous Idle char. */ ! 405: #define C0_NAK 7 /* Negative Acknowledgement */ ! 406: #define C0_DLE 8 /* Data Link Escape */ ! 407: #define C0_ENQ 9 /* Enquiry */ ! 408: #define C0_EOT 10 /* End of Transmission (Session) */ ! 409: ! 410: /* state 0 = initialization ! 411: * state 1 = collect heading following SOH ! 412: * state 2 = collect data following STX ! 413: * state 3 = interpret character after DLE ! 414: * state 4 = collect transparent data ! 415: * state 5 = interpret character after DLE in transparent mode ! 416: * ! 417: * ! 418: * Date structure of table entries is: ! 419: * high order nibble = next state ! 420: * low order nibble = action to take ! 421: * ! 422: */ ! 423: ! 424: /* state:0 1 2 3 4 5 */ ! 425: char clstbl[] = { ! 426: 0x02, 0x12, 0x24, 0x0b, 0x44, 0x44, /* 0: data */ ! 427: 0x11, 0x12, 0x24, 0x02, 0x44, 0x44, /* 1: soh */ ! 428: 0x21, 0x20, 0x24, 0x47, 0x44, 0x44, /* 2: stx */ ! 429: 0x02, 0x06, 0x06, 0x02, 0x44, 0x06, /* 3: etx */ ! 430: 0x02, 0x06, 0x06, 0x02, 0x44, 0x06, /* 4: etb */ ! 431: 0x02, 0x12, 0x25, 0x02, 0x44, 0x25, /* 5: ius */ ! 432: 0x0c, 0x1c, 0x2c, 0x0c, 0x44, 0x4c, /* 6: syn */ ! 433: 0x08, 0x12, 0x24, 0x02, 0x44, 0x44, /* 7: nak */ ! 434: 0x30, 0x30, 0x30, 0x02, 0x5c, 0x44, /* 8: dle */ ! 435: 0x09, 0x03, 0x03, 0x02, 0x44, 0x03, /* 9: enq */ ! 436: 0x0a, 0x12, 0x24, 0x0a, 0x44, 0x44}; /*10: eot */ ! 437: ! 438: /* SOH, STX, ETX, ETB, IUS, SYN, NAK, DLE, ENQ, EOT */ ! 439: char ebccls[] = { 0x01,0x02,0x03,0x26,0x1f,0x32,0x3d,0x10,0x2d,0x37 }; ! 440: char asccls[] = { 0x01,0x02,0x03,0x17,0x1f,0x16,0x15,0x10,0x05,0x04 }; ! 441: ! 442: static int tval = 5; ! 443: static dev_t sdev; ! 444: ! 445: bel_psm(bp) ! 446: register struct bsc *bp; ! 447: { ! 448: if ((!bp->b_rclptr) || (states[bp->b_state].s_type != 'r')) ! 449: printf("\nthrowing away messages"); ! 450: else { ! 451: bp->b_state = bp->b_rclptr[bp->b_class1]; ! 452: bp->b_alenb = 0; ! 453: bp->b_rclptr = (char *)0; ! 454: bscpsm(bp-&bsc[0]); ! 455: } ! 456: } ! 457: ! 458: bscrxc(c,tp) /* Receive Single Character */ ! 459: struct tty *tp; ! 460: short c; ! 461: { ! 462: register struct bsc *bp; ! 463: register char *p; ! 464: register dev_t dev; ! 465: int class, stact; ! 466: short cc; /* Character in 'c' */ ! 467: char tc; /* Same char for trace call */ ! 468: ! 469: /*** dev = tp - vx_tty; ! 470: dev -= (((struct vcx *)(bsc[0].b_devregs))->v_nbr * 16); ! 471: ***/ ! 472: dev = (dev_t)tp->t_dstat; /* set in bsclopb() */ ! 473: bp = &bsc[dev]; ! 474: cc = c; /* Obtain character */ ! 475: cc &= 0xff; /* Keep lower 8 bits of char */ ! 476: tc = (char)cc; ! 477: if (bp->b_rxcnt) { /* Do minimal processing - crc/lrc */ ! 478: crccalc (1, &tc, bp); /* do crc inclusion */ ! 479: if (--bp->b_rxcnt) /* not end of crc sequence */ ! 480: goto brxrti; ! 481: if (bp->b_class1 == C_IUS) /* IUS - continue */ ! 482: goto brxrti; ! 483: if (bp->b_crc[0] || bp->b_crc[1]) /* if crc error */ ! 484: bp->b_hlflgs |= BSC_CRCERR; ! 485: brx_term: /* Termination of level-0 message */ ! 486: if ((bp->b_hlflgs & BSC_POLLWT) && ! 487: (bp->b_class1 == C_EOT)) { ! 488: bp->b_hlflgs &= ~BSC_POLLWT; ! 489: goto brxrti; ! 490: } ! 491: if (bp->b_class1 == C_EOT) { ! 492: bp->b_crc[0] = bp->b_crc[1] = 0; ! 493: bp->b_rxhptr = bp->b_iocout.b_hostid; ! 494: bp->b_rxhcnt = 0; ! 495: bp->b_rxst0 = 0; ! 496: } ! 497: else brxres(dev); ! 498: if ((!bp->b_rclptr) || (states[bp->b_state].s_type != 'r')) { ! 499: /* sdev = dev; */ ! 500: printf("\nbscrxc: timeout,(r%lx)(s%lx)(t%lx)", ! 501: bp->b_rclptr,bp->b_state,states[bp->b_state].s_type&0xff); ! 502: timeout(bel_psm,bp,tval); ! 503: goto brxrti; ! 504: } ! 505: bp->b_state = bp->b_rclptr[bp->b_class1]; ! 506: bp->b_alenb = 0; ! 507: bp->b_rclptr = (char *) 0; ! 508: if (bp->b_trace) ! 509: bsctr (dev, bp->b_class1, 'c'); ! 510: bscpsm(dev); ! 511: goto brxrti; ! 512: } ! 513: ! 514: /* Check for HUNT mode */ ! 515: if (bp->b_cntl & X_HUNT) { ! 516: if (cc != 0) /* We get a null when hunt done */ ! 517: goto brxrti; ! 518: /* c = spl8(); */ ! 519: ! 520: /* Release command buffer */ ! 521: /*vrelease (bp->b_devregs, bp->b_cmdbuf);*/ ! 522: /* splx(c); */ ! 523: bp->b_cntl &= ~X_HUNT; ! 524: goto brxrti; ! 525: } ! 526: ! 527: if (bp->b_rclptr == (char *)0) /* Is PSM waiting on us? */ ! 528: goto brxrti; /* no - ignore this character */ ! 529: ! 530: /* Classify current data character, get new state, do action */ ! 531: p = strlchr(bp->b_rxcls, cc, sizeof asccls); ! 532: if (p == (char *) 0) ! 533: class = 0; ! 534: else class = (p - bp->b_rxcls) + 1; ! 535: ! 536: ! 537: stact = (clstbl[class*6 + bp->b_rxst0]) & 0xff; ! 538: ! 539: #ifdef BSC_DEBUG ! 540: if (bscdebug & LRCVCHAR) ! 541: printf("\nbscrcx: (%lx)",cc & 0xff); ! 542: if (bscdebug & LSTATE) ! 543: printf("\nbscrcx: (lstate=%d)(event=%d)(nstate=%d)(act=%d)", ! 544: bp->b_rxst0, class, stact >> 4, stact & 15); ! 545: #endif ! 546: ! 547: bp->b_rxst0 = stact >> 4; /* new state 0 */ ! 548: switch (stact & 15) { /* take action */ ! 549: case 0: ! 550: break; ! 551: ! 552: case 1: /* Prepare to receive data */ ! 553: bp->b_hlflgs &= ~BSC_XTRN; /* reset transp indicator */ ! 554: act1a: bp->b_hlflgs &= ~BSC_CRCERR; /* reset CRC error flag */ ! 555: bp->b_rxdptr = bp->b_buffer; /* receive data ptr */ ! 556: bp->b_bsize = 0; /* data count <- 0 */ ! 557: if (class == C0_SOH) { /* if header, reset hptr */ ! 558: bp->b_rxhptr = bp->b_iocout.b_hostid; ! 559: bp->b_rxhcnt = 0; ! 560: } ! 561: bp->b_crc[0] = bp->b_crc[1] = 0; /* clear crc/lrc */ ! 562: bp->b_cntl |= X_ACMCRC; /* set accum flag */ ! 563: break; ! 564: ! 565: case 2: /* Save current character as heading info */ ! 566: /* Must be 'printable' character in code set in use */ ! 567: if (bp->b_rxhcnt < sizeof bp->b_iocout.b_hostid && ! 568: (((bp->b_hlflgs & BSCASCII) && cc >= 0x20 && cc < 0x7e) || ! 569: (!(bp->b_hlflgs& BSCASCII) && cc >= 0x40 && cc < 0xf9))) { ! 570: *bp->b_rxhptr++ = (char)cc; ! 571: ++bp->b_rxhcnt; ! 572: } else ! 573: brxres(dev); ! 574: if (bp->b_cntl & X_ACMCRC) ! 575: crccalc (1, &tc, bp); ! 576: break; ! 577: ! 578: case 3: /* Terminate, class = TTD */ ! 579: bp->b_class1 = C_TTD; ! 580: goto brx_term; ! 581: ! 582: case 5: /* crc/lrc for IUS follows - skip processing it */ ! 583: bp->b_class1 = C_IUS; ! 584: bp->b_rxcnt = (bp->b_hlflgs & BSCASCII) ? 1 : 2; ! 585: /* Fall through to case 4, saving IUS as data */ ! 586: ! 587: case 4: /* Save current character as data */ ! 588: crccalc (1, &tc, bp); ! 589: if (++bp->b_bsize <= BSCMBLK) ! 590: *bp->b_rxdptr++ = (char)cc; ! 591: if (bp->b_trace > 1) { /* data trace? */ ! 592: tc = (char)cc; ! 593: bsctr(dev,bp->b_class1,'y',(short)1,&tc); ! 594: } ! 595: break; ! 596: ! 597: case 6: /* crc/lrc for ETB/ETX follows - skip processing it */ ! 598: crccalc (1, &tc, bp); ! 599: bp->b_class1 = class - C0_ETX + C_ETX; ! 600: if (bp->b_hlflgs & BSCASCII) ! 601: bp->b_rxcnt = 1; /* Lrc for Ascii */ ! 602: else ! 603: bp->b_rxcnt = 2; /* 2 for crc */ ! 604: break; ! 605: ! 606: case 7: /* Set crc accum and transparency flag */ ! 607: bp->b_hlflgs |= BSC_XTRN; ! 608: goto act1a; ! 609: ! 610: case 8: /* Terminate; NAK */ ! 611: bp->b_class1 = C_NAK; ! 612: goto brx_term; ! 613: ! 614: case 9: /* Terminate; ENQ */ ! 615: bp->b_class1 = C_ENQ; ! 616: goto brx_term; ! 617: ! 618: case 10:/* Terminate; EOT */ ! 619: bp->b_class1 = C_EOT; ! 620: goto brx_term; ! 621: ! 622: case 11:/* Check for DLE-xxx sequence; terminate with L1 code */ ! 623: /* if applicable, else ignore */ ! 624: if (bp->b_hlflgs & BSCASCII) { ! 625: p = strlchr(adlelst,cc,sizeof adlelst); ! 626: if (p == (char *)0) ! 627: break; ! 628: bp->b_class1 = dlexxx[p - adlelst]; ! 629: } else { ! 630: p = strlchr(edlelst,cc,sizeof edlelst); ! 631: if (p == (char *)0) ! 632: break; ! 633: bp->b_class1 = dlexxx[p - edlelst]; ! 634: } ! 635: goto brx_term; ! 636: ! 637: case 12:/* Don't accum crc/lrc on this. */ ! 638: bp->b_alarm = 2*PSMTPS; /* Set 2 sec. timeout */ ! 639: break; ! 640: } ! 641: brxrti:; ! 642: } ! 643: ! 644: brxres(dev) /* Reset Receiver (Hunt Mode) */ ! 645: dev_t dev; ! 646: { ! 647: register struct bsc *bp = &bsc[dev]; ! 648: register struct vxcmd *cp; ! 649: register struct vcx *xp; ! 650: struct vxcmd * vobtain(); ! 651: int x = spl8(); ! 652: ! 653: xp = (struct vcx *) bp->b_devregs; ! 654: cp = vobtain(xp); /* Get command buffer for Hunt Command */ ! 655: /* splx(x); */ /* Should be after vcmd(); dn 2/27/85 */ ! 656: cp->cmd = HUNTMD; /* Synch. Hunt Mode Command */ ! 657: cp->par[0] = 0; /* Not used */ ! 658: cp->par[1] = (dev%NBSC)+xp->v_loport; /* Port Number */ ! 659: vcmd(xp->v_nbr, &cp->cmd); /* Execute Command */ ! 660: splx(x); ! 661: bp->b_cntl |= X_HUNT; ! 662: bp->b_crc[0] = bp->b_crc[1] = 0; /* Reset lrc */ ! 663: bp->b_rxhptr = bp->b_iocout.b_hostid; /* reset ptr for header */ ! 664: bp->b_rxhcnt = 0; /* Reset current header count */ ! 665: bp->b_rxst0 = 0; /* Reset lvl 0 state */ ! 666: } ! 667: ! 668: char * strlchr(s,c,l) /* locate character in string */ ! 669: register char *s, c; ! 670: register int l; ! 671: { while (--l >= 0) { ! 672: if (*s == c) ! 673: return (s); ! 674: ++s; ! 675: } ! 676: return (char *) 0; ! 677: } ! 678: ! 679: /* CRC table - crc-16 */ ! 680: short crctab[] = { ! 681: 0x0000, /* 00 */ ! 682: 0xc0c1, /* 01 */ ! 683: 0xc181, /* 02 */ ! 684: 0x0140, /* 03 */ ! 685: 0xc301, /* 04 */ ! 686: 0x03c0, /* 05 */ ! 687: 0x0280, /* 06 */ ! 688: 0xc241, /* 07 */ ! 689: 0xc601, /* 08 */ ! 690: 0x06c0, /* 09 */ ! 691: 0x0780, /* 0a */ ! 692: 0xc741, /* 0b */ ! 693: 0x0500, /* 0c */ ! 694: 0xc5c1, /* 0d */ ! 695: 0xc481, /* 0e */ ! 696: 0x0440, /* 0f */ ! 697: 0xcc01, /* 10 */ ! 698: 0x0cc0, /* 11 */ ! 699: 0x0d80, /* 12 */ ! 700: 0xcd41, /* 13 */ ! 701: 0x0f00, /* 14 */ ! 702: 0xcfc1, /* 15 */ ! 703: 0xce81, /* 16 */ ! 704: 0x0e40, /* 17 */ ! 705: 0x0a00, /* 18 */ ! 706: 0xcac1, /* 19 */ ! 707: 0xcb81, /* 1a */ ! 708: 0x0b40, /* 1b */ ! 709: 0xc901, /* 1c */ ! 710: 0x09c0, /* 1d */ ! 711: 0x0880, /* 1e */ ! 712: 0xc841, /* 1f */ ! 713: 0xd801, /* 20 */ ! 714: 0x18c0, /* 21 */ ! 715: 0x1980, /* 22 */ ! 716: 0xd941, /* 23 */ ! 717: 0x1b00, /* 24 */ ! 718: 0xdbc1, /* 25 */ ! 719: 0xda81, /* 26 */ ! 720: 0x1a40, /* 27 */ ! 721: 0x1e00, /* 28 */ ! 722: 0xdec1, /* 29 */ ! 723: 0xdf81, /* 2a */ ! 724: 0x1f40, /* 2b */ ! 725: 0xdd01, /* 2c */ ! 726: 0x1dc0, /* 2d */ ! 727: 0x1c80, /* 2e */ ! 728: 0xdc41, /* 2f */ ! 729: 0x1400, /* 30 */ ! 730: 0xd4c1, /* 31 */ ! 731: 0xd581, /* 32 */ ! 732: 0x1540, /* 33 */ ! 733: 0xd701, /* 34 */ ! 734: 0x17c0, /* 35 */ ! 735: 0x1680, /* 36 */ ! 736: 0xd641, /* 37 */ ! 737: 0xd201, /* 38 */ ! 738: 0x12c0, /* 39 */ ! 739: 0x1380, /* 3a */ ! 740: 0xd341, /* 3b */ ! 741: 0x1100, /* 3c */ ! 742: 0xd1c1, /* 3d */ ! 743: 0xd081, /* 3e */ ! 744: 0x1040, /* 3f */ ! 745: 0xf001, /* 40 */ ! 746: 0x30c0, /* 41 */ ! 747: 0x3180, /* 42 */ ! 748: 0xf141, /* 43 */ ! 749: 0x3300, /* 44 */ ! 750: 0xf3c1, /* 45 */ ! 751: 0xf281, /* 46 */ ! 752: 0x3240, /* 47 */ ! 753: 0x3600, /* 48 */ ! 754: 0xf6c1, /* 49 */ ! 755: 0xf781, /* 4a */ ! 756: 0x3740, /* 4b */ ! 757: 0xf501, /* 4c */ ! 758: 0x35c0, /* 4d */ ! 759: 0x3480, /* 4e */ ! 760: 0xf441, /* 4f */ ! 761: 0x3c00, /* 50 */ ! 762: 0xfcc1, /* 51 */ ! 763: 0xfd81, /* 52 */ ! 764: 0x3d40, /* 53 */ ! 765: 0xff01, /* 54 */ ! 766: 0x3fc0, /* 55 */ ! 767: 0x3e80, /* 56 */ ! 768: 0xfe41, /* 57 */ ! 769: 0xfa01, /* 58 */ ! 770: 0x3ac0, /* 59 */ ! 771: 0x3b80, /* 5a */ ! 772: 0xfb41, /* 5b */ ! 773: 0x3900, /* 5c */ ! 774: 0xf9c1, /* 5d */ ! 775: 0xf881, /* 5e */ ! 776: 0x3840, /* 5f */ ! 777: 0x2800, /* 60 */ ! 778: 0xe8c1, /* 61 */ ! 779: 0xe981, /* 62 */ ! 780: 0x2940, /* 63 */ ! 781: 0xeb01, /* 64 */ ! 782: 0x2bc0, /* 65 */ ! 783: 0x2a80, /* 66 */ ! 784: 0xea41, /* 67 */ ! 785: 0xee01, /* 68 */ ! 786: 0x2ec0, /* 69 */ ! 787: 0x2f80, /* 6a */ ! 788: 0xef41, /* 6b */ ! 789: 0x2d00, /* 6c */ ! 790: 0xedc1, /* 6d */ ! 791: 0xec81, /* 6e */ ! 792: 0x2c40, /* 6f */ ! 793: 0xe401, /* 70 */ ! 794: 0x24c0, /* 71 */ ! 795: 0x2580, /* 72 */ ! 796: 0xe541, /* 73 */ ! 797: 0x2700, /* 74 */ ! 798: 0xe7c1, /* 75 */ ! 799: 0xe681, /* 76 */ ! 800: 0x2640, /* 77 */ ! 801: 0x2200, /* 78 */ ! 802: 0xe2c1, /* 79 */ ! 803: 0xe381, /* 7a */ ! 804: 0x2340, /* 7b */ ! 805: 0xe101, /* 7c */ ! 806: 0x21c0, /* 7d */ ! 807: 0x2080, /* 7e */ ! 808: 0xe041, /* 7f */ ! 809: 0xa001, /* 80 */ ! 810: 0x60c0, /* 81 */ ! 811: 0x6180, /* 82 */ ! 812: 0xa141, /* 83 */ ! 813: 0x6300, /* 84 */ ! 814: 0xa3c1, /* 85 */ ! 815: 0xa281, /* 86 */ ! 816: 0x6240, /* 87 */ ! 817: 0x6600, /* 88 */ ! 818: 0xa6c1, /* 89 */ ! 819: 0xa781, /* 8a */ ! 820: 0x6740, /* 8b */ ! 821: 0xa501, /* 8c */ ! 822: 0x65c0, /* 8d */ ! 823: 0x6480, /* 8e */ ! 824: 0xa441, /* 8f */ ! 825: 0x6c00, /* 90 */ ! 826: 0xacc1, /* 91 */ ! 827: 0xad81, /* 92 */ ! 828: 0x6d40, /* 93 */ ! 829: 0xaf01, /* 94 */ ! 830: 0x6fc0, /* 95 */ ! 831: 0x6e80, /* 96 */ ! 832: 0xae41, /* 97 */ ! 833: 0xaa01, /* 98 */ ! 834: 0x6ac0, /* 99 */ ! 835: 0x6b80, /* 9a */ ! 836: 0xab41, /* 9b */ ! 837: 0x6900, /* 9c */ ! 838: 0xa9c1, /* 9d */ ! 839: 0xa881, /* 9e */ ! 840: 0x6840, /* 9f */ ! 841: 0x7800, /* a0 */ ! 842: 0xb8c1, /* a1 */ ! 843: 0xb981, /* a2 */ ! 844: 0x7940, /* a3 */ ! 845: 0xbb01, /* a4 */ ! 846: 0x7bc0, /* a5 */ ! 847: 0x7a80, /* a6 */ ! 848: 0xba41, /* a7 */ ! 849: 0xbe01, /* a8 */ ! 850: 0x7ec0, /* a9 */ ! 851: 0x7f80, /* aa */ ! 852: 0xbf41, /* ab */ ! 853: 0x7d00, /* ac */ ! 854: 0xbdc1, /* ad */ ! 855: 0xbc81, /* ae */ ! 856: 0x7c40, /* af */ ! 857: 0xb401, /* b0 */ ! 858: 0x74c0, /* b1 */ ! 859: 0x7580, /* b2 */ ! 860: 0xb541, /* b3 */ ! 861: 0x7700, /* b4 */ ! 862: 0xb7c1, /* b5 */ ! 863: 0xb681, /* b6 */ ! 864: 0x7640, /* b7 */ ! 865: 0x7200, /* b8 */ ! 866: 0xb2c1, /* b9 */ ! 867: 0xb381, /* ba */ ! 868: 0x7340, /* bb */ ! 869: 0xb101, /* bc */ ! 870: 0x71c0, /* bd */ ! 871: 0x7080, /* be */ ! 872: 0xb041, /* bf */ ! 873: 0x5000, /* c0 */ ! 874: 0x90c1, /* c1 */ ! 875: 0x9181, /* c2 */ ! 876: 0x5140, /* c3 */ ! 877: 0x9301, /* c4 */ ! 878: 0x53c0, /* c5 */ ! 879: 0x5280, /* c6 */ ! 880: 0x9241, /* c7 */ ! 881: 0x9601, /* c8 */ ! 882: 0x56c0, /* c9 */ ! 883: 0x5780, /* ca */ ! 884: 0x9741, /* cb */ ! 885: 0x5500, /* cc */ ! 886: 0x95c1, /* cd */ ! 887: 0x9481, /* ce */ ! 888: 0x5440, /* cf */ ! 889: 0x9c01, /* d0 */ ! 890: 0x5cc0, /* d1 */ ! 891: 0x5d80, /* d2 */ ! 892: 0x9d41, /* d3 */ ! 893: 0x5f00, /* d4 */ ! 894: 0x9fc1, /* d5 */ ! 895: 0x9e81, /* d6 */ ! 896: 0x5e40, /* d7 */ ! 897: 0x5a00, /* d8 */ ! 898: 0x9ac1, /* d9 */ ! 899: 0x9b81, /* da */ ! 900: 0x5b40, /* db */ ! 901: 0x9901, /* dc */ ! 902: 0x59c0, /* dd */ ! 903: 0x5880, /* de */ ! 904: 0x9841, /* df */ ! 905: 0x8801, /* e0 */ ! 906: 0x48c0, /* e1 */ ! 907: 0x4980, /* e2 */ ! 908: 0x8941, /* e3 */ ! 909: 0x4b00, /* e4 */ ! 910: 0x8bc1, /* e5 */ ! 911: 0x8a81, /* e6 */ ! 912: 0x4a40, /* e7 */ ! 913: 0x4e00, /* e8 */ ! 914: 0x8ec1, /* e9 */ ! 915: 0x8f81, /* ea */ ! 916: 0x4f40, /* eb */ ! 917: 0x8d01, /* ec */ ! 918: 0x4dc0, /* ed */ ! 919: 0x4c80, /* ee */ ! 920: 0x8c41, /* ef */ ! 921: 0x4400, /* f0 */ ! 922: 0x84c1, /* f1 */ ! 923: 0x8581, /* f2 */ ! 924: 0x4540, /* f3 */ ! 925: 0x8701, /* f4 */ ! 926: 0x47c0, /* f5 */ ! 927: 0x4680, /* f6 */ ! 928: 0x8641, /* f7 */ ! 929: 0x8201, /* f8 */ ! 930: 0x42c0, /* f9 */ ! 931: 0x4380, /* fa */ ! 932: 0x8341, /* fb */ ! 933: 0x4100, /* fc */ ! 934: 0x81c1, /* fd */ ! 935: 0x8081, /* fe */ ! 936: 0x4040, /* ff */ ! 937: }; ! 938: ! 939: crccalc(count, buffer, bp) ! 940: register int count; ! 941: register char *buffer; ! 942: struct bsc *bp; ! 943: { ! 944: register unsigned int work, crc; ! 945: ! 946: crc = ((bp->b_crc[1] & 0xff)<<8) | (bp->b_crc[0] & 0xff); ! 947: if (bp->b_hlflgs & BSCASCII) ! 948: while (--count >= 0) { ! 949: work = (*buffer++) & 0xff; ! 950: crc ^= work | (work << 8); ! 951: } ! 952: else ! 953: while (--count >= 0) { ! 954: work = crctab[0xff & (crc ^ *buffer++)]; ! 955: crc = (work & 0xff00) | ! 956: (0xff & ((crc >> 8) ^ work)); ! 957: } ! 958: bp->b_crc[0] = crc; ! 959: bp->b_crc[1] = crc >> 8; ! 960: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.