From owner-svn-src-head@freebsd.org Tue May 29 16:16:25 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A8EF2EF5C7C; Tue, 29 May 2018 16:16:25 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 55A0B72DB6; Tue, 29 May 2018 16:16:25 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 346A11E42A; Tue, 29 May 2018 16:16:25 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w4TGGOon017362; Tue, 29 May 2018 16:16:24 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w4TGGOsa017358; Tue, 29 May 2018 16:16:24 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201805291616.w4TGGOsa017358@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Tue, 29 May 2018 16:16:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r334340 - in head/sys: dev/uart kern sys x86/acpica X-SVN-Group: head X-SVN-Commit-Author: avg X-SVN-Commit-Paths: in head/sys: dev/uart kern sys x86/acpica X-SVN-Commit-Revision: 334340 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 May 2018 16:16:25 -0000 Author: avg Date: Tue May 29 16:16:24 2018 New Revision: 334340 URL: https://svnweb.freebsd.org/changeset/base/334340 Log: add support for console resuming, implement it for uart, use on x86 This change adds a new optional console method cn_resume and a kernel console interface cnresume. Consoles that may need to re-initialize their hardware after suspend (e.g., because firmware does not care to do it) will implement cn_resume. Note that it is called in rather early environment not unlike early boot, so the same restrictions apply. Platform specific code, for platforms that support hardware suspend, should call cnresume early after resume, before any console output is expected. This change fixes a problem with a system of mine failing to resume when a serial console is used. I found that the serial port was in a strange configuration and an attempt to write to it likely resulted in an infinite loop. To avoid adding cn_resume method to every console driver, CONSOLE_DRIVER macro has been extended to support optional methods. Reviewed by: imp, mav MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D15552 Modified: head/sys/dev/uart/uart_tty.c head/sys/kern/kern_cons.c head/sys/sys/cons.h head/sys/x86/acpica/acpi_wakeup.c Modified: head/sys/dev/uart/uart_tty.c ============================================================================== --- head/sys/dev/uart/uart_tty.c Tue May 29 16:04:53 2018 (r334339) +++ head/sys/dev/uart/uart_tty.c Tue May 29 16:16:24 2018 (r334340) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); static cn_probe_t uart_cnprobe; static cn_init_t uart_cninit; +static cn_init_t uart_cnresume; static cn_term_t uart_cnterm; static cn_getc_t uart_cngetc; static cn_putc_t uart_cnputc; @@ -69,7 +70,10 @@ static tsw_modem_t uart_tty_modem; static tsw_free_t uart_tty_free; static tsw_busy_t uart_tty_busy; -CONSOLE_DRIVER(uart); +CONSOLE_DRIVER( + uart, + .cn_resume = uart_cnresume, +); static struct uart_devinfo uart_console; @@ -112,6 +116,13 @@ uart_cninit(struct consdev *cp) di->type = UART_DEV_CONSOLE; uart_add_sysdev(di); uart_init(di); +} + +static void +uart_cnresume(struct consdev *cp) +{ + + uart_init(cp->cn_arg); } static void Modified: head/sys/kern/kern_cons.c ============================================================================== --- head/sys/kern/kern_cons.c Tue May 29 16:04:53 2018 (r334339) +++ head/sys/kern/kern_cons.c Tue May 29 16:16:24 2018 (r334340) @@ -384,6 +384,19 @@ cnungrab() } } +void +cnresume() +{ + struct cn_device *cnd; + struct consdev *cn; + + STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) { + cn = cnd->cnd_cn; + if (cn->cn_ops->cn_resume != NULL) + cn->cn_ops->cn_resume(cn); + } +} + /* * Low level console routines. */ Modified: head/sys/sys/cons.h ============================================================================== --- head/sys/sys/cons.h Tue May 29 16:04:53 2018 (r334339) +++ head/sys/sys/cons.h Tue May 29 16:16:24 2018 (r334340) @@ -66,6 +66,8 @@ struct consdev_ops { /* grab console for exclusive kernel use */ cn_ungrab_t *cn_ungrab; /* ungrab console */ + cn_init_t *cn_resume; + /* set up console after sleep, optional */ }; struct consdev { @@ -105,8 +107,9 @@ extern struct tty *constty; /* Temporary virtual conso }; \ DATA_SET(cons_set, name) -#define CONSOLE_DRIVER(name) \ +#define CONSOLE_DRIVER(name, ...) \ static const struct consdev_ops name##_consdev_ops = { \ + /* Mandatory methods. */ \ .cn_probe = name##_cnprobe, \ .cn_init = name##_cninit, \ .cn_term = name##_cnterm, \ @@ -114,6 +117,8 @@ extern struct tty *constty; /* Temporary virtual conso .cn_putc = name##_cnputc, \ .cn_grab = name##_cngrab, \ .cn_ungrab = name##_cnungrab, \ + /* Optional fields. */ \ + __VA_ARGS__ \ }; \ CONSOLE_DEVICE(name##_consdev, name##_consdev_ops, NULL) @@ -126,6 +131,7 @@ void cnremove(struct consdev *); void cnselect(struct consdev *); void cngrab(void); void cnungrab(void); +void cnresume(void); int cncheckc(void); int cngetc(void); void cngets(char *, size_t, int); Modified: head/sys/x86/acpica/acpi_wakeup.c ============================================================================== --- head/sys/x86/acpica/acpi_wakeup.c Tue May 29 16:04:53 2018 (r334339) +++ head/sys/x86/acpica/acpi_wakeup.c Tue May 29 16:16:24 2018 (r334340) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -296,6 +297,12 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state) for (;;) ia32_pause(); } else { + /* + * Re-initialize console hardware as soon as possibe. + * No console output (e.g. printf) is allowed before + * this point. + */ + cnresume(); #ifdef __amd64__ fpuresume(susppcbs[0]->sp_fpususpend); #else