/* Initialization for serial console */ int sacominit(bus_space_tag_t iot, bus_addr_t iobase, int baud, tcflag_t cflag, bus_space_handle_t *iohp) { int brd, cr0; if (bus_space_map(iot, iobase, SACOM_NPORTS, 0, iohp)) printf("register map failed\n"); /* wait for the Tx queue to drain and disable the UART */ while (bus_space_read_4(iot, *iohp, SACOM_SR1) & SR1_TBY) continue; bus_space_write_4(iot, *iohp, SACOM_CR3, 0); cr0 = cflag2cr0(cflag); bus_space_write_4(iot, *iohp, SACOM_CR0, cr0); brd = SACOMSPEED(baud); sacomconsrate = baud; sacomconsaddr = iobase; sacomconscflag = cflag; /* XXX assumes little endian */ bus_space_write_4(iot, *iohp, SACOM_CR1, brd >> 8); bus_space_write_4(iot, *iohp, SACOM_CR2, brd & 0xff); /* enable the UART */ bus_space_write_4(iot, *iohp, SACOM_CR3, CR3_RXE | CR3_TXE); return 0; }
static int sa1110_bus_param(struct uart_softc *sc, int baudrate, int databits, int stopbits, int parity) { int brd; if (baudrate > 0) { brd = SACOMSPEED(baudrate); uart_setreg(&sc->sc_bas, SACOM_CR1, brd >> 8); uart_setreg(&sc->sc_bas, SACOM_CR2, brd & 0xff); }
static void sa1110_init(struct uart_bas *bas, int baudrate, int databits, int stopbits, int parity) { int brd; if (bas->rclk == 0) bas->rclk = DEFAULT_RCLK; while (uart_getreg(bas, SACOM_SR1) & SR1_TBY); uart_setreg(bas, SACOM_CR3, 0); brd = SACOMSPEED(baudrate); uart_setreg(bas, SACOM_CR1, brd >> 8); uart_setreg(bas, SACOM_CR2, brd & 0xff); uart_setreg(bas, SACOM_CR3, CR3_RXE | CR3_TXE); }
int sacomparam(struct tty *tp, struct termios *t) { struct sacom_softc *sc = device_lookup_private(&sacom_cd, COMUNIT(tp->t_dev)); int ospeed = SACOMSPEED(t->c_ospeed); u_int cr0; int s; if (COM_ISALIVE(sc) == 0) return EIO; /* Check requested parameters. */ if (ospeed < 0) return EINVAL; if (t->c_ispeed && t->c_ispeed != t->c_ospeed) return EINVAL; /* * For the console, always force CLOCAL and !HUPCL, so that the port * is always active. */ if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) || ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { SET(t->c_cflag, CLOCAL); CLR(t->c_cflag, HUPCL); } /* * If there were no changes, don't do anything. This avoids dropping * input and improves performance when all we did was frob things like * VMIN and VTIME. */ if (tp->t_ospeed == t->c_ospeed && tp->t_cflag == t->c_cflag) return 0; cr0 = cflag2cr0(t->c_cflag); s = splserial(); COM_LOCK(sc); sc->sc_cr0 = cr0; sc->sc_speed = ospeed; /* And copy to tty. */ tp->t_ispeed = 0; tp->t_ospeed = t->c_ospeed; tp->t_cflag = t->c_cflag; if (!sc->sc_heldchange) { if (sc->sc_tx_busy) { sc->sc_heldtbc = sc->sc_tbc; sc->sc_tbc = 0; sc->sc_heldchange = 1; } else sacom_loadchannelregs(sc); } if (!ISSET(t->c_cflag, CHWFLOW)) { /* Disable the high water mark. */ if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); sacom_schedrx(sc); } if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) { CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED); sacom_hwiflow(sc); } } COM_UNLOCK(sc); splx(s); (void) (*tp->t_linesw->l_modem)(tp, 1); #ifdef COM_DEBUG if (sacom_debug) comstatus(sc, "comparam "); #endif return 0; }
void sacom_attach_subr(struct sacom_softc *sc) { bus_addr_t iobase = sc->sc_baseaddr; bus_space_tag_t iot = sc->sc_iot; struct tty *tp; /* XXX Do we need to disable interrupts here? */ if (iot == sacomconstag && iobase == sacomconsaddr) { sacomconsattached = 1; sc->sc_speed = SACOMSPEED(sacomconsrate); /* Make sure the console is always "hardwired". */ delay(10000); /* wait for output to finish */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, TIOCFLAG_SOFTCAR); } tp = ttymalloc(); tp->t_oproc = sacomstart; tp->t_param = sacomparam; tp->t_hwiflow = sacomhwiflow; sc->sc_tty = tp; sc->sc_rbuf = malloc(SACOM_RING_SIZE << 1, M_DEVBUF, M_NOWAIT); sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf; sc->sc_rbavail = SACOM_RING_SIZE; if (sc->sc_rbuf == NULL) { printf("%s: unable to allocate ring buffer\n", sc->sc_dev.dv_xname); return; } sc->sc_ebuf = sc->sc_rbuf + (SACOM_RING_SIZE << 1); sc->sc_tbc = 0; tty_attach(tp); if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; /* locate the major number */ maj = cdevsw_lookup_major(&sacom_cdevsw); cn_tab->cn_dev = makedev(maj, device_unit(&sc->sc_dev)); delay(10000); /* XXX */ printf("%s: console\n", sc->sc_dev.dv_xname); delay(10000); /* XXX */ } sc->sc_si = softint_establish(SOFTINT_SERIAL, sacomsoft, sc); #if NRND > 0 && defined(RND_COM) rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, RND_TYPE_TTY, 0); #endif /* if there are no enable/disable functions, assume the device is always enabled */ if (!sc->enable) sc->enabled = 1; sacom_config(sc); SET(sc->sc_hwflags, COM_HW_DEV_OK); }