Skip to contentSkip to conversation

USB Serial console support for 2.5.7

PATCH New Greg KH 1 participant 1 message Mar 27, 2002

Subsystems (2)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 USB Serial console support for 2.5.7

Hi all,

Here's a patch against my most recent 2.5.7 tree (see
http://marc.theaimsgroup.com/?l=linux-usb-devel&m=101675847419296 for the only patch you need against a clean 2.5.7 kernel) that adds USB serial console support.

It works just like the normal serial console support, but you need to specify a ttyUSB port instead of a ttyS port on the kernel command line. For example, add this to the kernel command line to use the ttyUSB0 port at 57600 baud as a console:

	console=ttyUSB0,57600

I've tested this driver out with a pl2303 device, but would not really recommend this device. It drops data sent to the console, as the console subsystem doesn't care about the return value of write(). It helps to set the baud rate very high :) This is a fault of the driver, not the device. I'll be working on fixing this in the future.

I've also made some changes to the belkin and visor serial drivers so they should work well. Most of the other usb-serial drivers might need some minor changes to work properly (there is no tty device assigned to a serial console, and the usb-serial drivers used to assume that a tty device is present at all times.)

The visor or other Palm device looks like it would make a very nice console, if you can run a terminal program on your device (no ppp is needed.) I think only the HandSpring devices will work this way.

One downside is that the USB subsystem and device probing happen pretty late in the boot process, so if you are trying to debug an oops very early on, I would not recommend using this as a debugging aid.

Thanks to Randy Dunlap for the initial version of this patch, and for the push to fix it up to work with all usb-serial devices.

Let me know if anyone has any problems with this patch.

thanks,

greg k-h

drivers/usb/serial/Config.help +20 -0
diff -Nru a/drivers/usb/serial/Config.help b/drivers/usb/serial/Config.help
@@ -12,6 +12,26 @@
   The module will be called usbserial.o. If you want to compile it
   as a module, say M here and read <file:Documentation/modules.txt>.
 
+CONFIG_USB_SERIAL_CONSOLE
+  If you say Y here, it will be possible to use a USB to serial
+  converter port as the system console (the system console is the
+  device which receives all kernel messages and warnings and which
+  allows logins in single user mode). This could be useful if some
+  terminal or printer is connected to that serial port.
+
+  Even if you say Y here, the currently visible virtual console
+  (/dev/tty0) will still be used as the system console by default, but
+  you can alter that using a kernel command line option such as
+  "console=ttyUSB0". (Try "man bootparam" or see the documentation of
+  your boot loader (lilo or loadlin) about how to pass options to the
+  kernel at boot time.)
+
+  If you don't have a VGA card installed and you say Y here, the
+  kernel will automatically use the first USB to serial converter
+  port, /dev/ttyUSB0, as system console.
+
+  If unsure, say N.
+
 CONFIG_USB_SERIAL_GENERIC
   Say Y here if you want to use the generic USB serial driver.  Please
   read <file:Documentation/usb/usb-serial.txt> for more information on
drivers/usb/serial/Config.in +1 -0
diff -Nru a/drivers/usb/serial/Config.in b/drivers/usb/serial/Config.in
@@ -8,6 +8,7 @@
 if [ "$CONFIG_USB_SERIAL" = "y" ]; then
   dep_mbool '  USB Serial Converter verbose debug' CONFIG_USB_SERIAL_DEBUG $CONFIG_USB_SERIAL
 fi
+dep_mbool '  USB Serial Console device support (EXPERIMENTAL)' CONFIG_USB_SERIAL_CONSOLE $CONFIG_USB_SERIAL
 dep_mbool '  USB Generic Serial Driver' CONFIG_USB_SERIAL_GENERIC $CONFIG_USB_SERIAL
 dep_tristate '  USB Belkin and Peracom Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_BELKIN $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
 dep_tristate '  USB ConnectTech WhiteHEAT Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_WHITEHEAT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
