📄 dz.c
字号:
case TCSAFLUSH: /* POSIX termios */ case TCSETA: /* SVID termio */ case TCSETAW: /* SVID termio */ case TCSETAF: /* SVID termio */ case TIOCSETP: /* Berkeley sgttyb */ case TIOCSETN: /* Berkeley sgttyb */ case TIOCLBIS: /* Berkeley lmode */ case TIOCLBIC: /* Berkeley lmode */ case TIOCLSET: /* Berkeley lmode */ case TIOCLGET: /* Berkeley lmode */ dzparam(unit); break; } return (error); } switch (cmd) { case TIOCSBRK: dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; if (dzaddr->dzcsr&DZ_32) (void) dzmctl(dev, DZ_BRK, DMBIS); else dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&LINEMASK)); break; case TIOCCBRK: dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; if (dzaddr->dzcsr&DZ_32) (void) dzmctl(dev, DZ_BRK, DMBIC); else dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&LINEMASK))); break; case TIOCSDTR: (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); break; case TIOCCDTR: (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); break; case TIOCMSET: (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); break; case TIOCMBIS: (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); break; case TIOCMBIC: (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); break; case TIOCMGET: *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); break;#ifdef 0 /* Doesn't work yet ! */ /* Set local loopback mode. WARNING: setting local loopback on the dz * will place ALL of the lines in loopback mode. This is in contrast * to the other drivers which operate on a per-line basis. */ case TIOCSMLB: if (u.u_uid) return(EPERM); s=spl5(); dzaddr->dzcsr = DZ_IEN; dzaddr->dzcsr |= DZ_MAINT; splx(s); break; case TIOCCMLB: if (u.u_uid) return(EPERM); s=spl5(); dzaddr->dzcsr = DZ_IEN; dzaddr->dzcsr &= ~(DZ_MAINT); splx(s); break;#endif 0 case TIOCNMODEM: /* ignore modem status */ s = spl5(); dzsoftCAR[dz] |= (1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dzdefaultCAR[dz] |= (1<<(unit&LINEMASK)); tp->t_state |= TS_CARR_ON; tp->t_cflag |= CLOCAL; /* Map to termio */ splx(s); break; case TIOCMODEM: /* look at modem status - sleep if no carrier */ s = spl5(); dzsoftCAR[dz] &= ~(1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ dzdefaultCAR[dz] &= ~(1<<(unit&LINEMASK)); dzaddr = (struct dzdevice *)(dzpdma[unit].p_addr); if (dzaddr->dzcsr & DZ_32){ if (dzaddr->dzlcs & DZ_CD) { tp->t_state &= ~TS_ONDELAY; tp->t_state |= TS_CARR_ON; } else tp->t_state &= ~(TS_CARR_ON); } else { if (dzaddr->dzmsr & (1<<(unit&LINEMASK)) ){ tp->t_state &= ~TS_ONDELAY; tp->t_state |= TS_CARR_ON; } else tp->t_state &= ~(TS_CARR_ON); } tp->t_cflag &= ~CLOCAL; /* Map to termio */ splx(s); break; case TIOCWONLINE: s = spl5(); while ((tp->t_state & TS_CARR_ON) == 0) sleep((caddr_t)&tp->t_rawq, TTIPRI); splx(s); break; case DEVIOCGET: /* device status */ devget = (struct devget *)data; bzero(devget,sizeof(struct devget)); if(dzsoftCAR[dz] & (tp->t_cflag & CLOCAL)) { sc->sc_category_flags[unit&LINEMASK] |= DEV_MODEM; sc->sc_category_flags[unit&LINEMASK] &= ~DEV_MODEM_ON; } else sc->sc_category_flags[unit&LINEMASK] |= (DEV_MODEM|DEV_MODEM_ON); devget->category = DEV_TERMINAL; if(ui->ui_hd->uba_type & (UBAUVI|UBAUVII)) { devget->bus = DEV_QB; } else { devget->bus = DEV_UB; } switch (devget->bus) { case DEV_UB: dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; if (dzaddr->dzcsr & DZ_32) { bcopy(DEV_DZ32,devget->interface, strlen(DEV_DZ32)); } else { bcopy(DEV_DZ11,devget->interface, strlen(DEV_DZ11)); } break; case DEV_QB: dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; if (dzaddr->dzcsr & DZ_32) { bcopy(DEV_DZQ11,devget->interface, strlen(DEV_DZQ11)); } else { bcopy(DEV_DZV11,devget->interface, strlen(DEV_DZV11)); } break; } bcopy(DEV_UNKNOWN,devget->device, strlen(DEV_UNKNOWN)); /* terminal */ devget->adpt_num = ui->ui_adpt; /* which adapter*/ devget->nexus_num = ui->ui_nexus; /* which nexus */ devget->bus_num = ui->ui_ubanum; /* which UBA/QB */ devget->ctlr_num = dz; /* which interf.*/ devget->slave_num = unit&LINEMASK; /* which line */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "dz" */ devget->unit_num = unit&LINEMASK; /* dz line? */ devget->soft_count = sc->sc_softcnt[unit&LINEMASK]; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt[unit&LINEMASK]; /* hard er cnt. */ devget->stat = sc->sc_flags[unit&LINEMASK]; /* status */ devget->category_stat = sc->sc_category_flags[unit&LINEMASK]; /* cat. stat. */ break; default: if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); } return (0);}dmtodz(bits) register int bits;{ register int b; b = (bits >>1) & 0370; if (bits & DML_ST) b |= DZ_ST; if (bits & DML_RTS) b |= DZ_RTS; if (bits & DML_DTR) b |= DZ_DTR; if (bits & DML_LE) b |= DZ_LE; return(b);}dztodm(bits) register int bits;{ register int b; b = (bits << 1) & 0360; if (bits & DZ_DSR) b |= DML_DSR; if (bits & DZ_DTR) b |= DML_DTR; if (bits & DZ_ST) b |= DML_ST; if (bits & DZ_RTS) b |= DML_RTS; return(b);}dzparam(unit) register int unit;{ register struct tty *tp; register struct dzdevice *dzaddr; register int lpr; tp = &dz_tty[unit]; dzaddr = dzpdma[unit].p_addr; if (dzsilos & (1 << (unit >> 3))) dzaddr->dzcsr = DZ_IEN | DZ_SAE; else dzaddr->dzcsr = DZ_IEN; dzact |= (1<<(unit>>3)); /* * Disconnect modem line if baudrate is zero. POSIX checks the output * baud rate, while non-POSIX checks the input baud rate. */ if ((((tp->t_cflag&CBAUD)==B0) && (u.u_procp->p_progenv != A_POSIX)) || (((tp->t_cflag_ext & CBAUD)==B0) && (u.u_procp->p_progenv == A_POSIX))) { (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ return; } lpr = (dz_speeds[tp->t_cflag&CBAUD]<<8) | (unit & LINEMASK); /* * Berkeley-only dinosaur */ if (tp->t_line != TERMIODISC) { if ((tp->t_cflag_ext & CBAUD) == B110){ lpr |= TWOSB; tp->t_cflag |= CSTOPB; } } /* * Set device registers according to the specifications of the termio * structure. */ if (tp->t_cflag & CREAD) lpr |= DZ_RE; else lpr &= ~DZ_RE; if (tp->t_cflag & CSTOPB) lpr |= TWOSB; else lpr &= ~TWOSB; /* parity is enable */ if (tp->t_cflag & PARENB) { if ((tp->t_cflag & PARODD) == 0) /* set even */ lpr = (lpr | PENABLE) &~OPAR; else /* else set odd */ lpr |= PENABLE|OPAR; } /* * character size. * clear bits and check for 6,7,and 8, else its 5 bits. */ lpr &= ~BITS8; switch(tp->t_cflag&CSIZE) { case CS6: lpr |= BITS6; break; case CS7: lpr |= BITS7; break; case CS8: lpr |= BITS8; break; } dzaddr->dzlpr = lpr;}dzxint(tp) register struct tty *tp;{ register struct pdma *dp; register dz, unit; dp = (struct pdma *)tp->t_addr; /* it appears that the dz will ocassionally give spurious transmit ready interupts even when not enabled. If the line was never opened, the following is necessary */ if (dp == NULL) { tp->t_addr = (caddr_t) &dzpdma[minor(tp->t_dev)]; dp = (struct pdma *) tp->t_addr; } tp->t_state &= ~TS_BUSY; if (tp->t_state & TS_FLUSH) tp->t_state &= ~TS_FLUSH; else { ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); dp->p_end = dp->p_mem = tp->t_outq.c_cf; } if (tp->t_line) (*linesw[tp->t_line].l_start)(tp); else dzstart(tp); dz = minor(tp->t_dev) >> 3; unit = minor(tp->t_dev) & 7; /* The BUSY flag will not be set in two cases: */ /* 1: if there are no more chars in the outq OR */ /* 2. there are chars in the outq but tty is in stopped */ /* state. */ if ((tp->t_state&TS_BUSY)==0) { if (dp->p_addr->dzcsr & DZ_32) dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); else dp->p_addr->dztcr &= ~(1<<unit); }}dzstart(tp) register struct tty *tp;{ register struct pdma *dp; register struct dzdevice *dzaddr; register int cc; int s, dz, unit; dp = (struct pdma *)tp->t_addr; dzaddr = dp->p_addr; s = spl5(); if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; if (tp->t_outq.c_cc <= TTLOWAT(tp)) { if (tp->t_state&TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } if (tp->t_wsel) { selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); tp->t_wsel = 0; tp->t_state &= ~TS_WCOLL; } } if (tp->t_outq.c_cc == 0) goto out; if ((tp->t_lflag_ext & PRAW) || (tp->t_oflag_ext & PLITOUT) || ((tp->t_oflag & OPOST) == 0)) cc = ndqb(&tp->t_outq, 0); else { cc = ndqb(&tp->t_outq, DELAY_FLAG); if (cc == 0) { cc = getc(&tp->t_outq); timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); tp->t_state |= TS_TIMEOUT; goto out; } } tp->t_state |= TS_BUSY; dp->p_end = dp->p_mem = tp->t_outq.c_cf; dp->p_end += cc; dz = minor(tp->t_dev) >> 3; unit = minor(tp->t_dev) & 7; if (dzaddr->dzcsr & DZ_32) dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); else dzaddr->dztcr |= (1<<unit);out: splx(s);}/* * Stop output on a line. *//*ARGSUSED*/dzstop(tp, flag) register struct tty *tp;{ register struct pdma *dp; register int s; dp = (struct pdma *)tp->t_addr; s = spl5(); if (tp->t_state & TS_BUSY) { dp->p_end = dp->p_mem; if ((tp->t_state&TS_TTSTOP)==0) tp->t_state |= TS_FLUSH; } splx(s);}dzmctl(dev, bits, how) dev_t dev; int bits, how;{ register struct dzdevice *dzaddr; register int unit, mbits; int b, s; unit = minor(dev); b = 1<<(unit&7); dzaddr = dzpdma[unit].p_addr; s = spl5(); if (dzaddr->dzcsr & DZ_32) { dzwait(dzaddr) DELAY(100); /* IS 100 TOO MUCH? */ dzaddr->dzlcs = unit&7; DELAY(100); dzwait(dzaddr) DELAY(100); mbits = dzaddr->dzlcs; mbits &= 0177770; } else { mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; } switch (how) { case DMSET: mbits = bits; break; case DMBIS: mbits |= bits; break; case DMBIC: mbits &= ~bits; break; case DMGET: (void) splx(s); return(mbits); } if (dzaddr->dzcsr & DZ_32) { mbits |= DZ_ACK|(unit&7); dzaddr->dzlcs = mbits; } else { if (mbits & DZ_DTR) dzaddr->dzdtr |= b; else dzaddr->dzdtr &= ~b; } (void) splx(s); return(mbits);}int dztransitions, dzfasttimers; /*DEBUG*/dzscan(){ register i; register struct dzdevice *dzaddr; register bit; register struct tty *tp; register car; int olddzsilos = dzsilos; int dztimer(); for (i = 0; i < dz_cnt ; i++) { dzaddr = dzpdma[i].p_addr; if (dzaddr == 0) continue; tp = &dz_tty[i]; bit = 1<<(i&LINEMASK); car = 0; if (tp->t_cflag & CLOCAL) car = 1; else if (dzaddr->dzcsr & DZ_32) { dzaddr->dzlcs = i&LINEMASK; dzwait(dzaddr); car = dzaddr->dzlcs & DZ_CD; } else car = dzaddr->dzmsr&bit; if (car) { /* carrier present */ if ((tp->t_state & TS_CARR_ON) == 0) { wakeup((caddr_t)&tp->t_rawq); tp->t_state |= TS_CARR_ON; tp->t_state &= ~TS_ONDELAY; } } else { if ((tp->t_state&TS_CARR_ON) && (tp->t_flags&NOHANG) == 0) { /* carrier lost */ if (tp->t_state&TS_ISOPEN) { gsignal(tp->t_pgrp, SIGHUP); gsignal(tp->t_pgrp, SIGCONT); dzaddr->dzdtr &= ~bit; ttyflush(tp, FREAD|FWRITE); } tp->t_state &= ~TS_CARR_ON; } } } for (i = 0; i < nNDZ; i++) { ave(dzrate[i], dzchars[i], 8); if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) { dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE; dzsilos |= (1 << i); dztransitions++; /*DEBUG*/ } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) { dzpdma[i << 3].p_addr->dzcsr = DZ_IEN; dzsilos &= ~(1 << i); } dzchars[i] = 0; } if (dzsilos && !olddzsilos) timeout(dztimer, (caddr_t)0, dztimerintvl); timeout(dzscan, (caddr_t)0, hz);}dztimer(){ register int dz; register int s; if (dzsilos == 0) return; s = spl5(); dzfasttimers++; /*DEBUG*/ for (dz = 0; dz < nNDZ; dz++) if (dzsilos & (1 << dz)) dzrint(dz); splx(s); timeout(dztimer, (caddr_t) 0, dztimerintvl);}/* * Reset state of driver if UBA reset was necessary. * Reset parameters and restart transmission on open lines. */dzreset(uban) int uban;{ register int unit; register struct tty *tp; register struct uba_device *ui; for (unit = 0; unit < nNDZLINE; unit++) { ui = dzinfo[unit >> 3]; if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) continue; if (unit%8 == 0) printf(" dz%d", unit>>3); tp = &dz_tty[unit]; if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { dzparam(unit); (void) dzmctl(unit, DZ_ON, DMSET); tp->t_state &= ~TS_BUSY; dzstart(tp); } }}dzbaudrate(speed)register int speed;{ if (dz_valid_speeds & (1 << speed)) return (1); else return (0);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -