Fix a minor bug in the auto-console selection (handle the -m mute option
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 27 Jun 2004 08:00:46 +0000 (08:00 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 27 Jun 2004 08:00:46 +0000 (08:00 +0000)
properly).

Detect when the serial port is unmapped (reads 0xFF) by putting a limit in
the flush code and returning a testable value, then refuse to automatically
configure it if so because an unmapped serial port always looks like it has
input pending.

This fixes a dual-console issue with laptops that don't map the serial port
during the boot stage (e.g. my emachines amd64 laptop).

Be ultra conservative for now, do not try to initialize the FIFO.

sys/boot/i386/boot2/boot2.c
sys/boot/i386/boot2/lib.h
sys/boot/i386/boot2/sio.S
sys/boot/i386/boot2/sio.s
sys/boot/pc32/boot2/boot2.c
sys/boot/pc32/boot2/lib.h
sys/boot/pc32/boot2/sio.S

index 4cf48f4..a6a48ec 100644 (file)
@@ -13,7 +13,7 @@
  * purpose.
  *
  * $FreeBSD: src/sys/boot/i386/boot2/boot2.c,v 1.64 2003/08/25 23:28:31 obrien Exp $
- * $DragonFly: src/sys/boot/i386/boot2/Attic/boot2.c,v 1.9 2004/06/26 23:41:06 dillon Exp $
+ * $DragonFly: src/sys/boot/i386/boot2/Attic/boot2.c,v 1.10 2004/06/27 08:00:46 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/disklabel.h>
@@ -50,6 +50,7 @@
 #define RBX_PROBEKBD   0x1e    /* -P */
 /* 0x1f is reserved for the historical RB_BOOTINFO option */
 
+#define RBF_MUTE       (1 << RBX_MUTE)
 #define RBF_SERIAL     (1 << RBX_SERIAL)
 #define RBF_VIDEO      (1 << RBX_VIDEO)
 
@@ -246,12 +247,16 @@ main(void)
     }
 
     /*
-     * Setup our (serial) console after processing the config file
+     * Setup our (serial) console after processing the config file.  If
+     * the initialization fails, don't try to use the serial port.  This
+     * can happen if the serial port is unmaped (happens on new laptops a lot).
      */
-    if ((opts & (RBF_SERIAL|RBF_VIDEO)) == 0)
+    if ((opts & (RBF_MUTE|RBF_SERIAL|RBF_VIDEO)) == 0)
        opts |= RBF_SERIAL|RBF_VIDEO;
