1*8568Sroot /* dn.c 4.9 82/10/17 */ 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" 184737Swnj 198474Sroot #include "../vaxuba/ubavar.h" 208474Sroot 214737Swnj struct dndevice { 226593Ssam u_short dn_reg[4]; 234737Swnj }; 244737Swnj 254737Swnj struct uba_device *dninfo[NDN]; 264737Swnj int dnprobe(), dnattach(); 274737Swnj u_short dnstd[] = { 0175200 }; 284737Swnj struct uba_driver dndriver = 294737Swnj { dnprobe, 0, dnattach, 0, dnstd, "dn", dninfo }; 304737Swnj 316593Ssam #define CRQ 0x001 /* call request */ 326593Ssam #define DPR 0x002 /* digit present */ 336593Ssam #define MENABLE 0x004 /* master enable */ 346593Ssam #define MAINT 0x008 /* maintenance mode */ 356593Ssam #define PND 0x010 /* present next digit */ 366593Ssam #define DSS 0x020 /* data set status */ 376593Ssam #define IENABLE 0x040 /* interrupt enable */ 386593Ssam #define DONE 0x080 /* operation complete */ 396593Ssam #define DLO 0x1000 /* data line occupied */ 406593Ssam #define ACR 0x4000 /* abandon call and retry */ 416593Ssam #define PWI 0x8000 /* power indicate */ 424737Swnj 434737Swnj #define DNPRI (PZERO+5) 444737Swnj #define DNUNIT(dev) (minor(dev)>>2) 454737Swnj #define DNREG(dev) ((dev)&03) 464737Swnj 474737Swnj #define OBUFSIZ 40 /* largest phone # dialer can handle */ 484737Swnj 494737Swnj /* 504737Swnj * There's no good way to determine the correct number of dialers attached 514933Swnj * to a single device (especially when dialers such as Vadic-821 MACS 526593Ssam * exist which can address four chassis, each with its own dialer). 534737Swnj */ 544737Swnj dnprobe(reg) 554737Swnj caddr_t reg; 564737Swnj { 576593Ssam register int br, cvec; /* value-result, must be r11, r10 */ 584737Swnj register struct dndevice *dnaddr = (struct dndevice *)reg; 594737Swnj 604737Swnj /* 614737Swnj * If there's at least one dialer out there it better be 626593Ssam * at chassis 0. 634737Swnj */ 644737Swnj dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE; 654737Swnj DELAY(5); 664737Swnj dnaddr->dn_reg[0] = 0; 677409Skre return (sizeof (struct dndevice)); 684737Swnj } 694737Swnj 704737Swnj dnattach(ui) 714737Swnj struct uba_device *ui; 72*8568Sroot { 734933Swnj 74*8568Sroot } 75*8568Sroot 764737Swnj /*ARGSUSED*/ 774737Swnj dnopen(dev, flag) 784737Swnj dev_t dev; 794737Swnj { 804737Swnj register struct dndevice *dp; 816593Ssam register u_short unit, *dnreg; 824737Swnj register struct uba_device *ui; 834737Swnj register short dialer; 844737Swnj 854737Swnj if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 || 86*8568Sroot ui->ui_alive == 0) 87*8568Sroot return (ENXIO); 886593Ssam dialer = DNREG(dev); 896593Ssam dp = (struct dndevice *)ui->ui_addr; 90*8568Sroot if (dp->dn_reg[dialer] & PWI) 91*8568Sroot return (ENXIO); 924737Swnj dnreg = &(dp->dn_reg[dialer]); 93*8568Sroot if (*dnreg&(DLO|CRQ)) 94*8568Sroot return (EBUSY); 954737Swnj dp->dn_reg[0] |= MENABLE; 964737Swnj *dnreg = IENABLE|MENABLE|CRQ; 97*8568Sroot return (0); 984737Swnj } 994737Swnj 1004737Swnj /*ARGSUSED*/ 1014737Swnj dnclose(dev, flag) 1024737Swnj dev_t dev; 1034737Swnj { 1044737Swnj register struct dndevice *dp; 1054737Swnj 1064737Swnj dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 1074737Swnj dp->dn_reg[DNREG(dev)] = MENABLE; 1084737Swnj } 1094737Swnj 1107833Sroot dnwrite(dev, uio) 1114737Swnj dev_t dev; 1127833Sroot struct uio *uio; 1134737Swnj { 1146593Ssam register u_short *dnreg; 1156593Ssam register int cc; 1164737Swnj register struct dndevice *dp; 1176593Ssam char buf[OBUFSIZ]; 1184737Swnj register char *cp; 1194737Swnj extern lbolt; 1208491Sroot int error; 1214737Swnj 1224737Swnj dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 1234737Swnj dnreg = &(dp->dn_reg[DNREG(dev)]); 1247833Sroot cc = MIN(uio->uio_resid, OBUFSIZ); 1256593Ssam cp = buf; 1268491Sroot error = uiomove(cp, (unsigned)cc, UIO_WRITE, uio); 1278491Sroot if (error) 1288491Sroot return (error); 1294737Swnj while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) { 1306593Ssam spl4(); 1316593Ssam if ((*dnreg & PND) == 0 || cc == 0) 1324737Swnj sleep((caddr_t)dnreg, DNPRI); 1334737Swnj else switch(*cp) { 1344737Swnj 1354737Swnj case '-': 1364737Swnj sleep((caddr_t)&lbolt, DNPRI); 1374737Swnj sleep((caddr_t)&lbolt, DNPRI); 1384737Swnj break; 1394737Swnj 1404737Swnj case 'f': 1414737Swnj *dnreg &= ~CRQ; 1424737Swnj sleep((caddr_t)&lbolt, DNPRI); 1434737Swnj *dnreg |= CRQ; 1444737Swnj break; 1454737Swnj 1464737Swnj case '*': case ':': 1474737Swnj *cp = 012; 1484737Swnj goto dial; 1494737Swnj 1504737Swnj case '#': case ';': 1514737Swnj *cp = 013; 1524737Swnj goto dial; 1534737Swnj 1544737Swnj case 'e': case '<': 1554737Swnj *cp = 014; 1564737Swnj goto dial; 1574737Swnj 1584737Swnj case 'w': case '=': 1594737Swnj *cp = 015; 1604737Swnj goto dial; 1614737Swnj 1624737Swnj default: 1634737Swnj if (*cp < '0' || *cp > '9') 1644737Swnj break; 1654737Swnj dial: 1666593Ssam *dnreg = (*cp << 8) | (IENABLE|MENABLE|DPR|CRQ); 1674737Swnj sleep((caddr_t)dnreg, DNPRI); 1684737Swnj } 1694737Swnj cp++, cc--; 1704737Swnj spl0(); 1714737Swnj } 1726593Ssam if (*dnreg & (PWI|ACR)) 1738491Sroot return (EIO); 1748491Sroot return (0); 1754737Swnj } 1764737Swnj 1774737Swnj dnintr(dev) 1784737Swnj dev_t dev; 1794737Swnj { 1806593Ssam register u_short *basereg, *dnreg; 1814737Swnj 1826593Ssam basereg = (u_short *)dninfo[dev]->ui_addr; 1834737Swnj *basereg &= ~MENABLE; 1846593Ssam for (dnreg = basereg; dnreg < basereg + 4; dnreg++) 1856593Ssam if (*dnreg & DONE) { 1864737Swnj *dnreg &= ~(DONE|DPR); 1874737Swnj wakeup((caddr_t)dnreg); 1884737Swnj } 1894737Swnj *basereg |= MENABLE; 1904737Swnj } 1914737Swnj #endif 192