At least KuroBox Classic and HG seem to have buggy UART, for which

ETXRDY interrupts are sometimes (once per a few hours?) lost; TX stalls
until next RX arrives.

Since interrupt-based I/O works just fine for other devices, I believe
this problem is due to UART and not to PIC or its driver.

In order to work around this bug, enable COM_HW_BROKEN_ETXRDY bit, as
well as carry out polling once per 10 sec or 1k tics (arbitrary, but
1 min seems too long).

XXX
Apply this for other MPC824x-based boards?
This commit is contained in:
rin 2021-03-25 05:35:50 +00:00
parent 5805f20f6c
commit b917c45d10
2 changed files with 18 additions and 4 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: KUROBOX,v 1.8 2020/01/03 03:44:42 thorpej Exp $
# $NetBSD: KUROBOX,v 1.9 2021/03/25 05:35:50 rin Exp $
#
# KuroBox/LinkStation support
#
@ -7,7 +7,8 @@ include "arch/sandpoint/conf/GENERIC"
no com0
no satmgr0
com0 at eumb? unit 1 # console at 0x4600
com0 at eumb? unit 1 flags 0x1 # console at 0x4600
# XXX flags 0x1 to work around H/W bug
#com1 at eumb? unit 0
satmgr0 at eumb? unit 0 # satmgr at 0x4500

View File

@ -1,4 +1,4 @@
/* $NetBSD: com_eumb.c,v 1.11 2021/03/17 14:50:11 rin Exp $ */
/* $NetBSD: com_eumb.c,v 1.12 2021/03/25 05:35:50 rin Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: com_eumb.c,v 1.11 2021/03/17 14:50:11 rin Exp $");
__KERNEL_RCSID(0, "$NetBSD: com_eumb.c,v 1.12 2021/03/25 05:35:50 rin Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -99,6 +99,19 @@ com_eumb_attach(device_t parent, device_t self, void *aux)
sc->sc_frequency = 4 * ticks_per_sec;
epicirq = (eaa->eumb_unit == 1) ? 25 : 24;
/*
* XXX
* At least KuroBox Classic and HG seem to have a hardware bug, by
* which ETXRDY interrupt is sometimes, say, once per few hours,
* lost; output stalls until next input arrives. In order to work
* around this problem, push TX queue manually by low-rate.
*/
#define COM_EUMB_FLAG_BROKEN_ETXRDY __BIT(0)
if (device_cfdata(self)->cf_flags & COM_EUMB_FLAG_BROKEN_ETXRDY) {
SET(sc->sc_hwflags, COM_HW_BROKEN_ETXRDY);
sc->sc_poll_ticks = 10 * hz; /* once per 10 sec */
}
com_attach_subr(sc);
intr_establish_xname(epicirq + I8259_ICU, IST_LEVEL, IPL_SERIAL,