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