Lines Matching refs:ch

153 static void sbscn_enable_debugport(struct sbscn_channel *ch);
155 void sbscn_config(struct sbscn_channel *ch);
156 void sbscn_shutdown(struct sbscn_channel *ch);
254 #define GET_INPUT_SIGNALS(ch) \
255 ((~READ_REG(MIPS_PHYS_TO_KSEG1((ch)->ch_sc->sc_addr + 0x280))) & (ch)->ch_i_mask)
256 #define SET_OUTPUT_SIGNALS(ch, val) \
260 sigs_to_set = (ch)->ch_o_mask & val; \
261 sigs_to_clr = (ch)->ch_o_mask & ~val; \
264 WRITE_REG(MIPS_PHYS_TO_KSEG1((ch)->ch_sc->sc_addr + 0x2c0), \
266 WRITE_REG(MIPS_PHYS_TO_KSEG1((ch)->ch_sc->sc_addr + 0x2b0), \
304 struct sbscn_channel *ch = &sc->sc_channels[chan];
308 ch->ch_sc = sc;
309 ch->ch_num = chan;
312 ch->ch_base = (void *)MIPS_PHYS_TO_KSEG1(chan_addr);
313 ch->ch_isr_base =
315 ch->ch_imr_base =
318 ch->ch_inchg_base =
322 ch->ch_i_dcd = ch->ch_i_dcd_pin = 0 /* XXXCGD */;
323 ch->ch_i_cts = ch->ch_i_cts_pin = 0 /* XXXCGD */;
324 ch->ch_i_dsr = ch->ch_i_dsr_pin = 0 /* XXXCGD */;
325 ch->ch_i_ri = ch->ch_i_ri_pin = 0 /* XXXCGD */;
326 ch->ch_i_mask =
327 ch->ch_i_dcd | ch->ch_i_cts | ch->ch_i_dsr | ch->ch_i_ri;
328 ch->ch_o_dtr = ch->ch_o_dtr_pin = 0 /* XXXCGD */;
329 ch->ch_o_rts = ch->ch_o_rts_pin = 0 /* XXXCGD */;
330 ch->ch_o_mask = ch->ch_o_dtr | ch->ch_o_rts;
332 ch->ch_intrhand = cpu_intr_establish(intr, IPL_SERIAL, sbscn_intr, ch);
333 callout_init(&ch->ch_diag_callout, 0);
336 ch->ch_imr = 0;
337 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
345 SET(ch->ch_hwflags, SBSCN_HW_CONSOLE);
346 SET(ch->ch_swflags, TIOCFLAG_SOFTCAR);
354 ch->ch_tty = tp;
355 ch->ch_rbuf = kmem_alloc(sbscn_rbuf_size << 1, KM_SLEEP);
356 ch->ch_ebuf = ch->ch_rbuf + (sbscn_rbuf_size << 1);
360 if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) {
388 ch->ch_si = softint_establish(SOFTINT_SERIAL, sbscn_soft, ch);
391 rnd_attach_source(&ch->ch_rnd_source, device_xname(sc->sc_dev),
396 sbscn_config(ch);
398 SET(ch->ch_hwflags, SBSCN_HW_DEV_OK);
433 sbscn_status(struct sbscn_channel *ch, const char *str)
435 struct sbscn_softc *sc = ch->ch_sc;
436 struct tty *tp = ch->ch_tty;
440 ch->ch_num, str,
442 ISSET(ch->ch_iports, ch->ch_i_dcd) ? "+" : "-",
444 ISSET(ch->ch_oports, ch->ch_o_dtr) ? "+" : "-",
445 ch->ch_tx_stopped ? "+" : "-");
449 ch->ch_num, str,
451 ISSET(ch->ch_iports, ch->ch_i_cts) ? "+" : "-",
453 ISSET(ch->ch_oports, ch->ch_o_rts) ? "+" : "-",
454 ch->ch_rx_flags);
460 sbscn_enable_debugport(struct sbscn_channel *ch)
468 ch->ch_imr = 0x04;
470 ch->ch_imr = 0x00;
472 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
473 SET(ch->ch_oports, ch->ch_o_dtr | ch->ch_o_rts);
474 SET_OUTPUT_SIGNALS(ch, ch->ch_oports);
481 sbscn_config(struct sbscn_channel *ch)
485 ch->ch_imr = 0x00;
486 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
489 if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE))
490 sbscn_enable_debugport(ch);
498 if (ISSET(ch->ch_hwflags, SBSCN_HW_KGDB))
499 sbscn_enable_debugport(ch);
504 sbscn_shutdown(struct sbscn_channel *ch)
506 struct tty *tp = ch->ch_tty;
512 SET(ch->ch_rx_flags, RX_IBUF_BLOCKED);
513 sbscn_dohwiflow(ch);
516 sbscn_break(ch, 0);
524 sbscn_modem(ch, 0);
527 (void) tsleep(ch, TTIPRI, ttclos, hz);
533 if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE))
535 ch->ch_imr = 0x04; /* interrupt on break */
537 ch->ch_imr = 0x00;
541 ch->ch_imr = 0;
542 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
552 struct sbscn_channel *ch;
560 ch = &sc->sc_channels[chan];
561 if (!ISSET(ch->ch_hwflags, SBSCN_HW_DEV_OK) || ch->ch_rbuf == NULL)
568 if (ISSET(ch->ch_hwflags, SBSCN_HW_KGDB))
572 tp = ch->ch_tty;
591 ch->ch_imr = 0xe;
593 ch->ch_imr = 0x2;
595 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
598 ch->ch_iports = GET_INPUT_SIGNALS(ch);
599 ch->ch_iports_delta = 0;
607 if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) {
614 if (ISSET(ch->ch_swflags, TIOCFLAG_CLOCAL))
616 if (ISSET(ch->ch_swflags, TIOCFLAG_CRTSCTS))
618 if (ISSET(ch->ch_swflags, TIOCFLAG_MDMBUF))
638 sbscn_modem(ch, 1);
641 ch->ch_rbput = ch->ch_rbget = ch->ch_rbuf;
642 ch->ch_rbavail = sbscn_rbuf_size;
643 sbscn_iflush(ch);
644 CLR(ch->ch_rx_flags, RX_ANY_BLOCK);
645 sbscn_dohwiflow(ch);
649 sbscn_status(ch, "sbscnopen ");
673 sbscn_shutdown(ch);
683 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(dev)];
684 struct tty *tp = ch->ch_tty;
699 sbscn_shutdown(ch);
709 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(dev)];
710 struct tty *tp = ch->ch_tty;
719 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(dev)];
720 struct tty *tp = ch->ch_tty;
729 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(dev)];
730 struct tty *tp = ch->ch_tty;
739 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(dev)];
740 struct tty *tp = ch->ch_tty;
749 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(dev)];
750 struct tty *tp = ch->ch_tty;
768 sbscn_break(ch, 1);
772 sbscn_break(ch, 0);
776 sbscn_modem(ch, 1);
780 sbscn_modem(ch, 0);
784 *(int *)data = ch->ch_swflags;
792 ch->ch_swflags = *(int *)data;
798 tiocm_to_sbscn(ch, cmd, *(int *)data);
802 *(int *)data = sbscn_to_tiocm(ch);
814 sbscn_status(ch, "sbscn_ioctl ");
821 sbscn_schedrx(struct sbscn_channel *ch)
824 ch->ch_rx_ready = 1;
827 softint_schedule(ch->ch_si);
831 sbscn_break(struct sbscn_channel *ch, int onoff)
836 WRITE_REG(ch->ch_base + 0x50, 0x60);
838 WRITE_REG(ch->ch_base + 0x50, 0x70);
841 if (!ch->ch_heldchange) {
842 if (ch->ch_tx_busy) {
843 ch->ch_heldtbc = ch->ch_tbc;
844 ch->ch_tbc = 0;
845 ch->ch_heldchange = 1;
847 sbscn_loadchannelregs(ch);
853 sbscn_modem(struct sbscn_channel *ch, int onoff)
856 if (ch->ch_o_dtr == 0)
860 SET(ch->ch_oports, ch->ch_o_dtr);
862 CLR(ch->ch_oports, ch->ch_o_dtr);
864 if (!ch->ch_heldchange) {
865 if (ch->ch_tx_busy) {
866 ch->ch_heldtbc = ch->ch_tbc;
867 ch->ch_tbc = 0;
868 ch->ch_heldchange = 1;
870 sbscn_loadchannelregs(ch);
875 tiocm_to_sbscn(struct sbscn_channel *ch, int how, int ttybits)
881 SET(bits, ch->ch_o_dtr);
883 SET(bits, ch->ch_o_rts);
887 CLR(ch->ch_oports, bits);
891 SET(ch->ch_oports, bits);
895 ch->ch_oports = bits;
899 if (!ch->ch_heldchange) {
900 if (ch->ch_tx_busy) {
901 ch->ch_heldtbc = ch->ch_tbc;
902 ch->ch_tbc = 0;
903 ch->ch_heldchange = 1;
905 sbscn_loadchannelregs(ch);
910 sbscn_to_tiocm(struct sbscn_channel *ch)
915 hwbits = ch->ch_oports;
916 if (ISSET(hwbits, ch->ch_o_dtr))
918 if (ISSET(hwbits, ch->ch_o_rts))
921 hwbits = ch->ch_iports;
922 if (ISSET(hwbits, ch->ch_i_dcd))
924 if (ISSET(hwbits, ch->ch_i_cts))
926 if (ISSET(hwbits, ch->ch_i_dsr))
928 if (ISSET(hwbits, ch->ch_i_ri))
931 if (ch->ch_imr != 0)
982 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(tp->t_dev)];
1002 if (ISSET(ch->ch_swflags, TIOCFLAG_SOFTCAR) ||
1003 ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) {
1022 ch->ch_mode1 = mode1;
1023 ch->ch_mode2 = mode2;
1030 ch->ch_i_dcd = 0;
1032 ch->ch_i_dcd = ch->ch_i_dcd_pin;
1038 ch->ch_o_dtr = ch->ch_o_dtr_pin;
1039 ch->ch_o_rts = ch->ch_o_rts_pin;
1040 ch->ch_i_cts = ch->ch_i_cts_pin;
1047 ch->ch_o_dtr = 0;
1048 ch->ch_o_rts = ch->ch_o_dtr_pin;
1049 ch->ch_i_cts = ch->ch_i_dcd_pin;
1056 ch->ch_o_dtr = ch->ch_o_dtr_pin | ch->ch_o_rts_pin;
1057 ch->ch_o_rts = 0;
1058 ch->ch_i_cts = 0;
1059 if (ISSET(ch->ch_oports, ch->ch_o_dtr_pin))
1060 SET(ch->ch_oports, ch->ch_o_rts_pin);
1062 CLR(ch->ch_oports, ch->ch_o_rts_pin);
1066 ch->ch_brc = brc;
1075 if (!ch->ch_heldchange) {
1076 if (ch->ch_tx_busy) {
1077 ch->ch_heldtbc = ch->ch_tbc;
1078 ch->ch_tbc = 0;
1079 ch->ch_heldchange = 1;
1081 sbscn_loadchannelregs(ch);
1086 ch->ch_r_hiwat = 0;
1087 ch->ch_r_lowat = 0;
1088 if (ISSET(ch->ch_rx_flags, RX_TTY_OVERFLOWED)) {
1089 CLR(ch->ch_rx_flags, RX_TTY_OVERFLOWED);
1090 sbscn_schedrx(ch);
1092 if (ISSET(ch->ch_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
1093 CLR(ch->ch_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
1094 sbscn_dohwiflow(ch);
1097 ch->ch_r_hiwat = sbscn_rbuf_hiwat;
1098 ch->ch_r_lowat = sbscn_rbuf_lowat;
1109 ISSET(ch->ch_iports, ch->ch_i_dcd));
1113 sbscn_status(ch, "sbscnparam ");
1117 if (ch->ch_tx_stopped) {
1118 ch->ch_tx_stopped = 0;
1127 sbscn_iflush(struct sbscn_channel *ch)
1139 while (ISSET(READ_REG(ch->ch_base + 0x20), 0x01)
1146 READ_REG(ch->ch_base + 0x60);
1149 aprint_debug_dev(ch->ch_sc->sc_dev,
1155 sbscn_loadchannelregs(struct sbscn_channel *ch)
1159 sbscn_iflush(ch);
1161 WRITE_REG(ch->ch_imr_base, 0);
1164 WRITE_REG(ch->ch_base + 0x00, ch->ch_mode1);
1165 WRITE_REG(ch->ch_base + 0x10, ch->ch_mode2);
1166 WRITE_REG(ch->ch_base + 0x30, ch->ch_brc);
1168 ch->ch_oports_active = ch->ch_oports;
1169 SET_OUTPUT_SIGNALS(ch, ch->ch_oports_active);
1171 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1178 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(tp->t_dev)];
1181 if (ch->ch_o_rts == 0)
1186 if (!ISSET(ch->ch_rx_flags, RX_TTY_BLOCKED)) {
1187 SET(ch->ch_rx_flags, RX_TTY_BLOCKED);
1188 sbscn_dohwiflow(ch);
1191 if (ISSET(ch->ch_rx_flags, RX_TTY_OVERFLOWED)) {
1192 CLR(ch->ch_rx_flags, RX_TTY_OVERFLOWED);
1193 sbscn_schedrx(ch);
1195 if (ISSET(ch->ch_rx_flags, RX_TTY_BLOCKED)) {
1196 CLR(ch->ch_rx_flags, RX_TTY_BLOCKED);
1197 sbscn_dohwiflow(ch);
1208 sbscn_dohwiflow(struct sbscn_channel *ch)
1211 if (ch->ch_o_rts == 0)
1214 if (ISSET(ch->ch_rx_flags, RX_ANY_BLOCK)) {
1215 CLR(ch->ch_oports, ch->ch_o_rts);
1216 CLR(ch->ch_oports_active, ch->ch_o_rts);
1218 SET(ch->ch_oports, ch->ch_o_rts);
1219 SET(ch->ch_oports_active, ch->ch_o_rts);
1221 SET_OUTPUT_SIGNALS(ch, ch->ch_oports_active);
1228 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(tp->t_dev)];
1234 if (ch->ch_tx_stopped)
1249 ch->ch_tba = tba;
1250 ch->ch_tbc = tbc;
1254 ch->ch_tx_busy = 1;
1257 if (!ISSET(ch->ch_imr, 0x1)) {
1258 SET(ch->ch_imr, 0x1);
1259 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1266 while (ch->ch_tbc && READ_REG(ch->ch_base + 0x20) & 0x04) {
1267 c = *ch->ch_tba++;
1268 ch->ch_tbc--;
1269 WRITE_REG(ch->ch_base + 0x70, c);
1284 struct sbscn_channel *ch = &sc->sc_channels[SBSCN_CHAN(tp->t_dev)];
1290 ch->ch_tbc = 0;
1291 ch->ch_heldtbc = 0;
1301 struct sbscn_channel *ch = arg;
1302 struct sbscn_softc *sc = ch->ch_sc;
1307 overflows = ch->ch_overflows;
1308 ch->ch_overflows = 0;
1309 floods = ch->ch_floods;
1310 ch->ch_floods = 0;
1311 ch->ch_errors = 0;
1315 device_xname(sc->sc_dev), ch->ch_num,
1321 sbscn_rxsoft(struct sbscn_channel *ch, struct tty *tp)
1330 end = ch->ch_ebuf;
1331 get = ch->ch_rbget;
1332 scc = cc = sbscn_rbuf_size - ch->ch_rbavail;
1335 ch->ch_floods++;
1336 if (ch->ch_errors++ == 0)
1337 callout_reset(&ch->ch_diag_callout, 60 * hz,
1338 sbscn_diag, ch);
1346 ch->ch_overflows++;
1347 if (ch->ch_errors++ == 0)
1348 callout_reset(&ch->ch_diag_callout,
1349 60 * hz, sbscn_diag, ch);
1360 if (!ISSET(ch->ch_rx_flags, RX_TTY_BLOCKED)) {
1380 SET(ch->ch_rx_flags, RX_TTY_OVERFLOWED);
1386 get = ch->ch_rbuf;
1391 ch->ch_rbget = get;
1393 cc = ch->ch_rbavail += scc - cc;
1395 if (cc >= ch->ch_r_lowat) {
1396 if (ISSET(ch->ch_rx_flags, RX_IBUF_OVERFLOWED)) {
1397 CLR(ch->ch_rx_flags, RX_IBUF_OVERFLOWED);
1398 SET(ch->ch_imr, 0x02);
1399 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1401 if (ISSET(ch->ch_rx_flags, RX_IBUF_BLOCKED)) {
1402 CLR(ch->ch_rx_flags, RX_IBUF_BLOCKED);
1403 sbscn_dohwiflow(ch);
1411 sbscn_txsoft(struct sbscn_channel *ch, struct tty *tp)
1418 ndflush(&tp->t_outq, (int)(ch->ch_tba - tp->t_outq.c_cf));
1423 sbscn_stsoft(struct sbscn_channel *ch, struct tty *tp)
1429 iports = ch->ch_iports;
1430 delta = ch->ch_iports_delta;
1431 ch->ch_iports_delta = 0;
1434 if (ISSET(delta, ch->ch_i_dcd)) {
1439 ISSET(iports, ch->ch_i_dcd));
1442 if (ISSET(delta, ch->ch_i_cts)) {
1444 if (ISSET(iports, ch->ch_i_cts)) {
1445 ch->ch_tx_stopped = 0;
1448 ch->ch_tx_stopped = 1;
1454 sbscn_status(ch, "sbscn_stsoft");
1461 struct sbscn_channel *ch = arg;
1462 struct tty *tp = ch->ch_tty;
1464 if (ch->ch_rx_ready) {
1465 ch->ch_rx_ready = 0;
1466 sbscn_rxsoft(ch, tp);
1469 if (ch->ch_st_check) {
1470 ch->ch_st_check = 0;
1471 sbscn_stsoft(ch, tp);
1474 if (ch->ch_tx_done) {
1475 ch->ch_tx_done = 0;
1476 sbscn_txsoft(ch, tp);
1483 struct sbscn_channel *ch = arg;
1489 isr = READ_REG(ch->ch_isr_base) & ch->ch_imr;
1493 end = ch->ch_ebuf;
1494 put = ch->ch_rbput;
1495 cc = ch->ch_rbavail;
1502 sr = READ_REG(ch->ch_base + 0x20);
1508 if (ISSET(ch->ch_hwflags, SBSCN_HW_CONSOLE)) {
1509 (void)READ_REG(ch->ch_base + 0x60);
1515 if (ISSET(ch->ch_hwflags, SBSCN_HW_KGDB)) {
1516 (void)READ_REG(ch->ch_base + 0x60);
1524 if (!ISSET(ch->ch_rx_flags, RX_IBUF_OVERFLOWED)) {
1526 put[0] = READ_REG(ch->ch_base + 0x60);
1530 put = ch->ch_rbuf;
1533 sr = READ_REG(ch->ch_base + 0x20);
1545 ch->ch_rbput = put;
1546 ch->ch_rbavail = cc;
1547 if (!ISSET(ch->ch_rx_flags, RX_TTY_OVERFLOWED))
1548 ch->ch_rx_ready = 1;
1555 if (!ISSET(ch->ch_rx_flags, RX_IBUF_BLOCKED) &&
1556 cc < ch->ch_r_hiwat) {
1557 SET(ch->ch_rx_flags, RX_IBUF_BLOCKED);
1558 sbscn_dohwiflow(ch);
1567 SET(ch->ch_rx_flags,
1569 CLR(ch->ch_imr, 0x02);
1570 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1574 CLR(ch->ch_imr, 0x02);
1575 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1581 CLR(ch->ch_imr, 0x01);
1582 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1591 iports = GET_INPUT_SIGNALS(ch);
1592 delta = iports ^ ch->ch_iports;
1593 ch->ch_iports = iports;
1598 if (ISSET(delta, ch->ch_i_mask)) {
1599 SET(ch->ch_iports_delta, delta);
1605 if (ISSET(~iports, ch->ch_i_mask)) {
1606 ch->ch_tbc = 0;
1607 ch->ch_heldtbc = 0;
1610 sbscn_status(ch, "sbscn_intr ");
1614 ch->ch_st_check = 1;
1616 } while ((isr = (READ_REG(ch->ch_isr_base) & ch->ch_imr)) != 0);
1624 sr = READ_REG(ch->ch_base + 0x20);
1631 if (ch->ch_heldchange) {
1632 sbscn_loadchannelregs(ch);
1633 ch->ch_heldchange = 0;
1634 ch->ch_tbc = ch->ch_heldtbc;
1635 ch->ch_heldtbc = 0;
1639 if (ch->ch_tbc > 0) {
1644 while (ch->ch_tbc &&
1645 READ_REG(ch->ch_base + 0x20) & 0x04) {
1647 c = *ch->ch_tba++;
1648 ch->ch_tbc--;
1649 WRITE_REG(ch->ch_base + 0x70, c);
1652 SET(ch->ch_imr, 0x01);
1653 WRITE_REG(ch->ch_imr_base, ch->ch_imr);
1660 if (ch->ch_tx_busy) {
1661 ch->ch_tx_busy = 0;
1662 ch->ch_tx_done = 1;
1668 softint_schedule(ch->ch_si);
1671 rnd_add_uint32(&ch->ch_rnd_source, isr | sr);