Annotation of researchv8dc/sys/chncp/chdr11c.c, revision 1.1.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.