|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)dn.c 7.6 (Berkeley) 4/3/90 ! 7: */ ! 8: ! 9: #include "dn.h" ! 10: #if NDN > 0 ! 11: /* ! 12: * DN-11 ACU interface ! 13: */ ! 14: #include "machine/pte.h" ! 15: ! 16: #include "param.h" ! 17: #include "systm.h" ! 18: #include "user.h" ! 19: #include "buf.h" ! 20: #include "map.h" ! 21: #include "conf.h" ! 22: #include "uio.h" ! 23: ! 24: #include "ubavar.h" ! 25: ! 26: struct dndevice { ! 27: u_short dn_reg[4]; ! 28: }; ! 29: ! 30: struct uba_device *dninfo[NDN]; ! 31: int dnprobe(), dnattach(), dnintr(); ! 32: u_short dnstd[] = { 0175200, 0 }; ! 33: struct uba_driver dndriver = ! 34: { dnprobe, 0, dnattach, 0, dnstd, "dn", dninfo }; ! 35: ! 36: #define CRQ 0x001 /* call request */ ! 37: #define DPR 0x002 /* digit present */ ! 38: #define MENABLE 0x004 /* master enable */ ! 39: #define MAINT 0x008 /* maintenance mode */ ! 40: #define PND 0x010 /* present next digit */ ! 41: #define DSS 0x020 /* data set status */ ! 42: #define IENABLE 0x040 /* interrupt enable */ ! 43: #define DONE 0x080 /* operation complete */ ! 44: #define DLO 0x1000 /* data line occupied */ ! 45: #define ACR 0x4000 /* abandon call and retry */ ! 46: #define PWI 0x8000 /* power indicate */ ! 47: ! 48: #define DNPRI (PZERO+5) ! 49: #define DNUNIT(dev) (minor(dev)>>2) ! 50: #define DNREG(dev) ((dev)&03) ! 51: ! 52: #define OBUFSIZ 40 /* largest phone # dialer can handle */ ! 53: ! 54: /* ! 55: * There's no good way to determine the correct number of dialers attached ! 56: * to a single device (especially when dialers such as Vadic-821 MACS ! 57: * exist which can address four chassis, each with its own dialer). ! 58: */ ! 59: dnprobe(reg) ! 60: caddr_t reg; ! 61: { ! 62: register int br, cvec; /* value-result, must be r11, r10 */ ! 63: register struct dndevice *dnaddr = (struct dndevice *)reg; ! 64: ! 65: #ifdef lint ! 66: br = 0; cvec = 0; br = cvec; cvec = br; ! 67: dnintr(0); ! 68: #endif ! 69: /* ! 70: * If there's at least one dialer out there it better be ! 71: * at chassis 0. ! 72: */ ! 73: dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE; ! 74: DELAY(5); ! 75: dnaddr->dn_reg[0] = 0; ! 76: return (sizeof (struct dndevice)); ! 77: } ! 78: ! 79: /*ARGSUSED*/ ! 80: dnattach(ui) ! 81: struct uba_device *ui; ! 82: { ! 83: ! 84: } ! 85: ! 86: /*ARGSUSED*/ ! 87: dnopen(dev, flag) ! 88: dev_t dev; ! 89: int flag; ! 90: { ! 91: register struct dndevice *dp; ! 92: register u_short unit, *dnreg; ! 93: register struct uba_device *ui; ! 94: register short dialer; ! 95: ! 96: if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 || ! 97: ui->ui_alive == 0) ! 98: return (ENXIO); ! 99: dialer = DNREG(dev); ! 100: dp = (struct dndevice *)ui->ui_addr; ! 101: if (dp->dn_reg[dialer] & PWI) ! 102: return (ENXIO); ! 103: dnreg = &(dp->dn_reg[dialer]); ! 104: if (*dnreg&(DLO|CRQ)) ! 105: return (EBUSY); ! 106: dp->dn_reg[0] |= MENABLE; ! 107: *dnreg = IENABLE|MENABLE|CRQ; ! 108: return (0); ! 109: } ! 110: ! 111: /*ARGSUSED*/ ! 112: dnclose(dev, flag) ! 113: dev_t dev; ! 114: { ! 115: register struct dndevice *dp; ! 116: ! 117: dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; ! 118: dp->dn_reg[DNREG(dev)] = MENABLE; ! 119: return (0); ! 120: } ! 121: ! 122: dnwrite(dev, uio) ! 123: dev_t dev; ! 124: struct uio *uio; ! 125: { ! 126: register u_short *dnreg; ! 127: register int cc; ! 128: register struct dndevice *dp; ! 129: char obuf[OBUFSIZ]; ! 130: register char *cp; ! 131: extern lbolt; ! 132: int error; ! 133: ! 134: dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; ! 135: dnreg = &(dp->dn_reg[DNREG(dev)]); ! 136: cc = MIN(uio->uio_resid, OBUFSIZ); ! 137: cp = obuf; ! 138: error = uiomove(cp, cc, uio); ! 139: if (error) ! 140: return (error); ! 141: while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0 && error == 0) { ! 142: (void) spl4(); ! 143: if ((*dnreg & PND) == 0 || cc == 0) ! 144: error = tsleep((caddr_t)dnreg, DNPRI | PCATCH, ! 145: devout, 0); ! 146: else switch(*cp) { ! 147: ! 148: case '-': ! 149: error = tsleep((caddr_t)&lbolt, DNPRI | PCATCH, ! 150: devout, 0); ! 151: if (error == 0) ! 152: error = tsleep((caddr_t)&lbolt, DNPRI | PCATCH, ! 153: devout, 0); ! 154: break; ! 155: ! 156: case 'f': ! 157: *dnreg &= ~CRQ; ! 158: error = tsleep((caddr_t)&lbolt, DNPRI | PCATCH, ! 159: devout, 0); ! 160: *dnreg |= CRQ; ! 161: break; ! 162: ! 163: case '*': case ':': ! 164: *cp = 012; ! 165: goto dial; ! 166: ! 167: case '#': case ';': ! 168: *cp = 013; ! 169: goto dial; ! 170: ! 171: case 'e': case '<': ! 172: *cp = 014; ! 173: goto dial; ! 174: ! 175: case 'w': case '=': ! 176: *cp = 015; ! 177: goto dial; ! 178: ! 179: default: ! 180: if (*cp < '0' || *cp > '9') ! 181: break; ! 182: dial: ! 183: *dnreg = (*cp << 8) | (IENABLE|MENABLE|DPR|CRQ); ! 184: error = tsleep((caddr_t)dnreg, DNPRI | PCATCH, ! 185: devout, 0); ! 186: } ! 187: cp++, cc--; ! 188: spl0(); ! 189: } ! 190: if (error) ! 191: return (error); ! 192: if (*dnreg & (PWI|ACR)) ! 193: return (EIO); ! 194: return (0); ! 195: } ! 196: ! 197: dnintr(dev) ! 198: dev_t dev; ! 199: { ! 200: register u_short *basereg, *dnreg; ! 201: ! 202: basereg = (u_short *)dninfo[dev]->ui_addr; ! 203: *basereg &= ~MENABLE; ! 204: for (dnreg = basereg; dnreg < basereg + 4; dnreg++) ! 205: if (*dnreg & DONE) { ! 206: *dnreg &= ~(DONE|DPR); ! 207: wakeup((caddr_t)dnreg); ! 208: } ! 209: *basereg |= MENABLE; ! 210: } ! 211: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.