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