|
|
1.1 ! root 1: /* ! 2: * Datakit driver ! 3: */ ! 4: #include "dk.h" ! 5: #if NDK ! 6: #include "../h/param.h" ! 7: #include "../h/systm.h" ! 8: #include "../h/stream.h" ! 9: #include "../h/ioctl.h" ! 10: #include "../h/pte.h" ! 11: #include "../h/map.h" ! 12: #include "../h/buf.h" ! 13: #include "../h/ubavar.h" ! 14: #include "../h/conf.h" ! 15: #include "../h/dkstat.h" ! 16: #include "../h/dkmod.h" ! 17: #include "sparam.h" ! 18: ! 19: struct device { ! 20: unsigned short csr; ! 21: unsigned short dko; ! 22: unsigned short dki; ! 23: }; ! 24: ! 25: struct device *DKADDR; ! 26: #ifndef NDKLINE ! 27: #define NDKLINE 64 ! 28: #endif NDKLINE ! 29: ! 30: struct dk { ! 31: struct queue *dkrq; ! 32: u_char chan; ! 33: } dk[NDKLINE]; ! 34: ! 35: int dkalive; ! 36: struct dkstat dkstat; ! 37: extern struct dkmodule dkmod[]; ! 38: struct dkmodule *dkmodp; ! 39: char dkstate[NDKLINE]; ! 40: ! 41: /* ! 42: * channel states ! 43: */ ! 44: #define CLOSED 0 ! 45: #define RCLOSE 1 /* remote hung up, local still around */ ! 46: #define LCLOSE 2 /* closed locally, CMC hasn't acked yet */ ! 47: #define OPEN 3 /* in use */ ! 48: ! 49: /* ! 50: * Hardware control bits ! 51: */ ! 52: #define DKTENAB 0100 ! 53: #define DKRENAB 040 ! 54: #define ENABS (DKRENAB) ! 55: #define DKTDONE 0200 ! 56: #define DKRDONE 0100000 ! 57: #define D_OSEQ 0 ! 58: #define D_READ 01 ! 59: #define D_WRITE 02 ! 60: #define D_XPACK 03 ! 61: #define DKMARK 01000 ! 62: #define DKDATA 0400 ! 63: #define DKPARITY 0100000 ! 64: ! 65: #define DKISIZ 16 ! 66: ! 67: int nodev(), dkopen(), dkclose(), dkput(); ! 68: ! 69: static struct qinit dkrinit = { nodev, NULL, dkopen, dkclose, 0, 0 }; ! 70: struct qinit dkwinit = { dkput, NULL, dkopen, dkclose, 0, 0 }; ! 71: struct streamtab dkinfo = { &dkrinit, &dkwinit }; ! 72: ! 73: int dkattach(), dkprobe(); ! 74: struct uba_device *dkstuff[NDK]; ! 75: u_short dkstd[] = { 0 }; ! 76: struct uba_driver dkdriver = ! 77: { dkprobe, 0, dkattach, 0, dkstd, "dk", dkstuff }; ! 78: ! 79: dkprobe(reg) ! 80: caddr_t reg; ! 81: { ! 82: register int br, cvec; ! 83: register struct device *dkaddr = (struct device *)reg; ! 84: ! 85: dkaddr->csr = D_OSEQ; ! 86: dkaddr->dko = 0; /* this clears fifos */ ! 87: DELAY(1000); /* wait for board to reset */ ! 88: dkaddr->csr = D_WRITE; ! 89: dkaddr->dko = DKMARK + 511; /* pack on 511 */ ! 90: dkaddr->csr = D_XPACK+DKTENAB; ! 91: dkaddr->dko = 0; ! 92: DELAY(10000); ! 93: dkaddr->csr = 0; ! 94: DKADDR = dkaddr; ! 95: return(1); ! 96: } ! 97: ! 98: dkattach() ! 99: { ! 100: } ! 101: ! 102: /* ! 103: * open DK channel ! 104: */ ! 105: dkopen(q, dev) ! 106: register struct queue *q; ! 107: register dev_t dev; ! 108: { ! 109: register struct dk *dkp; ! 110: static opened, badtime; ! 111: register maj = major(dev); ! 112: ! 113: dev = minor(dev); ! 114: if (dev<=0 || dev>=NDKLINE) ! 115: return(0); ! 116: if (!opened) { ! 117: register sane; ! 118: ! 119: if (DKADDR == NULL) ! 120: return(0); ! 121: DKADDR->csr = D_OSEQ; ! 122: DKADDR->dko = 0; /* Clear fifo's */ ! 123: sane = 256; ! 124: do { ! 125: if (DKADDR->csr & DKTDONE) { ! 126: dkalive = 0; ! 127: if (time > badtime + 300) { ! 128: badtime = time; ! 129: printf("DK interface bad\n"); ! 130: } ! 131: return(0); ! 132: } ! 133: } while (--sane); ! 134: for (dkmodp=dkmod; ; dkmodp++) { ! 135: if (dkmodp->dev==0 || dkmodp->dev==maj) { ! 136: dkmodp->dev = maj; ! 137: dkmodp->dkstate = dkstate; ! 138: dkmodp->nchan = NDKLINE; ! 139: break; ! 140: } ! 141: } ! 142: dkalive = 1; ! 143: for (dkp = &dk[0]; dkp < &dk[NDKLINE]; dkp++) ! 144: dkp->chan = dkp - &dk[0]; ! 145: DKADDR->csr = ENABS; ! 146: opened++; ! 147: dkrecover(dev); ! 148: } ! 149: dkp = &dk[dev]; ! 150: if (dkmodp->dkstate[dev] != CLOSED) { /* already open */ ! 151: if (dev&01 && dev>1) /* outgoing channels can't reopen */ ! 152: return(0); ! 153: if (dkmodp->dkstate[dev] != OPEN) ! 154: return(0); /* closing channels can't reopen */ ! 155: return(1); ! 156: } ! 157: dkp->dkrq = q; ! 158: q->ptr = (caddr_t)dkp; ! 159: WR(q)->ptr = (caddr_t)dkp; ! 160: dkmodp->dkstate[dev] = OPEN; ! 161: return(1); ! 162: } ! 163: ! 164: /* ! 165: * Timer to recover from lost interrupt condition. ! 166: */ ! 167: dkrecover(dev) ! 168: dev_t dev; ! 169: { ! 170: register int ps = spl5(); ! 171: ! 172: if (DKADDR->csr & DKRDONE) ! 173: dkrint(dev); ! 174: splx(ps); ! 175: ! 176: timeout(dkrecover, dev, hz/2); ! 177: } ! 178: ! 179: /* ! 180: * close DK channel ! 181: */ ! 182: dkclose(q) ! 183: register struct queue *q; ! 184: { ! 185: register struct dk *dkp; ! 186: ! 187: dkp = (struct dk *)q->ptr; ! 188: dkp->dkrq = NULL; ! 189: if (dkmodp->dkstate[dkp->chan] == RCLOSE || dkmodp->listnrq==NULL) ! 190: dkmodp->dkstate[dkp->chan] = CLOSED; ! 191: else if (dkmodp->dkstate[dkp->chan] == OPEN) ! 192: dkmodp->dkstate[dkp->chan] = LCLOSE; ! 193: if (dkmodp->listnrq) ! 194: putctl1(RD(dkmodp->listnrq), M_CLOSE, dkp->chan); ! 195: } ! 196: ! 197: /* ! 198: * DK receiver interrupt. ! 199: */ ! 200: dkrint(dev) ! 201: { ! 202: register struct queue *q; ! 203: register struct block *bp, **bpp; ! 204: register c, nbytes, sts, sane, chan; ! 205: struct block *blist[DKISIZ+1]; ! 206: ! 207: sts = DKADDR->csr; ! 208: c = 0; ! 209: while (DKADDR->csr & DKRDONE) { ! 210: DKADDR->csr = D_READ|ENABS; ! 211: if ((c & DKMARK) == 0) { ! 212: /* Search for channel number */ ! 213: sane = 256; ! 214: do { ! 215: c = DKADDR->dki; ! 216: if (c & DKMARK || --sane==0) ! 217: break; ! 218: } while (DKADDR->csr & DKRDONE); ! 219: } ! 220: if ((c & DKMARK) == 0) { ! 221: dkstat.markflt++; ! 222: continue; ! 223: } ! 224: if ((c & DKPARITY) == 0) { ! 225: dkstat.markparity++; ! 226: c = 0; ! 227: continue; ! 228: } ! 229: /* check channel */ ! 230: chan = c & 0777; ! 231: if (chan == 0 || chan >= NDKLINE || (q = dk[chan].dkrq)==NULL) { ! 232: if (chan>0 && chan<NDKLINE) { ! 233: if (dkmodp->listnrq) ! 234: putctl1(RD(dkmodp->listnrq), ! 235: M_CLOSE, chan); ! 236: dkstat.closepack++; ! 237: } else if (chan == 0) ! 238: dkstat.pack0++; ! 239: else ! 240: dkstat.packstrange++; ! 241: for (nbytes=0; nbytes<DKISIZ; nbytes++) { ! 242: c = DKADDR->dki; ! 243: if (c & DKMARK) ! 244: break; ! 245: } ! 246: continue; ! 247: } ! 248: bp = allocb(DKISIZ); ! 249: if (bp == NULL) ! 250: return; ! 251: bpp = blist; ! 252: for (nbytes=0; nbytes<DKISIZ; nbytes++) { ! 253: if ((DKADDR->csr&DKRDONE) == 0) ! 254: break; ! 255: c = DKADDR->dki; ! 256: if ((c & (DKPARITY|DKDATA|DKMARK))!=(DKPARITY|DKDATA)) { ! 257: if (c & DKMARK) { ! 258: dkstat.shortpack++; ! 259: break; ! 260: } ! 261: if ((c & DKPARITY) == 0) { ! 262: dkstat.parity++; ! 263: break; ! 264: } else { /* it's control */ ! 265: if ((c & 0377) == 0) ! 266: continue; ! 267: if (bp->wptr > bp->rptr) { ! 268: *bpp++ = bp; ! 269: bp = allocb(DKISIZ); ! 270: if (bp == NULL) ! 271: break; ! 272: } ! 273: } ! 274: bp->type = M_CTL; ! 275: } ! 276: *bp->wptr++ = c; ! 277: } ! 278: *bpp++ = bp; ! 279: *bpp++ = NULL; ! 280: bpp = blist; ! 281: if (nbytes!=DKISIZ) { ! 282: while (*bpp) ! 283: freeb(*bpp++); ! 284: continue; ! 285: } ! 286: while (*bpp) { ! 287: dkstat.input += bp->wptr - bp->rptr; ! 288: if ((q->next->flag & QFULL) == 0) ! 289: (*q->next->qinfo->putp)(q->next, *bpp++); ! 290: else ! 291: freeb(*bpp++); ! 292: } ! 293: } ! 294: DKADDR->csr = sts; ! 295: } ! 296: ! 297: /* ! 298: * DK put procedure ! 299: */ ! 300: dkput(q, bp) ! 301: register struct queue *q; ! 302: register struct block *bp; ! 303: { ! 304: register n, isdata = DKDATA; ! 305: struct dk *dp; ! 306: int chan, s; ! 307: struct ioctl1 { ! 308: int com; ! 309: int lhn; ! 310: } *iop; ! 311: ! 312: dp = (struct dk *)q->ptr; ! 313: chan = dp->chan; ! 314: switch (bp->type) { ! 315: ! 316: case M_IOCTL: ! 317: bp->type = M_IOCACK; ! 318: iop = (struct ioctl1 *)bp->rptr; ! 319: switch (iop->com) { ! 320: ! 321: default: ! 322: bp->type = M_IOCNAK; ! 323: break; ! 324: } ! 325: qreply(q, bp); ! 326: return; ! 327: ! 328: case M_CTL: ! 329: isdata = 0; ! 330: case M_DATA: ! 331: break; ! 332: ! 333: case M_CLOSE: ! 334: n = *bp->rptr; ! 335: if (n < NDKLINE) { ! 336: if (dkmodp->dkstate[n] == OPEN) { ! 337: dkmodp->dkstate[n] = RCLOSE; ! 338: putctl(dk[n].dkrq->next, M_HANGUP); ! 339: } else if (dkmodp->dkstate[n] == LCLOSE) ! 340: dkmodp->dkstate[n] = CLOSED; ! 341: } ! 342: freeb(bp); ! 343: return; ! 344: ! 345: default: ! 346: freeb(bp); ! 347: return; ! 348: } ! 349: dkstat.output += bp->wptr - bp->rptr; ! 350: s = spl6(); ! 351: if (dkalive) { ! 352: register struct device *dkaddr = DKADDR; ! 353: int r = dkaddr->csr; ! 354: while ((n = bp->wptr - bp->rptr) > 0) { ! 355: if (n > DKISIZ) ! 356: n = DKISIZ; ! 357: dkaddr->csr = D_WRITE + ENABS; ! 358: dkaddr->dko = DKMARK + chan; ! 359: dkaddr->dko = *bp->rptr++ | isdata; ! 360: while (--n) ! 361: dkaddr->dko = *bp->rptr++ | DKDATA; ! 362: dkaddr->csr = D_XPACK + ENABS; ! 363: dkaddr->dko = 0; ! 364: } ! 365: dkaddr->csr = r; ! 366: } ! 367: splx(s); ! 368: freeb(bp); ! 369: } ! 370: ! 371: /* ! 372: * unibus reset ! 373: */ ! 374: dkreset() ! 375: { ! 376: if (DKADDR) ! 377: DKADDR->csr = ENABS; ! 378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.