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