summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpst <pst@FreeBSD.org>1997-06-04 04:52:40 +0000
committerpst <pst@FreeBSD.org>1997-06-04 04:52:40 +0000
commit21afca66c65ed0bb20c121b3620e5032a90181d9 (patch)
treeba61e76271148f01545f170829c0636d4b29fdbe
parent593f5fe73a975236cdb133762163da61f1c92b11 (diff)
downloadFreeBSD-src-21afca66c65ed0bb20c121b3620e5032a90181d9.zip
FreeBSD-src-21afca66c65ed0bb20c121b3620e5032a90181d9.tar.gz
If the boot blocks were using the serial port, read the system console
speed using the boot blocks, instead of a hardcoded value stuck in the kernel. This way, you can have systems using the same kernel but different console speeds. Add a sysctl entry for changing the system console speed. Lock the user tty speed to match the system console speed. Nuke CONSPEED. Reviewed by: bde
-rw-r--r--sys/dev/sio/sio.c123
-rw-r--r--sys/dev/sio/sioreg.h7
-rw-r--r--sys/i386/isa/sio.c123
-rw-r--r--sys/i386/isa/sioreg.h7
-rw-r--r--sys/isa/sio.c123
-rw-r--r--sys/isa/sioreg.h7
6 files changed, 357 insertions, 33 deletions
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index 570f24b..70a1b1d 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.168 1997/05/29 05:00:34 peter Exp $
+ * $Id: sio.c,v 1.169 1997/06/01 20:42:01 phk Exp $
*/
#include "opt_comconsole.h"
@@ -60,6 +60,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <sys/sysctl.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
@@ -345,7 +346,7 @@ static struct cdevsw sio_cdevsw = {
};
static int comconsole = -1;
-static volatile speed_t comdefaultrate = CONSPEED;
+static volatile speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */
static Port_t siocniobase;
static int sio_timeout;
@@ -385,6 +386,66 @@ static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
#endif
+/*
+ * handle sysctl read/write requests for console speed
+ *
+ * In addition to setting comdefaultrate for I/O through /dev/console,
+ * also set the initial and lock values for the /dev/ttyXX device
+ * if there is one associated with the console. Finally, if the /dev/tty
+ * device has already been open, change the speed on the open running port
+ * itself.
+ */
+
+static int
+sysctl_machdep_comdefaultrate SYSCTL_HANDLER_ARGS
+{
+ int error, s;
+ speed_t newspeed;
+ struct com_s *com;
+ struct tty *tp;
+
+ newspeed = comdefaultrate;
+
+ error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req);
+ if (error || !req->newptr)
+ return (error);
+
+ comdefaultrate = newspeed;
+
+ if (comconsole < 0) /* serial console not selected? */
+ return (0);
+
+ com = com_addr(comconsole);
+ if (!com)
+ return (ENXIO);
+
+ /*
+ * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
+ * (note, the lock rates really are boolean -- if non-zero, disallow
+ * speed changes)
+ */
+ com->it_in.c_ispeed = com->it_in.c_ospeed =
+ com->lt_in.c_ispeed = com->lt_in.c_ospeed =
+ com->it_out.c_ispeed = com->it_out.c_ospeed =
+ com->lt_out.c_ispeed = com->lt_out.c_ospeed = comdefaultrate;
+
+ /*
+ * if we're open, change the running rate too
+ */
+ tp = com->tp;
+ if (tp && (tp->t_state & TS_ISOPEN)) {
+ tp->t_termios.c_ispeed =
+ tp->t_termios.c_ospeed = comdefaultrate;
+ s = spltty();
+ error = comparam(tp, &tp->t_termios);
+ splx(s);
+ }
+ return error;
+}
+
+SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
+ 0, 0, sysctl_machdep_comdefaultrate, "I", "");
+
#if NCRD > 0
/*
* PC-Card (PCMCIA) specific code.
@@ -596,10 +657,10 @@ sioprobe(dev)
DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
else {
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
- outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
- outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
+ outb(iobase + com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
+ outb(iobase + com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
outb(iobase + com_cfcr, CFCR_8BITS);
- DELAY((16 + 1) * 1000000 / (9600 / 10));
+ DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
}
/*
@@ -635,7 +696,7 @@ sioprobe(dev)
* it's unlikely to do more than allow the null byte out.
*/
outb(iobase + com_data, 0);
- DELAY((1 + 2) * 1000000 / (9600 / 10));
+ DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
/*
* Turn off loopback mode so that the interrupt gate works again
@@ -834,6 +895,8 @@ sioattach(isdp)
com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
com->it_in.c_lflag = TTYDEF_LFLAG;
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
+ com->lt_out.c_ispeed = com->lt_out.c_ospeed =
+ com->lt_in.c_ispeed = com->lt_in.c_ospeed =
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
} else
com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
@@ -943,6 +1006,8 @@ determined_type: ;
COM_MPMASTER(isdp))->id_irq == 0;
}
#endif /* COM_MULTIPORT */
+ if (unit == comconsole)
+ printf(", console");
printf("\n");
s = spltty();
@@ -2395,6 +2460,7 @@ struct siocnstate {
u_char mcr;
};
+static speed_t siocngetspeed __P((Port_t, struct speedtab *));
static void siocnclose __P((struct siocnstate *sp));
static void siocnopen __P((struct siocnstate *sp));
static void siocntxwait __P((void));
@@ -2415,6 +2481,42 @@ siocntxwait()
;
}
+/*
+ * Read the serial port specified and try to figure out what speed
+ * it's currently running at. We're assuming the serial port has
+ * been initialized and is basicly idle. This routine is only intended
+ * to be run at system startup.
+ *
+ * If the value read from the serial port doesn't make sense, return 0.
+ */
+
+static speed_t
+siocngetspeed(iobase, table)
+ Port_t iobase;
+ struct speedtab *table;
+{
+ int code;
+ u_char dlbh;
+ u_char dlbl;
+ u_char cfcr;
+
+ cfcr = inb(iobase + com_cfcr);
+ outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
+
+ dlbl = inb(iobase + com_dlbl);
+ dlbh = inb(iobase + com_dlbh);
+
+ outb(iobase + com_cfcr, cfcr);
+
+ code = dlbh << 8 | dlbl;
+
+ for ( ; table->sp_speed != -1; table++)
+ if (table->sp_code == code)
+ return (table->sp_speed);
+
+ return 0; /* didn't match anything sane */
+}
+
static void
siocnopen(sp)
struct siocnstate *sp;
@@ -2489,8 +2591,9 @@ siocnprobe(cp)
struct consdev *cp;
{
struct isa_device *dvp;
- int s;
+ int s;
struct siocnstate sp;
+ speed_t boot_speed;
/*
* Find our first enabled console, if any. If it is a high-level
@@ -2512,6 +2615,12 @@ siocnprobe(cp)
&& COM_CONSOLE(dvp)) {
siocniobase = dvp->id_iobase;
s = spltty();
+ if (boothowto & RB_SERIAL) {
+ boot_speed = siocngetspeed(siocniobase,
+ comspeedtab);
+ if (boot_speed)
+ comdefaultrate = boot_speed;
+ }
siocnopen(&sp);
splx(s);
if (!COM_LLCONSOLE(dvp)) {
diff --git a/sys/dev/sio/sioreg.h b/sys/dev/sio/sioreg.h
index dbb6999..97a737a 100644
--- a/sys/dev/sio/sioreg.h
+++ b/sys/dev/sio/sioreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)comreg.h 7.2 (Berkeley) 5/9/91
- * $Id: sioreg.h,v 1.7 1997/02/22 09:37:10 peter Exp $
+ * $Id: sioreg.h,v 1.8 1997/04/05 13:15:50 bde Exp $
*/
@@ -106,6 +106,5 @@
#define MSR_DDSR 0x02
#define MSR_DCTS 0x01
-#ifndef CONSPEED
-#define CONSPEED (9600)
-#endif
+/* speed to initialize to during chip tests */
+#define SIO_TEST_SPEED 9600
diff --git a/sys/i386/isa/sio.c b/sys/i386/isa/sio.c
index 570f24b..70a1b1d 100644
--- a/sys/i386/isa/sio.c
+++ b/sys/i386/isa/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.168 1997/05/29 05:00:34 peter Exp $
+ * $Id: sio.c,v 1.169 1997/06/01 20:42:01 phk Exp $
*/
#include "opt_comconsole.h"
@@ -60,6 +60,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <sys/sysctl.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
@@ -345,7 +346,7 @@ static struct cdevsw sio_cdevsw = {
};
static int comconsole = -1;
-static volatile speed_t comdefaultrate = CONSPEED;
+static volatile speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */
static Port_t siocniobase;
static int sio_timeout;
@@ -385,6 +386,66 @@ static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
#endif
+/*
+ * handle sysctl read/write requests for console speed
+ *
+ * In addition to setting comdefaultrate for I/O through /dev/console,
+ * also set the initial and lock values for the /dev/ttyXX device
+ * if there is one associated with the console. Finally, if the /dev/tty
+ * device has already been open, change the speed on the open running port
+ * itself.
+ */
+
+static int
+sysctl_machdep_comdefaultrate SYSCTL_HANDLER_ARGS
+{
+ int error, s;
+ speed_t newspeed;
+ struct com_s *com;
+ struct tty *tp;
+
+ newspeed = comdefaultrate;
+
+ error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req);
+ if (error || !req->newptr)
+ return (error);
+
+ comdefaultrate = newspeed;
+
+ if (comconsole < 0) /* serial console not selected? */
+ return (0);
+
+ com = com_addr(comconsole);
+ if (!com)
+ return (ENXIO);
+
+ /*
+ * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
+ * (note, the lock rates really are boolean -- if non-zero, disallow
+ * speed changes)
+ */
+ com->it_in.c_ispeed = com->it_in.c_ospeed =
+ com->lt_in.c_ispeed = com->lt_in.c_ospeed =
+ com->it_out.c_ispeed = com->it_out.c_ospeed =
+ com->lt_out.c_ispeed = com->lt_out.c_ospeed = comdefaultrate;
+
+ /*
+ * if we're open, change the running rate too
+ */
+ tp = com->tp;
+ if (tp && (tp->t_state & TS_ISOPEN)) {
+ tp->t_termios.c_ispeed =
+ tp->t_termios.c_ospeed = comdefaultrate;
+ s = spltty();
+ error = comparam(tp, &tp->t_termios);
+ splx(s);
+ }
+ return error;
+}
+
+SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
+ 0, 0, sysctl_machdep_comdefaultrate, "I", "");
+
#if NCRD > 0
/*
* PC-Card (PCMCIA) specific code.
@@ -596,10 +657,10 @@ sioprobe(dev)
DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
else {
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
- outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
- outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
+ outb(iobase + com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
+ outb(iobase + com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
outb(iobase + com_cfcr, CFCR_8BITS);
- DELAY((16 + 1) * 1000000 / (9600 / 10));
+ DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
}
/*
@@ -635,7 +696,7 @@ sioprobe(dev)
* it's unlikely to do more than allow the null byte out.
*/
outb(iobase + com_data, 0);
- DELAY((1 + 2) * 1000000 / (9600 / 10));
+ DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
/*
* Turn off loopback mode so that the interrupt gate works again
@@ -834,6 +895,8 @@ sioattach(isdp)
com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
com->it_in.c_lflag = TTYDEF_LFLAG;
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
+ com->lt_out.c_ispeed = com->lt_out.c_ospeed =
+ com->lt_in.c_ispeed = com->lt_in.c_ospeed =
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
} else
com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
@@ -943,6 +1006,8 @@ determined_type: ;
COM_MPMASTER(isdp))->id_irq == 0;
}
#endif /* COM_MULTIPORT */
+ if (unit == comconsole)
+ printf(", console");
printf("\n");
s = spltty();
@@ -2395,6 +2460,7 @@ struct siocnstate {
u_char mcr;
};
+static speed_t siocngetspeed __P((Port_t, struct speedtab *));
static void siocnclose __P((struct siocnstate *sp));
static void siocnopen __P((struct siocnstate *sp));
static void siocntxwait __P((void));
@@ -2415,6 +2481,42 @@ siocntxwait()
;
}
+/*
+ * Read the serial port specified and try to figure out what speed
+ * it's currently running at. We're assuming the serial port has
+ * been initialized and is basicly idle. This routine is only intended
+ * to be run at system startup.
+ *
+ * If the value read from the serial port doesn't make sense, return 0.
+ */
+
+static speed_t
+siocngetspeed(iobase, table)
+ Port_t iobase;
+ struct speedtab *table;
+{
+ int code;
+ u_char dlbh;
+ u_char dlbl;
+ u_char cfcr;
+
+ cfcr = inb(iobase + com_cfcr);
+ outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
+
+ dlbl = inb(iobase + com_dlbl);
+ dlbh = inb(iobase + com_dlbh);
+
+ outb(iobase + com_cfcr, cfcr);
+
+ code = dlbh << 8 | dlbl;
+
+ for ( ; table->sp_speed != -1; table++)
+ if (table->sp_code == code)
+ return (table->sp_speed);
+
+ return 0; /* didn't match anything sane */
+}
+
static void
siocnopen(sp)
struct siocnstate *sp;
@@ -2489,8 +2591,9 @@ siocnprobe(cp)
struct consdev *cp;
{
struct isa_device *dvp;
- int s;
+ int s;
struct siocnstate sp;
+ speed_t boot_speed;
/*
* Find our first enabled console, if any. If it is a high-level
@@ -2512,6 +2615,12 @@ siocnprobe(cp)
&& COM_CONSOLE(dvp)) {
siocniobase = dvp->id_iobase;
s = spltty();
+ if (boothowto & RB_SERIAL) {
+ boot_speed = siocngetspeed(siocniobase,
+ comspeedtab);
+ if (boot_speed)
+ comdefaultrate = boot_speed;
+ }
siocnopen(&sp);
splx(s);
if (!COM_LLCONSOLE(dvp)) {
diff --git a/sys/i386/isa/sioreg.h b/sys/i386/isa/sioreg.h
index dbb6999..97a737a 100644
--- a/sys/i386/isa/sioreg.h
+++ b/sys/i386/isa/sioreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)comreg.h 7.2 (Berkeley) 5/9/91
- * $Id: sioreg.h,v 1.7 1997/02/22 09:37:10 peter Exp $
+ * $Id: sioreg.h,v 1.8 1997/04/05 13:15:50 bde Exp $
*/
@@ -106,6 +106,5 @@
#define MSR_DDSR 0x02
#define MSR_DCTS 0x01
-#ifndef CONSPEED
-#define CONSPEED (9600)
-#endif
+/* speed to initialize to during chip tests */
+#define SIO_TEST_SPEED 9600
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index 570f24b..70a1b1d 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.168 1997/05/29 05:00:34 peter Exp $
+ * $Id: sio.c,v 1.169 1997/06/01 20:42:01 phk Exp $
*/
#include "opt_comconsole.h"
@@ -60,6 +60,7 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <sys/sysctl.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
@@ -345,7 +346,7 @@ static struct cdevsw sio_cdevsw = {
};
static int comconsole = -1;
-static volatile speed_t comdefaultrate = CONSPEED;
+static volatile speed_t comdefaultrate = TTYDEF_SPEED;
static u_int com_events; /* input chars + weighted output completions */
static Port_t siocniobase;
static int sio_timeout;
@@ -385,6 +386,66 @@ static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
#endif
+/*
+ * handle sysctl read/write requests for console speed
+ *
+ * In addition to setting comdefaultrate for I/O through /dev/console,
+ * also set the initial and lock values for the /dev/ttyXX device
+ * if there is one associated with the console. Finally, if the /dev/tty
+ * device has already been open, change the speed on the open running port
+ * itself.
+ */
+
+static int
+sysctl_machdep_comdefaultrate SYSCTL_HANDLER_ARGS
+{
+ int error, s;
+ speed_t newspeed;
+ struct com_s *com;
+ struct tty *tp;
+
+ newspeed = comdefaultrate;
+
+ error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req);
+ if (error || !req->newptr)
+ return (error);
+
+ comdefaultrate = newspeed;
+
+ if (comconsole < 0) /* serial console not selected? */
+ return (0);
+
+ com = com_addr(comconsole);
+ if (!com)
+ return (ENXIO);
+
+ /*
+ * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX
+ * (note, the lock rates really are boolean -- if non-zero, disallow
+ * speed changes)
+ */
+ com->it_in.c_ispeed = com->it_in.c_ospeed =
+ com->lt_in.c_ispeed = com->lt_in.c_ospeed =
+ com->it_out.c_ispeed = com->it_out.c_ospeed =
+ com->lt_out.c_ispeed = com->lt_out.c_ospeed = comdefaultrate;
+
+ /*
+ * if we're open, change the running rate too
+ */
+ tp = com->tp;
+ if (tp && (tp->t_state & TS_ISOPEN)) {
+ tp->t_termios.c_ispeed =
+ tp->t_termios.c_ospeed = comdefaultrate;
+ s = spltty();
+ error = comparam(tp, &tp->t_termios);
+ splx(s);
+ }
+ return error;
+}
+
+SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW,
+ 0, 0, sysctl_machdep_comdefaultrate, "I", "");
+
#if NCRD > 0
/*
* PC-Card (PCMCIA) specific code.
@@ -596,10 +657,10 @@ sioprobe(dev)
DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
else {
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
- outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
- outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
+ outb(iobase + com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
+ outb(iobase + com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
outb(iobase + com_cfcr, CFCR_8BITS);
- DELAY((16 + 1) * 1000000 / (9600 / 10));
+ DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
}
/*
@@ -635,7 +696,7 @@ sioprobe(dev)
* it's unlikely to do more than allow the null byte out.
*/
outb(iobase + com_data, 0);
- DELAY((1 + 2) * 1000000 / (9600 / 10));
+ DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
/*
* Turn off loopback mode so that the interrupt gate works again
@@ -834,6 +895,8 @@ sioattach(isdp)
com->it_in.c_cflag = TTYDEF_CFLAG | CLOCAL;
com->it_in.c_lflag = TTYDEF_LFLAG;
com->lt_out.c_cflag = com->lt_in.c_cflag = CLOCAL;
+ com->lt_out.c_ispeed = com->lt_out.c_ospeed =
+ com->lt_in.c_ispeed = com->lt_in.c_ospeed =
com->it_in.c_ispeed = com->it_in.c_ospeed = comdefaultrate;
} else
com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED;
@@ -943,6 +1006,8 @@ determined_type: ;
COM_MPMASTER(isdp))->id_irq == 0;
}
#endif /* COM_MULTIPORT */
+ if (unit == comconsole)
+ printf(", console");
printf("\n");
s = spltty();
@@ -2395,6 +2460,7 @@ struct siocnstate {
u_char mcr;
};
+static speed_t siocngetspeed __P((Port_t, struct speedtab *));
static void siocnclose __P((struct siocnstate *sp));
static void siocnopen __P((struct siocnstate *sp));
static void siocntxwait __P((void));
@@ -2415,6 +2481,42 @@ siocntxwait()
;
}
+/*
+ * Read the serial port specified and try to figure out what speed
+ * it's currently running at. We're assuming the serial port has
+ * been initialized and is basicly idle. This routine is only intended
+ * to be run at system startup.
+ *
+ * If the value read from the serial port doesn't make sense, return 0.
+ */
+
+static speed_t
+siocngetspeed(iobase, table)
+ Port_t iobase;
+ struct speedtab *table;
+{
+ int code;
+ u_char dlbh;
+ u_char dlbl;
+ u_char cfcr;
+
+ cfcr = inb(iobase + com_cfcr);
+ outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
+
+ dlbl = inb(iobase + com_dlbl);
+ dlbh = inb(iobase + com_dlbh);
+
+ outb(iobase + com_cfcr, cfcr);
+
+ code = dlbh << 8 | dlbl;
+
+ for ( ; table->sp_speed != -1; table++)
+ if (table->sp_code == code)
+ return (table->sp_speed);
+
+ return 0; /* didn't match anything sane */
+}
+
static void
siocnopen(sp)
struct siocnstate *sp;
@@ -2489,8 +2591,9 @@ siocnprobe(cp)
struct consdev *cp;
{
struct isa_device *dvp;
- int s;
+ int s;
struct siocnstate sp;
+ speed_t boot_speed;
/*
* Find our first enabled console, if any. If it is a high-level
@@ -2512,6 +2615,12 @@ siocnprobe(cp)
&& COM_CONSOLE(dvp)) {
siocniobase = dvp->id_iobase;
s = spltty();
+ if (boothowto & RB_SERIAL) {
+ boot_speed = siocngetspeed(siocniobase,
+ comspeedtab);
+ if (boot_speed)
+ comdefaultrate = boot_speed;
+ }
siocnopen(&sp);
splx(s);
if (!COM_LLCONSOLE(dvp)) {
diff --git a/sys/isa/sioreg.h b/sys/isa/sioreg.h
index dbb6999..97a737a 100644
--- a/sys/isa/sioreg.h
+++ b/sys/isa/sioreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)comreg.h 7.2 (Berkeley) 5/9/91
- * $Id: sioreg.h,v 1.7 1997/02/22 09:37:10 peter Exp $
+ * $Id: sioreg.h,v 1.8 1997/04/05 13:15:50 bde Exp $
*/
@@ -106,6 +106,5 @@
#define MSR_DDSR 0x02
#define MSR_DCTS 0x01
-#ifndef CONSPEED
-#define CONSPEED (9600)
-#endif
+/* speed to initialize to during chip tests */
+#define SIO_TEST_SPEED 9600
OpenPOWER on IntegriCloud