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