From nobody@FreeBSD.org  Tue Dec 17 04:47:42 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
	(using TLSv1 with cipher ADH-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by hub.freebsd.org (Postfix) with ESMTPS id B069E915
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 17 Dec 2013 04:47:42 +0000 (UTC)
Received: from oldred.freebsd.org (oldred.freebsd.org [IPv6:2001:1900:2254:206a::50:4])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by mx1.freebsd.org (Postfix) with ESMTPS id 9216B1854
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 17 Dec 2013 04:47:42 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id rBH4lgOx092141
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 17 Dec 2013 04:47:42 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id rBH4lgsN092122;
	Tue, 17 Dec 2013 04:47:42 GMT
	(envelope-from nobody)
Message-Id: <201312170447.rBH4lgsN092122@oldred.freebsd.org>
Date: Tue, 17 Dec 2013 04:47:42 GMT
From: John Wehle <john@feith.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: uart infrastructure missing console grab / ungrab hooks
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         184919
>Category:       kern
>Synopsis:       uart infrastructure missing console grab / ungrab hooks
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 17 04:50:00 UTC 2013
>Closed-Date:    Sun Dec 22 11:41:19 MST 2013
>Last-Modified:  Sun Dec 22 11:41:19 MST 2013
>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:
State-Changed-From-To: open->closed 
State-Changed-By: imp 
State-Changed-When: Sun Dec 22 11:39:44 MST 2013 
State-Changed-Why:  
Committed similar patch without even knowing about this PR. 
that patch will be merged to stable/10 later today, but not to release/10.0 
For earlier revs of FreeBSD, you'll need to defer enabling that interrupt, see atmel's uart for an example (also to be committed later today). 
This is less complete, but adequate to cover the mountroot prompt case. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=184919 
>Unformatted:
