summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart/uart_dev_ns8250.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-04-01 19:04:54 +0000
committermarcel <marcel@FreeBSD.org>2006-04-01 19:04:54 +0000
commit01ed5990aef062b97e91680895804b9689c8076b (patch)
treef866ed454b38b3e3ed100d7237faffef820e51f3 /sys/dev/uart/uart_dev_ns8250.c
parent6d14bcd43fdc1e895dd4255bb9f88dba939296ce (diff)
downloadFreeBSD-src-01ed5990aef062b97e91680895804b9689c8076b.zip
FreeBSD-src-01ed5990aef062b97e91680895804b9689c8076b.tar.gz
Don't hold the hardware mutex across getc(). It can wait indefinitely
for a character to be received. Instead let getc() do any necesary locking.
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 378639f..adb4502 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -217,7 +217,7 @@ static void ns8250_init(struct uart_bas *bas, int, int, int, int);
static void ns8250_term(struct uart_bas *bas);
static void ns8250_putc(struct uart_bas *bas, int);
static int ns8250_poll(struct uart_bas *bas);
-static int ns8250_getc(struct uart_bas *bas);
+static int ns8250_getc(struct uart_bas *bas, struct mtx *);
struct uart_ops uart_ns8250_ops = {
.probe = ns8250_probe,
@@ -321,16 +321,26 @@ ns8250_poll(struct uart_bas *bas)
}
static int
-ns8250_getc(struct uart_bas *bas)
+ns8250_getc(struct uart_bas *bas, struct mtx *hwmtx)
{
- int delay;
+ int c, delay;
+
+ uart_lock(hwmtx);
/* 1/10th the time to transmit 1 character (estimate). */
delay = ns8250_delay(bas);
- while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0)
+ while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0) {
+ uart_unlock(hwmtx);
DELAY(delay);
- return (uart_getreg(bas, REG_DATA));
+ uart_lock(hwmtx);
+ }
+
+ c = uart_getreg(bas, REG_DATA);
+
+ uart_unlock(hwmtx);
+
+ return (c);
}
/*
OpenPOWER on IntegriCloud