📄 fc.c
字号:
{ register struct tty *tp; register int unit; unit = minor(dev); if((ff_diagcons) && (major(dev) == CONSOLEMAJOR) && ((unit&LINEMASK) == 0)) unit |= 3; if((unit == 1) && vs_gdwrite) return((*vs_gdwrite)(dev, uio)); /* * Don't allow writes to the mouse, * just fake the I/O and return. */ if (vs_gdopen && (unit == 1)) { uio->uio_offset = uio->uio_resid; uio->uio_resid = 0; return(0); } if (vs_gdopen && (unit == 2) && (major(dev) == CONSOLEMAJOR)) tp = &sm_tty; else tp = &fc_tty[unit]; return ((*linesw[tp->t_line].l_write)(tp, uio));}fcselect(dev, rw)dev_t dev;{ register int unit = minor(dev); if((ff_diagcons) && (major(dev) == CONSOLEMAJOR) && ((unit&3) == 0)) dev |= 3; if(((unit == 1) || (unit == 2)) && vs_gdselect && (major(dev) == CONSOLEMAJOR)) return((*vs_gdselect)(dev, rw)); else return(ttselect(dev, rw));}/* * Used to pass mouse (or tablet) reports to the graphics * device driver interrupt service routine. * Entire report passed instead of byte at a time. */struct mouse_report current_rep;u_short sm_pointer_id;#define MOUSE_ID 0x2 /*ARGSUSED*/fcrint(fc) int fc;{ register struct tty *tp; register int c; register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; register struct tty *tp0; register int unit; register int flg; int overrun = 0; struct fc_softc *sc; struct mouse_report *new_rep; u_short data; if ((fcact & (1<<fc)) == 0) return; unit = fc * 4; tp0 = &fc_tty[unit]; new_rep = ¤t_rep; /* mouse report pointer */ while (fcaddr->fccsr&FC_RDONE) { /* character present */ c = fcaddr->fcrbuf; fcchars[fc]++; unit = (c>>8)&LINEMASK; tp = tp0 + unit; if (tp >= &fc_tty[fc_cnt]) continue; sc = &fc_softc[fc]; /* * If console is a graphics device, * pass keyboard input characters to * its device driver's receive interrupt routine. * Save up complete mouse report and pass it. *//*cprintf("FCDRIVER unit = %d c = %d ID = %d\n",unit, c, sm_pointer_id);*/ if ((unit <= 1) && vs_gdkint) { if(unit == 0) { /* keyboard char */ (*vs_gdkint)(c); continue; } else { /* mouse or tablet report */ if (sm_pointer_id == MOUSE_ID) { /* mouse report */ data = c & 0xff; /* get report byte */ ++new_rep->bytcnt; /* inc report byte count */ if (data & START_FRAME) { /* 1st byte of report? */ new_rep->state = data; if (new_rep->bytcnt > 1) new_rep->bytcnt = 1; /* start new frame */ } else if (new_rep->bytcnt == 2) /* 2nd byte */ new_rep->dx = data; else if (new_rep->bytcnt == 3) { /* 3rd byte */ new_rep->dy = data; new_rep->bytcnt = 0; (*vs_gdkint)(0400); /* 400 says line 1 */ } continue; } else { /* tablet report */ data = c; /* get report byte */ ++new_rep->bytcnt; /* inc report byte count */ if (data & START_FRAME) { /* 1st byte of report? */ new_rep->state = data; if (new_rep->bytcnt > 1) new_rep->bytcnt = 1; /* start new frame */ } else if (new_rep->bytcnt == 2) /* 2nd byte */ new_rep->dx = data & 0x3f; else if (new_rep->bytcnt == 3) /* 3rd byte */ new_rep->dx |= (data & 0x3f) << 6; else if (new_rep->bytcnt == 4) /* 4th byte */ new_rep->dy = data & 0x3f; else if (new_rep->bytcnt == 5){ /* 5th byte */ new_rep->dy |= (data & 0x3f) << 6; new_rep->bytcnt = 0; (*vs_gdkint)(0400); /* 400 says line 1 */ } continue; } } } if ((tp->t_state & TS_ISOPEN) == 0) { wakeup((caddr_t)&tp->t_rawq);#ifdef PORTSELECTOR if ((tp->t_state&TS_WOPEN) == 0)#endif continue; } flg = tp->t_iflag;/* This code handles the following termio input flags. Also * listed is what the default should be for propper Ultrix * backward compatibility. * * IGNBRK FALSE * BRKINT TRUE * IGNPAR TRUE * PARMRK FALSE * INPCK TRUE * ISTRIP TRUE */ /* FC_FE is interpreted as a break */ if (c & FC_FE) { /* * If configured for trusted path, initiate * trusted path handling. */ if (do_tpath) { tp->t_tpath |= TP_DOSAK; (*linesw[tp->t_line].l_rint)(c, tp); break; } if (flg & IGNBRK) continue; if (flg & BRKINT) {# ifdef FCDEBUG if (fcdebug) mprintf("fcrint: BREAK RECEIVED\n");# endif FCDEBUG if ((tp->t_lflag_ext & PRAW) && (tp->t_line != TERMIODISC)) c = 0; else { ttyflush(tp, FREAD|FWRITE);#ifdef FCDEBUG if (fcdebug) mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif FCDEBUG gsignal(tp->t_pgrp, SIGINT); continue; } } /* * TERMIO: If neither IGNBRK or BRKINT is set, a * break condition is read as a single '\0', * or if PARMRK is set as '\377','\0,'\0'. */ else { if (flg & PARMRK){ (*linesw[tp->t_line].l_rint)(0377,tp); (*linesw[tp->t_line].l_rint)(0,tp); } c = 0; } } /* Parity Error */ else if (c & FC_PE){ /* * If input parity checking is not enabled, clear out * parity error in this character. */# ifdef FCDEBUG if (fcdebug > 1) mprintf("fcrint: Parity Error\n");# endif FCDEBUG if ((flg & INPCK) == 0) c &= ~FC_PE; else { if (flg & IGNPAR) continue; /* If PARMRK is set, return a character with * framing or parity errors as a 3 character * sequence (0377,0,c). */ if (flg & PARMRK){ (*linesw[tp->t_line].l_rint)(0377,tp); (*linesw[tp->t_line].l_rint)(0,tp); } /* * TERMIO: If neither PARMRK or IGNPAR is set, a * parity error is read as a single '\0'. */ else c = 0; } } /* SVID does not say what to do with overrun errors */ if (c&FC_DO) { if(overrun == 0) { printf("fc%d: input silo overflow\n", fc); overrun = 1; } sc->sc_softcnt[unit]++; } if (flg & ISTRIP){ c &= 0177; } else { c &= 0377; /* If ISTRIP is not set a valid character of 377 * is read as 0377,0377 to avoid ambiguity with * the PARMARK sequence. */ if ((c == 0377) && (tp->t_line == TERMIODISC) && (flg & PARMRK)) (*linesw[tp->t_line].l_rint)(0377,tp); }#if NHC > 0 if (tp->t_line == HCLDISC) { HCINPUT(c, tp); } else#endif (*linesw[tp->t_line].l_rint)(c, tp); }}/*ARGSUSED*/fcioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register int unit; register struct tty *tp; register int fc; register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; register int s; struct uba_device *ui; struct fc_softc *sc; struct devget *devget; int error; unit = minor(dev); if((ff_diagcons) && ((unit&LINEMASK) == 0)) unit |= 3; /* * If there is a graphics device and the ioctl call * is for it, pass the call to the graphics driver. */ if (vs_gdioctl && (unit <= 1)) { error = (*vs_gdioctl)(dev, cmd, data, flag); return(error); } if (vs_gdioctl && (unit == 2) && (major(dev) == CONSOLEMAJOR)) { error = (*vs_gdioctl)(dev, cmd, data, flag); return(error); } tp = &fc_tty[unit]; fc = unit >> 2; ui = fcinfo[fc]; sc = &fc_softc[ui->ui_unit]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); if (error >= 0) return (error); error = ttioctl(tp, cmd, data, flag); if (error >= 0) { /* * If the call is to set terminal attributes which are * represented in the device's line parameter register then * call the param routine to update the device registers. */ switch(cmd) { case TCSANOW: /* POSIX termios */ case TCSADRAIN: /* POSIX termios */ 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 */ fcparam(unit); break; } return (error); } switch (cmd) { case TIOCSBRK: fcaddr->fcbrk = (fc_brk[fc] |= 1 << (unit&LINEMASK)); break; case TIOCCBRK: fcaddr->fcbrk = (fc_brk[fc] &= ~(1 << (unit&LINEMASK))); break; case TIOCSDTR: (void) fcmctl(dev, FC_DTR|FC_RTS, DMBIS); break; case TIOCCDTR: (void) fcmctl(dev, FC_DTR|FC_RTS, DMBIC); break; case TIOCMSET: (void) fcmctl(dev, dmtofc(*(int *)data), DMSET); break; case TIOCMBIS: (void) fcmctl(dev, dmtofc(*(int *)data), DMBIS); break; case TIOCMBIC: (void) fcmctl(dev, dmtofc(*(int *)data), DMBIC); break; case TIOCMGET: *(int *)data = fctodm(fcmctl(dev, 0, DMGET)); break; case TIOCNMODEM: /* ignore modem status */ /* * By setting the software representation of modem signals * to "on" we fake the system into thinking that this is an * established modem connection. */ s = spl6(); fcsoftCAR[fc] |= (1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ fcdefaultCAR[fc] |= (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 */ if(unit != MODEM_UNIT) break; /* ONLY line 2 has modem control */ s = spl6(); fcsoftCAR[fc] &= ~(1<<(unit&LINEMASK)); if (*(int *)data) /* make mode permanent */ fcdefaultCAR[fc] &= ~(1<<(unit&LINEMASK)); /* * See if all signals necessary for modem connection are present * * If fcdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((fcdsr && ((fcaddr->fcmsr&FC_XMIT) == FC_XMIT)) || ((fcdsr==0) && ((fcaddr->fcmsr&FC_NODSR) == FC_NODSR))) { tp->t_state &= ~(TS_ONDELAY); tp->t_state |= TS_CARR_ON; fcmodem = MODEM_CTS|MODEM_CD|MODEM_DSR; } else { tp->t_state &= ~(TS_CARR_ON); fcmodem &= ~(MODEM_CTS|MODEM_CD|MODEM_DSR); } tp->t_cflag &= ~CLOCAL; /* Map to termio */ splx(s); break; case TIOCWONLINE: if(unit != MODEM_UNIT) break; /* ONLY line 2 has modem control */ s = spl6(); /* * See if all signals necessary for modem connection are present * * If fcdsr is set look for DSR|CTS|CD, otherwise look * for CD|CTS only. */ if ((fcdsr && ((fcaddr->fcmsr&FC_XMIT) == FC_XMIT)) || ((fcdsr==0) && ((fcaddr->fcmsr&FC_NODSR) == FC_NODSR))) { tp->t_state |= TS_CARR_ON; tp->t_state &= ~(TS_ONDELAY); fcmodem = MODEM_CTS|MODEM_CD|MODEM_DSR; } else 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(unit == MODEM_UNIT) { if (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; /* terminal cat.*/ devget->bus = DEV_NB; /* NO bus */ bcopy(DEV_FF_SLU,devget->interface, strlen(DEV_FF_SLU)); /* interface */ bcopy(DEV_UNKNOWN,devget->device, strlen(DEV_UNKNOWN)); /* terminal */ devget->adpt_num = 0; /* NO adapter */ devget->nexus_num = 0; /* fake nexus 0 */ devget->bus_num = 0; /* NO bus */ devget->ctlr_num = fc; /* cntlr number */ devget->slave_num = unit&LINEMASK; /* line number */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "fc" */ devget->unit_num = unit&LINEMASK; /* fc line? */ devget->soft_count = sc->sc_softcnt[unit&LINEMASK]; /* soft err cnt */ devget->hard_count = sc->sc_hardcnt[unit&LINEMASK]; /* hard err 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);}dmtofc(bits) register int bits;{ register int b; b = (bits >>1) & 0370; if (bits & SML_ST) b |= FC_ST; if (bits & SML_RTS) b |= FC_RTS; if (bits & SML_DTR) b |= FC_DTR; if (bits & SML_LE) b |= FC_LE; return(b);}fctodm(bits) register int bits;{ register int b; b = (bits << 1) & 0360; if (bits & FC_DSR) b |= SML_DSR; if (bits & FC_DTR) b |= SML_DTR; if (bits & FC_ST) b |= SML_ST; if (bits & FC_RTS) b |= SML_RTS; return(b);}fcparam(unit) register int unit;{ register struct tty *tp; register struct fc_regs *fcaddr = (struct fc_regs *)ffcons; register int lpr; tp = &fc_tty[unit]; if (fcsilos & (1 << (unit >> 2))) fcaddr->fccsr = FC_MSE | FC_SAE; else fcaddr->fccsr = FC_MSE;/* * Reversing the order of the following two lines fixes the * problem where the console device locks up if you type a * character during autoconf and you must halt/continue to * unlock the console. Interrupts were being enabled on the SLU * before the fcact flag was set, so the driver would just return * and not process the waiting character (caused by you typing). * This locked up the cosnole SLU (interrupt posted but never really * servcied). Halting the system caused the console firmware to unlock * the SLU because it needs to use it. * Should fcparam() be called as spl6?????? */ fcact |= (1<<(unit>>2)); fcaddr->fccsr |= FC_RIE | FC_TIE; 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) fcmctl(unit, FC_OFF, DMSET); /* hang up line */ return; } /* * If diagnostic console on line 3, * line parameters must be: 9600 BPS, 8 BIT, NO PARITY, 1 STOP. * Same for color/monochrome video, except 4800 BPS. * Mouse/tablet: 4800 BPS, 8 BIT, ODD PARITY, 1 STOP. * If none of the above, assume attached console on line 0, * same paramaters as diagnostic console on line 3. */ if ((unit == 3) && (ff_diagcons)) fcaddr->fclpr = (FC_RE | FC_B9600 | BITS8 | 3); else if (unit == 0) { if (vs_gdopen) fcaddr->fclpr = (FC_RE | FC_B4800 | BITS8); else fcaddr->fclpr = (FC_RE | FC_B9600 | BITS8); } else if (vs_gdopen && (unit == 1)) fcaddr->fclpr = (FC_RE | FC_B4800 | OPAR | PENABLE | BITS8 | 1); /* * Set parameters in accordance with user specification. */ else { lpr = (fc_speeds[tp->t_cflag&CBAUD]<<8) | (unit & LINEMASK); /* * Berkeley-only dinosaur
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -