xref: /original-bsd/sys/vax/uba/dn.c (revision a304ca22)
1 /*	dn.c	4.3	82/03/14	*/
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 	int	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	PWI	0100000		/* power indicate */
31 #define	ACR	040000		/* abandon call and retry */
32 #define	DLO	010000		/* data line occupied */
33 #define	DONE	0200		/* operation complete */
34 #define	IENABLE	0100		/* interrupt enable */
35 #define	DSS	040		/* data set status */
36 #define	PND	020		/* present next digit */
37 #define MAINT	010		/* maintenance mode */
38 #define	MENABLE	04		/* master enable */
39 #define	DPR	02		/* digit present */
40 #define	CRQ	01		/* call request */
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), so
52  * we take the "flags" value supplied by config as the number of devices
53  * attached (see dnintr).
54  */
55 dnprobe(reg)
56 	caddr_t reg;
57 {
58 	register int br, cvec;		/* value-result */
59 	register struct dndevice *dnaddr = (struct dndevice *)reg;
60 
61 #ifdef lint
62 	br = 0; cvec = br; br = cvec;
63 	dnintr(0);
64 #endif
65 
66 	/*
67 	 * If there's at least one dialer out there it better be
68 	 * at chassis 0.
69 	 */
70 	dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE;
71 	DELAY(5);
72 	dnaddr->dn_reg[0] = 0;
73 }
74 
75 dnattach(ui)
76 	struct uba_device *ui;
77 {
78 
79 	if (ui->ui_flags == 0)	/* no flags =>'s don't care */
80 		ui->ui_flags = 4;
81 	else if (ui->ui_flags > 4 || ui->ui_flags < 0) {
82 		printf("dn%d: bad flags value %d (disabled)\n", ui->ui_unit,
83 			ui->ui_flags);
84 		ui->ui_flags = 0;
85 		ui->ui_alive = 0;
86 	}
87 }
88 
89 /*ARGSUSED*/
90 dnopen(dev, flag)
91 	dev_t dev;
92 {
93 	register struct dndevice *dp;
94 	register int unit, *dnreg;
95 	register struct uba_device *ui;
96 	register short dialer;
97 
98 	if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 ||
99 	    ui->ui_alive == 0 || (dialer = DNREG(dev)) >= ui->ui_flags ||
100 	    ((dp = (struct dndevice *)ui->ui_addr)->dn_reg[dialer]&PWI)) {
101 		u.u_error = ENXIO;
102 		return;
103 	}
104 	dnreg = &(dp->dn_reg[dialer]);
105 	if (*dnreg&(DLO|CRQ)) {
106 		u.u_error = EBUSY;
107 		return;
108 	}
109 	dp->dn_reg[0] |= MENABLE;
110 	*dnreg = IENABLE|MENABLE|CRQ;
111 }
112 
113 /*ARGSUSED*/
114 dnclose(dev, flag)
115 	dev_t dev;
116 {
117 	register struct dndevice *dp;
118 
119 	dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr;
120 	dp->dn_reg[DNREG(dev)] = MENABLE;
121 }
122 
123 dnwrite(dev)
124 	dev_t dev;
125 {
126 	register int *dnreg, cc;
127 	register struct dndevice *dp;
128 	char digits[OBUFSIZ];
129 	register char *cp;
130 	extern lbolt;
131 
132 	dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr;
133 	dnreg = &(dp->dn_reg[DNREG(dev)]);
134 	cc = MIN(u.u_count, OBUFSIZ);
135 	cp = digits;
136 	iomove(cp, (unsigned)cc, B_WRITE);
137 	if (u.u_error)
138 		return;
139 	while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) {
140 		(void) spl4();
141 		if ((*dnreg&PND) == 0 || cc == 0)
142 			sleep((caddr_t)dnreg, DNPRI);
143 		else switch(*cp) {
144 
145 		case '-':
146 			sleep((caddr_t)&lbolt, DNPRI);
147 			sleep((caddr_t)&lbolt, DNPRI);
148 			break;
149 
150 		case 'f':
151 			*dnreg &= ~CRQ;
152 			sleep((caddr_t)&lbolt, DNPRI);
153 			*dnreg |= CRQ;
154 			break;
155 
156 		case '*': case ':':
157 			*cp = 012;
158 			goto dial;
159 
160 		case '#': case ';':
161 			*cp = 013;
162 			goto dial;
163 
164 		case 'e': case '<':
165 			*cp = 014;
166 			goto dial;
167 
168 		case 'w': case '=':
169 			*cp = 015;
170 			goto dial;
171 
172 		default:
173 			if (*cp < '0' || *cp > '9')
174 				break;
175 		dial:
176 			*dnreg = (*cp<<8)|IENABLE|MENABLE|DPR|CRQ;
177 			sleep((caddr_t)dnreg, DNPRI);
178 		}
179 		cp++, cc--;
180 		spl0();
181 	}
182 	if (*dnreg&(PWI|ACR))
183 		u.u_error = EIO;
184 }
185 
186 /*
187  * NOTE that the flags from the config file define the number
188  * of dialers attached to this controller.
189  */
190 dnintr(dev)
191 	dev_t dev;
192 {
193 	register int *basereg, *dnreg, *lastreg;
194 
195 	basereg = (int *)dninfo[dev]->ui_addr;
196 	*basereg &= ~MENABLE;
197 	lastreg = basereg+dninfo[dev]->ui_flags;
198 	for (dnreg = basereg; dnreg < lastreg; dnreg++)
199 		if (*dnreg&DONE) {
200 			*dnreg &= ~(DONE|DPR);
201 			wakeup((caddr_t)dnreg);
202 		}
203 	*basereg |= MENABLE;
204 }
205 #endif
206