|
|
1.1 ! root 1: #include "../chunix/chsys.h" ! 2: #include "../chunix/chconf.h" ! 3: #include "../chaos/chaos.h" ! 4: /* ! 5: * Chaos device driver for the ch11 (CHAOS-11) broadcast network ! 6: * interface. ! 7: */ ! 8: struct chxcvr ch11xcvr[NCHCH]; ! 9: #define xc_chrtries xc_info.xc_ch11.ch_rtries ! 10: int chchstart(), chchreset(); ! 11: ! 12: #ifdef VMUNIX ! 13: #include "../h/buf.h" ! 14: #include "../h/ubavar.h" ! 15: int chchndev; ! 16: /* ! 17: * Autoconfiguration support for VMUNIX ! 18: */ ! 19: int chchprobe(), chchattach(), chchintr(); ! 20: struct uba_device *chchdinfo[NCHCH]; ! 21: unsigned short chchstd[] = { 0164140, 0165140, 0166140 }; ! 22: struct uba_driver chchdriver = ! 23: { chchprobe, 0, chchattach, 0, chchstd, "chch", chchdinfo }; ! 24: ! 25: chchprobe(reg) ! 26: caddr_t reg; ! 27: { ! 28: register int br, cvec; ! 29: ! 30: #ifdef lint ! 31: br = 0; cvec = br; br = cvec; ! 32: #endif ! 33: ((struct ch11 *)reg)->ch_csr = CHTCLR; ! 34: ((struct ch11 *)reg)->ch_csr = CHTIEN; ! 35: DELAY(10000); ! 36: ((struct ch11 *)reg)->ch_csr = 0; ! 37: return (1); ! 38: } ! 39: ! 40: /*ARGSUSED*/ ! 41: chchattach(ui) ! 42: register struct uba_device *ui; ! 43: { ! 44: ! 45: if (++chchndev > NCHCH) ! 46: panic("too many ch11's"); ! 47: chchsetup(&ch11xcvr[chchndev - 1], (struct ch11 *)ui->ui_addr); ! 48: } ! 49: #else VMUNIX ! 50: int chchndev = NCHCH; ! 51: int chchaddr[NCHCH] = { CHCH_ADDR }; ! 52: #endif VMUNIX ! 53: /* ! 54: * Do the run-time initialization of the given transceiver. ! 55: */ ! 56: chchsetup(xp, cp) ! 57: register struct chxcvr *xp; ! 58: register struct ch11 *cp; ! 59: { ! 60: xp->xc_devaddr = (unsigned *)cp; ! 61: xp->xc_addr = cp->ch_myaddr; ! 62: xp->xc_start = chchstart; ! 63: xp->xc_reset = chchreset; ! 64: printf("CHAOS cable: subnet: %o, host: %o, (%o)\n", ! 65: xp->xc_subnet, xp->xc_host, xp->xc_addr); ! 66: if (xp->xc_subnet >= CHNSUBNET) ! 67: panic("bad ch11 address"); ! 68: } ! 69: ! 70: /* ! 71: * chaos11 initialization. Also does initialization to the static xcvr ! 72: * structure since initialized unions don't work anyway. ! 73: */ ! 74: chchinit() ! 75: { ! 76: register struct chxcvr *xp; ! 77: register int i; ! 78: ! 79: for (i = 0, xp = &ch11xcvr[0]; xp < &ch11xcvr[chchndev]; xp++, i++) { ! 80: #ifndef VMUNIX ! 81: chchsetup(xp, (struct ch11 *)chchaddr[i]); ! 82: #endif not VMUNIX ! 83: chchreset(xp); ! 84: } ! 85: } ! 86: /* ! 87: * Reset things from an unknown state ! 88: */ ! 89: chchreset(xp) ! 90: register struct chxcvr *xp; ! 91: { ! 92: register struct ch11 *cp = (struct ch11 *)xp->xc_devaddr; ! 93: register struct chroute *r; ! 94: ! 95: if (cp == 0) ! 96: return; ! 97: r = &Chroutetab[xp->xc_subnet]; ! 98: r->rt_type = CHDIRECT; ! 99: r->rt_cost = CHHCOST/2; ! 100: r->rt_xcvr = xp; ! 101: cp->ch_csr = CHRST | CHRIEN | CHREN | CHTIEN; ! 102: } ! 103: ! 104: /* ! 105: * Start output on an idle line ! 106: */ ! 107: chchstart(xp) ! 108: register struct chxcvr *xp; ! 109: { ! 110: if (xp->xc_tpkt != NOPKT) ! 111: panic("chchstart: already busy"); ! 112: chchtint(xp); ! 113: } ! 114: ! 115: /* ! 116: * Receiver interrupt ! 117: */ ! 118: chchrint(xcvr) ! 119: struct chxcvr *xcvr; ! 120: { ! 121: register nshorts; ! 122: register struct ch11 *cp; ! 123: register short *p; ! 124: register struct chxcvr *xp = xcvr; /* needed so xp is last reg */ ! 125: ! 126: cp = (struct ch11 *)xp->xc_devaddr; ! 127: nshorts = (((cp->ch_rbc & 07777) + 1) >> 4) - 3; ! 128: if ((cp->ch_rbc & 017) != 017 || nshorts < 8) ! 129: xp->xc_leng++; /* bit count not multiple of 16 */ ! 130: else if (cp->ch_csr & CHCRC) ! 131: xp->xc_crcr++; /* crc error during reception */ ! 132: else if ((xp->xc_rpkt = hpkalloc(nshorts)) == NOPKT) ! 133: xp->xc_rej++; /* can't allocate a packet */ ! 134: else { ! 135: p = (short *)&xp->xc_rpkt->pk_phead; ! 136: do { ! 137: *p++ = cp->ch_rbf; ! 138: } while (--nshorts); ! 139: nshorts = cp->ch_rbf; ! 140: nshorts = cp->ch_rbf; ! 141: nshorts = cp->ch_rbf; ! 142: if (cp->ch_csr & CHCRC) { ! 143: xp->xc_crci++; /* crc error during readout */ ! 144: ch_free((char *)xp->xc_rpkt); ! 145: } else { ! 146: register struct chroute *r; ! 147: ! 148: LOCK; ! 149: r = &Chroutetab[xp->xc_subnet]; ! 150: r->rt_type = CHDIRECT; ! 151: r->rt_cost = CHCCOST; ! 152: r->rt_xcvr = xp; ! 153: xp->xc_rcvd++; ! 154: rcvpkt((struct packet *)xp->xc_rpkt); ! 155: } ! 156: } ! 157: xp->xc_lost += (cp->ch_csr >> CHLCPOS) & CHLCMASK; ! 158: cp->ch_csr |= CHREN | CHRIEN; /* CHRIEN is "not really needed" */ ! 159: } ! 160: /* ! 161: * Transmit interrupt ! 162: */ ! 163: chchtint(xcvr) ! 164: struct chxcvr *xcvr; ! 165: { ! 166: register struct ch11 *cp; ! 167: register struct packet *pkt; /* shouldn't be reg on pdp11 */ ! 168: ! 169: { ! 170: register struct chxcvr *xp = xcvr; ! 171: ! 172: LOCK; ! 173: cp = (struct ch11 *)xp->xc_devaddr; ! 174: cp->ch_csr &= ~CHTIEN; ! 175: if ((pkt = xp->xc_tpkt) != NOPKT) { /* if a real interrupt */ ! 176: if (cp->ch_csr & CHABRT) { /* should retry here first */ ! 177: xp->xc_abrt++; ! 178: if (++xp->xc_chrtries < 5) ! 179: goto retry; ! 180: } else ! 181: xp->xc_xmtd++; ! 182: xmitdone(pkt); ! 183: xp->xc_chrtries = 0; ! 184: } ! 185: if ((pkt = xmitnext(xp)) == NOPKT) ! 186: return; ! 187: retry: ; ! 188: }{ ! 189: register int nshorts; ! 190: register short *p; ! 191: ! 192: nshorts = (sizeof(struct pkt_header) + pkt->pk_len + sizeof(short)-1) ! 193: /* / sizeof(short) */ >> 1; ! 194: debug(DTRANS,printf("Trans size=%d, %x\n", nshorts, pkt)); ! 195: cp->ch_csr |= CHTCLR; ! 196: p = (short *)&pkt->pk_phead; ! 197: do { ! 198: cp->ch_wbf = *p++; ! 199: } while (--nshorts); ! 200: }{ ! 201: register struct chroute *r; ! 202: ! 203: r = &Chroutetab[pkt->pk_dsubnet]; ! 204: if (r->rt_type != CHDIRECT) ! 205: cp->ch_wbf = r->rt_addr; ! 206: else ! 207: cp->ch_wbf = pkt->pk_daddr; /* where to send it */ ! 208: r = (struct chroute *)cp->ch_xmt; /* start transmission */ ! 209: cp->ch_csr |= CHTIEN; ! 210: } ! 211: } ! 212: /* ! 213: * CHAOS-11 interrupt ! 214: * call chchrint and/or chchtint ! 215: */ ! 216: chchintr(dev) ! 217: { ! 218: register struct chxcvr *xp = &ch11xcvr[dev]; ! 219: register struct ch11 *cp = (struct ch11 *)xp->xc_devaddr; ! 220: ! 221: if (cp->ch_csr & (CHTDN | CHRDN)) { ! 222: if (cp->ch_csr & CHRDN) ! 223: if (cp->ch_csr & CHRIEN) ! 224: chchrint(xp); ! 225: if (cp->ch_csr & CHTDN) ! 226: if (cp->ch_csr & CHTIEN) ! 227: chchtint(xp); ! 228: } else ! 229: debug(DTRANS, printf("spurious CHAOS11 interrupt\n")); ! 230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.