📄 fc.c
字号:
*/ 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) == 0) lpr &= ~FC_RE; /* This was set from speeds */ if (tp->t_cflag & CSTOPB) lpr |= TWOSB; else lpr &= ~TWOSB; 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; }# ifdef DEBUG if (fcdebug) mprintf("fcparam: tp = %x, lpr = %x\n",tp,lpr);# endif DEBUG fcaddr->fclpr = lpr; }}/*ARGUSED*/fcxint(tp) register struct tty *tp;{ register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; register struct pdma *dp; register fc, unit; dp = (struct pdma *)tp->t_addr; fc = minor(tp->t_dev) >> 2; unit = minor(tp->t_dev) & 3; if ((ff_diagcons) && (unit == 0) && (major(tp->t_dev) == CONSOLEMAJOR)) { unit = 3; fc = 0; } /* * Don't know if the following is true for the * VAXstar SLU, but it stays in just to be safe. * Fred Canter -- 6/28/86 */ /* it appears that the fc 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) &fcpdma[unit]; 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 fcstart(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) fcaddr->fctcr &= ~(1<<unit); else fcaddr->fccsr |= FC_TIE;}fcstart(tp) register struct tty *tp;{ register struct pdma *dp; register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; register int cc; int s, fc, unit; dp = (struct pdma *)tp->t_addr; s = spl6(); /* * 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) && (fcmodem&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 ((ff_diagcons) && (unit == 0) && (major(tp->t_dev) == CONSOLEMAJOR)) unit = 3; /* * Enable transmitter interrupts */ fcaddr->fccsr |= FC_TIE; fcaddr->fctcr |= (1<<unit);out: splx(s);}/* * Stop output on a line. *//*ARGSUSED*/fcstop(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 = spl6(); 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 fcreg.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. * */fcmctl(dev, bits, how) dev_t dev; int bits, how;{ register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; 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 = spl6(); mbits = (fcaddr->fcdtr & FC_RDTR) ? FC_DTR : 0; mbits |= (fcaddr->fcdtr & FC_RRTS) ? FC_RTS : 0; mbits |= (fcaddr->fcmsr & FC_RCD) ? FC_CD : 0; mbits |= (fcaddr->fcmsr & FC_RDSR) ? FC_DSR : 0; mbits |= (fcaddr->fcmsr & FC_RCTS) ? FC_CTS : 0; mbits |= (fcaddr->fctbuf & b) ? FC_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 & FC_DTR) fcaddr->fcdtr |= (b|FC_RRTS); else fcaddr->fcdtr &= ~(b|FC_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????????? */fc_allow_silos = 0;int fctransitions, fcfasttimers; /*DEBUG*/fcscan(){ register i; register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; register bit; register struct tty *tp; int oldfcsilos = fcsilos; int fctimer(); register u_char fccan_modem; for (i = 0; i < fc_cnt; i++) { if (fcpdma[i].p_addr == 0) continue; tp = &fc_tty[i]; fccan_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 (!(fcaddr->fcmsr&FC_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 (fcdsr) fc_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 (fcdsr && ((fcmodem&MODEM_DSR)==0)) { fcmodem |= (MODEM_DSR_START|MODEM_DSR); /* * we should not look for CTS|CD for * about 500 ms. */ timeout(fc_dsr_check, tp, hz*30); timeout(fc_dsr_check, tp, hz/2); } } /* * Look for modem transitions in an already established * connection. */ if (tp->t_state & TS_CARR_ON) { if (fcaddr->fcmsr&FC_RCD) { /* * CD has come up again. * Stop timeout from occurring if set. * If interval is more than 2 secs then * drop DTR. */ if ((fcmodem&MODEM_CD)==0) { untimeout(fc_cd_drop, tp); if (fc_cd_down(tp)){ /* drop connection */ fc_tty_drop(tp); } fcmodem |= MODEM_CD; } } else { /* * Carrier must be down for greater than 2 secs * before closing down the line. */ if ( fcmodem & MODEM_CD) { /* only start timer once */ fcmodem &= ~MODEM_CD; /* * Record present time so that if carrier * comes up after 2 secs , the line will drop. */ fctimestamp = time; timeout(fc_cd_drop, tp, hz*2); } } /* CTS flow control check */ if (!(fcaddr->fcmsr&FC_RCTS)) { /* * Only allow transmission when CTS is set. */ tp->t_state |= TS_TTSTOP; fcmodem &= ~MODEM_CTS;# ifdef DEBUG if (fcdebug) cprintf("fcscan: CTS stop, tp=%x,line=%d\n", tp,i);# endif DEBUG fcstop(tp, 0); } else if ((fcmodem&MODEM_CTS)==0) { /* * Restart transmission upon return of CTS. */ tp->t_state &= ~TS_TTSTOP; fcmodem |= MODEM_CTS;# ifdef DEBUG if (fcdebug) cprintf("fcscan: CTS start, tp=%x,line=%d\n", tp,i);# endif DEBUG fcstart(tp); } } /* * See if a modem transition has occured. If we are waiting * for this signal cause action to be taken via fc_tty_start. */ if ((fccan_modem=fcaddr->fcmsr&FC_XMIT) != fccan_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 (fcdebug) cprintf("fcscan: MODEM Transition,fccan_modem=%x, fccan_prev=%x\n",fccan_modem,fccan_previous);# endif DEBUG /* * If fcdsr is set look for DSR|CTS|CD,else look * for CD|CTS only. */ if (fcdsr) { if (((fcaddr->fcmsr&FC_XMIT)==FC_XMIT) && ((fcmodem&MODEM_DSR_START)==0) && ((tp->t_state&TS_CARR_ON)==0)) {# ifdef DEBUG if (fcdebug) cprintf("fcscan:FC_XMIT call fc_start,line=%d\n",i);# endif DEBUG fc_start_tty(tp); } } /* * Ignore DSR. */ else if ((fcaddr->fcmsr&FC_NODSR)==FC_NODSR) fc_start_tty(tp); } fccan_previous = fccan_modem; /* save for next iteration */ } } for (i = 0; i < nNFC; i++) { ave(fcrate[i], fcchars[i], 8); /* * Allow silo mode only if no graphics device. * Silo mode blows away with mouse tracking. */ if (fc_allow_silos) { if (fcchars[i] > fchighrate && ((fcsilos&(1 << i)) == 0)) { fcaddr->fccsr = FC_MSE | FC_SAE; fcsilos |= (1 << i); fctransitions++; /*DEBUG*/ } if ((fcsilos&(1 << i)) && (fcrate[i] < fclowrate)) { fcaddr->fccsr = FC_MSE; fcsilos &= ~(1 << i); } } fcchars[i] = 0; } if (fcsilos && !oldfcsilos) timeout(fctimer, (caddr_t)0, fctimerintvl); timeout(fcscan, (caddr_t)0, hz);}fctimer(){ register int fc; register int s; if (fcsilos == 0) return; s = spl6(); fcfasttimers++; /*DEBUG*/ for (fc = 0; fc < nNFC; fc++) if (fcsilos & (1 << fc)) fcrint(fc); splx(s); timeout(fctimer, (caddr_t) 0, fctimerintvl);}/* 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 fcputc();int fcgetc();extern (*v_consputc)();extern (*v_consgetc)();extern int fgcons_init();fccons_init(){ register struct fc_regs *fcaddr; register struct fbic_regs *fbp; register struct pte *pteptr; register struct mb_node *mbp; int pri_cpuid; int i, base; int constype; int memctlr = 0; char *iocsraddr, *io_base_addr; int *scbptr; pri_cpuid = mfpr(CPUID); /* * The constant MB_2ND_FBIC_OFFSET is used here as which processor * this is, is determined from the CPUID register bit 1. */ cpu_fbic_addr = (long)(MB_SLOT0_BASE + MB_2ND_FBIC_OFFSET + ((pri_cpuid & 0x1e) << 23)); /* * I would have liked to do all of the mapping in ka60conf(), * but I need to get the console SLU registers mapped before I * can use the console, and in order to map the console, I need * to set up the FBIC, and so it needs to be mapped. The probe * of the M-Bus is done in ka60conf() in ka60.c */ /* * Look for a module in each slot and map it. */ pteptr = FFIOmap; fbp = (struct fbic_regs *)ffiom; mbp = mbus_nodes; for (i = MB_SLOT0_BASE; i <= MB_SLOT7_BASE; i = i + MB_SLOT_SIZE) { nxaccess((long)(i + MB_FBIC_OFFSET), pteptr++, 512); if((*cpup->badaddr)((caddr_t)&fbp->f_modtype, 4)) { fbp++; continue; } switch(fbp->f_modtype & FMOD_CLASS) { case FMOD_QBUS: ka60_mbfillin(mbp, fbp, (i + MB_FBIC_OFFSET), 0); /* * Map the CQBIC */ nxaccess((long *)cpup->nexaddr(0,1), FFQREGmap, 512); /* * Map the Q-bus Map registers */ nxaccess((long *)cpup->nexaddr(0,3), CVQBMmap, (512 * 68)); /* * The FQAM from Design Associates has the PROC field * in the cpuid register set to 3, where the FTAM has * them set to 0. This is how to determine if the module * is an FTAM or a FQAM. * The FQAM CSR is initialized by power-on diagnostics. * We don't initialize it. */ if (fbp->f_cpuid & FCPU_PROCA) { /* FQAM */ nxaccess((long *)FF_FQAM_CSR, FFFQAMCSRmap, 512); } /* * Initiaize the FBIC */ fbp->f_busaddr = 0; fbp->f_busctl = 0; fbp->f_buscsr = FBCSR_CLEAR; fbp->f_fbicsr |= FFCSR_IRQE_X | FFCSR_IRQD_X | FFCSR_PRI0EN | FFCSR_NORMAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -