1*114Sbill /* dz.c 3.2 10/14/12 */ 217Sbill 317Sbill /* 417Sbill * DZ-11 Driver 517Sbill */ 617Sbill #include "../h/param.h" 717Sbill #include "../h/systm.h" 817Sbill #include "../h/tty.h" 917Sbill #include "../h/dir.h" 1017Sbill #include "../h/user.h" 1117Sbill #include "../h/map.h" 1217Sbill #include "../h/pte.h" 1317Sbill #include "../h/uba.h" 1417Sbill #include "../h/conf.h" 1517Sbill #include "../h/pdma.h" 16*114Sbill #include "../h/bk.h" 1717Sbill 1817Sbill #define DZADDR (UBA0_DEV + 0160100) 1917Sbill #ifdef ERNIE 2017Sbill #define NDZ (3*8) 2117Sbill #else 2217Sbill #define NDZ (8) 2317Sbill #endif 2417Sbill 2517Sbill #define BITS7 020 2617Sbill #define BITS8 030 2717Sbill #define TWOSB 040 2817Sbill #define PENABLE 0100 2917Sbill #define OPAR 0200 3017Sbill #define MSE 040 /* Master Scan Enable */ 3117Sbill #define RIE 0100 /* Receiver Interrupt Enable */ 3217Sbill #define TIE 040000 /* Transmit interrupt enable */ 3317Sbill #define DZ_IEN (MSE+RIE+TIE) 3417Sbill #define PERROR 010000 3517Sbill #define FRERROR 020000 3617Sbill #define SSPEED 7 /* std speed = 300 baud */ 3717Sbill 3817Sbill 3917Sbill #define dzlpr dzrbuf 4017Sbill #define dzmsr dzbrk 4117Sbill #define ON 1 4217Sbill #define OFF 0 4317Sbill 4417Sbill int dzstart(); 4517Sbill int dzxint(); 46*114Sbill int ttrstrt(); 4717Sbill struct tty dz_tty[NDZ]; 4817Sbill int dz_cnt = { NDZ }; 4917Sbill 5017Sbill struct device { 5117Sbill short dzcsr; 5217Sbill short dzrbuf; 5317Sbill char dztcr; 5417Sbill char dzdtr; 5517Sbill char dztbuf; 5617Sbill char dzbrk; 5717Sbill }; 5817Sbill 5917Sbill struct pdma dzpdma[] = { 6017Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint, 6117Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint, 6217Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint, 6317Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint, 6417Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint, 6517Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint, 6617Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint, 6717Sbill (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint, 6817Sbill #ifdef ERNIE 6917Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint, 7017Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint, 7117Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint, 7217Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint, 7317Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint, 7417Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint, 7517Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint, 7617Sbill (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint, 7717Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint, 7817Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint, 7917Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint, 8017Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint, 8117Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint, 8217Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint, 8317Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint, 8417Sbill (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint, 8517Sbill #endif 8617Sbill }; 8717Sbill char dz_timer; 8817Sbill char dz_speeds[] = { 8917Sbill 0, 020 , 021 , 022 , 023 , 024 , 0, 025, 9017Sbill 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0, 9117Sbill }; 9217Sbill 9317Sbill /*ARGSUSED*/ 9417Sbill dzopen(d, flag) 9517Sbill { 9617Sbill register struct tty *tp; 9717Sbill register dev; 9817Sbill extern dzscan(); 9917Sbill 10017Sbill dev = minor(d); 10117Sbill if (dev >= dz_cnt) { 10217Sbill u.u_error = ENXIO; 10317Sbill return; 10417Sbill } 10517Sbill if (dz_timer == 0) { 10617Sbill dz_timer++; 10717Sbill timeout(dzscan, (caddr_t)0, 60); 10817Sbill } 10917Sbill tp = &dz_tty[dev]; 11017Sbill tp->t_addr = (caddr_t)&dzpdma[dev]; 11117Sbill tp->t_oproc = dzstart; 11217Sbill tp->t_iproc = NULL; 11317Sbill tp->t_state |= WOPEN; 11417Sbill if ((tp->t_state & ISOPEN) == 0) { 11517Sbill ttychars(tp); 11617Sbill tp->t_ospeed = tp->t_ispeed = SSPEED; 11717Sbill tp->t_flags = ODDP|EVENP|ECHO; 11817Sbill /*tp->t_state |= HUPCLS;*/ 11917Sbill dzparam(dev); 12017Sbill } else if (tp->t_state&XCLUDE && u.u_uid != 0) { 12117Sbill u.u_error = EBUSY; 12217Sbill return; 12317Sbill } 12417Sbill dzmodem(dev, ON); 125*114Sbill (void) spl5(); 12617Sbill while ((tp->t_state & CARR_ON) == 0) { 12717Sbill tp->t_state |= WOPEN; 12817Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 12917Sbill } 130*114Sbill (void) spl0(); 13117Sbill (*linesw[tp->t_line].l_open)(d, tp); 13217Sbill } 13317Sbill 13417Sbill dzclose(d) 13517Sbill { 13617Sbill register struct tty *tp; 13717Sbill register dev; 13817Sbill 13917Sbill dev = minor(d); 14017Sbill tp = &dz_tty[dev]; 14117Sbill (*linesw[tp->t_line].l_close)(tp); 14217Sbill if (tp->t_state & HUPCLS) 14317Sbill dzmodem(dev, OFF); 14417Sbill ttyclose(tp); 14517Sbill } 14617Sbill 14717Sbill dzread(d) 14817Sbill { 14917Sbill register struct tty *tp; 15017Sbill 15117Sbill tp = &dz_tty[minor(d)]; 15217Sbill (*linesw[tp->t_line].l_read)(tp); 15317Sbill } 15417Sbill 15517Sbill dzwrite(d) 15617Sbill { 15717Sbill register struct tty *tp; 15817Sbill 15917Sbill tp = &dz_tty[minor(d)]; 16017Sbill (*linesw[tp->t_line].l_write)(tp); 16117Sbill } 16217Sbill 16317Sbill dzrint(dev) 16417Sbill { 16517Sbill register struct tty *tp; 16617Sbill register int c; 16717Sbill register struct device *dzaddr; 16817Sbill 16917Sbill dzaddr = dzpdma[dev*8].p_addr; 17017Sbill while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 17117Sbill tp = &dz_tty[((c>>8)&07)|(dev<<3)]; 17217Sbill if (tp >= &dz_tty[dz_cnt]) 17317Sbill continue; 17417Sbill if ((tp->t_state & ISOPEN) == 0) { 17517Sbill wakeup((caddr_t)&tp->t_rawq); 17617Sbill continue; 17717Sbill } 17817Sbill if (c & FRERROR) 17917Sbill /* framing error = break */ 18017Sbill if (tp->t_flags & RAW) 18117Sbill c = 0; /* null for getty */ 18217Sbill else 18317Sbill c = 0177; /* DEL = interrupt */ 18417Sbill if (c & PERROR) 18517Sbill /* parity error */ 18617Sbill if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 18717Sbill || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 18817Sbill continue; 189*114Sbill #ifdef BERKNET 190*114Sbill if (tp->t_line == BNETLDIS) { 191*114Sbill c &= 0177; 192*114Sbill NETINPUT(c, tp); 193*114Sbill } else 194*114Sbill #endif 195*114Sbill (*linesw[tp->t_line].l_rint)(c, tp); 19617Sbill } 19717Sbill } 19817Sbill 19917Sbill /*ARGSUSED*/ 20017Sbill dzioctl(dev, cmd, addr, flag) 20117Sbill caddr_t addr; 20217Sbill dev_t dev; 20317Sbill { 20417Sbill register struct tty *tp; 20517Sbill 20617Sbill tp = &dz_tty[minor(dev)]; 207*114Sbill cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 208*114Sbill if (cmd == 0) 209*114Sbill return; 21017Sbill if (ttioccomm(cmd, tp, addr, dev)) { 21117Sbill if (cmd==TIOCSETP || cmd==TIOCSETN) 21217Sbill dzparam(minor(dev)); 21317Sbill } else 21417Sbill u.u_error = ENOTTY; 21517Sbill } 21617Sbill 21717Sbill dzparam(dev) 21817Sbill { 21917Sbill register struct tty *tp; 22017Sbill register struct device *dzaddr; 22117Sbill register short lpr; 22217Sbill 22317Sbill tp = &dz_tty[dev]; 22417Sbill dzaddr = dzpdma[dev].p_addr; 22517Sbill dzaddr->dzcsr = DZ_IEN; 22617Sbill if (tp->t_ispeed == 0) { 22717Sbill dzmodem(dev, OFF); /* hang up line */ 22817Sbill return; 22917Sbill } 23017Sbill lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07); 23117Sbill if (tp->t_flags & RAW) 23217Sbill lpr |= BITS8; 23317Sbill else 23417Sbill lpr |= (BITS7|PENABLE); 23517Sbill if ((tp->t_flags & EVENP) == 0) 23617Sbill lpr |= OPAR; 23717Sbill if (tp->t_ispeed == 3) 23817Sbill lpr |= TWOSB; /* 110 baud: 2 stop bits */ 23917Sbill dzaddr->dzlpr = lpr; 24017Sbill } 24117Sbill 24217Sbill dzxint(tp) 24317Sbill register struct tty *tp; 24417Sbill { 24517Sbill register struct pdma *dp; 24617Sbill 24717Sbill dp = &dzpdma[tp-dz_tty]; 24817Sbill tp->t_state &= ~BUSY; 24917Sbill if (tp->t_state & FLUSH) 25017Sbill tp->t_state &= ~FLUSH; 25117Sbill else 25217Sbill ndflush(&tp->t_outq, dp->p_end-tp->t_outq.c_cf); 25317Sbill if (tp->t_line) 25417Sbill (*linesw[tp->t_line].l_start)(tp); 25517Sbill else 25617Sbill dzstart(tp); 25717Sbill if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0) 25817Sbill dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8)); 25917Sbill } 26017Sbill 26117Sbill dzstart(tp) 26217Sbill register struct tty *tp; 26317Sbill { 26417Sbill register struct pdma *dp; 26517Sbill register struct device *dzaddr; 26617Sbill register cc; 26717Sbill int sps; 26817Sbill 26917Sbill dp = &dzpdma[tp-dz_tty]; 27017Sbill dzaddr = dp->p_addr; 27117Sbill sps = spl5(); 27217Sbill if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) 27317Sbill goto out; 27417Sbill if (tp->t_outq.c_cc <= TTLOWAT && tp->t_state&ASLEEP) { 27517Sbill tp->t_state &= ~ASLEEP; 27617Sbill if (tp->t_chan) 27717Sbill mcstart(tp->t_chan, (caddr_t)&tp->t_outq); 27817Sbill else 27917Sbill wakeup((caddr_t)&tp->t_outq); 28017Sbill } 28117Sbill if (tp->t_outq.c_cc == 0) 28217Sbill goto out; 28317Sbill if (tp->t_flags&RAW) 28417Sbill cc = ndqb(&tp->t_outq, 0); 28517Sbill else { 28617Sbill cc = ndqb(&tp->t_outq, 0200); 28717Sbill if (cc == 0) { 28817Sbill cc = getc(&tp->t_outq); 28917Sbill timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6); 29017Sbill tp->t_state |= TIMEOUT; 29117Sbill goto out; 29217Sbill } 29317Sbill } 29417Sbill tp->t_state |= BUSY; 29517Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 29617Sbill dp->p_end += cc; 29717Sbill dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8); 29817Sbill out: 29917Sbill splx(sps); 30017Sbill } 30117Sbill 30217Sbill /* 30317Sbill * Stop output on a line. 30417Sbill * Assume call is made at spl6. 30517Sbill */ 30617Sbill /*ARGSUSED*/ 30717Sbill dzstop(tp, flag) 30817Sbill register struct tty *tp; 30917Sbill { 31017Sbill register struct pdma *dp; 31117Sbill register int s; 31217Sbill 31317Sbill dp = &dzpdma[tp-dz_tty]; 31417Sbill s = spl6(); 31517Sbill if (tp->t_state & BUSY) { 31617Sbill dp->p_end = dp->p_mem; 31717Sbill if ((tp->t_state&TTSTOP)==0) { 31817Sbill tp->t_state |= FLUSH; 31917Sbill } 32017Sbill } 32117Sbill splx(s); 32217Sbill } 32317Sbill 32417Sbill dzmodem(dev, flag) 32517Sbill register int dev; 32617Sbill { 32717Sbill register struct device *dzaddr; 32817Sbill register char bit; 32917Sbill 33017Sbill dzaddr = dzpdma[dev].p_addr; 33117Sbill bit = 1<<(dev&07); 33217Sbill if (flag == OFF) 33317Sbill dzaddr->dzdtr &= ~bit; 33417Sbill else 33517Sbill dzaddr->dzdtr |= bit; 33617Sbill } 33717Sbill 33817Sbill dzscan() 33917Sbill { 34017Sbill register i; 34117Sbill register struct device *dzaddr; 34217Sbill register bit; 34317Sbill register struct tty *tp; 34417Sbill 34517Sbill for (i = 0; i < dz_cnt ; i++) { 34617Sbill dzaddr = dzpdma[i].p_addr; 34717Sbill tp = &dz_tty[i]; 34817Sbill bit = 1<<(i&07); 34917Sbill if (dzaddr->dzmsr & bit) { 35017Sbill /* carrier present */ 35117Sbill if ((tp->t_state & CARR_ON) == 0) { 35217Sbill wakeup((caddr_t)&tp->t_rawq); 35317Sbill tp->t_state |= CARR_ON; 35417Sbill } 35517Sbill } else { 35617Sbill if ((tp->t_state & CARR_ON)) { 35717Sbill /* carrier lost */ 35817Sbill signal(tp->t_pgrp, SIGHUP); 35917Sbill dzaddr->dzdtr &= ~bit; 36017Sbill flushtty(tp); 36117Sbill } 36217Sbill tp->t_state &= ~CARR_ON; 36317Sbill } 36417Sbill } 36517Sbill timeout(dzscan, (caddr_t)0, 2*HZ); 36617Sbill } 367