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,

Reply via email to