summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorambrisko <ambrisko@FreeBSD.org>2004-04-30 21:16:52 +0000
committerambrisko <ambrisko@FreeBSD.org>2004-04-30 21:16:52 +0000
commitc14039802334822a4159818e193f9e41eb2cca8e (patch)
tree644cd61e3cf523d53f642ccb76abc585b0edd1a8
parenta7f0f62fc064d21a3552570d4df9d35133baad13 (diff)
downloadFreeBSD-src-c14039802334822a4159818e193f9e41eb2cca8e.zip
FreeBSD-src-c14039802334822a4159818e193f9e41eb2cca8e.tar.gz
Some enhancements and bug fix.
- Define option FORCECONSPEED to force the serial console to be CONSPEED. I've run into a lot of boards in which the detect for prior speed doesn't work and ends up with broken console since it is at the wrong speed. - If a serial port is marked as a console, but console=vidconsole and if the serial ports doesn't exist it will be probed and attached at a 8250 chip. Then writes to that will freeze the system. - Add an option flags 0x400000 to mark this as a potential comconsole in-case the one flaged with 0x10 does not exist in the system. This makes it easier to deploy on systems with one or two serial ports. Obtained from: IronPort
-rw-r--r--share/man/man4/sio.42
-rw-r--r--sys/conf/NOTES2
-rw-r--r--sys/conf/options1
-rw-r--r--sys/dev/sio/sio.c125
4 files changed, 81 insertions, 49 deletions
diff --git a/share/man/man4/sio.4 b/share/man/man4/sio.4
index 864714c..7905401 100644
--- a/share/man/man4/sio.4
+++ b/share/man/man4/sio.4
@@ -178,6 +178,8 @@ minor number of master port
PPS timestamping on CTS instead of DCD
.It 0x20000
device is assumed to use a 16650A-type (extended FIFO) chip
+.It 0x400000
+If no comconsole found then mark as a comconsole
.El
.Pp
Minor numbering:
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 1d99f5d..0965f8b 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1466,6 +1466,8 @@ options COM_ESP # Code for Hayes ESP.
options COM_MULTIPORT # Code for some cards with shared IRQs.
options CONSPEED=115200 # Speed for serial console
# (default 9600).
+options FORCECONSPEED # no matter what use CONSPEED for
+ # console.
# `flags' specific to sio(4). See below for flags used by both sio(4) and
# uart(4).
diff --git a/sys/conf/options b/sys/conf/options
index 2191fe7..bb2841a 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -519,6 +519,7 @@ BKTR_NEW_MSP34XX_DRIVER opt_bktr.h
# options for serial support
COM_ESP opt_sio.h
COM_MULTIPORT opt_sio.h
+FORCECONSPEED opt_sio.h
BREAK_TO_DEBUGGER opt_comconsole.h
ALT_BREAK_TO_DEBUGGER opt_comconsole.h
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index 192973d..0cd3557 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -123,6 +123,7 @@ __FBSDID("$FreeBSD$");
#define COM_PPSCTS(flags) ((flags) & 0x10000)
#define COM_ST16650A(flags) ((flags) & 0x20000)
#define COM_TI16754(flags) ((flags) & 0x200000)
+#define COM_ALTCONSOLE(flags) ((flags) & 0x400000)
#define sio_getreg(com, off) \
(bus_space_read_1((com)->bst, (com)->bsh, (off)))
@@ -749,7 +750,7 @@ sioprobe(dev, xrid, rclk, noprobe)
sio_setreg(com, com_cfcr, CFCR_8BITS);
mtx_unlock_spin(&sio_lock);
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- if (iobase == siocniobase)
+ if (comconsole != -1 && iobase == siocniobase)
result = 0;
if (result != 0) {
device_set_softc(dev, NULL);
@@ -795,6 +796,7 @@ sioprobe(dev, xrid, rclk, noprobe)
mtx_unlock_spin(&sio_lock);
+ result = 0;
irqs = irqmap[1] & ~irqmap[0];
if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 &&
((1 << xirq) & irqs) == 0) {
@@ -804,14 +806,14 @@ sioprobe(dev, xrid, rclk, noprobe)
printf(
"sio%d: port may not be enabled\n",
device_get_unit(dev));
+ result = ENXIO;
}
if (bootverbose)
printf("sio%d: irq maps: %#x %#x %#x %#x\n",
device_get_unit(dev),
irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
- result = 0;
- for (fn = 0; fn < sizeof failures; ++fn)
+ for (fn = 0; result == 0 && fn < sizeof failures; ++fn)
if (failures[fn]) {
sio_setreg(com, com_mcr, 0);
result = ENXIO;
@@ -826,7 +828,7 @@ sioprobe(dev, xrid, rclk, noprobe)
break;
}
bus_release_resource(dev, SYS_RES_IOPORT, rid, port);
- if (iobase == siocniobase)
+ if (comconsole != -1 && iobase == siocniobase)
result = 0;
if (result != 0) {
device_set_softc(dev, NULL);
@@ -2814,6 +2816,9 @@ siocngetspeed(iobase, rclk)
u_char cfcr;
cfcr = inb(iobase + com_cfcr);
+ outb(iobase + com_cfcr, 0x0e);
+ if (inb(iobase + com_cfcr) != 0x0e)
+ return (0);
outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
dlbl = inb(iobase + com_dlbl);
@@ -2826,7 +2831,12 @@ siocngetspeed(iobase, rclk)
/* XXX there should be more sanity checking. */
if (divisor == 0)
return (CONSPEED);
+
+#ifdef FORCECONSPEED
+ return (CONSPEED);
+#else
return (rclk / (16UL * divisor));
+#endif
}
#endif
@@ -2907,7 +2917,7 @@ siocnprobe(cp)
speed_t boot_speed;
u_char cfcr;
u_int divisor;
- int s, unit;
+ int s, unit, check_flags;
struct siocnstate sp;
/*
@@ -2926,28 +2936,42 @@ siocnprobe(cp)
*/
cp->cn_pri = CN_DEAD;
- for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */
- int flags;
+ siocniobase = 0;
+ for(check_flags = 1; check_flags >= 0 && !siocniobase; check_flags--) {
+ for (unit = 0; unit < 16; unit++) { /* XXX need to know how
+ many */
+ int flags;
- if (resource_disabled("sio", unit))
- continue;
- if (resource_int_value("sio", unit, "flags", &flags))
- continue;
- if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) {
- int port;
- Port_t iobase;
-
- if (resource_int_value("sio", unit, "port", &port))
+ if (resource_disabled("sio", unit))
+ continue;
+ if (resource_int_value("sio", unit, "flags", &flags))
continue;
- iobase = port;
- s = spltty();
- if (boothowto & RB_SERIAL) {
- boot_speed =
- siocngetspeed(iobase, comdefaultrclk);
- if (boot_speed)
- comdefaultrate = boot_speed;
+
+ if (!check_flags && COM_ALTCONSOLE(flags)
+ && !siocniobase){
+ flags |= 0x10;
}
+ if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) {
+ int port;
+ Port_t iobase;
+
+ if (resource_int_value("sio", unit, "port",
+ &port))
+ continue;
+ iobase = port;
+ s = spltty();
+ if (boothowto & RB_SERIAL) {
+ boot_speed = siocngetspeed(iobase,
+ comdefaultrclk);
+ if (boot_speed)
+ comdefaultrate = boot_speed;
+ else {
+ splx(s);
+ continue;
+ }
+ }
+
/*
* Initialize the divisor latch. We can't rely on
* siocnopen() to do this the first time, since it
@@ -2957,34 +2981,37 @@ siocnprobe(cp)
* need to set the speed in hardware so that
* switching it later is null.
*/
- cfcr = inb(iobase + com_cfcr);
- outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
- divisor = siodivisor(comdefaultrclk, comdefaultrate);
- outb(iobase + com_dlbl, divisor & 0xff);
- outb(iobase + com_dlbh, divisor >> 8);
- outb(iobase + com_cfcr, cfcr);
-
- siocnopen(&sp, iobase, comdefaultrate);
-
- splx(s);
- if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) {
- siocnset(cp, unit);
- cp->cn_pri = COM_FORCECONSOLE(flags)
- || boothowto & RB_SERIAL
- ? CN_REMOTE : CN_NORMAL;
- siocniobase = iobase;
- siocnunit = unit;
- }
- if (COM_DEBUGGER(flags)) {
- printf("sio%d: gdb debugging port\n", unit);
- siogdbiobase = iobase;
- siogdbunit = unit;
+ cfcr = inb(iobase + com_cfcr);
+ outb(iobase + com_cfcr, CFCR_DLAB | cfcr);
+ divisor = siodivisor(comdefaultrclk, comdefaultrate);
+ outb(iobase + com_dlbl, divisor & 0xff);
+ outb(iobase + com_dlbh, divisor >> 8);
+ outb(iobase + com_cfcr, cfcr);
+
+ siocnopen(&sp, iobase, comdefaultrate);
+
+ splx(s);
+ if (!siocniobase && COM_CONSOLE(flags)
+ && !COM_LLCONSOLE(flags)) {
+ siocnset(cp, unit);
+ cp->cn_pri = COM_FORCECONSOLE(flags)
+ || boothowto & RB_SERIAL
+ ? CN_REMOTE : CN_NORMAL;
+ siocniobase = iobase;
+ siocnunit = unit;
+ }
+ if (COM_DEBUGGER(flags)) {
+ printf("sio%d: gdb debugging port\n",
+ unit);
+ siogdbiobase = iobase;
+ siogdbunit = unit;
#if DDB > 0
- siocnset(&gdbconsdev, unit);
- gdb_arg = &gdbconsdev;
- gdb_getc = siocngetc;
- gdb_putc = siocnputc;
+ siocnset(&gdbconsdev, unit);
+ gdb_arg = &gdbconsdev;
+ gdb_getc = siocngetc;
+ gdb_putc = siocnputc;
#endif
+ }
}
}
}
OpenPOWER on IntegriCloud