diff --git a/sys/arch/sparc64/dev/sab.c b/sys/arch/sparc64/dev/sab.c index d4e20c44c08c..c711b6b92c76 100644 --- a/sys/arch/sparc64/dev/sab.c +++ b/sys/arch/sparc64/dev/sab.c @@ -1,4 +1,4 @@ -/* $NetBSD: sab.c,v 1.10 2003/06/11 22:51:03 petrov Exp $ */ +/* $NetBSD: sab.c,v 1.11 2003/06/13 01:33:32 petrov Exp $ */ /* $OpenBSD: sab.c,v 1.7 2002/04/08 17:49:42 jason Exp $ */ /* @@ -115,6 +115,8 @@ struct sabtty_softc *sabtty_cons_output; bus_space_read_1((sc)->sc_bt, (sc)->sc_bh, (r)) #define SAB_WRITE(sc,r,v) \ bus_space_write_1((sc)->sc_bt, (sc)->sc_bh, (r), (v)) +#define SAB_WRITE_BLOCK(sc,r,p,c) \ + bus_space_write_region_1((sc)->sc_bt, (sc)->sc_bh, (r), (p), (c)) int sab_match(struct device *, struct cfdata *, void *); void sab_attach(struct device *, struct device *, void *); @@ -276,6 +278,9 @@ sab_attach(parent, self, aux) } printf("\n"); + /* Let current output drain */ + DELAY(100000); + /* Set all pins, except DTR pins to be inputs */ SAB_WRITE(sc, SAB_PCR, ~(SAB_PVR_DTR_A | SAB_PVR_DTR_B)); /* Disable port interrupts */ @@ -424,9 +429,6 @@ sabtty_attach(parent, self, aux) break; } - /* Let current output drain */ - DELAY(100000); - t.c_ispeed= 0; t.c_ospeed = 9600; t.c_cflag = CREAD | CS8 | HUPCL; @@ -519,7 +521,41 @@ sabtty_intr(sc, needsoftp) if (isr1 & SAB_ISR1_BRKT) sabtty_abort(sc); - if (isr1 & SAB_ISR1_ALLS) { + if (isr1 & (SAB_ISR1_XPR | SAB_ISR1_ALLS)) { + if ((SAB_READ(sc, SAB_STAR) & SAB_STAR_XFW) && + (sc->sc_flags & SABTTYF_STOP) == 0) { + if (sc->sc_txc < 32) + len = sc->sc_txc; + else + len = 32; + + if (len > 0) { + SAB_WRITE_BLOCK(sc, SAB_XFIFO, sc->sc_txp, len); + sc->sc_txp += len; + sc->sc_txc -= len; + + sabtty_cec_wait(sc); + SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF); + + /* + * Prevent the false end of xmit from + * confusing things below. + */ + isr1 &= ~SAB_ISR1_ALLS; + } + } + + if ((sc->sc_txc == 0) || (sc->sc_flags & SABTTYF_STOP)) { + if ((sc->sc_imr1 & SAB_IMR1_XPR) == 0) { + sc->sc_imr1 |= SAB_IMR1_XPR; + sc->sc_imr1 &= ~SAB_IMR1_ALLS; + SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); + } + } + } + + if ((isr1 & SAB_ISR1_ALLS) && ((sc->sc_txc == 0) || + (sc->sc_flags & SABTTYF_STOP))) { if (sc->sc_flags & SABTTYF_TXDRAIN) wakeup(sc); sc->sc_flags &= ~SABTTYF_STOP; @@ -529,31 +565,6 @@ sabtty_intr(sc, needsoftp) needsoft = 1; } - if (isr1 & SAB_ISR1_XPR) { - r = 1; - if ((sc->sc_flags & SABTTYF_STOP) == 0) { - if (sc->sc_txc < 32) - len = sc->sc_txc; - else - len = 32; - for (i = 0; i < len; i++) { - SAB_WRITE(sc, SAB_XFIFO + i, *sc->sc_txp); - sc->sc_txp++; - sc->sc_txc--; - } - if (i != 0) { - sabtty_cec_wait(sc); - SAB_WRITE(sc, SAB_CMDR, SAB_CMDR_XF); - } - } - - if ((sc->sc_txc == 0) || (sc->sc_flags & SABTTYF_STOP)) { - sc->sc_imr1 |= SAB_IMR1_XPR; - sc->sc_imr1 &= ~SAB_IMR1_ALLS; - SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); - } - } - if (needsoft) *needsoftp = needsoft; return (r); @@ -1079,7 +1090,7 @@ sabtty_start(tp) sc->sc_txc = ndqb(&tp->t_outq, 0); sc->sc_txp = tp->t_outq.c_cf; tp->t_state |= TS_BUSY; - sc->sc_imr1 &= ~SAB_IMR1_XPR; + sc->sc_imr1 &= ~(SAB_ISR1_XPR | SAB_ISR1_ALLS); SAB_WRITE(sc, SAB_IMR1, sc->sc_imr1); } }