[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