📄 dc7085.c
字号:
#endif DEBUG if ((flag & (O_NDELAY|O_NONBLOCK)) == 0) { /* * Delay before examining other signals if DSR is being followed * otherwise proceed directly to dc_dsr_check to look for * carrier detect and clear to send. */#ifdef DEBUG if (dcdebug) { cprintf("dcopen: "); PRINT_SIGNALS(); }#endif DEBUG if ((sc->dcmsr)&dc_rdsr[unit]) { dcmodem[unit] |= (MODEM_DSR_START|MODEM_DSR); tp->t_dev = dev; /* need it for timeouts */ if (!dc_modem_ctl) { /* * Assume carrier will come up in less * than 1 sec. If not DSR will drop * and the line will close */ timeout(dc_dsr_check, tp, hz); } else { /* * Give CD and CTS 30 sec. to * come up. Start transmission * immediately, no longer need * 500ms delay. */ timeout(dc_dsr_check, tp, hz*30); dc_dsr_check(tp); } } }# ifdef DEBUG if (dcdebug) cprintf("dcopen: 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 (dcdebug) { cprintf("dc_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 (dcmodem[unit]&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));}dcclose(dev, flag) dev_t dev;{ register struct dc_softc *sc; register struct tty *tp; register int unit, ctlr, maj; register int s; extern int wakeup(); unit = minor(dev); ctlr = unit >> 2; maj = major(dev); sc = &dc_softc[ctlr]; if((consDev != GRAPHIC_DEV) && (maj == CONSOLEMAJOR) && (unit == 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 (dc_base_board && (ctlr == 0)) if (vs_gdclose && (unit <= 1)) { (*vs_gdclose)(dev, flag); return; }# ifdef DEBUG if (dcdebug) cprintf("dcclose: unit=%x\n",unit);# endif DEBUG tp = &dc_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); /* * dcbrk 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. */ s = spltty(); brk_stop[unit] = 1; sc->dccsr |= DC_TIE; sc->dctcr |= (1 << (unit & LINEMASK)); splx(s); 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 */ /* * Drop appropriate signals to terminate the connection. */ dcmodem_active[ctlr] &= ~(1 << (unit & LINEMASK)); sc->dcdtr &= ~(dc_rdtr[unit] | dc_rrts[unit]); if ((tp->t_cflag & CLOCAL) == 0) { s = spltty(); /*drop DTR for at least a sec. if modem line*/# ifdef DEBUG if (dcdebug) cprintf("dcclose: 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 (sc->dcmsr & dc_rdsr[unit]) { 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 */ dcsoftCAR[ctlr] &= ~(1<<(unit&LINEMASK)); dcsoftCAR[ctlr] |= (1<<(unit&LINEMASK)) & dcdefaultCAR[ctlr]; dcmodem[unit] = 0; /* ttyclose() must be called before clear up termio flags */ ttyclose(tp); tty_def_close(tp);}dcread(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; register int unit, ctlr; unit = minor(dev); ctlr = unit >> 2; if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && (unit == 0)) unit |= 3; /* diag console on SLU line 3 */ tp = &dc_tty[unit]; return ((*linesw[tp->t_line].l_read)(tp, uio));}dcwrite(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; register int unit, ctlr; unit = minor(dev); ctlr = unit >> 2; if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && (unit == 0)) unit |= 3; /* diag console on SLU line 3 */ if (dc_base_board && (ctlr == 0)) { /* * 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); } } tp = &dc_tty[unit]; return ((*linesw[tp->t_line].l_write)(tp, uio));}dcselect(dev, rw)dev_t dev;{ register int ctlr, unit; unit = minor(dev); ctlr = unit >> 2;/*printf("in dcselect, dev = %x, ctlr = %d, unit = %d\n", dev, ctlr, unit);*/ if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && (unit == 0)) dev |= 3; if (dc_base_board && (ctlr == 0)) if ((unit == 1) && vs_gdselect) {/*printf("calling vs_gdselect = %x\n", vs_gdselect); */ return((*vs_gdselect)(dev, rw));} return(ttselect(dev, rw));}dcintr(ctlr)int ctlr;{ register struct dc_softc *sc; register unsigned int csr; sc = &dc_softc[ctlr]; csr = sc->dccsr; if (csr & DC_TRDY) _dcpdma(ctlr); if (csr & DC_RDONE) dcrint(ctlr);}/* * 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 pointer_id;#define MOUSE_ID 0x2dcrint(ctlr)int ctlr;{ register struct dc_softc *sc; register struct tty *tp; register u_short c; /* rbuf register is 16 bits long */ register int unit, linenum; register int flg; int overrun = 0; struct mouse_report *new_rep; u_short data; int counter = 0; sc = &dc_softc[ctlr]; new_rep = ¤t_rep; /* mouse report pointer */ while (sc->dccsr&DC_RDONE) { /* character present */ c = sc->dcrbuf; linenum = ((c >> 8) & LINEMASK); unit = (ctlr * NDCLINE) + linenum; tp = &dc_tty[unit]; if (tp >= &dc_tty[dc_cnt]) continue; /* * 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 ((dc_base_board) && (ctlr == 0) && (unit <= 1) && vs_gdkint) { if(unit == 0) { /* keyboard char */ (*vs_gdkint)(c); continue; } else { /* mouse or tablet report */ if (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); 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 */ /* DC_FE is interpreted as a break */ if (c & DC_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 DCDEBUG if (dcdebug) mprintf("dcrint: BREAK RECEIVED\n");# endif DCDEBUG if ((tp->t_lflag_ext & PRAW) && (tp->t_line != TERMIODISC)) c = 0; else { ttyflush(tp, FREAD | FWRITE); 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 & DC_PE){ /* * If input parity checking is not enabled, clear out * parity error in this character. */# ifdef DCDEBUG if (dcdebug > 1) mprintf("dcrint: Parity Error\n");# endif DCDEBUG if ((flg & INPCK) == 0) c &= ~DC_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&DC_DO) { if(overrun == 0) { printf("dc%d: input silo overflow\n", ctlr); overrun = 1; } sc->sc_softcnt[linenum]++; } 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*/dcioctl(dev, cmd, data, flag) dev_t dev; register int cmd; caddr_t data; int flag;{ register struct dc_softc *sc; register int unit, ctlr; register struct tty *tp; register int s; struct uba_device *ui; struct devget *devget; int error; unit = minor(dev); ctlr = unit >> 2; sc = &dc_softc[ctlr]; if((consDev != GRAPHIC_DEV) && (major(dev) == CONSOLEMAJOR) && (unit == 0)) unit |= 3; /* diag console on SLU line 3 */ /* * If there is a graphics device and the ioctl call * is for it, pass the call to the graphics driver. */ if (dc_base_board && (ctlr == 0)) if (vs_gdioctl && (unit <= 1)) { return((*vs_gdioctl)(dev, cmd, data, flag)); } tp = &dc_tty[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 */ dcparam(unit); break; } return (error); } switch (cmd) { case TIOCSBRK: timeout(dcsetbreak, tp, dc_delay[tp->t_cflag & CBAUD]); TTY_SLEEP(tp, (caddr_t)&tp->t_dev, TTOPRI); s = spltty(); brk_start[unit] = 1; sc->dccsr |= DC_TIE; sc->dctcr |= (1 << unit); splx(s); break; case TIOCCBRK: s = spltty(); brk_stop[unit] = 1; sc->dccsr |= DC_TIE; sc->dctcr |= (1 << unit); splx(s); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -