serial console "detection" during boot

Andriy Gapon avg at FreeBSD.org
Mon Sep 17 20:23:14 UTC 2012


Guys,

what do you think of the following two diffs?

Most likely I overdid various checks in libi386/comconsole.c.
And, obviously, the RETRY_COUNT value is pulled out of thin air.
Any help and suggestions are very welcome.

With this patch I am able to boot with
boot_multicons="YES"
console="vidconsole,comconsole"
in loader.conf on hardware where serial ports are disabled in BIOS.
Previously loader would just hang trying to apply the console setting.


commit 60b4e960550229fb93efe98f5f5a386814c84652
Author: Andriy Gapon <avg at icyb.net.ua>
Date:   Sun Sep 16 11:01:00 2012 +0300

    boot/console: don't activate console if it's not able to probe

diff --git a/sys/boot/common/console.c b/sys/boot/common/console.c
index d140a96..28ae23a 100644
--- a/sys/boot/common/console.c
+++ b/sys/boot/common/console.c
@@ -218,8 +218,11 @@ cons_change(const char *string)
 		continue;
 	cons = cons_find(curpos);
 	if (cons >= 0) {
-	    consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
-	    consoles[cons]->c_init(0);
+	    if ((consoles[cons]->c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
+		    (C_PRESENTIN | C_PRESENTOUT)) {
+		consoles[cons]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
+		consoles[cons]->c_init(0);
+	    }
 	}
     }

commit 54da1b554eef3f88fb15ea481f48f5a83375203d
Author: Andriy Gapon <avg at icyb.net.ua>
Date:   Sun Sep 16 11:03:04 2012 +0300

    boot/i386/comconsole: probe hardware presence with limited number of attempts

    ... to initialize it.

diff --git a/sys/boot/i386/libi386/comconsole.c b/sys/boot/i386/libi386/comconsole.c
index bf0d67b..82e46ae 100644
--- a/sys/boot/i386/libi386/comconsole.c
+++ b/sys/boot/i386/libi386/comconsole.c
@@ -59,7 +59,7 @@ static int	comc_pcidev_set(struct env_var *ev, int flags,
 static int	comc_pcidev_handle(uint32_t locator);
 static int	comc_port_set(struct env_var *ev, int flags,
 		    const void *value);
-static void	comc_setup(int speed, int port);
+static int	comc_setup(int speed, int port);
 static int	comc_speed_set(struct env_var *ev, int flags,
 		    const void *value);

@@ -137,18 +137,23 @@ comc_probe(struct console *cp)
 	env_setenv("comconsole_pcidev", EV_VOLATILE, env, comc_pcidev_set,
 	    env_nounset);
     }
+    (void)comc_init(0);
 }

 static int
 comc_init(int arg)
 {
     if (comc_started && arg == 0)
-	return 0;
-    comc_started = 1;
-
-    comc_setup(comc_curspeed, comc_port);
+	return (CMD_OK);

-    return(0);
+    if (comc_setup(comc_curspeed, comc_port) == CMD_OK) {
+	comc_started = 1;
+	comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+	return (CMD_OK);
+    }
+    comc_started = 0;
+    comconsole.c_flags &= ~(C_PRESENTIN | C_PRESENTOUT);
+    return (CMD_ERROR);
 }

 static void
@@ -156,6 +161,8 @@ comc_putchar(int c)
 {
     int wait;

+    if (!comc_started)
+	return;
     for (wait = COMC_TXWAIT; wait > 0; wait--)
         if (inb(comc_port + com_lsr) & LSR_TXRDY) {
 	    outb(comc_port + com_data, (u_char)c);
@@ -166,13 +173,17 @@ comc_putchar(int c)
 static int
 comc_getchar(void)
 {
-    return(comc_ischar() ? inb(comc_port + com_data) : -1);
+    if (!comc_started)
+	return (-1);
+    return (comc_ischar() ? inb(comc_port + com_data) : -1);
 }

 static int
 comc_ischar(void)
 {
-    return(inb(comc_port + com_lsr) & LSR_RXRDY);
+    if (!comc_started)
+	return (0);
+    return (inb(comc_port + com_lsr) & LSR_RXRDY);
 }

 static int
@@ -314,9 +325,11 @@ comc_pcidev_set(struct env_var *ev, int flags, const void
*value)
 	return (CMD_OK);
 }

-static void
+static int
 comc_setup(int speed, int port)
 {
+    static int TRY_COUNT = 1000000;
+    int tries;

     comc_curspeed = speed;
     comc_port = port;
@@ -327,9 +340,11 @@ comc_setup(int speed, int port)
     outb(comc_port + com_cfcr, COMC_FMT);
     outb(comc_port + com_mcr, MCR_RTS | MCR_DTR);

+    tries = 0;
     do
         inb(comc_port + com_data);
-    while (inb(comc_port + com_lsr) & LSR_RXRDY);
+    while (inb(comc_port + com_lsr) & LSR_RXRDY && ++tries < TRY_COUNT);
+    return (tries < TRY_COUNT ? CMD_OK : CMD_ERROR);
 }

 static int

-- 
Andriy Gapon


More information about the freebsd-hackers mailing list