|
|
1.1 ! root 1: /* ! 2: * trilog driver ! 3: */ ! 4: ! 5: #include "tri.h" ! 6: #if NTRI>0 ! 7: #include "../h/param.h" ! 8: #include "../h/dir.h" ! 9: #include "../h/user.h" ! 10: #include "../h/buf.h" ! 11: #include "../h/pte.h" ! 12: #include "../h/ubavar.h" ! 13: #include "../h/ubareg.h" ! 14: #include "../h/systm.h" ! 15: ! 16: ! 17: #define LPPRI PZERO+10 ! 18: #define LPLOWAT 50 ! 19: ! 20: struct device { ! 21: short tricsr, tribuf; ! 22: }; ! 23: ! 24: #define ERRBIT 0100000 ! 25: #define BUFSIZ 512 ! 26: #define LPSIZ (2*BUFSIZ) ! 27: ! 28: struct tri { ! 29: char tricbuf[LPSIZ]; /* one buffer, no clist */ ! 30: char *trir,*triw; /* and two chasing pointers */ ! 31: int tricc; /* char count to disambiguate */ ! 32: char flag; /* the case of trir == triw */ ! 33: } tritab[NTRI]; ! 34: ! 35: int tritimeout; ! 36: ! 37: /* ! 38: * flag bits ! 39: */ ! 40: #define OPEN 010 ! 41: #define LBUSY 020 ! 42: #define NOCR 040 ! 43: #define ASLP 0100 ! 44: #define ESLP 0200 ! 45: ! 46: #define IENABLE 0100 ! 47: #define DONE 0200 ! 48: ! 49: int triattach(), triprobe(); ! 50: struct uba_device *triinfo[NTRI]; ! 51: u_short tristd[] = { 0 }; ! 52: struct uba_driver tridriver = ! 53: { triprobe, 0, triattach, 0, tristd, "tri", triinfo }; ! 54: ! 55: triprobe(reg) ! 56: caddr_t reg; ! 57: { ! 58: register int br, cvec; ! 59: register struct device *triaddr = (struct device *)reg; ! 60: ! 61: triaddr->tricsr = IENABLE; ! 62: triaddr->tribuf = '\0'; ! 63: DELAY(10000); ! 64: return(1); ! 65: } ! 66: ! 67: triattach() ! 68: { ! 69: } ! 70: ! 71: triopen(dev, flag) ! 72: dev_t dev; ! 73: { ! 74: register int s; ! 75: register unit, d; ! 76: int tritimer(); ! 77: register struct tri *tri; ! 78: register struct uba_device *ui; ! 79: ! 80: d = minor(dev); ! 81: unit = d&07; ! 82: tri = &tritab[unit]; ! 83: ui = triinfo[unit]; ! 84: if (unit>=NTRI || tri->flag || ui->ui_alive==0) { ! 85: u.u_error = ENXIO; ! 86: return; ! 87: } ! 88: tri->flag = (d&077)|OPEN; ! 89: tri->triw = tri->trir = tri->tricbuf; ! 90: tri->tricc = 0; ! 91: while ((((struct device *)ui->ui_addr)->tricsr&DONE) == 0) ! 92: sleep((caddr_t)&lbolt, LPPRI); ! 93: if (tritimeout==0) { ! 94: tritimeout++; ! 95: timeout(tritimer, (caddr_t)0, 10*hz); ! 96: } ! 97: } ! 98: ! 99: tritimer() ! 100: { ! 101: register struct tri *tri; ! 102: register unit, flag; ! 103: ! 104: for (unit=flag=0; unit<NTRI; unit++) { ! 105: tri = &tritab[unit]; ! 106: if (tri->flag==0) { ! 107: continue; ! 108: } ! 109: flag++; ! 110: if (tri->flag&ESLP) { ! 111: tri->flag &= ~ESLP; ! 112: triintr(unit); ! 113: } ! 114: } ! 115: if (flag) { ! 116: timeout(tritimer, (caddr_t)0, 10*hz); ! 117: } else { ! 118: tritimeout = 0; ! 119: } ! 120: } ! 121: ! 122: ! 123: ! 124: triclose(dev) ! 125: register dev_t dev; ! 126: { ! 127: register unit; ! 128: register struct tri *tri; ! 129: ! 130: unit = minor(dev)&07; ! 131: tri = &tritab[unit]; ! 132: ! 133: triwait(tri, 0); ! 134: tri->flag = 0; ! 135: ((struct device *)triinfo[unit]->ui_addr)->tricsr = 0; ! 136: } ! 137: ! 138: ! 139: triwait(tri, count) ! 140: register struct tri *tri; ! 141: register count; ! 142: { ! 143: register int s, times; ! 144: register r; ! 145: ! 146: times = 60; ! 147: while (tri->tricc > count) { ! 148: tri->flag |= ASLP; ! 149: r = tsleep((caddr_t)tri, LPPRI, 10); ! 150: if (r==TS_TIME) { ! 151: s = spl4(); ! 152: if ((tri->flag&LBUSY)==0) ! 153: triintr(tri-tritab); ! 154: splx(s); ! 155: times--; ! 156: if (times==0) { ! 157: printf ("cpr timeout, buffer flushed\n"); ! 158: goto flush; ! 159: } ! 160: } ! 161: if (r==TS_SIG) { ! 162: flush: ! 163: tri->trir = tri->triw = tri->tricbuf; ! 164: tri->tricc = 0; ! 165: } ! 166: } ! 167: } ! 168: ! 169: triwrite(dev) ! 170: { ! 171: register struct tri *tri; ! 172: register char *p; ! 173: register c, cc; ! 174: register s; ! 175: register char *trir; ! 176: ! 177: dev = minor(dev); ! 178: tri = &tritab[dev]; ! 179: while(u.u_count) { ! 180: trir = tri->trir; ! 181: if (trir > tri->triw) ! 182: cc = trir - tri->triw; ! 183: else if (trir == tri->triw && tri->tricc != 0) ! 184: cc = 0; /* buffer full */ ! 185: else /* from triw to the end of the buffer */ ! 186: cc = tri->tricbuf + LPSIZ - tri->triw; ! 187: if (u.u_count < cc) ! 188: cc = u.u_count; ! 189: if (cc == 0) { /* buffer must be full */ ! 190: s = spl4(); ! 191: if ((tri->flag&LBUSY) == 0) { ! 192: triintr(dev); /* poke it */ ! 193: } ! 194: splx(s); ! 195: triwait(tri,LPLOWAT); ! 196: } else { /* queue up some characters */ ! 197: iomove(tri->triw, cc, B_WRITE); ! 198: if ((tri->triw += cc) >= tri->tricbuf + LPSIZ) ! 199: tri->triw = tri->tricbuf; ! 200: tri->tricc += cc; ! 201: s = spl4(); ! 202: if ((tri->flag&LBUSY) == 0) ! 203: triintr(dev); ! 204: splx(s); ! 205: } ! 206: } ! 207: } ! 208: ! 209: ! 210: triintr(dev) ! 211: register dev; ! 212: { ! 213: register struct tri *tri; ! 214: register struct device *addr; ! 215: register c, cc; ! 216: ! 217: tri = &tritab[dev]; ! 218: addr = (struct device *)triinfo[dev]->ui_addr; ! 219: if ((addr->tricsr&DONE)==0) { ! 220: return; ! 221: } ! 222: tri->flag &= ~LBUSY; ! 223: if (addr->tricsr&ERRBIT) { ! 224: addr->tricsr = 0; ! 225: tri->flag &= ~LBUSY; ! 226: tri->flag |= ESLP; ! 227: return; ! 228: } ! 229: cc = 0; ! 230: while (addr->tricsr&DONE && (tri->tricc > 0)) { ! 231: addr->tribuf = *(tri->trir)++; ! 232: if (tri->trir == tri->tricbuf + LPSIZ) ! 233: tri->trir = tri->tricbuf; ! 234: tri->tricc--; ! 235: cc++; ! 236: } ! 237: if (cc) { ! 238: addr->tricsr |= IENABLE; ! 239: tri->flag |= LBUSY; ! 240: } ! 241: if (tri->tricc <= LPLOWAT && tri->flag&ASLP) { ! 242: tri->flag &= ~ASLP; ! 243: wakeup((caddr_t)tri); ! 244: } ! 245: } ! 246: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.