|
|
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.