Module Name: src Committed By: jmcneill Date: Sun Oct 17 22:34:17 UTC 2021
Modified Files: src/sys/arch/evbarm/dev: plcom.c plcomvar.h Log Message: plcom: speed up close with HUPCL set Instead of incurring a 1s penalty on close of a plcom device with HUPCL set, defer the sleep until the next open, and only sleep if necessary. To generate a diff of this commit: cvs rdiff -u -r1.62 -r1.63 src/sys/arch/evbarm/dev/plcom.c cvs rdiff -u -r1.17 -r1.18 src/sys/arch/evbarm/dev/plcomvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/evbarm/dev/plcom.c diff -u src/sys/arch/evbarm/dev/plcom.c:1.62 src/sys/arch/evbarm/dev/plcom.c:1.63 --- src/sys/arch/evbarm/dev/plcom.c:1.62 Mon Oct 19 17:00:02 2020 +++ src/sys/arch/evbarm/dev/plcom.c Sun Oct 17 22:34:17 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: plcom.c,v 1.62 2020/10/19 17:00:02 tnn Exp $ */ +/* $NetBSD: plcom.c,v 1.63 2021/10/17 22:34:17 jmcneill Exp $ */ /*- * Copyright (c) 2001 ARM Ltd @@ -94,7 +94,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.62 2020/10/19 17:00:02 tnn Exp $"); +__KERNEL_RCSID(0, "$NetBSD: plcom.c,v 1.63 2021/10/17 22:34:17 jmcneill Exp $"); #include "opt_plcom.h" #include "opt_ddb.h" @@ -686,10 +686,8 @@ plcom_shutdown(struct plcom_softc *sc) */ if (ISSET(tp->t_cflag, HUPCL)) { plcom_modem(sc, 0); - mutex_spin_exit(&sc->sc_lock); - /* XXX will only timeout */ - (void) kpause(ttclos, false, hz, NULL); - mutex_spin_enter(&sc->sc_lock); + microtime(&sc->sc_hup_pending); + sc->sc_hup_pending.tv_sec++; } sc->sc_cr = 0; @@ -773,6 +771,7 @@ plcomopen(dev_t dev, int flag, int mode, */ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { struct termios t; + struct timeval now, diff; tp->t_dev = dev; @@ -790,6 +789,18 @@ plcomopen(dev_t dev, int flag, int mode, mutex_spin_enter(&sc->sc_lock); } + if (timerisset(&sc->sc_hup_pending)) { + microtime(&now); + while (timercmp(&now, &sc->sc_hup_pending, <)) { + timersub(&sc->sc_hup_pending, &now, &diff); + const int ms = diff.tv_sec * 100 + + uimax(diff.tv_usec / 1000, 1); + kpause(ttclos, false, mstohz(ms), &sc->sc_lock); + microtime(&now); + } + timerclear(&sc->sc_hup_pending); + } + /* Turn on interrupts. */ /* IER_ERXRDY | IER_ERLS | IER_EMSC; */ /* Fetch the current modem control status, needed later. */ Index: src/sys/arch/evbarm/dev/plcomvar.h diff -u src/sys/arch/evbarm/dev/plcomvar.h:1.17 src/sys/arch/evbarm/dev/plcomvar.h:1.18 --- src/sys/arch/evbarm/dev/plcomvar.h:1.17 Thu Oct 12 20:05:42 2017 +++ src/sys/arch/evbarm/dev/plcomvar.h Sun Oct 17 22:34:17 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: plcomvar.h,v 1.17 2017/10/12 20:05:42 skrll Exp $ */ +/* $NetBSD: plcomvar.h,v 1.18 2021/10/17 22:34:17 jmcneill Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. @@ -104,6 +104,8 @@ struct plcom_softc { sc_swflags; u_int sc_fifolen; + struct timeval sc_hup_pending; + u_int sc_r_hiwat, sc_r_lowat; u_char *volatile sc_rbget,