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