1 /* dn.c 4.13 82/10/21 */ 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/conf.h" 17 #include "../h/ioctl.h" 18 #include "../h/uio.h" 19 20 #include "../vaxuba/ubavar.h" 21 22 struct dndevice { 23 u_short dn_reg[4]; 24 }; 25 26 struct uba_device *dninfo[NDN]; 27 int dnprobe(), dnattach(), dnintr(); 28 u_short dnstd[] = { 0175200 }; 29 struct uba_driver dndriver = 30 { dnprobe, 0, dnattach, 0, dnstd, "dn", dninfo }; 31 32 #define CRQ 0x001 /* call request */ 33 #define DPR 0x002 /* digit present */ 34 #define MENABLE 0x004 /* master enable */ 35 #define MAINT 0x008 /* maintenance mode */ 36 #define PND 0x010 /* present next digit */ 37 #define DSS 0x020 /* data set status */ 38 #define IENABLE 0x040 /* interrupt enable */ 39 #define DONE 0x080 /* operation complete */ 40 #define DLO 0x1000 /* data line occupied */ 41 #define ACR 0x4000 /* abandon call and retry */ 42 #define PWI 0x8000 /* power indicate */ 43 44 #define DNPRI (PZERO+5) 45 #define DNUNIT(dev) (minor(dev)>>2) 46 #define DNREG(dev) ((dev)&03) 47 48 #define OBUFSIZ 40 /* largest phone # dialer can handle */ 49 50 /* 51 * There's no good way to determine the correct number of dialers attached 52 * to a single device (especially when dialers such as Vadic-821 MACS 53 * exist which can address four chassis, each with its own dialer). 54 */ 55 dnprobe(reg) 56 caddr_t reg; 57 { 58 register int br, cvec; /* value-result, must be r11, r10 */ 59 register struct dndevice *dnaddr = (struct dndevice *)reg; 60 61 #ifdef lint 62 br = 0; cvec = 0; br = cvec; cvec = br; 63 dnintr(0); 64 #endif 65 /* 66 * If there's at least one dialer out there it better be 67 * at chassis 0. 68 */ 69 dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE; 70 DELAY(5); 71 dnaddr->dn_reg[0] = 0; 72 return (sizeof (struct dndevice)); 73 } 74 75 /*ARGSUSED*/ 76 dnattach(ui) 77 struct uba_device *ui; 78 { 79 80 } 81 82 /*ARGSUSED*/ 83 dnopen(dev, flag) 84 dev_t dev; 85 int flag; 86 { 87 register struct dndevice *dp; 88 register u_short unit, *dnreg; 89 register struct uba_device *ui; 90 register short dialer; 91 92 if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 || 93 ui->ui_alive == 0) 94 return (ENXIO); 95 dialer = DNREG(dev); 96 dp = (struct dndevice *)ui->ui_addr; 97 if (dp->dn_reg[dialer] & PWI) 98 return (ENXIO); 99 dnreg = &(dp->dn_reg[dialer]); 100 if (*dnreg&(DLO|CRQ)) 101 return (EBUSY); 102 dp->dn_reg[0] |= MENABLE; 103 *dnreg = IENABLE|MENABLE|CRQ; 104 return (0); 105 } 106 107 /*ARGSUSED*/ 108 dnclose(dev, flag) 109 dev_t dev; 110 { 111 register struct dndevice *dp; 112 113 dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 114 dp->dn_reg[DNREG(dev)] = MENABLE; 115 } 116 117 dnwrite(dev, uio) 118 dev_t dev; 119 struct uio *uio; 120 { 121 register u_short *dnreg; 122 register int cc; 123 register struct dndevice *dp; 124 char obuf[OBUFSIZ]; 125 register char *cp; 126 extern lbolt; 127 int error; 128 129 dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 130 dnreg = &(dp->dn_reg[DNREG(dev)]); 131 cc = MIN(uio->uio_resid, OBUFSIZ); 132 cp = obuf; 133 error = uiomove(cp, cc, UIO_WRITE, uio); 134 if (error) 135 return (error); 136 while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) { 137 (void) spl4(); 138 if ((*dnreg & PND) == 0 || cc == 0) 139 sleep((caddr_t)dnreg, DNPRI); 140 else switch(*cp) { 141 142 case '-': 143 sleep((caddr_t)&lbolt, DNPRI); 144 sleep((caddr_t)&lbolt, DNPRI); 145 break; 146 147 case 'f': 148 *dnreg &= ~CRQ; 149 sleep((caddr_t)&lbolt, DNPRI); 150 *dnreg |= CRQ; 151 break; 152 153 case '*': case ':': 154 *cp = 012; 155 goto dial; 156 157 case '#': case ';': 158 *cp = 013; 159 goto dial; 160 161 case 'e': case '<': 162 *cp = 014; 163 goto dial; 164 165 case 'w': case '=': 166 *cp = 015; 167 goto dial; 168 169 default: 170 if (*cp < '0' || *cp > '9') 171 break; 172 dial: 173 *dnreg = (*cp << 8) | (IENABLE|MENABLE|DPR|CRQ); 174 sleep((caddr_t)dnreg, DNPRI); 175 } 176 cp++, cc--; 177 spl0(); 178 } 179 if (*dnreg & (PWI|ACR)) 180 return (EIO); 181 return (0); 182 } 183 184 dnintr(dev) 185 dev_t dev; 186 { 187 register u_short *basereg, *dnreg; 188 189 basereg = (u_short *)dninfo[dev]->ui_addr; 190 *basereg &= ~MENABLE; 191 for (dnreg = basereg; dnreg < basereg + 4; dnreg++) 192 if (*dnreg & DONE) { 193 *dnreg &= ~(DONE|DPR); 194 wakeup((caddr_t)dnreg); 195 } 196 *basereg |= MENABLE; 197 } 198 #endif 199