1*17Sbill /* dz.c 3.1 10/14/12 */ 2*17Sbill 3*17Sbill /* 4*17Sbill * DZ-11 Driver 5*17Sbill */ 6*17Sbill #include "../h/param.h" 7*17Sbill #include "../h/systm.h" 8*17Sbill #include "../h/tty.h" 9*17Sbill #include "../h/dir.h" 10*17Sbill #include "../h/user.h" 11*17Sbill #include "../h/map.h" 12*17Sbill #include "../h/pte.h" 13*17Sbill #include "../h/uba.h" 14*17Sbill #include "../h/conf.h" 15*17Sbill #include "../h/pdma.h" 16*17Sbill 17*17Sbill #define DZADDR (UBA0_DEV + 0160100) 18*17Sbill #ifdef ERNIE 19*17Sbill #define NDZ (3*8) 20*17Sbill #else 21*17Sbill #define NDZ (8) 22*17Sbill #endif 23*17Sbill 24*17Sbill #define BITS7 020 25*17Sbill #define BITS8 030 26*17Sbill #define TWOSB 040 27*17Sbill #define PENABLE 0100 28*17Sbill #define OPAR 0200 29*17Sbill #define MSE 040 /* Master Scan Enable */ 30*17Sbill #define RIE 0100 /* Receiver Interrupt Enable */ 31*17Sbill #define TIE 040000 /* Transmit interrupt enable */ 32*17Sbill #define DZ_IEN (MSE+RIE+TIE) 33*17Sbill #define PERROR 010000 34*17Sbill #define FRERROR 020000 35*17Sbill #define SSPEED 7 /* std speed = 300 baud */ 36*17Sbill 37*17Sbill 38*17Sbill #define dzlpr dzrbuf 39*17Sbill #define dzmsr dzbrk 40*17Sbill #define ON 1 41*17Sbill #define OFF 0 42*17Sbill 43*17Sbill int dzstart(); 44*17Sbill int dzxint(); 45*17Sbill struct tty dz_tty[NDZ]; 46*17Sbill int dz_cnt = { NDZ }; 47*17Sbill 48*17Sbill struct device { 49*17Sbill short dzcsr; 50*17Sbill short dzrbuf; 51*17Sbill char dztcr; 52*17Sbill char dzdtr; 53*17Sbill char dztbuf; 54*17Sbill char dzbrk; 55*17Sbill }; 56*17Sbill 57*17Sbill struct pdma dzpdma[] = { 58*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint, 59*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint, 60*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint, 61*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint, 62*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint, 63*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint, 64*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint, 65*17Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint, 66*17Sbill #ifdef ERNIE 67*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint, 68*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint, 69*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint, 70*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint, 71*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint, 72*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint, 73*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint, 74*17Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint, 75*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint, 76*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint, 77*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint, 78*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint, 79*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint, 80*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint, 81*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint, 82*17Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint, 83*17Sbill #endif 84*17Sbill }; 85*17Sbill char dz_timer; 86*17Sbill char dz_speeds[] = { 87*17Sbill 0, 020 , 021 , 022 , 023 , 024 , 0, 025, 88*17Sbill 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0, 89*17Sbill }; 90*17Sbill 91*17Sbill /*ARGSUSED*/ 92*17Sbill dzopen(d, flag) 93*17Sbill { 94*17Sbill register struct tty *tp; 95*17Sbill register dev; 96*17Sbill extern dzscan(); 97*17Sbill 98*17Sbill dev = minor(d); 99*17Sbill if (dev >= dz_cnt) { 100*17Sbill u.u_error = ENXIO; 101*17Sbill return; 102*17Sbill } 103*17Sbill if (dz_timer == 0) { 104*17Sbill dz_timer++; 105*17Sbill timeout(dzscan, (caddr_t)0, 60); 106*17Sbill } 107*17Sbill tp = &dz_tty[dev]; 108*17Sbill tp->t_addr = (caddr_t)&dzpdma[dev]; 109*17Sbill tp->t_oproc = dzstart; 110*17Sbill tp->t_iproc = NULL; 111*17Sbill tp->t_state |= WOPEN; 112*17Sbill if ((tp->t_state & ISOPEN) == 0) { 113*17Sbill ttychars(tp); 114*17Sbill tp->t_ospeed = tp->t_ispeed = SSPEED; 115*17Sbill tp->t_flags = ODDP|EVENP|ECHO; 116*17Sbill /*tp->t_state |= HUPCLS;*/ 117*17Sbill dzparam(dev); 118*17Sbill } else if (tp->t_state&XCLUDE && u.u_uid != 0) { 119*17Sbill u.u_error = EBUSY; 120*17Sbill return; 121*17Sbill } 122*17Sbill dzmodem(dev, ON); 123*17Sbill VOID spl5(); 124*17Sbill while ((tp->t_state & CARR_ON) == 0) { 125*17Sbill tp->t_state |= WOPEN; 126*17Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 127*17Sbill } 128*17Sbill VOID spl0(); 129*17Sbill (*linesw[tp->t_line].l_open)(d, tp); 130*17Sbill } 131*17Sbill 132*17Sbill dzclose(d) 133*17Sbill { 134*17Sbill register struct tty *tp; 135*17Sbill register dev; 136*17Sbill 137*17Sbill dev = minor(d); 138*17Sbill tp = &dz_tty[dev]; 139*17Sbill (*linesw[tp->t_line].l_close)(tp); 140*17Sbill if (tp->t_state & HUPCLS) 141*17Sbill dzmodem(dev, OFF); 142*17Sbill ttyclose(tp); 143*17Sbill } 144*17Sbill 145*17Sbill dzread(d) 146*17Sbill { 147*17Sbill register struct tty *tp; 148*17Sbill 149*17Sbill tp = &dz_tty[minor(d)]; 150*17Sbill (*linesw[tp->t_line].l_read)(tp); 151*17Sbill } 152*17Sbill 153*17Sbill dzwrite(d) 154*17Sbill { 155*17Sbill register struct tty *tp; 156*17Sbill 157*17Sbill tp = &dz_tty[minor(d)]; 158*17Sbill (*linesw[tp->t_line].l_write)(tp); 159*17Sbill } 160*17Sbill 161*17Sbill dzrint(dev) 162*17Sbill { 163*17Sbill register struct tty *tp; 164*17Sbill register int c; 165*17Sbill register struct device *dzaddr; 166*17Sbill 167*17Sbill dzaddr = dzpdma[dev*8].p_addr; 168*17Sbill while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 169*17Sbill tp = &dz_tty[((c>>8)&07)|(dev<<3)]; 170*17Sbill if (tp >= &dz_tty[dz_cnt]) 171*17Sbill continue; 172*17Sbill if ((tp->t_state & ISOPEN) == 0) { 173*17Sbill wakeup((caddr_t)&tp->t_rawq); 174*17Sbill continue; 175*17Sbill } 176*17Sbill if (c & FRERROR) 177*17Sbill /* framing error = break */ 178*17Sbill if (tp->t_flags & RAW) 179*17Sbill c = 0; /* null for getty */ 180*17Sbill else 181*17Sbill c = 0177; /* DEL = interrupt */ 182*17Sbill if (c & PERROR) 183*17Sbill /* parity error */ 184*17Sbill if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 185*17Sbill || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 186*17Sbill continue; 187*17Sbill (*linesw[tp->t_line].l_rint)(c, tp); 188*17Sbill } 189*17Sbill } 190*17Sbill 191*17Sbill /*ARGSUSED*/ 192*17Sbill dzioctl(dev, cmd, addr, flag) 193*17Sbill caddr_t addr; 194*17Sbill dev_t dev; 195*17Sbill { 196*17Sbill register struct tty *tp; 197*17Sbill 198*17Sbill tp = &dz_tty[minor(dev)]; 199*17Sbill if (ttioccomm(cmd, tp, addr, dev)) { 200*17Sbill if (cmd==TIOCSETP || cmd==TIOCSETN) 201*17Sbill dzparam(minor(dev)); 202*17Sbill } else 203*17Sbill u.u_error = ENOTTY; 204*17Sbill } 205*17Sbill 206*17Sbill dzparam(dev) 207*17Sbill { 208*17Sbill register struct tty *tp; 209*17Sbill register struct device *dzaddr; 210*17Sbill register short lpr; 211*17Sbill 212*17Sbill tp = &dz_tty[dev]; 213*17Sbill dzaddr = dzpdma[dev].p_addr; 214*17Sbill dzaddr->dzcsr = DZ_IEN; 215*17Sbill if (tp->t_ispeed == 0) { 216*17Sbill dzmodem(dev, OFF); /* hang up line */ 217*17Sbill return; 218*17Sbill } 219*17Sbill lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07); 220*17Sbill if (tp->t_flags & RAW) 221*17Sbill lpr |= BITS8; 222*17Sbill else 223*17Sbill lpr |= (BITS7|PENABLE); 224*17Sbill if ((tp->t_flags & EVENP) == 0) 225*17Sbill lpr |= OPAR; 226*17Sbill if (tp->t_ispeed == 3) 227*17Sbill lpr |= TWOSB; /* 110 baud: 2 stop bits */ 228*17Sbill dzaddr->dzlpr = lpr; 229*17Sbill } 230*17Sbill 231*17Sbill dzxint(tp) 232*17Sbill register struct tty *tp; 233*17Sbill { 234*17Sbill register struct pdma *dp; 235*17Sbill 236*17Sbill dp = &dzpdma[tp-dz_tty]; 237*17Sbill tp->t_state &= ~BUSY; 238*17Sbill if (tp->t_state & FLUSH) 239*17Sbill tp->t_state &= ~FLUSH; 240*17Sbill else 241*17Sbill ndflush(&tp->t_outq, dp->p_end-tp->t_outq.c_cf); 242*17Sbill if (tp->t_line) 243*17Sbill (*linesw[tp->t_line].l_start)(tp); 244*17Sbill else 245*17Sbill dzstart(tp); 246*17Sbill if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0) 247*17Sbill dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8)); 248*17Sbill } 249*17Sbill 250*17Sbill dzstart(tp) 251*17Sbill register struct tty *tp; 252*17Sbill { 253*17Sbill register struct pdma *dp; 254*17Sbill register struct device *dzaddr; 255*17Sbill register cc; 256*17Sbill int sps; 257*17Sbill extern ttrstrt(); 258*17Sbill 259*17Sbill dp = &dzpdma[tp-dz_tty]; 260*17Sbill dzaddr = dp->p_addr; 261*17Sbill sps = spl5(); 262*17Sbill if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) 263*17Sbill goto out; 264*17Sbill if (tp->t_outq.c_cc <= TTLOWAT && tp->t_state&ASLEEP) { 265*17Sbill tp->t_state &= ~ASLEEP; 266*17Sbill if (tp->t_chan) 267*17Sbill mcstart(tp->t_chan, (caddr_t)&tp->t_outq); 268*17Sbill else 269*17Sbill wakeup((caddr_t)&tp->t_outq); 270*17Sbill } 271*17Sbill if (tp->t_outq.c_cc == 0) 272*17Sbill goto out; 273*17Sbill if (tp->t_flags&RAW) 274*17Sbill cc = ndqb(&tp->t_outq, 0); 275*17Sbill else { 276*17Sbill cc = ndqb(&tp->t_outq, 0200); 277*17Sbill if (cc == 0) { 278*17Sbill cc = getc(&tp->t_outq); 279*17Sbill timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6); 280*17Sbill tp->t_state |= TIMEOUT; 281*17Sbill goto out; 282*17Sbill } 283*17Sbill } 284*17Sbill tp->t_state |= BUSY; 285*17Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 286*17Sbill dp->p_end += cc; 287*17Sbill dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8); 288*17Sbill out: 289*17Sbill splx(sps); 290*17Sbill } 291*17Sbill 292*17Sbill /* 293*17Sbill * Stop output on a line. 294*17Sbill * Assume call is made at spl6. 295*17Sbill */ 296*17Sbill /*ARGSUSED*/ 297*17Sbill dzstop(tp, flag) 298*17Sbill register struct tty *tp; 299*17Sbill { 300*17Sbill register struct pdma *dp; 301*17Sbill register int s; 302*17Sbill 303*17Sbill dp = &dzpdma[tp-dz_tty]; 304*17Sbill s = spl6(); 305*17Sbill if (tp->t_state & BUSY) { 306*17Sbill dp->p_end = dp->p_mem; 307*17Sbill if ((tp->t_state&TTSTOP)==0) { 308*17Sbill tp->t_state |= FLUSH; 309*17Sbill } 310*17Sbill } 311*17Sbill splx(s); 312*17Sbill } 313*17Sbill 314*17Sbill dzmodem(dev, flag) 315*17Sbill register int dev; 316*17Sbill { 317*17Sbill register struct device *dzaddr; 318*17Sbill register char bit; 319*17Sbill 320*17Sbill dzaddr = dzpdma[dev].p_addr; 321*17Sbill bit = 1<<(dev&07); 322*17Sbill if (flag == OFF) 323*17Sbill dzaddr->dzdtr &= ~bit; 324*17Sbill else 325*17Sbill dzaddr->dzdtr |= bit; 326*17Sbill } 327*17Sbill 328*17Sbill dzscan() 329*17Sbill { 330*17Sbill register i; 331*17Sbill register struct device *dzaddr; 332*17Sbill register bit; 333*17Sbill register struct tty *tp; 334*17Sbill 335*17Sbill for (i = 0; i < dz_cnt ; i++) { 336*17Sbill dzaddr = dzpdma[i].p_addr; 337*17Sbill tp = &dz_tty[i]; 338*17Sbill bit = 1<<(i&07); 339*17Sbill if (dzaddr->dzmsr & bit) { 340*17Sbill /* carrier present */ 341*17Sbill if ((tp->t_state & CARR_ON) == 0) { 342*17Sbill wakeup((caddr_t)&tp->t_rawq); 343*17Sbill tp->t_state |= CARR_ON; 344*17Sbill } 345*17Sbill } else { 346*17Sbill if ((tp->t_state & CARR_ON)) { 347*17Sbill /* carrier lost */ 348*17Sbill signal(tp->t_pgrp, SIGHUP); 349*17Sbill dzaddr->dzdtr &= ~bit; 350*17Sbill flushtty(tp); 351*17Sbill } 352*17Sbill tp->t_state &= ~CARR_ON; 353*17Sbill } 354*17Sbill } 355*17Sbill timeout(dzscan, (caddr_t)0, 2*HZ); 356*17Sbill } 357