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