kern/184919: uart infrastructure missing console grab / ungrab hooks
John Wehle
john at feith.com
Tue Dec 17 04:50:01 UTC 2013
>Number: 184919
>Category: kern
>Synopsis: uart infrastructure missing console grab / ungrab hooks
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Dec 17 04:50:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator: John Wehle
>Release: svn head r259072
>Organization:
Personal
>Environment:
Not Yet
>Description:
In my spare time I'm working on bringing FreeBSD up on amlogic based
arm processors. If I load the kernel into memory, remove the SD card,
and then start the kernel it fails to mount root (as expected) so a
mountroot prompt is displayed. Typing anything at that prompt gives:
panic: bad stray interrupt
What appears to happen is typing a character causes the uart to generate
an interrupt. In the meantime uart_cngetc has retrieved the character
(meaning UART RX FIFO is now empty) so when uart_intr invokes UART_IPEND
ipend is set to zero causing uart_intr to return FILTER_STRAY. Basically
there's a race between the console routines and the uart routines due to
grab / ungrab not being implemented.
The attached patch adds support for grab / ungrab hooks which I take
advantage of in the aml8726 uart driver ... the driver's grab routine
tells the uart to not generate interrupts allowing the console routines
(which poll) to work properly and the ungrab routine tells the uart (if
the driver was attached) to go ahead and generate interrupts.
This suffices to avoid the panic and allows the mountroot prompt to work.
>How-To-Repeat:
>Fix:
Add support for grab / ungrab hooks and supply suitable implementations
in the device specific driver.
Patch to optionally support grab / ungrab hooks supplied below:
Patch attached with submission follows:
--- sys/dev/uart/uart_cpu.h.ORIGINAL 2013-09-06 23:01:55.000000000 -0400
+++ sys/dev/uart/uart_cpu.h 2013-12-15 00:13:19.000000000 -0500
@@ -40,6 +40,8 @@
int (*probe)(struct uart_bas *);
void (*init)(struct uart_bas *, int, int, int, int);
void (*term)(struct uart_bas *);
+ void (*grab)(struct uart_bas *);
+ void (*ungrab)(struct uart_bas *);
void (*putc)(struct uart_bas *, int);
int (*rxready)(struct uart_bas *);
int (*getc)(struct uart_bas *, struct mtx *);
@@ -128,6 +130,28 @@
}
static __inline void
+uart_grab(struct uart_devinfo *di)
+{
+ if (di->ops->grab == NULL)
+ return;
+
+ uart_lock(di->hwmtx);
+ di->ops->grab(&di->bas);
+ uart_unlock(di->hwmtx);
+}
+
+static __inline void
+uart_ungrab(struct uart_devinfo *di)
+{
+ if (di->ops->ungrab == NULL)
+ return;
+
+ uart_lock(di->hwmtx);
+ di->ops->ungrab(&di->bas);
+ uart_unlock(di->hwmtx);
+}
+
+static __inline void
uart_putc(struct uart_devinfo *di, int c)
{
uart_lock(di->hwmtx);
--- sys/dev/uart/uart_tty.c.ORIGINAL 2013-09-06 23:01:55.000000000 -0400
+++ sys/dev/uart/uart_tty.c 2013-12-15 00:14:15.000000000 -0500
@@ -112,11 +112,15 @@
static void
uart_cngrab(struct consdev *cp)
{
+
+ uart_grab(cp->cn_arg);
}
static void
uart_cnungrab(struct consdev *cp)
{
+
+ uart_ungrab(cp->cn_arg);
}
static void
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list