1*8779Sroot /* dn.c 4.13 82/10/21 */ 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/conf.h" 174737Swnj #include "../h/ioctl.h" 188608Sroot #include "../h/uio.h" 194737Swnj 208474Sroot #include "../vaxuba/ubavar.h" 218474Sroot 224737Swnj struct dndevice { 236593Ssam u_short dn_reg[4]; 244737Swnj }; 254737Swnj 264737Swnj struct uba_device *dninfo[NDN]; 27*8779Sroot int dnprobe(), dnattach(), dnintr(); 284737Swnj u_short dnstd[] = { 0175200 }; 294737Swnj struct uba_driver dndriver = 304737Swnj { dnprobe, 0, dnattach, 0, dnstd, "dn", dninfo }; 314737Swnj 326593Ssam #define CRQ 0x001 /* call request */ 336593Ssam #define DPR 0x002 /* digit present */ 346593Ssam #define MENABLE 0x004 /* master enable */ 356593Ssam #define MAINT 0x008 /* maintenance mode */ 366593Ssam #define PND 0x010 /* present next digit */ 376593Ssam #define DSS 0x020 /* data set status */ 386593Ssam #define IENABLE 0x040 /* interrupt enable */ 396593Ssam #define DONE 0x080 /* operation complete */ 406593Ssam #define DLO 0x1000 /* data line occupied */ 416593Ssam #define ACR 0x4000 /* abandon call and retry */ 426593Ssam #define PWI 0x8000 /* power indicate */ 434737Swnj 444737Swnj #define DNPRI (PZERO+5) 454737Swnj #define DNUNIT(dev) (minor(dev)>>2) 464737Swnj #define DNREG(dev) ((dev)&03) 474737Swnj 484737Swnj #define OBUFSIZ 40 /* largest phone # dialer can handle */ 494737Swnj 504737Swnj /* 514737Swnj * There's no good way to determine the correct number of dialers attached 524933Swnj * to a single device (especially when dialers such as Vadic-821 MACS 536593Ssam * exist which can address four chassis, each with its own dialer). 544737Swnj */ 554737Swnj dnprobe(reg) 564737Swnj caddr_t reg; 574737Swnj { 586593Ssam register int br, cvec; /* value-result, must be r11, r10 */ 594737Swnj register struct dndevice *dnaddr = (struct dndevice *)reg; 604737Swnj 618608Sroot #ifdef lint 628608Sroot br = 0; cvec = 0; br = cvec; cvec = br; 63*8779Sroot dnintr(0); 648608Sroot #endif 654737Swnj /* 664737Swnj * If there's at least one dialer out there it better be 678608Sroot * at chassis 0. 684737Swnj */ 694737Swnj dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE; 704737Swnj DELAY(5); 714737Swnj dnaddr->dn_reg[0] = 0; 727409Skre return (sizeof (struct dndevice)); 734737Swnj } 744737Swnj 758608Sroot /*ARGSUSED*/ 764737Swnj dnattach(ui) 774737Swnj struct uba_device *ui; 788568Sroot { 794933Swnj 808568Sroot } 818568Sroot 824737Swnj /*ARGSUSED*/ 834737Swnj dnopen(dev, flag) 844737Swnj dev_t dev; 858647Sroot int flag; 864737Swnj { 874737Swnj register struct dndevice *dp; 886593Ssam register u_short unit, *dnreg; 894737Swnj register struct uba_device *ui; 904737Swnj register short dialer; 914737Swnj 924737Swnj if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 || 938568Sroot ui->ui_alive == 0) 948568Sroot return (ENXIO); 956593Ssam dialer = DNREG(dev); 966593Ssam dp = (struct dndevice *)ui->ui_addr; 978568Sroot if (dp->dn_reg[dialer] & PWI) 988568Sroot return (ENXIO); 994737Swnj dnreg = &(dp->dn_reg[dialer]); 1008568Sroot if (*dnreg&(DLO|CRQ)) 1018568Sroot return (EBUSY); 1024737Swnj dp->dn_reg[0] |= MENABLE; 1034737Swnj *dnreg = IENABLE|MENABLE|CRQ; 1048568Sroot return (0); 1054737Swnj } 1064737Swnj 1074737Swnj /*ARGSUSED*/ 1084737Swnj dnclose(dev, flag) 1094737Swnj dev_t dev; 1104737Swnj { 1114737Swnj register struct dndevice *dp; 1124737Swnj 1134737Swnj dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 1144737Swnj dp->dn_reg[DNREG(dev)] = MENABLE; 1154737Swnj } 1164737Swnj 1177833Sroot dnwrite(dev, uio) 1184737Swnj dev_t dev; 1197833Sroot struct uio *uio; 1204737Swnj { 1216593Ssam register u_short *dnreg; 1226593Ssam register int cc; 1234737Swnj register struct dndevice *dp; 1248608Sroot char obuf[OBUFSIZ]; 1254737Swnj register char *cp; 1264737Swnj extern lbolt; 1278491Sroot int error; 1284737Swnj 1294737Swnj dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 1304737Swnj dnreg = &(dp->dn_reg[DNREG(dev)]); 1317833Sroot cc = MIN(uio->uio_resid, OBUFSIZ); 1328608Sroot cp = obuf; 1338647Sroot error = uiomove(cp, cc, UIO_WRITE, uio); 1348491Sroot if (error) 1358491Sroot return (error); 1364737Swnj while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) { 1378715Sroot (void) spl4(); 1386593Ssam if ((*dnreg & PND) == 0 || cc == 0) 1394737Swnj sleep((caddr_t)dnreg, DNPRI); 1404737Swnj else switch(*cp) { 1414737Swnj 1424737Swnj case '-': 1434737Swnj sleep((caddr_t)&lbolt, DNPRI); 1444737Swnj sleep((caddr_t)&lbolt, DNPRI); 1454737Swnj break; 1464737Swnj 1474737Swnj case 'f': 1484737Swnj *dnreg &= ~CRQ; 1494737Swnj sleep((caddr_t)&lbolt, DNPRI); 1504737Swnj *dnreg |= CRQ; 1514737Swnj break; 1524737Swnj 1534737Swnj case '*': case ':': 1544737Swnj *cp = 012; 1554737Swnj goto dial; 1564737Swnj 1574737Swnj case '#': case ';': 1584737Swnj *cp = 013; 1594737Swnj goto dial; 1604737Swnj 1614737Swnj case 'e': case '<': 1624737Swnj *cp = 014; 1634737Swnj goto dial; 1644737Swnj 1654737Swnj case 'w': case '=': 1664737Swnj *cp = 015; 1674737Swnj goto dial; 1684737Swnj 1694737Swnj default: 1704737Swnj if (*cp < '0' || *cp > '9') 1714737Swnj break; 1724737Swnj dial: 1736593Ssam *dnreg = (*cp << 8) | (IENABLE|MENABLE|DPR|CRQ); 1744737Swnj sleep((caddr_t)dnreg, DNPRI); 1754737Swnj } 1764737Swnj cp++, cc--; 1774737Swnj spl0(); 1784737Swnj } 1796593Ssam if (*dnreg & (PWI|ACR)) 1808491Sroot return (EIO); 1818491Sroot return (0); 1824737Swnj } 1834737Swnj 1844737Swnj dnintr(dev) 1854737Swnj dev_t dev; 1864737Swnj { 1876593Ssam register u_short *basereg, *dnreg; 1884737Swnj 1896593Ssam basereg = (u_short *)dninfo[dev]->ui_addr; 1904737Swnj *basereg &= ~MENABLE; 1916593Ssam for (dnreg = basereg; dnreg < basereg + 4; dnreg++) 1926593Ssam if (*dnreg & DONE) { 1934737Swnj *dnreg &= ~(DONE|DPR); 1944737Swnj wakeup((caddr_t)dnreg); 1954737Swnj } 1964737Swnj *basereg |= MENABLE; 1974737Swnj } 1984737Swnj #endif 199