-    if (opts & RBF_SERIAL)
-       sio_init();
+    if (opts & RBF_SERIAL) {
+       if (sio_init())
+           opts = RBF_VIDEO;
+    }
 
 
     /*
@@ -270,13 +275,10 @@ main(void)
     /* Present the user with the boot2 prompt. */
 
     for (;;) {
-       printf("\nDragonFly/i386 boot\n"
-              "Default: %u:%s(%u,%c)%s\n"
-              "boot: ",
+       printf("\nDragonFly boot\n"
+              "%u:%s(%u,%c)%s: ",
               dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
               'a' + dsk.part, kname);
-       if (opts & RBF_SERIAL)
-           sio_flush();
        if (!autoboot || keyhit(5*SECOND))
            getstr();
        else
index 23e4339..b1cd8f1 100644 (file)
 
 /*
  * $FreeBSD: src/sys/boot/i386/boot2/lib.h,v 1.2 1999/08/28 00:40:02 peter Exp $
- * $DragonFly: src/sys/boot/i386/boot2/Attic/lib.h,v 1.3 2003/11/10 06:08:35 dillon Exp $
+ * $DragonFly: src/sys/boot/i386/boot2/Attic/lib.h,v 1.4 2004/06/27 08:00:46 dillon Exp $
  */
 
-void sio_init(void);
+int sio_init(void);    /* returns non-zero if init failed */
 void sio_flush(void);
 void sio_putc(int);
 int sio_getc(void);
index c1cdc5b..396e588 100644 (file)
@@ -14,7 +14,7 @@
 #
 
 # $FreeBSD: src/sys/boot/i386/boot2/sio.s,v 1.4 1999/08/28 00:40:02 peter Exp $
-# $DragonFly: src/sys/boot/i386/boot2/Attic/sio.S,v 1.4 2004/06/26 23:41:06 dillon Exp $
+# $DragonFly: src/sys/boot/i386/boot2/Attic/sio.S,v 1.5 2004/06/27 08:00:46 dillon Exp $
 
                .set SIO_PRT,SIOPRT             # Base port
                .set SIO_FMT,SIOFMT             # 8N1
                .globl sio_getc
                .globl sio_ischar
 
-# void sio_init(void)
+# int sio_init(void)
+# 
+# returns non-zero if we couldn't init, which can happen if the
+# serial port is unmapped and the inb's all return 0xFF (we fail
+# to flush the input).
 
 sio_init:      movw $SIO_PRT+0x3,%dx           # Data format reg
                movb $SIO_FMT|0x80,%al          # Set format and DLAB
@@ -36,20 +40,27 @@ sio_init:   movw $SIO_PRT+0x3,%dx           # Data format reg
                outw %ax,(%dx)                  # BASE+0 (divisor w/ DLAB set)
                movw $SIO_PRT+0x2,%dx
                movb $0x01,%al                  # Enable FIFO
-               outb %al,(%dx)                  # BASE+2
+               # DISABLED - apparently many new laptops only implement 
+               # 8250s, this might crash them? XXX
+               # outb %al,(%dx)                        # BASE+2
                incl %edx
                movb $SIO_FMT,%al               # Clear DLAB
                outb %al,(%dx)                  # BASE+3
                incl %edx
                movb $0x3,%al                   # RTS+DTR
                outb %al,(%dx)                  # BASE+4
-               incl %edx                       # Line status reg
+               incl %edx                       # BASE+5 Line status reg
 
-# void sio_flush(void)
+               # fall through to io_flush
+               #
+               # sio_flush: flush pending data in the serial port,
+               # return non-zero if we were unable to flush (aka
+               # ischar always returned true)
 
-sio_flush.0:   call sio_getc.1                 # Get character
-sio_flush:     call sio_ischar                 # Check for character
-               jnz sio_flush.0                 # Till none
+sio_flush:     movb $1,%ch                     # let %cl be garbage
+1:             call sio_getc.1
+               call sio_ischar
+               loopnz 1b
                ret
 
 # void sio_putc(int c)
@@ -81,3 +92,8 @@ sio_ischar:   movw $SIO_PRT+0x5,%dx           # Line status register
                inb (%dx),%al                   # Received data ready?
                andb $0x1,%al
                ret
+
+               .globl inbser
+inbser:        movw $SIO_PRT+5,%dx
+               inb (%dx),%al
+               ret
index 0d178cc..191f97f 100644 (file)
@@ -14,7 +14,7 @@
 #
 
 # $FreeBSD: src/sys/boot/i386/boot2/sio.s,v 1.4 1999/08/28 00:40:02 peter Exp $
-# $DragonFly: src/sys/boot/i386/boot2/Attic/sio.s,v 1.4 2004/06/26 23:41:06 dillon Exp $
+# $DragonFly: src/sys/boot/i386/boot2/Attic/sio.s,v 1.5 2004/06/27 08:00:46 dillon Exp $
 
                .set SIO_PRT,SIOPRT             # Base port
                .set SIO_FMT,SIOFMT             # 8N1
                .globl sio_getc
                .globl sio_ischar
 
-# void sio_init(void)
+# int sio_init(void)
+# 
+# returns non-zero if we couldn't init, which can happen if the
+# serial port is unmapped and the inb's all return 0xFF (we fail
+# to flush the input).
 
 sio_init:      movw $SIO_PRT+0x3,%dx           # Data format reg
                movb $SIO_FMT|0x80,%al          # Set format and DLAB
@@ -36,20 +40,27 @@ sio_init:   movw $SIO_PRT+0x3,%dx           # Data format reg
                outw %ax,(%dx)                  # BASE+0 (divisor w/ DLAB set)
                movw $SIO_PRT+0x2,%dx
                movb $0x01,%al                  # Enable FIFO
-               outb %al,(%dx)                  # BASE+2
+               # DISABLED - apparently many new laptops only implement 
+               # 8250s, this might crash them? XXX
+               # outb %al,(%dx)                        # BASE+2
                incl %edx
                movb $SIO_FMT,%al               # Clear DLAB
                outb %al,(%dx)                  # BASE+3
                incl %edx
                movb $0x3,%al                   # RTS+DTR
                outb %al,(%dx)                  # BASE+4
-               incl %edx                       # Line status reg
+               incl %edx                       # BASE+5 Line status reg
 
-# void sio_flush(void)
+               # fall through to io_flush
+               #
+               # sio_flush: flush pending data in the serial port,
+               # return non-zero if we were unable to flush (aka
+               # ischar always returned true)
 
-sio_flush.0:   call sio_getc.1                 # Get character
-sio_flush:     call sio_ischar                 # Check for character
-               jnz sio_flush.0                 # Till none
+sio_flush:     movb $1,%ch                     # let %cl be garbage
+1:             call sio_getc.1
+               call sio_ischar
+               loopnz 1b
                ret
 
 # void sio_putc(int c)
@@ -81,3 +92,8 @@ sio_ischar:   movw $SIO_PRT+0x5,%dx           # Line status register
                inb (%dx),%al                   # Received data ready?
                andb $0x1,%al
                ret
+
+               .globl inbser
+inbser:        movw $SIO_PRT+5,%dx
+               inb (%dx),%al
+               ret
index ee3c19f..02fb5dc 100644 (file)
@@ -13,7 +13,7 @@
  * purpose.
  *
  * $FreeBSD: src/sys/boot/i386/boot2/boot2.c,v 1.64 2003/08/25 23:28:31 obrien Exp $
- * $DragonFly: src/sys/boot/pc32/boot2/boot2.c,v 1.9 2004/06/26 23:41:06 dillon Exp $
+ * $DragonFly: src/sys/boot/pc32/boot2/boot2.c,v 1.10 2004/06/27 08:00:46 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/disklabel.h>
@@ -50,6 +50,7 @@
 #define RBX_PROBEKBD   0x1e    /* -P */
 /* 0x1f is reserved for the historical RB_BOOTINFO option */
 
+#define RBF_MUTE       (1 << RBX_MUTE)
 #define RBF_SERIAL     (1 << RBX_SERIAL)
 #define RBF_VIDEO      (1 << RBX_VIDEO)
 
@@ -246,12 +247,16 @@ main(void)
     }
 
     /*
-     * Setup our (serial) console after processing the config file
+     * Setup our (serial) console after processing the config file.  If
+     * the initialization fails, don't try to use the serial port.  This
+     * can happen if the serial port is unmaped (happens on new laptops a lot).
      */
-    if ((opts & (RBF_SERIAL|RBF_VIDEO)) == 0)
+    if ((opts & (RBF_MUTE|RBF_SERIAL|RBF_VIDEO)) == 0)
        opts |= RBF_SERIAL|RBF_VIDEO;
-    if (opts & RBF_SERIAL)
-       sio_init();
+    if (opts & RBF_SERIAL) {
+       if (sio_init())
+           opts = RBF_VIDEO;
+    }
 
 
     /*
@@ -270,13 +275,10 @@ main(void)
     /* Present the user with the boot2 prompt. */
 
     for (;;) {
-       printf("\nDragonFly/i386 boot\n"
-              "Default: %u:%s(%u,%c)%s\n"
-              "boot: ",
+       printf("\nDragonFly boot\n"
+              "%u:%s(%u,%c)%s: ",
               dsk.drive & DRV_MASK, dev_nm[dsk.type], dsk.unit,
               'a' + dsk.part, kname);
-       if (opts & RBF_SERIAL)
-           sio_flush();
        if (!autoboot || keyhit(5*SECOND))
            getstr();
        else
index e4329e5..99d85b9 100644 (file)
 
 /*
  * $FreeBSD: src/sys/boot/i386/boot2/lib.h,v 1.2 1999/08/28 00:40:02 peter Exp $
- * $DragonFly: src/sys/boot/pc32/boot2/lib.h,v 1.3 2003/11/10 06:08:35 dillon Exp $
+ * $DragonFly: src/sys/boot/pc32/boot2/lib.h,v 1.4 2004/06/27 08:00:46 dillon Exp $
  */
 
-void sio_init(void);
+int sio_init(void);    /* returns non-zero if init failed */
 void sio_flush(void);
 void sio_putc(int);
 int sio_getc(void);
index 99e3736..9290898 100644 (file)
@@ -14,7 +14,7 @@
 #
 
 # $FreeBSD: src/sys/boot/i386/boot2/sio.s,v 1.4 1999/08/28 00:40:02 peter Exp $
-# $DragonFly: src/sys/boot/pc32/boot2/sio.S,v 1.4 2004/06/26 23:41:06 dillon Exp $
+# $DragonFly: src/sys/boot/pc32/boot2/sio.S,v 1.5 2004/06/27 08:00:46 dillon Exp $
 
                .set SIO_PRT,SIOPRT             # Base port
                .set SIO_FMT,SIOFMT             # 8N1
                .globl sio_getc
                .globl sio_ischar
 
-# void sio_init(void)
+# int sio_init(void)
+# 
+# returns non-zero if we couldn't init, which can happen if the
+# serial port is unmapped and the inb's all return 0xFF (we fail
+# to flush the input).
 
 sio_init:      movw $SIO_PRT+0x3,%dx           # Data format reg
                movb $SIO_FMT|0x80,%al          # Set format and DLAB
@@ -36,20 +40,27 @@ sio_init:   movw $SIO_PRT+0x3,%dx           # Data format reg
                outw %ax,(%dx)                  # BASE+0 (divisor w/ DLAB set)
                movw $SIO_PRT+0x2,%dx
                movb $0x01,%al                  # Enable FIFO
-               outb %al,(%dx)                  # BASE+2
+               # DISABLED - apparently many new laptops only implement 
+               # 8250s, this might crash them? XXX
+               # outb %al,(%dx)                        # BASE+2
                incl %edx
                movb $SIO_FMT,%al               # Clear DLAB
                outb %al,(%dx)                  # BASE+3
                incl %edx
                movb $0x3,%al                   # RTS+DTR
                outb %al,(%dx)                  # BASE+4
-               incl %edx                       # Line status reg
+               incl %edx                       # BASE+5 Line status reg
 
-# void sio_flush(void)
+               # fall through to io_flush
+               #
+               # sio_flush: flush pending data in the serial port,
+               # return non-zero if we were unable to flush (aka
+               # ischar always returned true)
 
-sio_flush.0:   call sio_getc.1                 # Get character
-sio_flush:     call sio_ischar                 # Check for character
-               jnz sio_flush.0                 # Till none
+sio_flush:     movb $1,%ch                     # let %cl be garbage
+1:             call sio_getc.1
+               call sio_ischar
+               loopnz 1b
                ret
 
 # void sio_putc(int c)
@@ -81,3 +92,8 @@ sio_ischar:   movw $SIO_PRT+0x5,%dx           # Line status register
                inb (%dx),%al                   # Received data ready?
                andb $0x1,%al
                ret
+
+               .globl inbser
+inbser:        movw $SIO_PRT+5,%dx
+               inb (%dx),%al
+               ret