xref: /csrg-svn/sys/vax/uba/dn.c (revision 4933)
1*4933Swnj /*	dn.c	4.2	81/11/18	*/
24737Swnj 
34737Swnj #include "dn.h"
44737Swnj #if NDN > 0
54737Swnj /*
64737Swnj  * DN-11 ACU interface
74737Swnj  */
84737Swnj 
94737Swnj #include "../h/param.h"
104737Swnj #include "../h/systm.h"
114737Swnj #include "../h/dir.h"
124737Swnj #include "../h/user.h"
134737Swnj #include "../h/buf.h"
144737Swnj #include "../h/map.h"
154737Swnj #include "../h/pte.h"
164737Swnj #include "../h/ubavar.h"
174737Swnj #include "../h/conf.h"
184737Swnj #include "../h/ioctl.h"
194737Swnj 
204737Swnj struct dndevice {
214737Swnj 	int	dn_reg[4];
224737Swnj };
234737Swnj 
244737Swnj struct uba_device *dninfo[NDN];
254737Swnj int dnprobe(), dnattach();
264737Swnj u_short dnstd[] = { 0175200 };
274737Swnj struct uba_driver dndriver =
284737Swnj 	{ dnprobe, 0, dnattach, 0, dnstd, "dn", dninfo };
294737Swnj 
304737Swnj #define	PWI	0100000		/* power indicate */
314737Swnj #define	ACR	040000		/* abandon call and retry */
324737Swnj #define	DLO	010000		/* data line occupied */
334737Swnj #define	DONE	0200		/* operation complete */
344737Swnj #define	IENABLE	0100		/* interrupt enable */
354737Swnj #define	DSS	040		/* data set status */
364737Swnj #define	PND	020		/* present next digit */
374737Swnj #define MAINT	010		/* maintenance mode */
384737Swnj #define	MENABLE	04		/* master enable */
394737Swnj #define	DPR	02		/* digit present */
404737Swnj #define	CRQ	01		/* call request */
414737Swnj 
424737Swnj #define	DNPRI	(PZERO+5)
434737Swnj #define DNUNIT(dev)	(minor(dev)>>2)
444737Swnj #define DNREG(dev)	((dev)&03)
454737Swnj 
464737Swnj #define OBUFSIZ	40		/* largest phone # dialer can handle */
474737Swnj 
484737Swnj /*
494737Swnj  * There's no good way to determine the correct number of dialers attached
50*4933Swnj  * to a single device (especially when dialers such as Vadic-821 MACS
51*4933Swnj  * exist which can address four chassis, each with its own dialer), so
52*4933Swnj  * we take the "flags" value supplied by config as the number of devices
53*4933Swnj  * attached (see dnintr).
544737Swnj  */
554737Swnj dnprobe(reg)
564737Swnj 	caddr_t reg;
574737Swnj {
58*4933Swnj 	register int br, cvec;		/* value-result */
594737Swnj 	register struct dndevice *dnaddr = (struct dndevice *)reg;
604737Swnj 
61*4933Swnj #ifdef lint
62*4933Swnj 	br = 0; cvec = br; br = cvec;
63*4933Swnj 	dnintr(0);
64*4933Swnj #endif
65*4933Swnj 
664737Swnj 	/*
674737Swnj 	 * If there's at least one dialer out there it better be
68*4933Swnj 	 * at chassis 0.
694737Swnj 	 */
704737Swnj 	dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE;
714737Swnj 	DELAY(5);
724737Swnj 	dnaddr->dn_reg[0] = 0;
734737Swnj }
744737Swnj 
754737Swnj dnattach(ui)
764737Swnj 	struct uba_device *ui;
774737Swnj {
78*4933Swnj 
794737Swnj 	if (ui->ui_flags == 0)	/* no flags =>'s don't care */
804737Swnj 		ui->ui_flags = 4;
814737Swnj 	else if (ui->ui_flags > 4 || ui->ui_flags < 0) {
824737Swnj 		printf("dn%d: bad flags value %d (disabled)\n", ui->ui_unit,
834737Swnj 			ui->ui_flags);
844737Swnj 		ui->ui_flags = 0;
854737Swnj 		ui->ui_alive = 0;
864737Swnj 	}
874737Swnj }
884737Swnj 
894737Swnj /*ARGSUSED*/
904737Swnj dnopen(dev, flag)
914737Swnj 	dev_t dev;
924737Swnj {
934737Swnj 	register struct dndevice *dp;
944737Swnj 	register int unit, *dnreg;
954737Swnj 	register struct uba_device *ui;
964737Swnj 	register short dialer;
974737Swnj 
984737Swnj 	if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 ||
994737Swnj 	    ui->ui_alive == 0 || (dialer = DNREG(dev)) >= ui->ui_flags ||
1004737Swnj 	    ((dp = (struct dndevice *)ui->ui_addr)->dn_reg[dialer]&PWI)) {
1014737Swnj 		u.u_error = ENXIO;
1024737Swnj 		return;
1034737Swnj 	}
1044737Swnj 	dnreg = &(dp->dn_reg[dialer]);
1054737Swnj 	if (*dnreg&(DLO|CRQ)) {
1064737Swnj 		u.u_error = EBUSY;
1074737Swnj 		return;
1084737Swnj 	}
1094737Swnj 	dp->dn_reg[0] |= MENABLE;
1104737Swnj 	*dnreg = IENABLE|MENABLE|CRQ;
1114737Swnj }
1124737Swnj 
1134737Swnj /*ARGSUSED*/
1144737Swnj dnclose(dev, flag)
1154737Swnj 	dev_t dev;
1164737Swnj {
1174737Swnj 	register struct dndevice *dp;
1184737Swnj 
1194737Swnj 	dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr;
1204737Swnj 	dp->dn_reg[DNREG(dev)] = MENABLE;
1214737Swnj }
1224737Swnj 
1234737Swnj dnwrite(dev)
1244737Swnj 	dev_t dev;
1254737Swnj {
1264737Swnj 	register int *dnreg, cc;
1274737Swnj 	register struct dndevice *dp;
1284737Swnj 	char buf[OBUFSIZ];
1294737Swnj 	register char *cp;
1304737Swnj 	extern lbolt;
1314737Swnj 
1324737Swnj 	dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr;
1334737Swnj 	dnreg = &(dp->dn_reg[DNREG(dev)]);
1344737Swnj 	cc = MIN(u.u_count, OBUFSIZ);
1354737Swnj 	cp = buf;
1364737Swnj 	iomove(cp, (unsigned)cc, B_WRITE);
1374737Swnj 	if (u.u_error)
1384737Swnj 		return;
1394737Swnj 	while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) {
1404737Swnj 		spl4();
1414737Swnj 		if ((*dnreg&PND) == 0 || cc == 0)
1424737Swnj 			sleep((caddr_t)dnreg, DNPRI);
1434737Swnj 		else switch(*cp) {
1444737Swnj 
1454737Swnj 		case '-':
1464737Swnj 			sleep((caddr_t)&lbolt, DNPRI);
1474737Swnj 			sleep((caddr_t)&lbolt, DNPRI);
1484737Swnj 			break;
1494737Swnj 
1504737Swnj 		case 'f':
1514737Swnj 			*dnreg &= ~CRQ;
1524737Swnj 			sleep((caddr_t)&lbolt, DNPRI);
1534737Swnj 			*dnreg |= CRQ;
1544737Swnj 			break;
1554737Swnj 
1564737Swnj 		case '*': case ':':
1574737Swnj 			*cp = 012;
1584737Swnj 			goto dial;
1594737Swnj 
1604737Swnj 		case '#': case ';':
1614737Swnj 			*cp = 013;
1624737Swnj 			goto dial;
1634737Swnj 
1644737Swnj 		case 'e': case '<':
1654737Swnj 			*cp = 014;
1664737Swnj 			goto dial;
1674737Swnj 
1684737Swnj 		case 'w': case '=':
1694737Swnj 			*cp = 015;
1704737Swnj 			goto dial;
1714737Swnj 
1724737Swnj 		default:
1734737Swnj 			if (*cp < '0' || *cp > '9')
1744737Swnj 				break;
1754737Swnj 		dial:
1764737Swnj 			*dnreg = (*cp<<8)|IENABLE|MENABLE|DPR|CRQ;
1774737Swnj 			sleep((caddr_t)dnreg, DNPRI);
1784737Swnj 		}
1794737Swnj 		cp++, cc--;
1804737Swnj 		spl0();
1814737Swnj 	}
1824737Swnj 	if (*dnreg&(PWI|ACR))
1834737Swnj 		u.u_error = EIO;
1844737Swnj }
1854737Swnj 
1864737Swnj /*
1874737Swnj  * NOTE that the flags from the config file define the number
188*4933Swnj  * of dialers attached to this controller.
1894737Swnj  */
1904737Swnj dnintr(dev)
1914737Swnj 	dev_t dev;
1924737Swnj {
1934737Swnj 	register int *basereg, *dnreg, *lastreg;
1944737Swnj 
1954737Swnj 	basereg = (int *)dninfo[dev]->ui_addr;
1964737Swnj 	*basereg &= ~MENABLE;
1974737Swnj 	lastreg = basereg+dninfo[dev]->ui_flags;
1984737Swnj 	for (dnreg = basereg; dnreg < lastreg; dnreg++)
1994737Swnj 		if (*dnreg&DONE) {
2004737Swnj 			*dnreg &= ~(DONE|DPR);
2014737Swnj 			wakeup((caddr_t)dnreg);
2024737Swnj 		}
2034737Swnj 	*basereg |= MENABLE;
2044737Swnj }
2054737Swnj #endif
206