|
|
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.