Annotation of researchv8dc/sys/chaosld/chaosld.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *             C H A O S  L D
                      3:  *
                      4:  * Chaosnet line discipline, to be pushed on an ethernet controller.
                      5:  * Handles xmit and rcv windows, packet numbering, and connection states.
                      6:  *
                      7:  *
                      8:  * (c) Copyright 1985  Nirvonics, Inc.
                      9:  *
                     10:  * Written by Kurt Gollhardt
                     11:  * Last update Tue Mar 12 04:18:58 1985
                     12:  *
                     13:  * This software is the property of Nirvonics, Inc.
                     14:  * All rights reserved.
                     15:  *
                     16:  */
                     17: 
                     18: #include "ch.h"
                     19: #if NCH
                     20: #include "../h/param.h"
                     21: #include "../h/systm.h"
                     22: #include "../h/stream.h"
                     23: #include "../h/ioctl.h"
                     24: #include "../h/ttyld.h"
                     25: #include "../h/map.h"
                     26: #include "../h/buf.h"
                     27: #include "../h/conf.h"
                     28: #include "../chaosld/types.h"
                     29: #define CHDEFINE
                     30: #include "../chaosld/globals.h"
                     31: 
                     32: 
                     33: extern int     chrcv(), chb_put();
                     34: int            chopen(), chclose(), chosrv(), chisrv();
                     35: static struct qinit chrinit = { chb_put, chisrv, chopen, chclose, 512, 64 };
                     36: static struct qinit chwinit = { putq, chosrv, chopen, chclose, 512, 64 };
                     37: struct streamtab chinfo = { &chrinit, &chwinit };
                     38: 
                     39: chopen(q, dev)
                     40:      register struct queue *q;
                     41: {
                     42:      if (q->ptr)
                     43:           return(1);
                     44:      if (ChaosQ != (struct queue *)0)   /* Already open */
                     45:           return(0);
                     46:      ChaosQ = q;     /* that's the RD q */
                     47:      q->flag |= QDELIM|QNOENB;     /* chiput calls qenable() */
                     48:      WR(q)->flag |= QDELIM;
                     49:      return(1);
                     50: }
                     51: 
                     52: chclose(q)
                     53:      struct queue   *q;
                     54: {
                     55:      struct connection   **connp;
                     56:      int       ps = spl6();
                     57: 
                     58:      for (connp = Chconn; connp < &Chconn[NCH]; ++connp)
                     59:           if (*connp != NOCONN)
                     60:               chld_close(*connp, NOPKT);
                     61: 
                     62:      freelist(Chlsnlist);
                     63:      freelist(Chrfclist);
                     64:      Chlsnlist = Chrfclist = Chrfctail = NOPKT;
                     65:      Chmyaddr.ch_addr = 0;
                     66: 
                     67:      ChaosQ = (struct queue *)0;
                     68:      splx(ps);
                     69: }
                     70: 
                     71: 
                     72: chisrv(q)
                     73:      struct queue   *q;
                     74: {
                     75:      register struct block    *bp;
                     76: 
                     77:      chrcv(q);   /* Receive the packet */
                     78: 
                     79:      /* See if there's another packet on the queue */
                     80:      for (bp = q->first; bp != NOBLOCK; bp = bp->next)
                     81:          if (bp->type == M_DELIM) {
                     82:               qenable(q);    /* re-enable queue for the next packet */
                     83:               break;
                     84:           }
                     85: }
                     86: 
                     87: 
                     88: chosrv(q)
                     89:      register struct queue *q;
                     90: {
                     91:      register union stmsg *sp;
                     92:      register struct block *bp;
                     93: 
                     94:      while(bp = getq(q)){
                     95:           if(bp->type == M_IOCTL){
                     96:                sp = (union stmsg *)bp->rptr;
                     97:                switch(sp->ioc0.com){
                     98:                    case CHIOCNAME:
                     99:                         copyin(*(caddr_t *)sp->iocx.xxx, Chmyname, CHSTATNAME);
                    100:                          bp->rptr = bp->wptr;
                    101:                         bp->type = M_IOCACK;
                    102:                         qreply(q, bp);
                    103:                         break;
                    104:                    case CHIOCADDR:
                    105:                         Chmyaddr.ch_addr = *(int *)sp->iocx.xxx;
                    106:                         /* fall through */
                    107:                     default:
                    108:                          (*q->next->qinfo->putp)(q->next, bp);
                    109:                          break;
                    110:                }
                    111:           } else
                    112:                (*q->next->qinfo->putp)(q->next, bp);
                    113:      }
                    114: }
                    115: 
                    116: chld_write(conn, pkt)
                    117:      register struct connection    *conn;
                    118:      register struct packet        *pkt;
                    119: {
                    120:      setconn(conn, pkt);
                    121: 
                    122:      switch (pkt->pk_op) {
                    123:           case ANSOP:
                    124:          case FWDOP:
                    125:               if (conn->cn_state != CSRFCRCVD ||
                    126:                         (conn->cn_flags & CHANSWER) == 0)
                    127:                     goto err;
                    128:                chld_close(conn, pkt);
                    129:               return 0;
                    130:           case RFCOP:
                    131:           case BRDOP:
                    132:               if (conn->cn_state != CSRFCSENT)
                    133:                    goto err;
                    134:                break;
                    135:           case UNCOP:
                    136:               pkt->pk_pkn = 0;
                    137:               pkt->next = NOPKT;
                    138:               senddata(pkt);
                    139:               return 0;
                    140:           default:
                    141:               if (!ISDATA(pkt))
                    142:                    goto err;
                    143:           case OPNOP:
                    144:          case EOFOP:
                    145:               if (conn->cn_state != CSOPEN)
                    146:                    goto err;
                    147:                setack(conn, pkt);
                    148:                break;
                    149:      }
                    150: 
                    151:      pkt->pk_pkn = ++conn->cn_tlast;
                    152:      senddata(pkt);
                    153:      return 0;
                    154: 
                    155: err:
                    156:      free_packet(pkt);
                    157:      return -1;
                    158: }
                    159: 
                    160: 
                    161: chld_eof(conn)
                    162:      struct connection   *conn;
                    163: {
                    164:      register struct packet   *pkt;
                    165: 
                    166:      if ((pkt = new_packet()) != NOPKT) {
                    167:          setconn(conn, pkt);
                    168:           pkt->pk_op = EOFOP;
                    169:          return chld_write(conn, pkt);
                    170:      }
                    171:      return 0;
                    172: }
                    173: 
                    174: 
                    175: chld_accept(conn)
                    176:      struct connection   *conn;
                    177: {
                    178:      conn->cn_state = CSOPEN;
                    179:      sendopn(conn);
                    180: }
                    181: 
                    182: 
                    183: chld_open(conn, daddr, rwsize, pkt)
                    184:      register struct connection    *conn;
                    185:      register struct packet   *pkt;
                    186: {
                    187:      conn->cn_faddr.ch_addr = daddr;
                    188:      conn->cn_state = CSRFCSENT;
                    189:      conn->cn_rwsize = rwsize;
                    190:      conn->cn_rsts = rwsize / 2;
                    191:      conn->cn_time = Chclock;
                    192:      pkt->pk_op = RFCOP;
                    193:      pkt->pk_fc = pkt->pk_ackn = 0;
                    194:      debug(DCONN,printf("Conn #%x: RFCS state\n", conn->cn_lidx.ci_idx));
                    195:      /*
                    196:       * By writing the RFC packet like a data packet, it will be kept
                    197:       * around for automatic retransmission until freed by the normal
                    198:       * receipting mechanism; xmitdone() and chrcv() facilitate this.
                    199:       * Since new_conn() clears the connection (including cn_tlast),
                    200:       * the packet number of the RFC will be 1 (pkn = ++cn_tlast).
                    201:       */
                    202:      chld_write(conn, pkt);
                    203: }
                    204: 
                    205: 
                    206: chld_listen(conn, rwsize, pkt)
                    207:      register struct connection    *conn;
                    208:      register struct packet   *pkt;
                    209: {
                    210:      register struct packet   *opkt, *pktl;
                    211:      int       ps;
                    212: 
                    213:      conn->cn_state = CSLISTEN;
                    214:      conn->cn_flags |= CHSERVER;
                    215:      conn->cn_rwsize = rwsize;
                    216:      pkt->pk_op = LSNOP;
                    217:      setconn(conn, pkt);
                    218: 
                    219:      if (flatten(pkt)) {
                    220:           free_packet(pkt);
                    221:          return;
                    222:      }
                    223: 
                    224:      ps = spl6();
                    225:      opkt = NOPKT;
                    226:      for (pktl = Chrfclist; pktl != NOPKT; pktl = (opkt = pktl)->next)
                    227:           if (concmp(pktl, pkt->data->rptr, (int)pkt->pk_len)) {
                    228:               if (opkt == NOPKT)
                    229:                    Chrfclist = pktl->next;
                    230:                else
                    231:                    opkt->next = pktl->next;
                    232:                if (pktl == Chrfctail)
                    233:                    Chrfctail = opkt;
                    234:                free_packet(pkt);
                    235:               lsnmatch(pktl, conn);
                    236:               chd_newstate(conn);
                    237:               splx(ps);
                    238:               return;
                    239:           }
                    240: 
                    241:      pkt->next = Chlsnlist;
                    242:      Chlsnlist = pkt;
                    243:      splx(ps);
                    244: 
                    245:      debug(DCONN,printf("Conn #%x: LISTEN state\n", conn->cn_lidx.ci_idx));
                    246: }
                    247: 
                    248: 
                    249: chld_close(conn, pkt)
                    250:      register struct connection    *conn;
                    251:      register struct packet        *pkt;
                    252: {
                    253:      int       ps = spl6();
                    254: 
                    255:      ch_busy++;
                    256:      switch (conn->cn_state) {
                    257:           case CSOPEN:
                    258:          case CSRFCRCVD:
                    259:               if (pkt != NOPKT) {
                    260:                    setconn(conn, pkt);
                    261:                    pkt->pk_ackn = pkt->pk_pkn = 0;
                    262:                    sendctl(pkt);
                    263:                    pkt = NOPKT;
                    264:                }
                    265:               /* Fall into ... */
                    266:           case CSRFCSENT:
                    267:               close_conn(conn, CSCLOSED, NOPKT);
                    268:               break;
                    269:           case CSLISTEN:
                    270:               rmlisten(conn);
                    271:               break;
                    272:      }
                    273:      --ch_busy;
                    274:      splx(ps);
                    275: 
                    276:      if (pkt != NOPKT)
                    277:           free_packet(pkt);
                    278: }
                    279: 
                    280: #endif

unix.superglobalmegacorp.com

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