📄 ss.c
字号:
tp->t_cflag &= ~CBAUD; tp->t_cflag = B9600; tp->t_cflag_ext &= ~CBAUD; tp->t_cflag_ext = B9600; tp->t_flags = ANYP|ECHO|CRMOD; tp->t_iflag |= ICRNL; /* Map CRMOD */ tp->t_oflag |= ONLCR; /* Map CRMOD */ } } ssparam(unit); /* enables interrupts */ (void) spl5(); /* * No modem control provided for lines with softCAR set. * Modem control provided only for line 2. */# ifdef DEBUG if (ssdebug) cprintf("ssopen: UNIT = %x\n",unit);# endif DEBUG if ((unit != MODEM_UNIT) || (tp->t_cflag & CLOCAL)) { /* * This is a local connection - ignore carrier * receive enable interrupts enabled above via ssparam() */ tp->t_state |= TS_CARR_ON; /* ssscan sets */ if (unit == MODEM_UNIT) ssaddr->ssdtr |= (SS_RDTR|SS_RRTS); /* * Set state bit to tell tty.c not to assign this line as the * controlling terminal for the process which opens this line. */ if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX)) tp->t_state |= TS_ONOCTTY; (void) spl0(); return ((*linesw[tp->t_line].l_open)(dev, tp)); } /* * this is a modem line */ /* receive enable interrupts enabled above via ssparam() */ ssaddr->ssdtr |= (SS_RDTR|SS_RRTS); /* * After DSR first comes up we must wait for the other signals * before commencing transmission. */#ifdef DEBUG if (ssdebug) { cprintf("open flag : %x\n", flag); if (flag & (O_NDELAY|O_NONBLOCK)) cprintf("flag & (O_NDELAY|O_NONBLOCK)\n"); }#endif DEBUG if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) { /* * Delay before examining other signals if DSR is being followed * otherwise proceed directly to ss_dsr_check to look for * carrier detect and clear to send. */#ifdef DEBUG if (ssdebug) { cprintf("ssopen: "); PRINT_SIGNALS(); }#endif DEBUG if (ssdsr) { if ((ssaddr->ssmsr)&SS_RDSR) { ssmodem |= (MODEM_DSR_START|MODEM_DSR); tp->t_dev = dev; /* need it for timeouts */ 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 { /* * Give Carrier and CTS 30 sec. to * come up. Prevent any transmission * in the first 500ms. */ timeout(ss_dsr_check, tp, hz*30); timeout(ss_dsr_check, tp, hz/2); } } } /* * Ignoring DSR so immediately check for CD & CTS. */ else { ssmodem |= (MODEM_DSR_START|MODEM_DSR); ss_dsr_check(tp); } }# ifdef DEBUG if (ssdebug) cprintf("ssopen: line=%d, state=%x, tp=%x\n", unit, tp->t_state, tp);# endif DEBUG if (flag & (O_NDELAY|O_NONBLOCK)) tp->t_state |= TS_ONDELAY; else while ((tp->t_state & TS_CARR_ON) == 0) { tp->t_state |= TS_WOPEN; inuse = tp->t_state&TS_INUSE;#ifdef DEBUG if (ssdebug) { cprintf("ss_open: going to sleep\n"); }#endif DEBUG sleep((caddr_t)&tp->t_rawq, TTIPRI); /* * See if we were awoken by a false call to the modem * line by a non-modem. */ if (ssmodem&MODEM_BADCALL){ (void) spl0(); return(EWOULDBLOCK); } /* if we opened "block if in use" and * the terminal was not inuse at that time * but is became "in use" while we were * waiting for carrier then return */ if ((flag & O_BLKINUSE) && (inuse==0) && (tp->t_state&TS_INUSE)) { (void) spl0(); return(EALREADY); } } /* * Set state bit to tell tty.c not to assign this line as the * controlling terminal for the process which opens this line. */ if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX)) tp->t_state |= TS_ONOCTTY; (void) spl0(); return ((*linesw[tp->t_line].l_open)(dev, tp));}/*ARGSUSED*/ssclose(dev, flag) dev_t dev;{ register struct tty *tp; register int unit; register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register int s; int ss; extern int wakeup(); unit = minor(dev); if((vs_cfgtst&VS_L3CON) && (major(dev) == CONSOLE_MAJOR) && ((unit&LINEMASK) == 0)) unit |= 3; /* diag console on SLU line 3 */ /* * Call the craphics device close routine * if ther is one and the close is for it. */ if ((vs_gdclose && (unit <= 1)) || (vs_gdclose && (unit == 2) && (major(dev) == CONSOLE_MAJOR))){ (*vs_gdclose)(dev, flag); return; } ss = unit >> 2;# ifdef DEBUG if (ssdebug) cprintf("ssclose: unit=%x, ss=%x\n",unit,ss);# endif DEBUG tp = &ss_tty[unit]; /* * Do line discipline specific close functions then return here * in the old line disc for final closing. */ if (tp->t_line) (*linesw[tp->t_line].l_close)(tp); /* * ssbrk is write-only and sends a BREAK (SPACE condition) until * the break control bit is cleared. Here we are clearing any * breaks for this line on close. */ ssaddr->ssbrk = (ss_brk[ss] &= ~(1 << (unit&LINEMASK))); if ((tp->t_cflag&HUPCL) || (tp->t_state&TS_WOPEN) || (tp->t_state&TS_ISOPEN)==0) { tp->t_state &= ~TS_CARR_ON; /* prevents recv intr. timeouts */ if (unit == MODEM_UNIT) { /* * Drop appropriate signals to terminate the connection. */ ssaddr->ssdtr &= ~(SS_RDTR|SS_RRTS); if ((tp->t_cflag & CLOCAL) == 0) { s = spl5(); /*drop DTR for at least a sec. if modem line*/# ifdef DEBUG if (ssdebug) cprintf("ssclose: DTR drop, state =%x\n" ,tp->t_state);# endif DEBUG tp->t_state |= TS_CLOSING; /* * Wait at most 5 sec for DSR to go off. * Also hold DTR down for a period. */ if (ssdsr && (ssaddr->ssmsr & SS_RDSR)) { timeout(wakeup,(caddr_t)&tp->t_dev,5*hz); sleep((caddr_t)&tp->t_dev, PZERO-10); } /* * Hold DTR down for 200+ ms. */ timeout(wakeup, (caddr_t) &tp->t_dev, hz/5); sleep((caddr_t)&tp->t_dev, PZERO-10); tp->t_state &= ~(TS_CLOSING); wakeup((caddr_t)&tp->t_rawq); splx(s); } } /* * No disabling of interrupts is done. Characters read in on * a non-open line will be discarded. */ } /* reset line to default mode */ sssoftCAR[ss] &= ~(1<<(unit&LINEMASK)); sssoftCAR[ss] |= (1<<(unit&LINEMASK)) & ssdefaultCAR[ss]; if (unit == MODEM_UNIT) ssmodem = 0; ttyclose(tp); tty_def_close(tp);}/* * ssread() shared with graphics device drivers (sm & sg). */ssread(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; register int unit; unit = minor(dev); if((vs_cfgtst&VS_L3CON) && (major(dev) == CONSOLE_MAJOR) && ((unit&LINEMASK) == 0)) unit |= 3; /* diag console on SLU line 3 */ if((unit == 1) && vs_gdread) return((*vs_gdread)(dev, uio)); /* color option */ if (vs_gdopen && (unit == 2) && (major(dev) == CONSOLE_MAJOR)) tp = &sm_tty; else tp = &ss_tty[unit]; return ((*linesw[tp->t_line].l_read)(tp, uio));}/* * sswrite() shared with graphics device drivers (sm & sg). */sswrite(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; register int unit; unit = minor(dev); if((vs_cfgtst&VS_L3CON) && (major(dev) == CONSOLE_MAJOR) && ((unit&LINEMASK) == 0)) unit |= 3; /* diag console on SLU line 3 */ if((unit == 1) && vs_gdwrite) return((*vs_gdwrite)(dev, uio)); /* color option */ /* * 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) == CONSOLE_MAJOR)) tp = &sm_tty; else tp = &ss_tty[unit]; return ((*linesw[tp->t_line].l_write)(tp, uio));}ssselect(dev, rw)dev_t dev;{ register int unit = minor(dev); if((vs_cfgtst&VS_L3CON) && (major(dev) == CONSOLE_MAJOR) && ((unit&3) == 0)) dev |= 3; if(((unit == 1) || (unit == 2)) && vs_gdselect && (major(dev) == CONSOLE_MAJOR)) 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*/ssrint(ss) int ss;{ register struct tty *tp; register int c; register struct nb_regs *ssaddr = (struct nb_regs *)nexus; register struct tty *tp0; register int unit; register int flg; int overrun = 0; struct ss_softc *sc; struct mouse_report *new_rep; u_short data; if ((ssact & (1<<ss)) == 0) return; unit = ss * 4; tp0 = &ss_tty[unit]; new_rep = ¤t_rep; /* mouse report pointer */ /* * 3/5/89 -- Fred Canter * Disable interrupts to prevent stray vectors * thru 0x1fc caused by polling with interrupts on. */ ssaddr->nb_int_msk &= ~SINT_SR; while (ssaddr->sscsr&SS_RDONE) { /* character present */ ssaddr->nb_int_reqclr = SINT_SR; c = ssaddr->ssrbuf; sschars[ss]++; unit = (c>>8)&LINEMASK; tp = tp0 + unit; if (tp >= &ss_tty[ss_cnt]) continue; sc = &ss_softc[ss]; /* * 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. */ 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 */ /* SS_FE is interpreted as a break */ if (c & SS_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 SSDEBUG if (ssdebug) mprintf("ssrint: BREAK RECEIVED\n");# endif SSDEBUG if ((tp->t_lflag_ext & PRAW) && (tp->t_line != TERMIODISC)) c = 0; else { ttyflush(tp, FREAD|FWRITE);#ifdef SSDEBUG if (ssdebug) mprintf("sending signal to tp->t_pgrp = %d\n", tp->t_pgrp);#endif SSDEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -