int at91usart_open(dev_t dev, int flag, int mode, struct lwp *l) { struct at91usart_softc *sc; struct tty *tp; int s; int error; sc = device_lookup_private(&at91usart_cd, COMUNIT(dev)); if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK)) return (ENXIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) return (EBUSY); #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; if (sc->enable) { if ((*sc->enable)(sc)) { splx(s); printf("%s: device enable failed\n", device_xname(sc->sc_dev)); return (EIO); } sc->enabled = 1; #if 0 /* XXXXXXXXXXXXXXX */ com_config(sc); #endif } /* reset fifos: */ AT91PDC_RESET_FIFO(sc->sc_iot, sc->sc_ioh, sc->sc_dmat, US_PDC, &sc->sc_rx_fifo, 0); AT91PDC_RESET_FIFO(sc->sc_iot, sc->sc_ioh, sc->sc_dmat, US_PDC, &sc->sc_tx_fifo, 1); /* reset receive */ at91usart_writereg(sc, US_CR, US_CR_RSTSTA | US_CR_STTTO); /* Turn on interrupts. */ sc->sc_ier = US_CSR_ENDRX|US_CSR_RXBUFF|US_CSR_TIMEOUT|US_CSR_RXBRK; at91usart_writereg(sc, US_IER, sc->sc_ier); /* enable DMA: */ at91usart_writereg(sc, US_PDC + PDC_PTCR, PDC_PTCR_RXTEN); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; /* if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { t.c_ospeed = usart_cn_sc.sc_ospeed; t.c_cflag = usart_cn_sc.sc_cflag; } else*/ { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure at91usart_param() will do something. */ tp->t_ospeed = 0; (void) at91usart_param(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); /* and unblock. */ CLR(sc->sc_rx_flags, RX_ANY_BLOCK); #ifdef COM_DEBUG if (at91usart_debug) comstatus(sc, "at91usart_open "); #endif } splx(s); error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ at91usart_shutdown(sc); } return (error); }
int sacomopen(dev_t dev, int flag, int mode, struct lwp *l) { struct sacom_softc *sc; struct tty *tp; int s, s2; int error; sc = device_lookup_private(&sacom_cd, COMUNIT(dev)); if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) || sc->sc_rbuf == NULL) return ENXIO; if (!device_is_active(&sc->sc_dev)) return ENXIO; tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; s2 = splserial(); COM_LOCK(sc); if (sc->enable) { if ((*sc->enable)(sc)) { COM_UNLOCK(sc); splx(s2); splx(s); printf("%s: device enable failed\n", sc->sc_dev.dv_xname); return EIO; } sc->enabled = 1; sacom_config(sc); } /* Turn on interrupts. */ sc->sc_cr3 = CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE; bus_space_write_4(sc->sc_iot, sc->sc_ioh, SACOM_CR3, sc->sc_cr3); COM_UNLOCK(sc); splx(s2); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { t.c_ospeed = sacomconsrate; t.c_cflag = sacomconscflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure sacomparam() will do something. */ tp->t_ospeed = 0; (void) sacomparam(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); s2 = splserial(); COM_LOCK(sc); /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR * immediately after setting CLOCAL, which applications do not * expect. We always assert DTR while the device is open * unless explicitly requested to deassert it. */ sacom_modem(sc, 1); /* Clear the input ring, and unblock. */ sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = SACOM_RING_SIZE; sacom_iflush(sc); CLR(sc->sc_rx_flags, RX_ANY_BLOCK); sacom_hwiflow(sc); #ifdef COM_DEBUG if (sacom_debug) comstatus(sc, "sacomopen "); #endif COM_UNLOCK(sc); splx(s2); } splx(s); error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return 0; bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ sacom_shutdown(sc); } return error; }
int at91dbgu_open(dev_t dev, int flag, int mode, struct lwp *l) { struct at91dbgu_softc *sc; struct tty *tp; int s, s2; int error; sc = device_lookup_private(&at91dbgu_cd, COMUNIT(dev)); if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) || sc->sc_rbuf == NULL) return (ENXIO); if (!device_is_active(sc->sc_dev)) return (ENXIO); #ifdef KGDB /* * If this is the kgdb port, no other use is permitted. */ if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) return (EBUSY); #endif tp = sc->sc_tty; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); /* * Do the following iff this is a first open. */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; tp->t_dev = dev; s2 = splserial(); if (sc->enable) { if ((*sc->enable)(sc)) { splx(s2); splx(s); printf("%s: device enable failed\n", device_xname(sc->sc_dev)); return (EIO); } sc->enabled = 1; #if 0 /* XXXXXXXXXXXXXXX */ com_config(sc); #endif } /* Turn on interrupts. */ sc->sc_ier |= DBGU_INT_RXRDY; DBGUREG(DBGU_IER) = DBGU_INT_RXRDY; #if 0 /* Fetch the current modem control status, needed later. */ sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr); /* Clear PPS capture state on first open. */ sc->sc_ppsmask = 0; sc->ppsparam.mode = 0; #endif splx(s2); /* * Initialize the termios status to the defaults. Add in the * sticky bits from TIOCSFLAGS. */ t.c_ispeed = 0; if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { t.c_ospeed = dbgu_cn_sc.sc_ospeed; t.c_cflag = dbgu_cn_sc.sc_cflag; } else { t.c_ospeed = TTYDEF_SPEED; t.c_cflag = TTYDEF_CFLAG; } if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL)) SET(t.c_cflag, CLOCAL); if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS)) SET(t.c_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF)) SET(t.c_cflag, MDMBUF); /* Make sure at91dbgu_param() will do something. */ tp->t_ospeed = 0; (void) at91dbgu_param(tp, &t); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; ttychars(tp); ttsetwater(tp); s2 = splserial(); /* Clear the input ring, and unblock. */ sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = AT91DBGU_RING_SIZE; at91dbgu_iflush(sc); CLR(sc->sc_rx_flags, RX_ANY_BLOCK); #ifdef COM_DEBUG if (at91dbgu_debug) comstatus(sc, "at91dbgu_open "); #endif splx(s2); } splx(s); error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) goto bad; error = (*tp->t_linesw->l_open)(dev, tp); if (error) goto bad; return (0); bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* * We failed to open the device, and nobody else had it opened. * Clean up the state as appropriate. */ at91dbgu_shutdown(sc); } return (error); }
int comopen(dev_t dev, int flag, int mode, struct lwp *l) { struct com_softc *sc; int iobase; struct tty *tp; int s; int error = 0; sc = device_lookup_private(&xcom_cd, COMUNIT(dev)); if (!sc) return ENXIO; if (!sc->sc_tty) { tp = sc->sc_tty = ttymalloc(); tty_attach(tp); } else tp = sc->sc_tty; tp->t_oproc = comstart; tp->t_param = comparam; tp->t_dev = dev; if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) return (EBUSY); s = spltty(); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { ttychars(tp); tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_cflag = TTYDEF_CFLAG; if (ISSET(sc->sc_swflags, COM_SW_CLOCAL)) SET(tp->t_cflag, CLOCAL); if (ISSET(sc->sc_swflags, COM_SW_CRTSCTS)) SET(tp->t_cflag, CRTSCTS); if (ISSET(sc->sc_swflags, COM_SW_MDMBUF)) SET(tp->t_cflag, MDMBUF); tp->t_lflag = TTYDEF_LFLAG; tp->t_ispeed = tp->t_ospeed = comdefaultrate; comparam(tp, &tp->t_termios); ttsetwater(tp); if (comsopen++ == 0) callout_reset(&com_poll_ch, 1, compollin, NULL); sc->sc_ibufp = sc->sc_ibuf = sc->sc_ibufs[0]; sc->sc_ibufhigh = sc->sc_ibuf + COM_IHIGHWATER; sc->sc_ibufend = sc->sc_ibuf + COM_IBUFSIZE; iobase = sc->sc_iobase; #ifdef COM_HAYESP /* Setup the ESP board */ if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) { int hayespbase = sc->sc_hayespbase; outb(iobase + com_fifo, FIFO_DMA_MODE|FIFO_ENABLE| FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_8); /* Set 16550 compatibility mode */ outb(hayespbase + HAYESP_CMD1, HAYESP_SETMODE); outb(hayespbase + HAYESP_CMD2, HAYESP_MODE_FIFO|HAYESP_MODE_RTS| HAYESP_MODE_SCALE); /* Set RTS/CTS flow control */ outb(hayespbase + HAYESP_CMD1, HAYESP_SETFLOWTYPE); outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_RTS); outb(hayespbase + HAYESP_CMD2, HAYESP_FLOW_CTS); /* Set flow control levels */ outb(hayespbase + HAYESP_CMD1, HAYESP_SETRXFLOW); outb(hayespbase + HAYESP_CMD2, HAYESP_HIBYTE(HAYESP_RXHIWMARK)); outb(hayespbase + HAYESP_CMD2, HAYESP_LOBYTE(HAYESP_RXHIWMARK)); outb(hayespbase + HAYESP_CMD2, HAYESP_HIBYTE(HAYESP_RXLOWMARK)); outb(hayespbase + HAYESP_CMD2, HAYESP_LOBYTE(HAYESP_RXLOWMARK)); } else #endif if (ISSET(sc->sc_hwflags, COM_HW_FIFO)) /* Set the FIFO threshold based on the receive speed. */ outb(pio(iobase , com_fifo), FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | (tp->t_ispeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8)); /* flush any pending I/O */ while (ISSET(inb(pio(iobase , com_lsr)), LSR_RXRDY)) (void) inb(pio(iobase , com_data)); /* you turn me on, baby */ sc->sc_mcr = MCR_DTR | MCR_RTS; if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN)) SET(sc->sc_mcr, MCR_IENABLE | MCR_DRS); /* */ outb(pio(iobase , com_mcr), sc->sc_mcr); sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC; outb(pio(iobase , com_ier), sc->sc_ier); sc->sc_msr = inb(pio(iobase , com_msr)); if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF)) SET(tp->t_state, TS_CARR_ON); else CLR(tp->t_state, TS_CARR_ON); } splx(s); error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (!error) error = (*tp->t_linesw->l_open)(dev, tp); /* XXX cleanup on error */ return error; }