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