diff options
author | Hugh Graham <hugh@cvs.openbsd.org> | 2003-04-06 01:33:33 +0000 |
---|---|---|
committer | Hugh Graham <hugh@cvs.openbsd.org> | 2003-04-06 01:33:33 +0000 |
commit | 42b3b4ebf0118752b22475639602e732dd4b8088 (patch) | |
tree | aa5ae9ec7347d476fc63aaf1c32af8e92e090e35 /sys/arch/vax/qbus | |
parent | 057d758e78c071130b4f93385190d9c5aea0b8b7 (diff) |
Significant DHU driver fixups:
. immediately service all available action reports in the transmit
. interrupt handler so we don't exhaust the action report fifo and
. hang the device when under high load
.
. set receive interrupt delay to 10ms if the hardware supports it,
. vastly reducing interrupts by allowing the receive fifo to fill
.
. always use dma when in DHU11 mode
Diffstat (limited to 'sys/arch/vax/qbus')
-rw-r--r-- | sys/arch/vax/qbus/dhu.c | 74 | ||||
-rw-r--r-- | sys/arch/vax/qbus/dhureg.h | 3 |
2 files changed, 47 insertions, 30 deletions
diff --git a/sys/arch/vax/qbus/dhu.c b/sys/arch/vax/qbus/dhu.c index 0b85e15e6bb..e08cf19cf15 100644 --- a/sys/arch/vax/qbus/dhu.c +++ b/sys/arch/vax/qbus/dhu.c @@ -1,6 +1,7 @@ -/* $OpenBSD: dhu.c,v 1.7 2003/04/03 22:47:27 hugh Exp $ */ +/* $OpenBSD: dhu.c,v 1.8 2003/04/06 01:33:32 hugh Exp $ */ /* $NetBSD: dhu.c,v 1.19 2000/06/04 06:17:01 matt Exp $ */ /* + * Copyright (c) 2003, Hugh Graham. * Copyright (c) 1996 Ken C. Wellsch. All rights reserved. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -300,8 +301,8 @@ dhurint(arg) (void)(*linesw[tp->t_line].l_modem)(tp, 1); } else if ((tp->t_state & TS_CARR_ON) && - (*linesw[tp->t_line].l_modem)(tp, 0) == 0) - (void) dhumctl(sc, line, 0, DMSET); + (*linesw[tp->t_line].l_modem)(tp, 0) == 0) + (void) dhumctl(sc, line, 0, DMSET); /* Do CRTSCTS flow control */ delta = c ^ sc->sc_dhu[line].dhu_modem; @@ -348,29 +349,41 @@ dhuxint(arg) { struct dhu_softc *sc = arg; struct tty *tp; - int line; + int line, i; - line = DHU_LINE(DHU_READ_BYTE(DHU_UBA_CSR_HI)); + while ((i = DHU_READ_BYTE(DHU_UBA_CSR_HI)) & (DHU_CSR_TX_ACTION >> 8)) { - tp = sc->sc_dhu[line].dhu_tty; + line = DHU_LINE(i); - tp->t_state &= ~TS_BUSY; - if (tp->t_state & TS_FLUSH) - tp->t_state &= ~TS_FLUSH; - else { - if (sc->sc_dhu[line].dhu_state == STATE_DMA_STOPPED) - sc->sc_dhu[line].dhu_cc -= - DHU_READ_WORD(DHU_UBA_TBUFCNT); - ndflush(&tp->t_outq, sc->sc_dhu[line].dhu_cc); - sc->sc_dhu[line].dhu_cc = 0; - } + tp = sc->sc_dhu[line].dhu_tty; - sc->sc_dhu[line].dhu_state = STATE_IDLE; + if (i & (DHU_CSR_TX_DMA_ERROR >> 8)) + printf("dhu%d: DMA ERROR on line: %d\n", + DHU_M2U(minor(tp->t_dev)), line); - if (tp->t_line) - (*linesw[tp->t_line].l_start)(tp); - else - dhustart(tp); + if (i & (DHU_CSR_DIAG_FAIL >> 8)) + printf("dhu%d: DIAG FAIL on line: %d\n", + DHU_M2U(minor(tp->t_dev)), line); + + tp->t_state &= ~TS_BUSY; + + if (tp->t_state & TS_FLUSH) + tp->t_state &= ~TS_FLUSH; + else { + if (sc->sc_dhu[line].dhu_state == STATE_DMA_STOPPED) + sc->sc_dhu[line].dhu_cc -= + DHU_READ_WORD(DHU_UBA_TBUFCNT); + ndflush(&tp->t_outq, sc->sc_dhu[line].dhu_cc); + sc->sc_dhu[line].dhu_cc = 0; + } + + sc->sc_dhu[line].dhu_state = STATE_IDLE; + + if (tp->t_line) + (*linesw[tp->t_line].l_start)(tp); + else + dhustart(tp); + } } int @@ -395,6 +408,13 @@ dhuopen(dev, flag, mode, p) if (line >= sc->sc_lines) return ENXIO; + if (sc->sc_type == IS_DHU) { + s = spltty(); /* CSR 3:0 must be 0 */ + DHU_WRITE_BYTE(DHU_UBA_CSR, DHU_CSR_RXIE); + DHU_WRITE_BYTE(DHU_UBA_RXTIME, 10); + splx(s); /* RX int delay 10ms */ + } + s = spltty(); DHU_WRITE_BYTE(DHU_UBA_CSR, DHU_CSR_RXIE | line); sc->sc_dhu[line].dhu_modem = DHU_READ_WORD(DHU_UBA_STAT); @@ -616,6 +636,7 @@ dhustart(tp) int s; s = spltty(); + if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; if (tp->t_outq.c_cc <= tp->t_lowat) { @@ -641,18 +662,13 @@ dhustart(tp) sc->sc_dhu[line].dhu_cc = cc; - if (cc == 1) { + if (cc == 1 && sc->sc_type == IS_DHV) { sc->sc_dhu[line].dhu_state = STATE_TX_ONE_CHAR; - if (sc->sc_type == IS_DHU) { - /* should check for room in fifo first */ - DHU_WRITE_BYTE(DHU_UBA_FIFO, *tp->t_outq.c_cf); - } else - DHU_WRITE_WORD(DHU_UBA_TXCHAR, - DHU_TXCHAR_DATA_VALID | *tp->t_outq.c_cf); + DHU_WRITE_WORD(DHU_UBA_TXCHAR, + DHU_TXCHAR_DATA_VALID | *tp->t_outq.c_cf); } else { - sc->sc_dhu[line].dhu_state = STATE_DMA_RUNNING; addr = sc->sc_dhu[line].dhu_dmah->dm_segs[0].ds_addr + diff --git a/sys/arch/vax/qbus/dhureg.h b/sys/arch/vax/qbus/dhureg.h index 45c76187352..4039fd13b13 100644 --- a/sys/arch/vax/qbus/dhureg.h +++ b/sys/arch/vax/qbus/dhureg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhureg.h,v 1.3 2003/04/03 22:47:27 hugh Exp $ */ +/* $OpenBSD: dhureg.h,v 1.4 2003/04/06 01:33:32 hugh Exp $ */ /* $NetBSD: dhureg.h,v 1.4 1999/05/28 20:17:29 ragge Exp $ */ /* * Copyright (c) 1996 Ken C. Wellsch. All rights reserved. @@ -66,6 +66,7 @@ typedef struct DHUregs dhuregs; #define DHU_UBA_CSR_HI 1 #define DHU_UBA_RBUF 2 #define DHU_UBA_TXCHAR 2 +#define DHU_UBA_RXTIME DHU_UBA_TXCHAR /* on a real dhu only */ #define DHU_UBA_LPR 4 #define DHU_UBA_STAT 6 #define DHU_UBA_FIFO DHU_UBA_STAT /* on a real dhu only */ |