summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2012-10-06 20:04:51 +0000
committeravg <avg@FreeBSD.org>2012-10-06 20:04:51 +0000
commit32321c36780eb0e0f1c299c3c21d41d0a49a5702 (patch)
tree9a5b56be597af964ccd010cbc1983e1e9219fe02
parent8f560f2f98ad513d615a52be1f0ddae0bb9c4824 (diff)
downloadFreeBSD-src-32321c36780eb0e0f1c299c3c21d41d0a49a5702.zip
FreeBSD-src-32321c36780eb0e0f1c299c3c21d41d0a49a5702.tar.gz
i386 comconsole: don't loop forever if hardware doesn't respond
- clear capability flags when hw timeouts - retire comc_started status variable and directly use c_flags to see if comconsole is selected for use Reviewed by: jhb Tested by: Uffe Jakobsen <uffe@uffe.org>, Olivier Cochard-Labbe <olivier@cochard.me> MFC after: 26 days
-rw-r--r--sys/boot/i386/libi386/comconsole.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/sys/boot/i386/libi386/comconsole.c b/sys/boot/i386/libi386/comconsole.c
index bf0d67b..3822597 100644
--- a/sys/boot/i386/libi386/comconsole.c
+++ b/sys/boot/i386/libi386/comconsole.c
@@ -63,7 +63,6 @@ static void comc_setup(int speed, int port);
static int comc_speed_set(struct env_var *ev, int flags,
const void *value);
-static int comc_started;
static int comc_curspeed;
static int comc_port = COMPORT;
static uint32_t comc_locator;
@@ -87,9 +86,6 @@ comc_probe(struct console *cp)
int speed, port;
uint32_t locator;
- /* XXX check the BIOS equipment list? */
- cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT);
-
if (comc_curspeed == 0) {
comc_curspeed = COMSPEED;
/*
@@ -137,18 +133,19 @@ comc_probe(struct console *cp)
env_setenv("comconsole_pcidev", EV_VOLATILE, env, comc_pcidev_set,
env_nounset);
}
+ comc_setup(comc_curspeed, comc_port);
}
static int
comc_init(int arg)
{
- if (comc_started && arg == 0)
- return 0;
- comc_started = 1;
comc_setup(comc_curspeed, comc_port);
- return(0);
+ if ((comconsole.c_flags & (C_PRESENTIN | C_PRESENTOUT)) ==
+ (C_PRESENTIN | C_PRESENTOUT))
+ return (CMD_OK);
+ return (CMD_ERROR);
}
static void
@@ -166,13 +163,13 @@ comc_putchar(int c)
static int
comc_getchar(void)
{
- return(comc_ischar() ? inb(comc_port + com_data) : -1);
+ return (comc_ischar() ? inb(comc_port + com_data) : -1);
}
static int
comc_ischar(void)
{
- return(inb(comc_port + com_lsr) & LSR_RXRDY);
+ return (inb(comc_port + com_lsr) & LSR_RXRDY);
}
static int
@@ -185,7 +182,8 @@ comc_speed_set(struct env_var *ev, int flags, const void *value)
return (CMD_ERROR);
}
- if (comc_started && comc_curspeed != speed)
+ if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
+ comc_curspeed != speed)
comc_setup(speed, comc_port);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
@@ -203,7 +201,8 @@ comc_port_set(struct env_var *ev, int flags, const void *value)
return (CMD_ERROR);
}
- if (comc_started && comc_port != port) {
+ if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
+ comc_port != port) {
comc_setup(comc_curspeed, port);
set_hw_console_hint();
}
@@ -305,7 +304,8 @@ comc_pcidev_set(struct env_var *ev, int flags, const void *value)
printf("Invalid pcidev\n");
return (CMD_ERROR);
}
- if (comc_started && comc_locator != locator) {
+ if ((comconsole.c_flags & (C_ACTIVEIN | C_ACTIVEOUT)) != 0 &&
+ comc_locator != locator) {
error = comc_pcidev_handle(locator);
if (error != CMD_OK)
return (error);
@@ -317,6 +317,8 @@ comc_pcidev_set(struct env_var *ev, int flags, const void *value)
static void
comc_setup(int speed, int port)
{
+ static int TRY_COUNT = 1000000;
+ int tries;
comc_curspeed = speed;
comc_port = port;
@@ -327,9 +329,15 @@ 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);
+
+ if (tries < TRY_COUNT)
+ comconsole.c_flags |= (C_PRESENTIN | C_PRESENTOUT);
+ else
+ comconsole.c_flags &= ~(C_PRESENTIN | C_PRESENTOUT);
}
static int
OpenPOWER on IntegriCloud