void dartstart(struct tty *tp) { struct dartsoftc *sc; dev_t dev; int s; u_int port, chip; int c, tries; bus_addr_t ptaddr; if ((tp->t_state & TS_ISOPEN) == 0) return; dev = tp->t_dev; chip = DART_CHIP(dev); port = DART_PORT(dev); sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) goto bail; ttwakeupwr(tp); if (tp->t_outq.c_cc == 0) goto bail; tp->t_state |= TS_BUSY; while (tp->t_outq.c_cc != 0) { /* load transmitter until it is full */ for (tries = 10000; tries != 0; tries --) if (dart_read(sc, ptaddr + DART_SRA) & TXRDY) break; if (tries == 0) { timeout_add(&tp->t_rstrt_to, 1); tp->t_state |= TS_TIMEOUT; break; } else { c = getc(&tp->t_outq); dart_write(sc, ptaddr + DART_TBA, c & 0xff); sc->sc_sv_reg->sv_imr |= port == A_PORT ? ITXRDYA : ITXRDYB; dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); } } tp->t_state &= ~TS_BUSY; bail: splx(s); }
int dartopen(dev_t dev, int flag, int mode, struct proc *p) { int s, port; struct dart_info *dart; struct dartsoftc *sc; struct tty *tp; port = DART_PORT(dev); if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS) return (ENODEV); sc = (struct dartsoftc *)dart_cd.cd_devs[0]; /* the only one */ dart = &sc->sc_dart[port]; s = spltty(); if (dart->tty != NULL) tp = dart->tty; else tp = dart->tty = ttymalloc(); tp->t_oproc = dartstart; tp->t_param = dartparam; tp->t_dev = dev; if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = B9600; dartparam(tp, &tp->t_termios); if (port == CONS_PORT) { /* console is 8N1 */ tp->t_cflag = (CREAD | CS8 | HUPCL); } else { tp->t_cflag = TTYDEF_CFLAG; } ttsetwater(tp); (void)dartmctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET); tp->t_state |= TS_CARR_ON; } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) { splx(s); return (EBUSY); } /* * Reset the tty pointer, as there could have been a dialout * use of the tty with a dialin open waiting. */ tp->t_dev = dev; splx(s); return ((*linesw[tp->t_line].l_open)(dev, tp)); }
struct tty * darttty(dev_t dev) { unsigned int port; struct dartsoftc *sc; port = DART_PORT(dev); if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS) return (NULL); sc = (struct dartsoftc *)dart_cd.cd_devs[0]; return sc->sc_dart[port].tty; }
struct tty * darttty(dev_t dev) { u_int port, chip; struct dartsoftc *sc; chip = DART_CHIP(dev); port = DART_PORT(dev); if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS) return (NULL); sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; if (sc == NULL) return (NULL); return sc->sc_dart[port].tty; }
int dartwrite(dev_t dev, struct uio *uio, int flag) { int port; struct tty *tp; struct dart_info *dart; struct dartsoftc *sc; sc = (struct dartsoftc *)dart_cd.cd_devs[0]; port = DART_PORT(dev); dart = &sc->sc_dart[port]; tp = dart->tty; if (tp == NULL) return (ENXIO); return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); }
int dartread(dev_t dev, struct uio *uio, int flag) { u_int port, chip; struct tty *tp; struct dart_info *dart; struct dartsoftc *sc; chip = DART_CHIP(dev); port = DART_PORT(dev); sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; dart = &sc->sc_dart[port]; tp = dart->tty; if (tp == NULL) return (ENXIO); return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); }
int dartclose(dev_t dev, int flag, int mode, struct proc *p) { struct tty *tp; struct dart_info *dart; struct dartsoftc *sc; int port; sc = (struct dartsoftc *)dart_cd.cd_devs[0]; port = DART_PORT(dev); dart = &sc->sc_dart[port]; tp = dart->tty; (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); return (0); }
int dartmctl(dev_t dev, int flags, int how) { struct dartsoftc *sc; int port; int newflags = 0; struct dart_info *dart; int s; port = DART_PORT(dev); if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS) return (ENODEV); sc = (struct dartsoftc *)dart_cd.cd_devs[0]; dart = &sc->sc_dart[port]; s = spltty(); HANDLE_FLAG(TIOCM_DTR, port, OPDTRA, OPDTRB); HANDLE_FLAG(TIOCM_RTS, port, OPRTSA, OPRTSB); switch (how) { case DMSET: dart_write(sc, DART_OPRS, newflags); dart_write(sc, DART_OPRR, ~newflags); break; case DMBIS: dart_write(sc, DART_OPRS, newflags); break; case DMBIC: dart_write(sc, DART_OPRR, newflags); break; case DMGET: flags = 0; /* XXX not supported */ break; } splx(s); return (flags); }
int dartopen(dev_t dev, int flag, int mode, struct proc *p) { int s; u_int port, chip; struct dart_info *dart; struct dartsoftc *sc; struct tty *tp; chip = DART_CHIP(dev); port = DART_PORT(dev); if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS) return (ENODEV); sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; if (sc == NULL) return (ENODEV); dart = &sc->sc_dart[port]; s = spltty(); if (dart->tty != NULL) tp = dart->tty; else tp = dart->tty = ttymalloc(0); tp->t_oproc = dartstart; tp->t_param = dartparam; tp->t_dev = dev; if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); if (tp->t_ispeed == 0) { tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = B9600; if (sc->sc_console && port == CONS_PORT) { /* console is 8N1 */ tp->t_cflag = (CREAD | CS8 | HUPCL); } else { tp->t_cflag = TTYDEF_CFLAG; } } if (dart->dart_swflags & TIOCFLAG_CLOCAL) tp->t_cflag |= CLOCAL; if (dart->dart_swflags & TIOCFLAG_CRTSCTS) tp->t_cflag |= CRTSCTS; if (dart->dart_swflags & TIOCFLAG_MDMBUF) tp->t_cflag |= MDMBUF; dartparam(tp, &tp->t_termios); ttsetwater(tp); (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMSET); tp->t_state |= TS_CARR_ON; } else if (tp->t_state & TS_XCLUDE && suser(p, 0) != 0) { splx(s); return (EBUSY); } /* * Reset the tty pointer, as there could have been a dialout * use of the tty with a dialin open waiting. */ tp->t_dev = dev; splx(s); return ((*linesw[tp->t_line].l_open)(dev, tp, p)); }
int dartparam(struct tty *tp, struct termios *t) { int flags; u_int port, chip; int speeds; unsigned char mr1, mr2; struct dart_info *dart; struct dartsoftc *sc; dev_t dev; bus_addr_t ptaddr; dev = tp->t_dev; chip = DART_CHIP(dev); port = DART_PORT(dev); sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; dart = &sc->sc_dart[port]; ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE; tp->t_ispeed = t->c_ispeed; tp->t_ospeed = t->c_ospeed; tp->t_cflag = t->c_cflag; flags = tp->t_flags; /* Reset to make global changes*/ /* disable Tx and Rx */ if (sc->sc_console == 0 || CONS_PORT != port) { if (port == A_PORT) sc->sc_sv_reg->sv_imr &= ~(ITXRDYA | IRXRDYA); else sc->sc_sv_reg->sv_imr &= ~(ITXRDYB | IRXRDYB); dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); /* hang up on zero baud rate */ if (tp->t_ispeed == 0) { dartmctl(sc, port, HUPCL, DMSET); return (0); } else { /* set baudrate */ speeds = dart_speed(tp->t_ispeed); if (speeds == NOBAUD) speeds = sc->sc_sv_reg->sv_csr[port]; dart_write(sc, ptaddr + DART_CSRA, speeds); sc->sc_sv_reg->sv_csr[port] = speeds; } /* get saved mode registers and clear set up parameters */ mr1 = sc->sc_sv_reg->sv_mr1[port]; mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK); mr2 = sc->sc_sv_reg->sv_mr2[port]; mr2 &= ~SBMASK; /* set up character size */ switch (t->c_cflag & CSIZE) { case CL8: mr1 |= CL8; break; case CL7: mr1 |= CL7; break; case CL6: mr1 |= CL6; break; case CL5: mr1 |= CL5; break; } /* set up stop bits */ if (tp->t_ospeed == B110) mr2 |= SB2; else mr2 |= SB1; /* set up parity */ if (t->c_cflag & PARENB) { mr1 |= PAREN; if (t->c_cflag & PARODD) mr1 |= ODDPAR; else mr1 |= EVENPAR; } else mr1 |= PARDIS; if (sc->sc_sv_reg->sv_mr1[port] != mr1 || sc->sc_sv_reg->sv_mr2[port] != mr2) { /* write mode registers to duart */ dart_write(sc, ptaddr + DART_CRA, MRRESET); dart_write(sc, ptaddr + DART_MR1A, mr1); dart_write(sc, ptaddr + DART_MR2A, mr2); /* save changed mode registers */ sc->sc_sv_reg->sv_mr1[port] = mr1; sc->sc_sv_reg->sv_mr2[port] = mr2; } } /* enable transmitter? */ if (tp->t_state & TS_BUSY) { sc->sc_sv_reg->sv_imr |= port == A_PORT ? ITXRDYA : ITXRDYB; dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); } /* re-enable the receiver */ #if 0 DELAY_CR; #endif sc->sc_sv_reg->sv_imr |= port == A_PORT ? IRXRDYA : IRXRDYB; dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr); return (0); }
int dartioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { int error; u_int port, chip; struct tty *tp; struct dart_info *dart; struct dartsoftc *sc; chip = DART_CHIP(dev); port = DART_PORT(dev); sc = (struct dartsoftc *)dart_cd.cd_devs[chip]; dart = &sc->sc_dart[port]; tp = dart->tty; if (tp == NULL) return (ENXIO); error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); if (error >= 0) return(error); error = ttioctl(tp, cmd, data, flag, p); if (error >= 0) return(error); switch (cmd) { case TIOCSBRK: case TIOCCBRK: break; case TIOCSDTR: (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIS); break; case TIOCCDTR: (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIC); break; case TIOCMSET: (void)dartmctl(sc, port, *(int *) data, DMSET); break; case TIOCMBIS: (void)dartmctl(sc, port, *(int *) data, DMBIS); break; case TIOCMBIC: (void)dartmctl(sc, port, *(int *) data, DMBIC); break; case TIOCMGET: *(int *)data = dartmctl(sc, port, 0, DMGET); break; case TIOCGFLAGS: *(int *)data = dart->dart_swflags; break; case TIOCSFLAGS: error = suser(p, 0); if (error != 0) return (EPERM); dart->dart_swflags = *(int *)data; dart->dart_swflags &= /* only allow valid flags */ (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS); break; default: return (ENOTTY); } return (0); }
void dartstart(struct tty *tp) { struct dartsoftc *sc; dev_t dev; int s; int port, tries; int c; bus_addr_t ptaddr; dev = tp->t_dev; port = DART_PORT(dev); if (dart_cd.cd_ndevs == 0 || port >= NDARTPORTS) return; if ((tp->t_state & TS_ISOPEN) == 0) return; sc = (struct dartsoftc *)dart_cd.cd_devs[0]; ptaddr = port ? DART_B_BASE : DART_A_BASE; s = spltty(); if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) goto bail; if (tp->t_outq.c_cc <= tp->t_lowat) { if (tp->t_state & TS_ASLEEP) { tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); } selwakeup(&tp->t_wsel); if (tp->t_outq.c_cc == 0) goto bail; } tp->t_state |= TS_BUSY; while (tp->t_outq.c_cc != 0) { /* load transmitter until it is full */ for (tries = 10000; tries != 0; tries --) if (dart_read(sc, ptaddr + DART_SRA) & TXRDY) break; if (tries == 0) { timeout_add(&tp->t_rstrt_to, 1); tp->t_state |= TS_TIMEOUT; break; } else { c = getc(&tp->t_outq); dart_write(sc, ptaddr + DART_TBA, c & 0xff); if (port == A_PORT) sc->sc_sv_reg.sv_imr |= ITXRDYA; else sc->sc_sv_reg.sv_imr |= ITXRDYB; dart_write(sc, DART_IMR, sc->sc_sv_reg.sv_imr); } } tp->t_state &= ~TS_BUSY; bail: splx(s); }