[syslinux:master] sysdump: make ymodem work even on a serial console
syslinux-bot for H. Peter Anvin
hpa at zytor.com
Sun Feb 7 20:12:07 PST 2010
Commit-ID: f9cf0cd843f83ec4214ad5d5ec2e75d5a6cd89dd
Gitweb: http://syslinux.zytor.com/commit/f9cf0cd843f83ec4214ad5d5ec2e75d5a6cd89dd
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Sun, 7 Feb 2010 20:06:27 -0800
Committer: H. Peter Anvin <hpa at zytor.com>
CommitDate: Sun, 7 Feb 2010 20:06:27 -0800
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 at zytor.com>
---
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 <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 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;
More information about the Syslinux-commits
mailing list