drivers/usb/serial/belkin_sa.c +23 -4
diff -Nru a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
@@ -324,12 +324,31 @@
 {
 	struct usb_serial *serial = port->serial;
 	struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private;
-	unsigned int iflag = port->tty->termios->c_iflag;
-	unsigned int cflag = port->tty->termios->c_cflag;
-	unsigned int old_iflag = old_termios->c_iflag;
-	unsigned int old_cflag = old_termios->c_cflag;
+	unsigned int iflag;
+	unsigned int cflag;
+	unsigned int old_iflag = 0;
+	unsigned int old_cflag = 0;
 	__u16 urb_value = 0; /* Will hold the new flags */
 	
+	if ((!port->tty) || (!port->tty->termios)) {
+		dbg ("%s - no tty or termios structure", __FUNCTION__);
+		return;
+	}
+
+	iflag = port->tty->termios->c_iflag;
+	cflag = port->tty->termios->c_cflag;
+
+	/* check that they really want us to change something */
+	if (old_termios) {
+		if ((cflag == old_termios->c_cflag) &&
+		    (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
+			dbg("%s - nothing to change...", __FUNCTION__);
+			return;
+		}
+		old_iflag = old_termios->c_iflag;
+		old_cflag = old_termios->c_cflag;
+	}
+
 	/* Set the baud rate */
 	if( (cflag&CBAUD) != (old_cflag&CBAUD) ) {
 		/* reassert DTR and (maybe) RTS on transition from B0 */
drivers/usb/serial/pl2303.c +20 -17
diff -Nru a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
@@ -1,7 +1,7 @@
 /*
  * Prolific PL2303 USB to serial adaptor driver
  *
- * Copyright (C) 2001 Greg Kroah-Hartman ([email protected])
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman ([email protected])
  *
  * Original driver for 2.2.x by anonymous
  *
@@ -12,6 +12,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2002_Mar_26 gkh
+ *	allowed driver to work properly if there is no tty assigned to a port
+ *	(this happens for serial console devices.)
+ *
  * 2001_Oct_06 gkh
  *	Added RTS and DTR line control.  Thanks to [email protected] for parts of it.
  *
@@ -173,11 +177,6 @@
 
 	dbg (__FUNCTION__ " - port %d, %d bytes", port->number, count);
 
-	if (!port->tty) {
-		err (__FUNCTION__ " - no tty???");
-		return 0;
-	}
-
 	if (port->write_urb->status == -EINPROGRESS) {
 		dbg (__FUNCTION__ " - already writing");
 		return 0;
@@ -390,10 +389,12 @@
 	SOUP (VENDOR_WRITE_REQUEST_TYPE, VENDOR_WRITE_REQUEST, 2, 4);
 
 	/* Setup termios */
-	*(port->tty->termios) = tty_std_termios;
-	port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	if (port->tty) {
+		*(port->tty->termios) = tty_std_termios;
+		port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 
-	pl2303_set_termios (port, &tmp_termios);
+		pl2303_set_termios (port, &tmp_termios);
+	}
 
 	//FIXME: need to assert RTS and DTR if CRTSCTS off
 
@@ -434,13 +435,15 @@
 	dbg (__FUNCTION__ " - port %d", port->number);
 
 	if (serial->dev) {
-		c_cflag = port->tty->termios->c_cflag;
-		if (c_cflag & HUPCL) {
-			/* drop DTR and RTS */
-			priv = port->private;
-			priv->line_control = 0;
-			set_control_lines (port->serial->dev,
-					   priv->line_control);
+		if (port->tty) {
+			c_cflag = port->tty->termios->c_cflag;
+			if (c_cflag & HUPCL) {
+				/* drop DTR and RTS */
+				priv = port->private;
+				priv->line_control = 0;
+				set_control_lines (port->serial->dev,
+						   priv->line_control);
+			}
 		}
 
 		/* shutdown our urbs */
@@ -643,7 +646,7 @@
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
 	tty = port->tty;
-	if (urb->actual_length) {
+	if (tty && urb->actual_length) {
 		for (i = 0; i < urb->actual_length; ++i) {
 			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 				tty_flip_buffer_push(tty);
drivers/usb/serial/usb-serial.h +5 -5
diff -Nru a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
@@ -1,7 +1,7 @@
 /*
  * USB Serial Converter driver
  *
- *	Copyright (C) 1999 - 2001
+ *	Copyright (C) 1999 - 2002
  *	    Greg Kroah-Hartman ([email protected])
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -11,6 +11,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (03/26/2002) gkh
+ *	removed the port->tty check from port_paranoia_check() due to serial
+ *	consoles not having a tty device assigned to them.
+ *
  * (12/03/2001) gkh
  *	removed active from the port structure.
  *	added documentation to the usb_serial_device_type structure
@@ -224,10 +228,6 @@
 	}
 	if (!port->serial) {
 		dbg("%s - port->serial == NULL", function);
-		return -1;
-	}
-	if (!port->tty) {
-		dbg("%s - port->tty == NULL", function);
 		return -1;
 	}
 
drivers/usb/serial/usbserial.c +286 -3

343 lines not on this page · raw message

drivers/usb/serial/visor.c +8 -3
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
@@ -12,6 +12,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (03/27/2002) gkh
+ *	Removed assumptions that port->tty was always valid (is not true
+ *	for usb serial console devices.)
+ *
  * (03/23/2002) gkh
  *	Added support for the Palm i705 device, thanks to Thomas Riemer
  *	<[email protected]> for the information.
@@ -287,7 +291,8 @@
 	 * through, otherwise it is scheduled, and with high data rates (like
 	 * with OHCI) data can get lost.
 	 */
-	port->tty->low_latency = 1;
+	if (port->tty)
+		port->tty->low_latency = 1;
 	
 	/* Start reading from the device */
 	usb_fill_bulk_urb (port->read_urb, serial->dev,
@@ -477,7 +482,7 @@
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
 	tty = port->tty;
-	if (urb->actual_length) {
+	if (tty && urb->actual_length) {
 		for (i = 0; i < urb->actual_length ; ++i) {
 			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
 			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
@@ -487,8 +492,8 @@
 			tty_insert_flip_char(tty, data[i], 0);
 		}
 		tty_flip_buffer_push(tty);
-		bytes_in += urb->actual_length;
 	}
+	bytes_in += urb->actual_length;
 
 	/* Continue trying to always read  */
 	usb_fill_bulk_urb (port->read_urb, serial->dev,