summaryrefslogtreecommitdiff
path: root/com32/sysdump
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-07 20:06:27 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-07 20:06:27 -0800
commitf9cf0cd843f83ec4214ad5d5ec2e75d5a6cd89dd (patch)
treef2afa112c21ebbb802708c834643409263c1b9db /com32/sysdump
parent17ab9b273139a1e81ced7ce1ea4f5a7fb063df00 (diff)
downloadsyslinux-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.c4
-rw-r--r--com32/sysdump/serial.c55
-rw-r--r--com32/sysdump/serial.h1
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;