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