PERFORCE change 94198 for review

Marcel Moolenaar marcel at FreeBSD.org
Tue Mar 28 19:51:28 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=94198

Change 94198 by marcel at marcel_nfs on 2006/03/28 19:25:52

	Have the sysdev methods grab and release the hardware lock.
	This prevents system console output tos with the hardware
	when the TTY layer is already doing that. By default there's
	no mutex associated with the sysdev, but when bus enumation
	links a sysdev to a softc, the hardware mutex is shared
	between them.
	
	Alternatively: put the mutex in the BAS.
	Pointed out by: grehan@
	Discussed with: grehan@

Affected files ...

.. //depot/projects/uart/dev/uart/uart_core.c#47 edit
.. //depot/projects/uart/dev/uart/uart_cpu.h#16 edit

Differences ...

==== //depot/projects/uart/dev/uart/uart_core.c#47 (text+ko) ====

@@ -205,7 +205,7 @@
 
 	if (sc->sc_opened)
 		uart_sched_softih(sc, SER_INT_SIGCHG);
-	return (0);
+	return (1);
 }
 
 /*
@@ -480,6 +480,9 @@
 	if (error)
 		goto fail;
 
+	if (sc->sc_sysdev != NULL)
+		sc->sc_sysdev->hwmtx = &sc->sc_hwmtx;
+
 	sc->sc_leaving = 0;
 	uart_intr(sc);
 	return (0);
@@ -509,6 +512,9 @@
 
 	sc->sc_leaving = 1;
 
+	if (sc->sc_sysdev != NULL)
+		sc->sc_sysdev->hwmtx = NULL;
+
 	UART_DETACH(sc);
 
 	if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL)

==== //depot/projects/uart/dev/uart/uart_cpu.h#16 (text+ko) ====

@@ -29,6 +29,10 @@
 #ifndef _DEV_UART_CPU_H_
 #define _DEV_UART_CPU_H_
 
+#include <sys/kdb.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
 /*
  * Low-level operations for use by console and/or debug port support.
  */
@@ -68,6 +72,7 @@
 	int	(*attach)(struct uart_softc*);
 	int	(*detach)(struct uart_softc*);
 	void	*cookie;		/* Type dependent use. */
+	struct mtx *hwmtx;
 };
 
 int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
@@ -80,41 +85,77 @@
  * Operations for low-level access to the UART. Primarily for use
  * by console and debug port logic.
  */
+
+static __inline void
+uart_lock_spin(struct mtx *hwmtx)
+{
+	if (!kdb_active && hwmtx != NULL)
+		mtx_lock_spin(hwmtx);
+}
+
+static __inline void
+uart_unlock_spin(struct mtx *hwmtx)
+{
+	if (!kdb_active && hwmtx != NULL)
+		mtx_unlock_spin(hwmtx);
+}
+
 static __inline int
 uart_probe(struct uart_devinfo *di)
 {
-	return (di->ops.probe(&di->bas));
+	int res;
+
+	uart_lock_spin(di->hwmtx);
+	res = di->ops.probe(&di->bas);
+	uart_unlock_spin(di->hwmtx);
+	return (res);
 }
 
 static __inline void
 uart_init(struct uart_devinfo *di)
 {
+	uart_lock_spin(di->hwmtx);
 	di->ops.init(&di->bas, di->baudrate, di->databits, di->stopbits,
 	    di->parity);
+	uart_unlock_spin(di->hwmtx);
 }
 
 static __inline void
 uart_term(struct uart_devinfo *di)
 {
+	uart_lock_spin(di->hwmtx);
 	di->ops.term(&di->bas);
+	uart_unlock_spin(di->hwmtx);
 }
 
 static __inline void
 uart_putc(struct uart_devinfo *di, int c)
 {
+	uart_lock_spin(di->hwmtx);
 	di->ops.putc(&di->bas, c);
+	uart_unlock_spin(di->hwmtx);
 }
 
 static __inline int
 uart_poll(struct uart_devinfo *di)
 {
-	return (di->ops.poll(&di->bas));
+	int res;
+
+	uart_lock_spin(di->hwmtx);
+	res = di->ops.poll(&di->bas);
+	uart_unlock_spin(di->hwmtx);
+	return (res);
 }
 
 static __inline int
 uart_getc(struct uart_devinfo *di)
 {
-	return (di->ops.getc(&di->bas));
+	int res;
+
+	uart_lock_spin(di->hwmtx);
+	res = di->ops.getc(&di->bas);
+	uart_unlock_spin(di->hwmtx);
+	return (res);
 }
 
 #endif /* _DEV_UART_CPU_H_ */


More information about the p4-projects mailing list