diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-07 20:06:27 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-07 20:06:27 -0800 |
commit | f9cf0cd843f83ec4214ad5d5ec2e75d5a6cd89dd (patch) | |
tree | f2afa112c21ebbb802708c834643409263c1b9db /com32/sysdump | |
parent | 17ab9b273139a1e81ced7ce1ea4f5a7fb063df00 (diff) | |
download | syslinux-f9cf0cd843f83ec4214ad5d5ec2e75d5a6cd89dd.tar.gz |
sysdump: make ymodem work even on a serial console
Make it possible to do a ymodem transfer even on the port used for a
serial console. Furthermore, on a serial console, get the parameters
from the serial console information, so port number and speed don't
have to be specified.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'com32/sysdump')
-rw-r--r-- | com32/sysdump/be_ymodem.c | 4 | ||||
-rw-r--r-- | com32/sysdump/serial.c | 55 | ||||
-rw-r--r-- | com32/sysdump/serial.h | 1 |
3 files changed, 47 insertions, 13 deletions
diff --git a/com32/sysdump/be_ymodem.c b/com32/sysdump/be_ymodem.c index 9d6c9011..316b3d4e 100644 --- a/com32/sysdump/be_ymodem.c +++ b/com32/sysdump/be_ymodem.c @@ -169,7 +169,7 @@ static int be_ymodem_write(struct backend *be) struct backend be_ymodem = { .name = "ymodem", - .helpmsg = "filename port [speed]", - .minargs = 2, + .helpmsg = "filename [port [speed]]", + .minargs = 1, .write = be_ymodem_write, }; diff --git a/com32/sysdump/serial.c b/com32/sysdump/serial.c index 03f6403a..e12d7bd5 100644 --- a/com32/sysdump/serial.c +++ b/com32/sysdump/serial.c @@ -1,8 +1,10 @@ #include <stdbool.h> #include <stdlib.h> #include <stdio.h> +#include <console.h> #include <sys/io.h> #include <sys/cpu.h> +#include <syslinux/config.h> #include "serial.h" @@ -24,25 +26,51 @@ enum { int serial_init(struct serial_if *sif, const char *argv[]) { + const struct syslinux_serial_console_info *sci + = syslinux_serial_console_info(); uint16_t port; - unsigned int speed, divisor; + unsigned int divisor; uint8_t dll, dlm, lcr; - port = strtoul(argv[0], NULL, 0); - if (port <= 3) { - uint16_t addr = ((uint16_t *)0x400)[port]; - printf("Serial port %u is at 0x%04x\n", port, addr); - port = addr; + if (!argv[0]) { + if (sci->iobase) { + port = sci->iobase; + } else { + printf("No port number specified and not using serial console!\n"); + return -1; + } + } else { + port = strtoul(argv[0], NULL, 0); + if (port <= 3) { + uint16_t addr = ((uint16_t *)0x400)[port]; + if (!addr) { + printf("No serial port address found!\n"); + return -1; + } + printf("Serial port %u is at 0x%04x\n", port, addr); + port = addr; + } } sif->port = port; + sif->console = false; - if (argv[1]) - speed = strtoul(argv[1], NULL, 0); - else - speed = 115200; + divisor = 1; /* Default speed = 115200 bps */ - divisor = 115200/speed; + /* Check to see if this is the same as the serial console */ + if (port == sci->iobase) { + /* Overlaying the console... */ + sif->console = true; + + /* Default to already configured speed */ + divisor = sci->divisor; + + /* Shut down I/O to the console for the time being */ + openconsole(&dev_null_r, &dev_null_w); + } + + if (argv[0] && argv[1]) + divisor = 115200/strtoul(argv[1], NULL, 0); cli(); /* Just in case... */ @@ -74,6 +102,7 @@ int serial_init(struct serial_if *sif, const char *argv[]) if (dll != (uint8_t)divisor || dlm != (uint8_t)(divisor >> 8) || lcr != 0x83) { + serial_cleanup(sif); printf("No serial port detected!\n"); return -1; /* This doesn't look like a serial port */ } @@ -133,4 +162,8 @@ void serial_cleanup(struct serial_if *sif) outb(sif->old.ier, port + IER); if (sif->old.iir < 0xc0) outb(0x00, port + FCR); /* Disable FIFOs */ + + /* Re-enable console messages, if we shut them down */ + if (sif->console) + openconsole(&dev_null_r, &dev_stdcon_w); } diff --git a/com32/sysdump/serial.h b/com32/sysdump/serial.h index be95f6c4..356f2cef 100644 --- a/com32/sysdump/serial.h +++ b/com32/sysdump/serial.h @@ -5,6 +5,7 @@ struct serial_if { uint16_t port; + bool console; struct { uint8_t dll, dlm, ier, iir, lcr, mcr; } old; |