Index: sys/boot/i386/boot2/boot2.c =================================================================== --- sys/boot/i386/boot2/boot2.c (revision 241434) +++ sys/boot/i386/boot2/boot2.c (working copy) @@ -415,8 +415,10 @@ parse() } ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) : OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD; - if (ioctrl & IO_SERIAL) - sio_init(115200 / comspeed); + if (ioctrl & IO_SERIAL) { + if (sio_init(115200 / comspeed)) + ioctrl &= ~IO_SERIAL; + } } else { for (q = arg--; *q && *q != '('; q++); if (*q) { Index: sys/boot/i386/boot2/lib.h =================================================================== --- sys/boot/i386/boot2/lib.h (revision 241434) +++ sys/boot/i386/boot2/lib.h (working copy) @@ -17,7 +17,7 @@ * $FreeBSD$ */ -void sio_init(int) __attribute__((regparm (3))); +int sio_init(int) __attribute__((regparm (3))); void sio_flush(void); void sio_putc(int) __attribute__((regparm (3))); int sio_getc(void); Index: sys/boot/i386/boot2/sio.S =================================================================== --- sys/boot/i386/boot2/sio.S (revision 241434) +++ sys/boot/i386/boot2/sio.S (working copy) @@ -24,12 +24,15 @@ .globl sio_getc .globl sio_ischar -/* void sio_init(int div) */ +/* int sio_init(int div) */ sio_init: pushl %eax movw $SIO_PRT+0x3,%dx # Data format reg movb $SIO_FMT|0x80,%al # Set format outb %al,(%dx) # and DLAB + inb (%dx),%al + cmpb $SIO_FMT|0x80,%al + jnz sio_init.1 subb $0x3,%dl # Divisor latch reg popl %eax outw %ax,(%dx) # BPS @@ -41,8 +44,13 @@ sio_init: pushl %eax outb %al,(%dx) # DTR incl %edx # Line status reg call sio_flush + xor %eax,%eax ret +sio_init.1: popl %eax + movb $0x1,%al + ret + /* void sio_flush(void) */ sio_flush.0: call sio_getc.1 # Get character Index: sys/boot/i386/libi386/comconsole.c =================================================================== --- sys/boot/i386/libi386/comconsole.c (revision 241434) +++ sys/boot/i386/libi386/comconsole.c (working copy) @@ -33,7 +33,7 @@ __FBSDID("$FreeBSD$"); #include "libi386.h" #define COMC_FMT 0x3 /* 8N1 */ -#define COMC_TXWAIT 0x40000 /* transmit timeout */ +#define COMC_TXWAIT 0x80 /* transmit timeout */ #define COMC_BPS(x) (115200 / (x)) /* speed to DLAB divisor */ #define COMC_DIV2BPS(x) (115200 / (x)) /* DLAB divisor to speed */ @@ -57,6 +57,7 @@ static int comc_speed_set(struct env_var *ev, int static int comc_started; static int comc_curspeed; +static int comc_disabled; struct console comconsole = { "comconsole", @@ -76,9 +77,12 @@ comc_probe(struct console *cp) char *cons, *speedenv; int speed; - /* XXX check the BIOS equipment list? */ - cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); + u_char dlbh; + u_char dlbl; + u_char cfcr; + comc_disabled = 0; + if (comc_curspeed == 0) { comc_curspeed = COMSPEED; /* @@ -102,6 +106,22 @@ comc_probe(struct console *cp) env_setenv("comconsole_speed", EV_VOLATILE, speedbuf, comc_speed_set, env_nounset); } + + cfcr = inb(COMPORT + com_cfcr); + outb(COMPORT + com_cfcr, CFCR_DLAB | cfcr); + + dlbl = inb(COMPORT + com_dlbl); + dlbh = inb(COMPORT + com_dlbh); + + outb(COMPORT + com_cfcr, cfcr); + + if (dlbl == 0xff && dlbh == 0xff && cfcr == 0xff) { + cp->c_flags &= ~(C_PRESENTIN | C_PRESENTOUT); + comc_disabled = 1; + return; + } + + cp->c_flags |= (C_PRESENTIN | C_PRESENTOUT); } static int @@ -121,6 +141,9 @@ comc_putchar(int c) { int wait; + if (comc_disabled) + return; + for (wait = COMC_TXWAIT; wait > 0; wait--) if (inb(COMPORT + com_lsr) & LSR_TXRDY) { outb(COMPORT + com_data, (u_char)c); @@ -131,6 +154,10 @@ comc_putchar(int c) static int comc_getchar(void) { + + if (comc_disabled) + return -1; + return(comc_ischar() ? inb(COMPORT + com_data) : -1); } @@ -161,6 +188,7 @@ comc_speed_set(struct env_var *ev, int flags, cons static void comc_setup(int speed) { + int retry = 0x80; comc_curspeed = speed; @@ -172,7 +200,7 @@ comc_setup(int speed) do inb(COMPORT + com_data); - while (inb(COMPORT + com_lsr) & LSR_RXRDY); + while (inb(COMPORT + com_lsr) & LSR_RXRDY && (--retry > 0)); } static int