From 4eee2aed2e8d45e6c9a72e03f734680d27c48bb3 Mon Sep 17 00:00:00 2001 From: ichiro Date: Sun, 29 Jun 2003 10:51:29 +0000 Subject: [PATCH] struct proc * -> struct lwp * ixp425_com: add some status flags --- sys/arch/arm/arm/vm_machdep_arm.c | 9 +- sys/arch/arm/arm32/arm32_machdep.c | 6 +- sys/arch/arm/xscale/ixp425_com.c | 280 +++++++++++++++++++++------- sys/arch/arm/xscale/ixp425_comvar.h | 11 +- sys/arch/arm/xscale/ixp425reg.h | 4 +- 5 files changed, 233 insertions(+), 77 deletions(-) diff --git a/sys/arch/arm/arm/vm_machdep_arm.c b/sys/arch/arm/arm/vm_machdep_arm.c index 34376ae134bd..84f69a9f5811 100644 --- a/sys/arch/arm/arm/vm_machdep_arm.c +++ b/sys/arch/arm/arm/vm_machdep_arm.c @@ -1,4 +1,4 @@ -/* $NetBSD: vm_machdep_arm.c,v 1.5 2003/01/17 22:28:49 thorpej Exp $ */ +/* $NetBSD: vm_machdep_arm.c,v 1.6 2003/06/29 10:51:29 ichiro Exp $ */ /* * Copyright (c) 1994-1998 Mark Brinicombe. @@ -37,7 +37,7 @@ #include -__KERNEL_RCSID(0, "$NetBSD: vm_machdep_arm.c,v 1.5 2003/01/17 22:28:49 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vm_machdep_arm.c,v 1.6 2003/06/29 10:51:29 ichiro Exp $"); #include #include @@ -58,7 +58,6 @@ int cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred, struct core *chdr) { - struct proc *p = l->l_proc; int error; struct { struct reg regs; @@ -86,13 +85,13 @@ cpu_coredump(struct lwp *l, struct vnode *vp, struct ucred *cred, error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize, (off_t)chdr->c_hdrsize, UIO_SYSSPACE, - IO_NODELOCKED|IO_UNIT, cred, NULL, p); + IO_NODELOCKED|IO_UNIT, cred, NULL, l); if (error) return error; error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cpustate, sizeof(cpustate), (off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE, - IO_NODELOCKED|IO_UNIT, cred, NULL, p); + IO_NODELOCKED|IO_UNIT, cred, NULL, l); if (error) return error; diff --git a/sys/arch/arm/arm32/arm32_machdep.c b/sys/arch/arm/arm32/arm32_machdep.c index c36ac902673d..017d51d434f2 100644 --- a/sys/arch/arm/arm32/arm32_machdep.c +++ b/sys/arch/arm/arm32/arm32_machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: arm32_machdep.c,v 1.34 2003/06/04 13:30:05 simonb Exp $ */ +/* $NetBSD: arm32_machdep.c,v 1.35 2003/06/29 10:51:30 ichiro Exp $ */ /* * Copyright (c) 1994-1998 Mark Brinicombe. @@ -349,14 +349,14 @@ cpu_startup() */ int -cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) +cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, l) int *name; u_int namelen; void *oldp; size_t *oldlenp; void *newp; size_t newlen; - struct proc *p; + struct lwp *l; { /* all sysctl names at this level are terminal */ if (namelen != 1) diff --git a/sys/arch/arm/xscale/ixp425_com.c b/sys/arch/arm/xscale/ixp425_com.c index 70fc91154fa7..07456a546922 100644 --- a/sys/arch/arm/xscale/ixp425_com.c +++ b/sys/arch/arm/xscale/ixp425_com.c @@ -1,4 +1,4 @@ -/* $NetBSD: ixp425_com.c,v 1.8 2003/06/03 14:13:30 ichiro Exp $ */ +/* $NetBSD: ixp425_com.c,v 1.9 2003/06/29 10:51:31 ichiro Exp $ */ /* * Copyright (c) 2003 * Ichiro FUKUHARA . @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ixp425_com.c,v 1.8 2003/06/03 14:13:30 ichiro Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ixp425_com.c,v 1.9 2003/06/29 10:51:31 ichiro Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -111,13 +111,15 @@ static void tiocm_to_ixp4xx_com(struct ixp4xx_com_softc *, u_long, int); static int ixp4xx_com_to_tiocm(struct ixp4xx_com_softc *); static void ixp4xx_com_set_cr(struct ixp4xx_com_softc *); +static void ixpcom_hwiflow(struct ixp4xx_com_softc *); static void ixp4xxcomsoft(void *); +static void ixpcomdiag(void *); inline static void ixp4xx_com_txsoft(struct ixp4xx_com_softc *, struct tty *); inline static void ixp4xx_com_rxsoft(struct ixp4xx_com_softc *, struct tty *); +inline static void ixpcom_schedrx(struct ixp4xx_com_softc *); int ixp4xx_cominit(bus_space_tag_t, bus_space_handle_t, int, int, tcflag_t); - int ixp4xx_comcngetc(dev_t); void ixp4xx_comcnputc(dev_t, int); void ixp4xx_comcnpollc(dev_t, int); @@ -155,6 +157,10 @@ const struct cdevsw ixpcom_cdevsw = { nommap, ttykqfilter, D_TTY }; +/* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */ +u_int ixpcom_rbuf_hiwat = (IXPCOM_RING_SIZE * 1) / 4; +u_int ixpcom_rbuf_lowat = (IXPCOM_RING_SIZE * 3) / 4; + #define COMUNIT_MASK 0x7ffff #define COMDIALOUT_MASK 0x80000 @@ -164,8 +170,6 @@ const struct cdevsw ixpcom_cdevsw = { #define COM_ISALIVE(sc) ((sc)->enabled != 0 && \ ISSET((sc)->sc_dev.dv_flags, DVF_ACTIVE)) -#define COM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, COM_NPORTS, (f)) - #define COM_LOCK(sc); #define COM_UNLOCK(sc); @@ -230,9 +234,8 @@ ixp4xx_com_attach_subr(struct ixp4xx_com_softc *sc) ixp4xx_com_sc = sc; -#if 0 callout_init(&sc->sc_diag_callout); -#endif + /* configuring the device. */ sc->sc_frequency = FREQ; sc->sc_dlbl = ixp4xx_comspeed(CONSPEED, sc->sc_frequency); @@ -242,7 +245,7 @@ ixp4xx_com_attach_subr(struct ixp4xx_com_softc *sc) sc->sc_ier = IER_UUE; bus_space_write_4(iot, ioh, IXP425_UART_IER, sc->sc_ier); - sc->sc_fcr = FCR_TRIGGER_8 | FCR_RESETTF | FCR_RESETRF | FCR_ENABLE; + sc->sc_fcr = FCR_TRIGGER_32 | FCR_RESETTF | FCR_RESETRF | FCR_ENABLE; bus_space_write_4(iot, ioh, IXP425_UART_FCR, sc->sc_fcr); if (iot == ixp4xx_comcn_sc.sc_iot @@ -282,6 +285,10 @@ ixp4xx_com_attach_subr(struct ixp4xx_com_softc *sc) tty_attach(tp); + sc->sc_mcr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_MCR); + SET(sc->sc_mcr, MCR_IENABLE); + bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_MCR, sc->sc_mcr); + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { int maj; @@ -425,6 +432,23 @@ ixp4xx_comparam(struct tty *tp, struct termios *t) ixp4xx_com_set_cr(sc); } + if (!ISSET(t->c_cflag, CHWFLOW)) { + /* Disable the high water mark. */ + sc->sc_r_hiwat = 0; + sc->sc_r_lowat = 0; + if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { + CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); + ixpcom_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); + ixpcom_hwiflow(sc); + } + } else { + sc->sc_r_hiwat = ixpcom_rbuf_hiwat; + sc->sc_r_lowat = ixpcom_rbuf_lowat; + } + COM_UNLOCK(sc); splx(s); @@ -432,7 +456,7 @@ ixp4xx_comparam(struct tty *tp, struct termios *t) * Update the tty layer's idea of the carrier bit. * We tell tty the carrier is always on. */ - (void) (*tp->t_linesw->l_modem)(tp, 1); + (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD)); #ifdef COM_DEBUG if (com_debug) @@ -457,6 +481,8 @@ ixp4xx_com_set_cr(struct ixp4xx_com_softc *sc) ixp4xx_com_iflush(sc); + bus_space_write_4(iot, ioh, IXP425_UART_IER, IER_UUE); + bus_space_write_4(iot, ioh, IXP425_UART_LCR, sc->sc_lcr | LCR_DLAB); bus_space_write_4(iot, ioh, IXP425_UART_DLL, sc->sc_dlbl); bus_space_write_4(iot, ioh, IXP425_UART_DLH, sc->sc_dlbh); @@ -469,7 +495,60 @@ ixp4xx_com_set_cr(struct ixp4xx_com_softc *sc) static int ixp4xx_comhwiflow(struct tty *tp, int block) { - return (0); + struct ixp4xx_com_softc *sc + = device_lookup(&ixpcom_cd, COMUNIT(tp->t_dev)); + int s; + + if (COM_ISALIVE(sc) == 0) + return (0); + + if (sc->sc_mcr_rts == 0) + return (0); + + s = splserial(); + COM_LOCK(sc); + + if (block) { + if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { + SET(sc->sc_rx_flags, RX_TTY_BLOCKED); + ixpcom_hwiflow(sc); + } + } else { + if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) { + CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED); + ixpcom_schedrx(sc); + } + if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) { + CLR(sc->sc_rx_flags, RX_TTY_BLOCKED); + ixpcom_hwiflow(sc); + } + } + + COM_UNLOCK(sc); + splx(s); + return (1); +} + +/* + * (un)block input via hw flowcontrol + */ +void +ixpcom_hwiflow(struct ixp4xx_com_softc *sc) +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + + if (sc->sc_mcr_rts == 0) + return; + + if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) { + CLR(sc->sc_mcr, sc->sc_mcr_rts); + CLR(sc->sc_mcr_active, sc->sc_mcr_rts); + } else { + SET(sc->sc_mcr, sc->sc_mcr_rts); + SET(sc->sc_mcr_active, sc->sc_mcr_rts); + } + bus_space_write_4(iot, ioh, IXP425_UART_MCR, sc->sc_mcr_active); } static void @@ -488,7 +567,9 @@ ixp4xx_com_filltx(struct ixp4xx_com_softc *sc) n++; } sc->sc_tbc -= n; + sc->sc_tba += n; } + static void ixp4xx_comstart(struct tty *tp) @@ -538,7 +619,7 @@ ixp4xx_comstart(struct tty *tp) if (!ISSET(sc->sc_ier, IER_TIE)) { SET(sc->sc_ier, IER_TIE); bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_IER, - sc->sc_ier | IER_UUE); + sc->sc_ier); } /* Output the first chunk of the contiguous buffer. */ @@ -550,6 +631,15 @@ out: return; } +inline static void +ixpcom_schedrx(struct ixp4xx_com_softc *sc) +{ + sc->sc_rx_ready = 1; + + /* Wake up the poller. */ + softintr_schedule(sc->sc_si); +} + static void ixp4xx_com_break(struct ixp4xx_com_softc *sc, int onoff) { @@ -597,9 +687,18 @@ ixp4xx_com_shutdown(struct ixp4xx_com_softc *sc) } /* Turn off interrupts. */ +#if 1 + if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) { + sc->sc_ier = IER_RAVIE | IER_RTOIE; + } else + sc->sc_ier = IER_UUE; + bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_IER, + sc->sc_ier); +#else sc->sc_ier &= ~(IER_RAVIE | IER_TIE); bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_IER, sc->sc_ier | IER_UUE); +#endif if (sc->disable) { #ifdef DIAGNOSTIC @@ -614,7 +713,7 @@ ixp4xx_com_shutdown(struct ixp4xx_com_softc *sc) } int -ixp4xx_comopen(dev_t dev, int flag, int mode, struct proc *p) +ixp4xx_comopen(dev_t dev, int flag, int mode, struct lwp *l) { struct ixp4xx_com_softc *sc; struct tty *tp; @@ -641,7 +740,7 @@ ixp4xx_comopen(dev_t dev, int flag, int mode, struct proc *p) if (ISSET(tp->t_state, TS_ISOPEN) && ISSET(tp->t_state, TS_XCLUDE) && - p->p_ucred->cr_uid != 0) + l->l_proc->p_ucred->cr_uid != 0) return (EBUSY); s = spltty(); @@ -669,15 +768,12 @@ ixp4xx_comopen(dev_t dev, int flag, int mode, struct proc *p) sc->enabled = 1; } /* Turn on interrupts. */ - sc->sc_mcr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_MCR); - SET(sc->sc_mcr, MCR_IENABLE); - bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_MCR, sc->sc_mcr); - SET(sc->sc_ier, IER_RAVIE | IER_TIE); + SET(sc->sc_ier, IER_RAVIE | IER_RTOIE | IER_RLSE | IER_RIE); bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_IER, sc->sc_ier); -#if 0 + /* Fetch the current modem control status, needed later. */ - sc->sc_msr = bus_space_read_4(iot, ioh, IXP425_UART_MSR); -#endif + sc->sc_msr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_MSR); + COM_UNLOCK(sc); splx(s2); @@ -724,6 +820,7 @@ ixp4xx_comopen(dev_t dev, int flag, int mode, struct proc *p) sc->sc_rbavail = IXPCOM_RING_SIZE; ixp4xx_com_iflush(sc); CLR(sc->sc_rx_flags, RX_ANY_BLOCK); + ixpcom_hwiflow(sc); #ifdef COM_DEBUG if (com_debug) @@ -757,7 +854,7 @@ bad: } int -ixp4xx_comclose(dev_t dev, int flag, int mode, struct proc *p) +ixp4xx_comclose(dev_t dev, int flag, int mode, struct lwp *l) { struct ixp4xx_com_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev)); @@ -812,7 +909,7 @@ ixp4xx_comwrite(dev_t dev, struct uio *uio, int flag) } int -ixp4xx_compoll(dev_t dev, int events, struct proc *p) +ixp4xx_compoll(dev_t dev, int events, struct lwp *l) { struct ixp4xx_com_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev)); @@ -821,7 +918,7 @@ ixp4xx_compoll(dev_t dev, int events, struct proc *p) if (COM_ISALIVE(sc) == 0) return (EIO); - return ((*tp->t_linesw->l_poll)(tp, events, p)); + return ((*tp->t_linesw->l_poll)(tp, events, l)); } struct tty * @@ -835,7 +932,7 @@ ixp4xx_comtty(dev_t dev) } int -ixp4xx_comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) +ixp4xx_comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct lwp *l) { struct ixp4xx_com_softc *sc = device_lookup(&ixpcom_cd, COMUNIT(dev)); @@ -846,11 +943,11 @@ ixp4xx_comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) if (COM_ISALIVE(sc) == 0) return (EIO); - error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p); + error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); - error = ttioctl(tp, cmd, data, flag, p); + error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) return (error); @@ -881,7 +978,7 @@ ixp4xx_comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) break; case TIOCSFLAGS: - error = suser(p->p_ucred, &p->p_acflag); + error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag); if (error) break; sc->sc_swflags = *(int *)data; @@ -1017,7 +1114,7 @@ ixp4xx_com_to_tiocm(struct ixp4xx_com_softc *sc) if (ISSET(combits, MSR_RI | MSR_TERI)) SET(ttybits, TIOCM_RI); - if ((sc->sc_ier & IER_UUE) != 0) + if ((sc->sc_ier & 0x0f) != 0) SET(ttybits, TIOCM_LE); return (ttybits); @@ -1112,6 +1209,29 @@ ixp4xx_com_txsoft(struct ixp4xx_com_softc *sc, struct tty *tp) (*tp->t_linesw->l_start)(tp); } +void +ixpcomdiag(void *arg) +{ + struct ixp4xx_com_softc *sc = arg; + int overflows, floods; + int s; + + s = splserial(); + COM_LOCK(sc); + overflows = sc->sc_overflows; + sc->sc_overflows = 0; + floods = sc->sc_floods; + sc->sc_floods = 0; + sc->sc_errors = 0; + COM_UNLOCK(sc); + splx(s); + + printf("%s: %d silo overflow%s, %d ibuf flood%s\n", + sc->sc_dev.dv_xname, + overflows, overflows == 1 ? "" : "s", + floods, floods == 1 ? "" : "s"); +} + inline static void ixp4xx_com_rxsoft(struct ixp4xx_com_softc *sc, struct tty *tp) { @@ -1128,8 +1248,14 @@ ixp4xx_com_rxsoft(struct ixp4xx_com_softc *sc, struct tty *tp) while (cc) { code = get[0]; lsr = get[1]; - if (ISSET(lsr, LSR_OE | LSR_FE | LSR_PE)) { - if (ISSET(lsr, LSR_FE)) + if (ISSET(lsr, LSR_OE | LSR_FE | LSR_PE | LSR_BI)) { + if (ISSET(lsr, LSR_OE)) { + sc->sc_overflows++; + if (sc->sc_errors++ == 0) + callout_reset(&sc->sc_diag_callout, + 60 * hz, ixpcomdiag, sc); + } + if (ISSET(lsr, LSR_BI | LSR_FE)) SET(code, TTY_FE); if (ISSET(lsr, LSR_PE)) SET(code, TTY_PE); @@ -1178,11 +1304,12 @@ ixp4xx_com_rxsoft(struct ixp4xx_com_softc *sc, struct tty *tp) if (cc >= 1) { if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); - SET(sc->sc_ier,IER_RAVIE); + SET(sc->sc_ier, IER_RAVIE | IER_RTOIE); ixp4xx_com_set_cr(sc); } if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) { CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED); + ixpcom_hwiflow(sc); } } COM_UNLOCK(sc); @@ -1197,48 +1324,59 @@ ixp4xxcomintr(void* arg) bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; u_char *put, *end; - u_int cc, res; - u_int32_t c; + u_int cc; + u_char iir, lsr; if (COM_ISALIVE(sc) == 0) return (0); COM_LOCK(sc); - res = bus_space_read_4(iot, ioh, IXP425_UART_IER) & IER_UUE; - - if (!res) { + iir = bus_space_read_4(iot, ioh, IXP425_UART_IIR); + if (ISSET(iir, IIR_NOPEND)) { COM_UNLOCK(sc); return (0); } - res = bus_space_read_4(iot, ioh, IXP425_UART_LSR); - if (!ISSET(res, LSR_DR | LSR_TDRQ)) - return (0); - end = sc->sc_ebuf; put = sc->sc_rbput; cc = sc->sc_rbavail; - if (ISSET(res, LSR_DR)) { - if (!ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { +again: do { + u_char msr; + + lsr = bus_space_read_4(iot, ioh, IXP425_UART_LSR); + if (ISSET(lsr, LSR_BI)) { + int cn_trapped = 0; + + cn_check_magic(sc->sc_tty->t_dev, + CNC_BREAK, ixp4xx_com_cnm_state); + if (cn_trapped) + continue; + } + + if (ISSET(lsr, LSR_RCV_MASK) && + !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) { while (cc > 0) { - if (!ISSET(res, LSR_DR)) - break; - c = bus_space_read_4(iot, ioh, IXP425_UART_DATA); - if (ISSET(res, LSR_FE)) { - cn_check_magic(sc->sc_tty->t_dev, - CNC_BREAK, - ixp4xx_com_cnm_state); - } - put[0] = c & 0xff; - put[1] = (c >> 8) & 0xff; + int cn_trapped = 0; + put[0] = bus_space_read_4(iot, ioh, IXP425_UART_DATA); + put[1] = lsr; cn_check_magic(sc->sc_tty->t_dev, - put[0], ixp4xx_com_cnm_state); + put[0], ixp4xx_com_cnm_state); + if (cn_trapped) { + lsr = bus_space_read_4(iot, ioh, + IXP425_UART_LSR); + if (!ISSET(lsr, LSR_RCV_MASK)) + break; + + continue; + } put += 2; if (put >= end) put = sc->sc_rbuf; cc--; - res = bus_space_read_4(iot, ioh, IXP425_UART_LSR); + lsr = bus_space_read_4(iot, ioh, IXP425_UART_LSR); + if (!ISSET(lsr, LSR_RCV_MASK)) + break; } /* @@ -1256,7 +1394,12 @@ ixp4xxcomintr(void* arg) * See if we are in danger of overflowing a buffer. If * so, use hardware flow control to ease the pressure. */ - /* later XXXX */ + + if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) && + cc < sc->sc_r_hiwat) { + SET(sc->sc_rx_flags, RX_IBUF_BLOCKED); + ixpcom_hwiflow(sc); + } /* * If we're out of space, disable receive interrupts @@ -1264,26 +1407,29 @@ ixp4xxcomintr(void* arg) */ if (!cc) { SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED); - CLR(sc->sc_ier, IER_RAVIE); + CLR(sc->sc_ier, IER_RAVIE | IER_RTOIE); ixp4xx_com_set_cr(sc); } } else { -#ifdef DIAGNOSTIC - panic("ixpcomintr: we shouldn't reach here"); -#endif - CLR(sc->sc_ier, IER_RAVIE); - ixp4xx_com_set_cr(sc); + if ((iir & IIR_IMASK) == IIR_RXRDY) { + sc->sc_ier = IER_UUE; + delay(10); + ixp4xx_com_set_cr(sc); + } } - } + + msr = bus_space_read_4(iot, ioh, IXP425_UART_MSR); + sc->sc_msr = msr; + + } while (ISSET((iir = bus_space_read_4(iot, ioh, IXP425_UART_IIR)), + IIR_RXRDY) || ((iir & IIR_IMASK) == 0)); /* * Done handling any receive interrupts. See if data can be * transmitted as well. Schedule tx done event if no data left * and tty was marked busy. */ - - res = bus_space_read_4(iot, ioh, IXP425_UART_LSR); - if (ISSET(res, LSR_TDRQ)) { + if (ISSET(lsr, LSR_TDRQ)) { /* * If we've delayed a parameter change, do it now, and restart * output. @@ -1310,6 +1456,10 @@ ixp4xxcomintr(void* arg) } } } + + if (!ISSET((iir = bus_space_read_4(iot, ioh, IXP425_UART_IIR)), IIR_NOPEND)) + goto again; + COM_UNLOCK(sc); /* Wake up the poller. */ diff --git a/sys/arch/arm/xscale/ixp425_comvar.h b/sys/arch/arm/xscale/ixp425_comvar.h index dbd7b80f1b96..83fa7554d098 100644 --- a/sys/arch/arm/xscale/ixp425_comvar.h +++ b/sys/arch/arm/xscale/ixp425_comvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ixp425_comvar.h,v 1.3 2003/06/01 01:49:56 ichiro Exp $ */ +/* $NetBSD: ixp425_comvar.h,v 1.4 2003/06/29 10:51:31 ichiro Exp $ */ /*- * Copyright (c) 2001, The NetBSD Foundation, Inc. All rights reserved. * @@ -77,14 +77,19 @@ struct ixp4xx_com_softc { volatile u_int sc_rbavail; /* status flags */ - int sc_hwflags, sc_swflags; - + int sc_hwflags, + sc_swflags; volatile u_int sc_rx_flags, sc_tx_busy, sc_tx_done, sc_tx_stopped, sc_st_check, sc_rx_ready; + u_int sc_overflows, + sc_floods, + sc_errors; + u_int sc_r_hiwat, + sc_r_lowat; volatile int sc_heldchange; volatile int sc_msr, sc_msr_delta, sc_msr_mask, sc_mcr, sc_mcr_active, sc_lcr, sc_ier, sc_fcr, diff --git a/sys/arch/arm/xscale/ixp425reg.h b/sys/arch/arm/xscale/ixp425reg.h index 515ead6d929f..ad786b308568 100644 --- a/sys/arch/arm/xscale/ixp425reg.h +++ b/sys/arch/arm/xscale/ixp425reg.h @@ -1,4 +1,4 @@ -/* $NetBSD: ixp425reg.h,v 1.5 2003/06/03 09:20:20 ichiro Exp $ */ +/* $NetBSD: ixp425reg.h,v 1.6 2003/06/29 10:51:31 ichiro Exp $ */ /* * Copyright (c) 2003 * Ichiro FUKUHARA . @@ -140,6 +140,7 @@ /* Interrupt Identification Register */ #define IXP425_UART_IIR 0x0008 +#define IIR_IMASK 0xf #define IIR_NOPEND (1U << 0) /* No pending interrupts */ #define IIR_MLSC (0U << 1) /* Modem status */ #define IIR_TXRDY (1U << 1) /* Transmitter ready */ @@ -191,6 +192,7 @@ #define LSR_PE (1U << 2) /* Parity error */ #define LSR_OE (1U << 1) /* Overrun, lost incoming byte */ #define LSR_DR (1U << 0) /* Byte ready in Receive Buffer */ +#define LSR_RCV_MASK 0x1f /* Incoming data and error */ /* Modem Status Register */ #define IXP425_UART_MSR 0x0018