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