1 /* dn.c 4.5 82/07/15 */ 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 u_short 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 CRQ 0x001 /* call request */ 31 #define DPR 0x002 /* digit present */ 32 #define MENABLE 0x004 /* master enable */ 33 #define MAINT 0x008 /* maintenance mode */ 34 #define PND 0x010 /* present next digit */ 35 #define DSS 0x020 /* data set status */ 36 #define IENABLE 0x040 /* interrupt enable */ 37 #define DONE 0x080 /* operation complete */ 38 #define DLO 0x1000 /* data line occupied */ 39 #define ACR 0x4000 /* abandon call and retry */ 40 #define PWI 0x8000 /* power indicate */ 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). 52 */ 53 dnprobe(reg) 54 caddr_t reg; 55 { 56 register int br, cvec; /* value-result, must be r11, r10 */ 57 register struct dndevice *dnaddr = (struct dndevice *)reg; 58 59 /* 60 * If there's at least one dialer out there it better be 61 * at chassis 0. 62 */ 63 dnaddr->dn_reg[0] = MENABLE|IENABLE|DONE; 64 DELAY(5); 65 dnaddr->dn_reg[0] = 0; 66 return (sizeof (struct dndevice)); 67 } 68 69 dnattach(ui) 70 struct uba_device *ui; 71 {} 72 73 /*ARGSUSED*/ 74 dnopen(dev, flag) 75 dev_t dev; 76 { 77 register struct dndevice *dp; 78 register u_short unit, *dnreg; 79 register struct uba_device *ui; 80 register short dialer; 81 82 if ((unit = DNUNIT(dev)) >= NDN || (ui = dninfo[unit]) == 0 || 83 ui->ui_alive == 0) { 84 u.u_error = ENXIO; 85 return; 86 } 87 dialer = DNREG(dev); 88 dp = (struct dndevice *)ui->ui_addr; 89 if (dp->dn_reg[dialer] & PWI) { 90 u.u_error = ENXIO; 91 return; 92 } 93 dnreg = &(dp->dn_reg[dialer]); 94 if (*dnreg&(DLO|CRQ)) { 95 u.u_error = EBUSY; 96 return; 97 } 98 dp->dn_reg[0] |= MENABLE; 99 *dnreg = IENABLE|MENABLE|CRQ; 100 } 101 102 /*ARGSUSED*/ 103 dnclose(dev, flag) 104 dev_t dev; 105 { 106 register struct dndevice *dp; 107 108 dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 109 dp->dn_reg[DNREG(dev)] = MENABLE; 110 } 111 112 dnwrite(dev) 113 dev_t dev; 114 { 115 register u_short *dnreg; 116 register int cc; 117 register struct dndevice *dp; 118 char buf[OBUFSIZ]; 119 register char *cp; 120 extern lbolt; 121 122 dp = (struct dndevice *)dninfo[DNUNIT(dev)]->ui_addr; 123 dnreg = &(dp->dn_reg[DNREG(dev)]); 124 cc = MIN(u.u_count, OBUFSIZ); 125 cp = buf; 126 iomove(cp, (unsigned)cc, B_WRITE); 127 if (u.u_error) 128 return; 129 while ((*dnreg & (PWI|ACR|DSS)) == 0 && cc >= 0) { 130 spl4(); 131 if ((*dnreg & PND) == 0 || cc == 0) 132 sleep((caddr_t)dnreg, DNPRI); 133 else switch(*cp) { 134 135 case '-': 136 sleep((caddr_t)&lbolt, DNPRI); 137 sleep((caddr_t)&lbolt, DNPRI); 138 break; 139 140 case 'f': 141 *dnreg &= ~CRQ; 142 sleep((caddr_t)&lbolt, DNPRI); 143 *dnreg |= CRQ; 144 break; 145 146 case '*': case ':': 147 *cp = 012; 148 goto dial; 149 150 case '#': case ';': 151 *cp = 013; 152 goto dial; 153 154 case 'e': case '<': 155 *cp = 014; 156 goto dial; 157 158 case 'w': case '=': 159 *cp = 015; 160 goto dial; 161 162 default: 163 if (*cp < '0' || *cp > '9') 164 break; 165 dial: 166 *dnreg = (*cp << 8) | (IENABLE|MENABLE|DPR|CRQ); 167 sleep((caddr_t)dnreg, DNPRI); 168 } 169 cp++, cc--; 170 spl0(); 171 } 172 if (*dnreg & (PWI|ACR)) 173 u.u_error = EIO; 174 } 175 176 dnintr(dev) 177 dev_t dev; 178 { 179 register u_short *basereg, *dnreg; 180 181 basereg = (u_short *)dninfo[dev]->ui_addr; 182 *basereg &= ~MENABLE; 183 for (dnreg = basereg; dnreg < basereg + 4; dnreg++) 184 if (*dnreg & DONE) { 185 *dnreg &= ~(DONE|DPR); 186 wakeup((caddr_t)dnreg); 187 } 188 *basereg |= MENABLE; 189 } 190 #endif 191