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