mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-04 10:19:26 +00:00
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
This commit is contained in:
parent
a1788fb41e
commit
33c5911242
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=128781
@ -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:
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
iobase = port;
|
||||
s = spltty();
|
||||
if (boothowto & RB_SERIAL) {
|
||||
boot_speed =
|
||||
siocngetspeed(iobase, comdefaultrclk);
|
||||
if (boot_speed)
|
||||
comdefaultrate = boot_speed;
|
||||
if (resource_int_value("sio", unit, "flags", &flags))
|
||||
continue;
|
||||
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user