Annotation of researchv8dc/sys/chncp/chdr11c.c, revision 1.1

1.1     ! root        1: #include "../chunix/chsys.h"
        !             2: #include "../chunix/chconf.h"
        !             3: #include "../chaos/chaos.h"
        !             4: /*
        !             5:  * DR11-C Chaos driver.
        !             6:  * This driver does framing and a block check for each packet.
        !             7:  * The framing is similar to standard synchronous links, except that
        !             8:  * the "byte" is 16 bits.  Basically a frame starts after 2 or more
        !             9:  * DRSYNC words, then the next word being a count and the next word being the
        !            10:  * complement of the count (both count and its complement must not be DRSYNC).
        !            11:  * Then the number of words specified by the count are the actual data,
        !            12:  * followed by an LRC-16.  Data words equal to DRSYNC or DRESC are preceded by
        !            13:  * DRESC. The count does not include the inserted DRESC words, but the CRC
        !            14:  * word does. The LRC word does not include the initial DRSYNC's or the count.
        !            15:  * This framing scheme was thought up quickly and may well be overkill.
        !            16:  * The LRC is a simple XOR of all data words.
        !            17:  * Chaos N.C.P.'s that use this file must include <chaos/dr11c.h> in their
        !            18:  * chconf.h files.
        !            19:  * Keep in mind that the interrupt priority level of this driver maybe less
        !            20:  * than either the clock or the LOCK macro supplied by the user.
        !            21:  * Also remember that the block check is not to great.
        !            22:  */
        !            23: 
        !            24: #define        xc_draddr       xc_info.xc_dr11c.dr_addr
        !            25: #define        xc_drtptr       xc_info.xc_dr11c.dr_tptr
        !            26: #define        xc_drrptr       xc_info.xc_dr11c.dr_rptr
        !            27: #define        xc_drtcnt       xc_info.xc_dr11c.dr_tcnt
        !            28: #define        xc_drrcnt       xc_info.xc_dr11c.dr_rcnt
        !            29: #define        xc_drrstate     xc_info.xc_dr11c.dr_rstate
        !            30: #define        xc_drtstate     xc_info.xc_dr11c.dr_tstate
        !            31: #define        xc_drrcheck     xc_info.xc_dr11c.dr_rcheck
        !            32: #define        xc_drtcheck     xc_info.xc_dr11c.dr_tcheck
        !            33: #define        xc_drintrup     xc_info.xc_dr11c.dr_intrup
        !            34: 
        !            35: struct chxcvr dr11cxcvr[NCHDR];
        !            36: 
        !            37: 
        !            38: /*
        !            39:  * dr11-c initialization. Also does initialization to the static chxcvr
        !            40:  * structure since initialized unions don't work anyway.
        !            41:  */
        !            42: 
        !            43: int chdrstart(), chdrreset();
        !            44: /*
        !            45:  * Initialize all dr11c interfaces - called from low priority
        !            46:  */
        !            47: chdrinit()
        !            48: {
        !            49:        register struct chxcvr *xp;
        !            50:        register short *hp;
        !            51: #ifdef VMUNIX
        !            52:        register int i = 0;
        !            53: #else
        !            54:        register char *dp = (char *)DR11CBASE;/* must be char * to use DR11CINC */
        !            55: #endif
        !            56: 
        !            57:        hp = &dr11chosts[0];
        !            58:        for (xp = &dr11cxcvr[0]; xp < &dr11cxcvr[NDR11C]; xp++) {
        !            59:                xp->xc_draddr =
        !            60: #ifdef VMUNIX
        !            61:                        (struct dr11c *) chdrdinfo[i++]->ui_addr;
        !            62: #else
        !            63:                        (struct dr11c *) dp;
        !            64:                dp += DR11CINC;
        !            65: #endif
        !            66:                /*DEBUG*/ if (xp->xc_draddr == 0) panic("draddr");
        !            67:                xp->xc_start = chdrstart;
        !            68:                xp->xc_reset = chdrreset;
        !            69:                xp->xc_host = *hp++;
        !            70:                LOCK;
        !            71:                chdrreset(xp);
        !            72:                UNLOCK;
        !            73:        }
        !            74: }
        !            75: /*
        !            76:  * Check for hung interfaces - if so flush the packet.
        !            77:  * Assumed called at clock level.
        !            78:  */
        !            79: chdrxtime()
        !            80: {
        !            81:        register struct chxcvr *xp;
        !            82: 
        !            83:        for (xp = &dr11cxcvr[0]; xp < &dr11cxcvr[NDR11C]; xp++) {
        !            84:                if (xp->xc_drintrup)
        !            85:                        continue;
        !            86:                if (xp->xc_rpkt != NOPKT &&
        !            87:                    Chclock - xp->xc_rtime > DR11CHUNG) {
        !            88:                        ch_free((char *)xp->xc_rpkt);
        !            89:                        xp->xc_rpkt = NOPKT;
        !            90:                        xp->xc_drrstate = DRIDLE;
        !            91:                        debug(DABNOR, printf("Rec pkt timeout\n"));
        !            92:                }
        !            93:                if (xp->xc_tpkt != NOPKT &&
        !            94:                    Chclock - xp->xc_ttime > DR11CHUNG) {
        !            95:                        debug(DABNOR, printf("Trans pkt timeout\n"));
        !            96:                        xp->xc_drtstate = DRTDONE;
        !            97:                        chdrxint(xp - dr11cxcvr);
        !            98:                }
        !            99:        }
        !           100: }
        !           101: 
        !           102: /*
        !           103:  * Reset things from an unknown state (high priority)
        !           104:  * Basically enable interrupts and tell him we're ready for input.
        !           105:  * If he already has a word, take it right away.
        !           106:  */
        !           107: chdrreset(xp)
        !           108: register struct chxcvr *xp;
        !           109: {
        !           110:        register struct dr11c *dp = xp->xc_draddr;
        !           111: 
        !           112:        xp->xc_drrstate = xp->xc_drtstate = DRIDLE;
        !           113:        dp->dr_csr = 0;
        !           114:        dp->dr_csr = DRIN|DROUT|DRIE|DROE;
        !           115: }
        !           116: /*
        !           117:  * Start output on an idle line - called when nothing happening
        !           118:  */
        !           119: chdrstart(xp)
        !           120: register struct chxcvr *xp;
        !           121: {
        !           122: 
        !           123:        if (xp->xc_tpkt != NOPKT)
        !           124:                panic("chdrstart: already busy");
        !           125:        chdrxint(xp - dr11cxcvr);
        !           126: }
        !           127: /*
        !           128:  * Receiver interrupt
        !           129:  */
        !           130: chdrrint(dev)
        !           131: {
        !           132:        register unsigned short data; /* register short is dubious - be careful! */
        !           133:        register struct chxcvr *xp = &dr11cxcvr[dev];
        !           134:        register struct dr11c *dp = xp->xc_draddr;
        !           135: 
        !           136:        if ((dp->dr_csr & DRIRDY) == 0) {
        !           137:                debug(DABNOR, printf("extra dr11c rint\n"));
        !           138:                return;
        !           139:        }
        !           140:        dp->dr_csr &= ~DRIN;
        !           141:        data = dp->dr_ibuf;
        !           142:        dp->dr_csr |= DRIN;             /* set his DRORDY, and cause his chdrxint */
        !           143:        
        !           144:        xp->xc_drintrup = 1;
        !           145:        switch(xp->xc_drrstate) {
        !           146:        case DRIDLE:
        !           147:                if (data == DRSYNC)
        !           148:                        xp->xc_drrstate = DRSYN1;
        !           149:                break;
        !           150:        case DRSYN1:
        !           151:                xp->xc_drrstate = data == DRSYNC ? DRSYN2 : DRIDLE;
        !           152:                break;
        !           153:        case DRSYN2:
        !           154:                if (data != DRSYNC) {
        !           155:                        xp->xc_drrcnt = data;
        !           156:                        xp->xc_drrstate = DRCNT1;
        !           157:                }
        !           158:                break;
        !           159:        case DRCNT1:
        !           160:                xp->xc_drrstate = DRIDLE;
        !           161:                data = ~data;
        !           162:                debug(DTRANS,printf("Rec size=%d\n", data));
        !           163:                if (data != xp->xc_drrcnt)
        !           164:                        debug(DABNOR, printf("Rec bad count\n"));
        !           165:                else if ((data <<= 1) < sizeof(struct pkt_header) ||
        !           166:                         data > CHMAXDATA + sizeof(struct pkt_header))
        !           167:                        debug(DABNOR, printf("Rec bad size: %d", data));
        !           168:                else {
        !           169:                        LOCK;   /* in case of clock interrupt */
        !           170:                        if ((xp->xc_rpkt = (struct packet *)ch_alloc(
        !           171:                            (int)data + sizeof(struct ncp_header) , 1))
        !           172:                                != NOPKT) {
        !           173:                        xp->xc_drrstate = DRDATA;
        !           174:                        xp->xc_drrptr = (short *)&xp->xc_rpkt->pk_phead;
        !           175:                        xp->xc_drrcheck = 0;
        !           176:                        xp->xc_rtime = Chclock;
        !           177:                        } else
        !           178:                                debug(DABNOR, printf("Rec alloc fail: %d\n", data));
        !           179:                }
        !           180:                break;
        !           181:        case DRDATA:
        !           182:                if (data == DRESC) {
        !           183:                        xp->xc_drrstate = DRESC1;
        !           184:                        xp->xc_drrcheck ^= data;
        !           185:                        break;
        !           186:                }
        !           187:                /* Falls into... */
        !           188:        case DRESC1:
        !           189:                xp->xc_drrcheck ^= data;
        !           190:                *xp->xc_drrptr++ = data;
        !           191:                if (--xp->xc_drrcnt == 0)
        !           192:                        xp->xc_drrstate = DRCHECK;
        !           193:                else
        !           194:                        xp->xc_drrstate = DRDATA;
        !           195:                break;
        !           196:        case DRCHECK:
        !           197:                xp->xc_drrstate = DRIDLE;
        !           198:                LOCK;   /* raise to possibly higher priority */
        !           199:                if (data == xp->xc_drrcheck)
        !           200:                        rcvpkt(xp->xc_rpkt);
        !           201:                else
        !           202:                        ch_free((char *)xp->xc_rpkt);
        !           203:                xp->xc_rpkt = NOPKT;
        !           204:        }
        !           205:        xp->xc_drintrup = 0;
        !           206: }
        !           207: /*
        !           208:  * Transmit interrupt
        !           209:  */
        !           210: chdrxint(dev)
        !           211: {
        !           212:        register struct chxcvr *xp = &dr11cxcvr[dev];
        !           213:        register struct dr11c *dp = xp->xc_draddr;
        !           214:        register struct packet *pkt;
        !           215:        unsigned short data;
        !           216: 
        !           217:        if (xp->xc_tpkt != NOPKT && (dp->dr_csr & DRORDY) == 0) {
        !           218:                debug(DABNOR, printf("Extra dr11c xint\n"));
        !           219:                /*return;*/
        !           220:        }
        !           221:        dp->dr_csr &= ~DROUT;
        !           222:        xp->xc_drintrup = 1;
        !           223:        switch (xp->xc_drtstate) {
        !           224:        case DRIDLE:
        !           225:                xp->xc_tpkt = NOPKT;
        !           226:        case DRTDONE:
        !           227:                LOCK;
        !           228:                if ((pkt = xcvrdone(xp)) == NOPKT)
        !           229:                        goto out;
        !           230:                xp->xc_ttime = Chclock;
        !           231:                data = sizeof(struct pkt_header) + pkt->pk_len;
        !           232:                data = (data + (sizeof(short) - 1)) >> 1;
        !           233:                xp->xc_drtcnt = data;
        !           234:                xp->xc_drtptr = (short *)&pkt->pk_phead;
        !           235:                debug(DTRANS,printf("Trans size=%d, %x\n",data, pkt));
        !           236:                data = DRSYNC;
        !           237:                xp->xc_drtstate = DRSYN1;
        !           238:                break;
        !           239:        case DRSYN1:
        !           240:                data = DRSYNC;
        !           241:                xp->xc_drtstate = DRSYN2;
        !           242:                break;
        !           243:        case DRSYN2:
        !           244:                data = xp->xc_drtcnt;
        !           245:                xp->xc_drtstate = DRCNT1;
        !           246:                break;
        !           247:        case DRCNT1:
        !           248:                data = ~xp->xc_drtcnt;
        !           249:                xp->xc_drtstate = DRDATA;
        !           250:                xp->xc_drtcheck = 0;
        !           251:                break;
        !           252:        case DRDATA:
        !           253:                if ((data = *xp->xc_drtptr) == DRESC || data == DRSYNC) {
        !           254:                        data = DRESC;
        !           255:                        xp->xc_drtcheck ^= data;
        !           256:                        xp->xc_drtstate = DRESC1;
        !           257:                        break;
        !           258:                }
        !           259:                /* Falls into... */
        !           260:        case DRESC1:
        !           261:                data = *xp->xc_drtptr++;
        !           262:                xp->xc_drtcheck ^= data;
        !           263:                if (--xp->xc_drtcnt == 0)
        !           264:                        xp->xc_drtstate = DRCHECK;
        !           265:                else
        !           266:                        xp->xc_drtstate = DRDATA;
        !           267:                break;
        !           268:        case DRCHECK:
        !           269:                data = xp->xc_drtcheck;
        !           270:                xp->xc_drtstate = DRTDONE;
        !           271:        }
        !           272:        dp->dr_obuf = data;
        !           273:        dp->dr_csr |= DROUT;            /* set his DRIRDY, cause his chdrrint */
        !           274: out:
        !           275:        xp->xc_drintrup = 0;
        !           276: }

unix.superglobalmegacorp.com

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