Annotation of cci/sys/bsc/bscll.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.