backout to recent changes w/o lwp changes
This commit is contained in:
parent
2f35689ef7
commit
25096a1afe
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ixp425_com.c,v 1.10 2003/06/29 22:28:11 fvdl Exp $ */
|
||||
/* $NetBSD: ixp425_com.c,v 1.11 2003/07/02 10:40:46 ichiro Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003
|
||||
* Ichiro FUKUHARA <ichiro@ichiro.org>.
|
||||
@ -68,7 +68,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ixp425_com.c,v 1.10 2003/06/29 22:28:11 fvdl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ixp425_com.c,v 1.11 2003/07/02 10:40:46 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
|
||||
@ -669,15 +768,14 @@ 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);
|
||||
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_UART_IER, sc->sc_ier);
|
||||
#if 0
|
||||
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);
|
||||
|
||||
/* 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 +822,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)
|
||||
@ -1017,7 +1116,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 +1211,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 +1250,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 +1306,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 +1326,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 +1396,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 +1409,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 +1458,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. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ixp425_comvar.h,v 1.5 2003/06/29 22:28:12 fvdl Exp $ */
|
||||
/* $NetBSD: ixp425_comvar.h,v 1.6 2003/07/02 10:40:47 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,
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: ixp425reg.h,v 1.7 2003/06/29 22:28:12 fvdl Exp $ */
|
||||
/* $NetBSD: ixp425reg.h,v 1.8 2003/07/02 10:40:47 ichiro Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2003
|
||||
* Ichiro FUKUHARA <ichiro@ichiro.org>.
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user