From f9cf0cd843f83ec4214ad5d5ec2e75d5a6cd89dd Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Sun, 7 Feb 2010 20:06:27 -0800 Subject: [PATCH] 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 --- com32/sysdump/be_ymodem.c | 4 ++-- com32/sysdump/serial.c | 55 +++++++++++++++++++++++++++++++++++++---------- 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 9d6c901..316b3d4 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 03f6403..e12d7bd 100644 --- a/com32/sysdump/serial.c +++ b/com32/sysdump/serial.c @@ -1,8 +1,10 @@ #include #include #include +#include #include #include +#include #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 be95f6c..356f2ce 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; -- 2.7.4