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