📄 ss.c
字号:
else ssstart(tp); /* 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) { ssaddr->sstcr &= ~(1<<unit); }}ssstart(tp) register struct tty *tp;{ register struct pdma *dp; register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int cc; int s, unit; dp = (struct pdma *)tp->t_addr; s = spl5(); /* * Do not do anything if currently delaying, or active. Also only * transmit when CTS is up. */ unit = minor(tp->t_dev) & 3; if ((tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) || (unit == MODEM_UNIT) && ((tp->t_cflag & CLOCAL) == 0) && ((tp->t_state&TS_CARR_ON) && (ssmodem&MODEM_CTS)==0)) 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; if ((vs_cfgtst&VS_L3CON) && (unit == 0) && (major(tp->t_dev) == CONSOLE_MAJOR)) unit = 3; ssaddr->sstcr |= (1<<unit);out: splx(s);}/* * Stop output on a line. *//*ARGSUSED*/ssstop(tp, flag) register struct tty *tp;{ register struct pdma *dp; register int s; int unit; /* * If there is a graphics device and the stop call * is for it, pass the call to the graphics device driver. */ unit = minor(tp->t_dev); if (vs_gdstop && (unit <= 1)) { (*vs_gdstop)(tp, flag); return; } 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);}/* * ***** FOR YOUR INFORMATION ***** * * Fred Canter -- 7/1/86 * * The VAXstar console SLU supports modem control * only on line 2. Modem control ioctls for other lines * will not return an error, but also will not do anything! * Hopefully, this is the lesser of two evils when it comes to * breaking users' programs. * * Line 2 has more modem control signals than ULTRIX uses * right now (see VAXstar system unit spec. chapter 11). * * CAUTION: the SML_* definitions in ssreg.h must match the * TIOCM_* definitions in ioctl.h. * * The line number in the dev argument to this routine will be * wrong (0 s/b 3) if VS_L3CON is set in the configuration and test * register, i.e., a diagnostic console terminal is attached to * the printer port. This fact is ignored because this routine only * acts on line 2 anyway. * */ssmctl(dev, bits, how) dev_t dev; int bits, how;{ register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int unit, mbits; int b, s; unit = minor(dev); if(unit != MODEM_UNIT) return(0); /* only line 2 has modem control */ b = 0x4; s = spl5(); mbits = (ssaddr->ssdtr & SS_RDTR) ? SS_DTR : 0; mbits |= (ssaddr->ssdtr & SS_RRTS) ? SS_RTS : 0; mbits |= (ssaddr->ssmsr & SS_RCD) ? SS_CD : 0; mbits |= (ssaddr->ssmsr & SS_RDSR) ? SS_DSR : 0; mbits |= (ssaddr->ssmsr & SS_RCTS) ? SS_CTS : 0; mbits |= (ssaddr->sstbuf & b) ? SS_RI : 0; switch (how) { /* No actual bit settings in device are really done ! */ case DMSET: mbits = bits; break; case DMBIS: mbits |= bits; break; case DMBIC: mbits &= ~bits; break; case DMGET: (void) splx(s); return(mbits); } if (mbits & SS_DTR) ssaddr->ssdtr |= (b|SS_RRTS); else ssaddr->ssdtr &= ~(b|SS_RRTS); (void) splx(s); return(mbits);}/* * Allows silo alarm mode, if set. * Enabling silo alarm mode will most likely * cause silo overrun errors. The system can't * seem to keep up????????? */ss_allow_silos = 0;int sstransitions, ssfasttimers; /*DEBUG*/#ifdef DEBUGint sscan_ctr = 1;#endif DEBUGssscan(){ register i; register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register struct tty *tp; int oldsssilos = sssilos; int sstimer(); register u_char sscan_modem;#ifdef DEBUG if (ssdebug) { if (sscan_ctr++ == 45) { cprintf("ssscan: "); PRINT_SIGNALS(); sscan_ctr = 1; } }#endif DEBUG for (i = 0; i < ss_cnt; i++) { if (sspdma[i].p_addr == 0) continue; tp = &ss_tty[i]; sscan_modem = 0; /* Modem Control only on line 2 */ if ((i == MODEM_UNIT) && ((tp->t_cflag & CLOCAL) == 0)) { /* * Drop DTR immediately if DSR has gone away. * If really an active close then do not * send signals. */ if (!(ssaddr->ssmsr&SS_RDSR)) { if (tp->t_state&TS_CLOSING) { untimeout(wakeup, (caddr_t) &tp->t_dev); wakeup((caddr_t) &tp->t_dev); } if (tp->t_state&TS_CARR_ON) { /* * Only drop if DECSTD52 is followed. */ if (ssdsr) ss_tty_drop(tp); } } else { /* DSR has come up */ /* * If DSR comes up for the first time we allow * 30 seconds for a live connection. */ if (ssdsr && ((ssmodem&MODEM_DSR)==0)) { ssmodem |= (MODEM_DSR_START|MODEM_DSR); /* * we should not look for CTS|CD for * about 500 ms. */ if (!ss_modem_ctl) { /* * Assume carrier will come up in less * than 1 sec. If not DSR will drop * and the line will close */ timeout(ss_dsr_check, tp, hz); } else { timeout(ss_dsr_check, tp, hz*30); timeout(ss_dsr_check, tp, hz/2); } } } /* * Look for modem transitions in an already * established connection. * * Ignore CD and CTS for PVAX. These signals * don't exist on the PVAX. */ if (ss_modem_ctl) { if (tp->t_state & TS_CARR_ON) { if (ssaddr->ssmsr&SS_RCD) { /* * CD has come up again. * Stop timeout from occurring if set. * If interval is more than 2 secs then * drop DTR. */ if ((ssmodem&MODEM_CD)==0) { untimeout(ss_cd_drop, tp); if (ss_cd_down(tp)){ /* drop connection */ ss_tty_drop(tp); } ssmodem |= MODEM_CD; } } else { /* * Carrier must be down for greater than 2 secs * before closing down the line. */ if ( ssmodem & MODEM_CD) { /* only start timer once */ ssmodem &= ~MODEM_CD; /* * Record present time so that if carrier * comes up after 2 secs , the line will drop. */ sstimestamp = time; timeout(ss_cd_drop, tp, hz*2); } } /* CTS flow control check */ if (!(ssaddr->ssmsr&SS_RCTS)) { /* * Only allow transmission when CTS is set. */ tp->t_state |= TS_TTSTOP; ssmodem &= ~MODEM_CTS;# ifdef DEBUG if (ssdebug) cprintf("ssscan: CTS stop, tp=%x,line=%d\n", tp,i);# endif DEBUG ssstop(tp, 0); } else if ((ssmodem&MODEM_CTS)==0) { /* * Restart transmission upon return of CTS. */ tp->t_state &= ~TS_TTSTOP; ssmodem |= MODEM_CTS;# ifdef DEBUG if (ssdebug) cprintf("ssscan: CTS start, tp=%x,line=%d\n", tp,i);# endif DEBUG ssstart(tp); } } /* * See if a modem transition has occured. If we are waiting * for this signal cause action to be taken via ss_tty_start. */ if ((sscan_modem=ssaddr->ssmsr&SS_XMIT) != sscan_previous){ /* * If 500 ms timer has not expired then dont * check anything yet. * Check to see if DSR|CTS|CD are asserted. * If so we have a live connection. */# ifdef DEBUG if (ssdebug) cprintf("ssscan: MODEM Transition,sscan_modem=%x, sscan_prev=%x\n",sscan_modem,sscan_previous);# endif DEBUG /* * If ssdsr is set look for DSR|CTS|CD,else look * for CD|CTS only. */ if (ssdsr) { if (((ssaddr->ssmsr&SS_XMIT)==SS_XMIT) && ((ssmodem&MODEM_DSR_START)==0) && ((tp->t_state&TS_CARR_ON)==0)) {# ifdef DEBUG if (ssdebug) cprintf("ssscan:SS_XMIT call ss_start,line=%d\n",i);# endif DEBUG ss_start_tty(tp); } } /* * Ignore DSR. */ else if ((ssaddr->ssmsr&SS_NODSR)==SS_NODSR) ss_start_tty(tp); } sscan_previous = sscan_modem; /* save for next iteration */ } } } for (i = 0; i < nNSS; i++) { ave(ssrate[i], sschars[i], 8); /* * Allow silo mode only if no graphics device. * Silo mode blows away with mouse tracking. */ if (ss_allow_silos && (vs_gdopen == 0)) { if (sschars[i] > sshighrate && ((sssilos&(1 << i)) == 0)) { ssaddr->sscsr = SS_MSE | SS_SAE; ssaddr->nb_int_msk |= (SINT_ST|SINT_SR); sssilos |= (1 << i); sstransitions++; /*DEBUG*/ } else if ((sssilos&(1 << i)) && (ssrate[i] < sslowrate)) { ssaddr->sscsr = SS_MSE; ssaddr->nb_int_msk |= (SINT_ST|SINT_SR); sssilos &= ~(1 << i); } } sschars[i] = 0; } if (sssilos && !oldsssilos) timeout(sstimer, (caddr_t)0, sstimerintvl); timeout(ssscan, (caddr_t)0, hz);}sstimer(){ register int ss; register int s; if (sssilos == 0) return; s = spl5(); ssfasttimers++; /*DEBUG*/ for (ss = 0; ss < nNSS; ss++) if (sssilos & (1 << ss)) ssrint(ss); splx(s); timeout(sstimer, (caddr_t) 0, sstimerintvl);}/* save record of sbis present for sbi error logging for 780 and 8600 */extern long sbi_there; /* bits 0-15 for nexi,sbi0; 16-31 for nexi on sbi1*//* * VAXstar virtual console initialization routine. * Configures the VAXstar serial line controller as the console, * maps in all of the VAXstar's address space, and * decides if LK201 keystrokes must be passed to the bit-map * or color driver's console routines. */int ssputc();int ssgetc();u_long scr_ram_addr; /* system scratch RAM phys. address used by */ /* color driver. */extern (*v_consputc)();extern (*v_consgetc)();extern int sgcons_init();extern int smcons_init();/* * This variable tells ssputc, smputc, and sgputc thhether or * not it is safe actually print characters. Those routines * just return if vs_safe2print is zero. This is nexcessary * because the putc routines must not attempt to access VAXstar * I/O space until it has been mapped (bu sscons_inions_init). *//* TODO: not fully implemented, finish it or remove it! */int vs_safe2print = 0;int cvs_exmode_on = 1; /* written to STC_MODE register */sscons_init(){ register struct nb_regs *ssaddr; register char *nxv, *nxp; /* nexus virtual/phys addr pointers */ int i; int constype; /* * ONLY on a VAXstation 2000 or MicroVAX 2000 * or CVAXstar. */ if ((cpu != VAXSTAR) && (cpu != C_VAXSTAR)) return(0); /* * Map the nexus. */ nxv = (char *)nexus; nxp = (char *)cpup->nexaddr(0,0); nxaccess (nxp, Nexmap[0], cpup->pc_nexsize); /* * See if there is anything there. */ /* NOTE: VAXstars/CVAXstars don't trap on bad addresses */ if ((*cpup->badaddr)((caddr_t) nxv, 4)) return(-1); sbi_there |= 1<<0; /* * May as well map the rest of I/O space * while we are at it.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -