Skip to contentSkip to conversation

TTY patches for 2.6.33-rc4

PATCH New Greg KH 3 participants 11 messages Jan 20, 2010 – Jan 21, 2010

Subsystems (3)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

PATCH 1/1 TTY patches for 2.6.33-rc4

Here's the big TTY patchset for your .33-rc4 tree.

Lots of bugfixes and a new device id was added.

Please pull from:

	master.kernel.org:/pub/scm/linux/kernel/git/gregkh/tty-2.6.git/

Patches will be sent to the linux-kernel mailing list, if anyone wants to see them.

thanks,

greg k-h

------------

 drivers/char/nozomi.c        |    2 +-
 drivers/char/tty_io.c        |    2 +-
 drivers/serial/8250_pnp.c    |   10 +----
 drivers/serial/imx.c         |    2 +-
 drivers/serial/serial_core.c |  105 ++++++++++++++++++------------------------
 drivers/serial/serial_cs.c   |    3 +-
 fs/compat_ioctl.c            |    3 +
 7 files changed, 54 insertions(+), 73 deletions(-)

---------------

Alan Cox (2):
nozomi: quick fix for the close/close bug
serial: Fix crash if the minimum rate of the device is > 9600 baud

Atsushi Nemoto (1):
compat_ioctl: Supress "unknown cmd" message on serial /dev/console

Greg Kroah-Hartman (1):
tty: fix race in tty_fasync

Matthew Garrett (1):
serial: 8250_pnp: use wildcard for serial Wacom tablets

Pavel Machek (1):
serial: serial_cs: oxsemi quirk breaks resume

Roel Kluin (1):
serial: imx: bit &/| confusion

Stanislav Brabec (1):
serial-core: resume serial hardware with no_console_suspend

#1 lore raw

PATCH 1/8 compat_ioctl: Supress "unknown cmd" message on serial /dev/console

From: Atsushi Nemoto <[email protected]>

After the commit fb07a5f8 ("compat_ioctl: remove all VT ioctl handling"), I got this error message on 64-bit mips kernel with 32-bit busybox userland:

ioctl32(init:1): Unknown cmd fd(0) cmd(00005600){t:'V';sz:0} arg(7fd76480) on /dev/console

The cmd 5600 is VT_OPENQRY. The busybox's init issues this ioctl to know vt-console or serial-console. If the console was serial console, VT ioctls are not handled by the serial driver.

And by quick search, I found some programs using VT_GETMODE to check vt-console is available or not.

---
 fs/compat_ioctl.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
fs/compat_ioctl.c +3 -0
index 332dd00..c5c45de 100644
@@ -1005,6 +1005,9 @@ COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
 COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
 #endif
+/* Big V (don't complain on serial console) */
+IGNORE_IOCTL(VT_OPENQRY)
+IGNORE_IOCTL(VT_GETMODE)
 /* Little p (/dev/rtc, /dev/envctrl, etc.) */
 COMPATIBLE_IOCTL(RTC_AIE_ON)
 COMPATIBLE_IOCTL(RTC_AIE_OFF)
Signature · 1 line
1.6.5.7
#3 lore raw

PATCH 2/8 nozomi: quick fix for the close/close bug

In reply to Greg KH

From: Alan Cox <[email protected]>

Nozomi goes wrong if you get the sequence

	open
	open
	close

	[stuff]
	close

which turns out to occur on some ppp type setups.

This is a quick patch up for the problem. It's not really fixing Nozomi which completely fails to implement tty open/close semantics and all the other needed stuff. Doing it right is a rather more invasive patch set and not one that will backport.

---
 drivers/char/nozomi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/char/nozomi.c +1 -1
index 7d73cd4..2ad7d37 100644
@@ -1651,10 +1651,10 @@ static void ntty_close(struct tty_struct *tty, struct file *file)
 
 	dc->open_ttys--;
 	port->count--;
-	tty_port_tty_set(port, NULL);
 
 	if (port->count == 0) {
 		DBG1("close: %d", nport->token_dl);
+		tty_port_tty_set(port, NULL);
 		spin_lock_irqsave(&dc->spin_mutex, flags);
 		dc->last_ier &= ~(nport->token_dl);
 		writew(dc->last_ier, dc->reg_ier);
Signature · 1 line
1.6.5.7
#5 lore raw

PATCH 4/8 serial-core: resume serial hardware with no_console_suspend

In reply to Greg KH

From: Stanislav Brabec <[email protected]>

Perform a tricky suspend/resume even with no_console_suspend.

With no_console_suspend, kernel skips serial port suspend/resume and the serial hardware may remain in undefined state after resume. It actually happens on devices that don't have BIOS that handle serial initialization. It makes impossible to use serial console after resume.

Devices affected by this problem include:
Sharp Zaurus devices
Several PXA based ARM embedded boards

The patch does:
- Save the hardware state
- Perform buffer flush in time of its suspend call
- Tell the driver that port is suspended
- But still accept new data
- And keep console hardware in state that allows to send them

It allows to capture late console messages without breaking console after resume.

This is just a resend of a patch discussed in these threads, as the patch was not yet applied.

"Possible suspend/resume regression in .32-rc?" (Nov 1-5, 2009, ARM list, later LKML)

"serial-core: resume serial hardware with no_console_suspend" (Sep 15-Oct 18, 2009, LKML & ARM lists)

---
 drivers/serial/serial_core.c |   88 ++++++++++++++++--------------------------
 1 files changed, 33 insertions(+), 55 deletions(-)
drivers/serial/serial_core.c +33 -55
index 047530b..fa4f170 100644
@@ -2006,12 +2006,6 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
 
 	mutex_lock(&port->mutex);
 
-	if (!console_suspend_enabled && uart_console(uport)) {
-		/* we're going to avoid suspending serial console */
-		mutex_unlock(&port->mutex);
-		return 0;
-	}
-
 	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
 	if (device_may_wakeup(tty_dev)) {
 		enable_irq_wake(uport->irq);
@@ -2019,20 +2013,23 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
 		mutex_unlock(&port->mutex);
 		return 0;
 	}
-	uport->suspended = 1;
+	if (console_suspend_enabled || !uart_console(uport))
+		uport->suspended = 1;
 
 	if (port->flags & ASYNC_INITIALIZED) {
 		const struct uart_ops *ops = uport->ops;
 		int tries;
 
-		set_bit(ASYNCB_SUSPENDED, &port->flags);
-		clear_bit(ASYNCB_INITIALIZED, &port->flags);
+		if (console_suspend_enabled || !uart_console(uport)) {
+			set_bit(ASYNCB_SUSPENDED, &port->flags);
+			clear_bit(ASYNCB_INITIALIZED, &port->flags);
 
-		spin_lock_irq(&uport->lock);
-		ops->stop_tx(uport);
-		ops->set_mctrl(uport, 0);
-		ops->stop_rx(uport);
-		spin_unlock_irq(&uport->lock);
+			spin_lock_irq(&uport->lock);
+			ops->stop_tx(uport);
+			ops->set_mctrl(uport, 0);
+			ops->stop_rx(uport);
+			spin_unlock_irq(&uport->lock);
+		}
 
 		/*
 		 * Wait for the transmitter to empty.
@@ -2047,16 +2044,18 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
 			       drv->dev_name,
 			       drv->tty_driver->name_base + uport->line);
 
-		ops->shutdown(uport);
+		if (console_suspend_enabled || !uart_console(uport))
+			ops->shutdown(uport);
 	}
 
 	/*
 	 * Disable the console device before suspending.
 	 */
-	if (uart_console(uport))
+	if (console_suspend_enabled && uart_console(uport))
 		console_stop(uport->cons);
 
-	uart_change_pm(state, 3);
+	if (console_suspend_enabled || !uart_console(uport))
+		uart_change_pm(state, 3);
 
 	mutex_unlock(&port->mutex);
 
@@ -2073,29 +2072,6 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
 
 	mutex_lock(&port->mutex);
 
-	if (!console_suspend_enabled && uart_console(uport)) {
-		/* no need to resume serial console, it wasn't suspended */
-		/*
-		 * First try to use the console cflag setting.
-		 */
-		memset(&termios, 0, sizeof(struct ktermios));
-		termios.c_cflag = uport->cons->cflag;
-		/*
-		 * If that's unset, use the tty termios setting.
-		 */
-		if (termios.c_cflag == 0)
-			termios = *state->port.tty->termios;
-		else {
-			termios.c_ispeed = termios.c_ospeed =
-				tty_termios_input_baud_rate(&termios);
-			termios.c_ispeed = termios.c_ospeed =
-				tty_termios_baud_rate(&termios);
-		}
-		uport->ops->set_termios(uport, &termios, NULL);
-		mutex_unlock(&port->mutex);
-		return 0;
-	}
-
 	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
 	if (!uport->suspended && device_may_wakeup(tty_dev)) {
 		disable_irq_wake(uport->irq);
@@ -2121,21 +2097,23 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
 		spin_lock_irq(&uport->lock);
 		ops->set_mctrl(uport, 0);
 		spin_unlock_irq(&uport->lock);
-		ret = ops->startup(uport);
-		if (ret == 0) {
-			uart_change_speed(state, NULL);
-			spin_lock_irq(&uport->lock);
-			ops->set_mctrl(uport, uport->mctrl);
-			ops->start_tx(uport);
-			spin_unlock_irq(&uport->lock);
-			set_bit(ASYNCB_INITIALIZED, &port->flags);
-		} else {
-			/*
-			 * Failed to resume - maybe hardware went away?
-			 * Clear the "initialized" flag so we won't try
-			 * to call the low level drivers shutdown method.
-			 */
-			uart_shutdown(state);
+		if (console_suspend_enabled || !uart_console(uport)) {
+			ret = ops->startup(uport);
+			if (ret == 0) {
+				uart_change_speed(state, NULL);
+				spin_lock_irq(&uport->lock);
+				ops->set_mctrl(uport, uport->mctrl);
+				ops->start_tx(uport);
+				spin_unlock_irq(&uport->lock);
+				set_bit(ASYNCB_INITIALIZED, &port->flags);
+			} else {
+				/*
+				 * Failed to resume - maybe hardware went away?
+				 * Clear the "initialized" flag so we won't try
+				 * to call the low level drivers shutdown method.
+				 */
+				uart_shutdown(state);
+			}
 		}
 
 		clear_bit(ASYNCB_SUSPENDED, &port->flags);
Signature · 1 line
1.6.5.7
#7 lore raw

PATCH 6/8 serial: imx: bit &/| confusion

In reply to Greg KH

From: Roel Kluin <[email protected]>

Since UCR1_UARTEN is defined 1, the port was always treated as enabled.

---
 drivers/serial/imx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/serial/imx.c +1 -1
index 18130f1..60d665a 100644
@@ -1088,7 +1088,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
 			   int *parity, int *bits)
 {
 
-	if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) {
+	if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) {
 		/* ok, the port was enabled */
 		unsigned int ucr2, ubir,ubmr, uartclk;
 		unsigned int baud_raw;
Signature · 1 line
1.6.5.7
#4 lore raw

PATCH 3/8 serial: 8250_pnp: use wildcard for serial Wacom tablets

In reply to Greg KH

From: Matthew Garrett <[email protected]>

Wacom claims that the WACF namespace will always be devoted to serial Wacom tablets. Remove the existing entries and add a wildcard to avoid having to update the kernel every time they add a new device.

---
 drivers/serial/8250_pnp.c |   10 +---------
 1 files changed, 1 insertions(+), 9 deletions(-)
drivers/serial/8250_pnp.c +1 -9
index b5496a1..24485cc 100644
@@ -328,15 +328,7 @@ static const struct pnp_device_id pnp_dev_table[] = {
 	/* U.S. Robotics 56K Voice INT PnP*/
 	{	"USR9190",		0	},
 	/* Wacom tablets */
-	{	"WACF004",		0	},
-	{	"WACF005",		0	},
-	{       "WACF006",              0       },
-	{       "WACF007",              0       },
-	{       "WACF008",              0       },
-	{       "WACF009",              0       },
-	{       "WACF00A",              0       },
-	{       "WACF00B",              0       },
-	{       "WACF00C",              0       },
+	{	"WACFXXX",		0	},
 	/* Compaq touchscreen */
 	{       "FPI2002",              0 },
 	/* Fujitsu Stylistic touchscreens */
Signature · 1 line
1.6.5.7
#10 lore raw

PATCH 8/8 tty: fix race in tty_fasync

In reply to Greg KH

We need to keep the lock held over the call to __f_setown() to prevent a PID race.

Thanks to Al Viro for pointing out the problem, and to Travis for making us look here in the first place.

Cc Eric W. Biederman <[email protected]>
Cc Al Viro <[email protected]>
Cc Alan Cox <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc Tavis Ormandy <[email protected]>
Cc Jeff Dike <[email protected]>
Cc Julien Tinnes <[email protected]>
Cc Matt Mackall <[email protected]>
Cc stable <[email protected]>
---
 drivers/char/tty_io.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/char/tty_io.c +1 -1
index f15df40..c6f3b48 100644
@@ -1951,8 +1951,8 @@ static int tty_fasync(int fd, struct file *filp, int on)
 			pid = task_pid(current);
 			type = PIDTYPE_PID;
 		}
-		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 		retval = __f_setown(filp, pid, type, 0);
+		spin_unlock_irqrestore(&tty->ctrl_lock, flags);
 		if (retval)
 			goto out;
 	} else {
Signature · 1 line
1.6.5.7
#6 lore raw

PATCH 5/8 serial: Fix crash if the minimum rate of the device is > 9600 baud

In reply to Greg KH

From: Alan Cox <[email protected]>

In that situation if the old rate is invalid and the new rate is invalid and the chip cannot do 9600 baud we report zero, which makes all the drivers explode.

Instead force the rate based on min/max

---
 drivers/serial/serial_core.c |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)
drivers/serial/serial_core.c +12 -5
index fa4f170..7f28307 100644
@@ -385,13 +385,20 @@ uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
 		}
 
 		/*
-		 * As a last resort, if the quotient is zero,
-		 * default to 9600 bps
+		 * As a last resort, if the range cannot be met then clip to
+		 * the nearest chip supported rate.
 		 */
-		if (!hung_up)
-			tty_termios_encode_baud_rate(termios, 9600, 9600);
+		if (!hung_up) {
+			if (baud <= min)
+				tty_termios_encode_baud_rate(termios,
+							min + 1, min + 1);
+			else
+				tty_termios_encode_baud_rate(termios,
+							max - 1, max - 1);
+		}
 	}
-
+	/* Should never happen */
+	WARN_ON(1);
 	return 0;
 }
 
Signature · 1 line
1.6.5.7
#9 lore raw

PATCH 7/8 serial: serial_cs: oxsemi quirk breaks resume

In reply to Greg KH

From: Pavel Machek <[email protected]>

Quirk is applied on all cards with given manfid (is it that correct?). Unfortunately, that quirk breaks resume on zaurus with billionton bluetooth card inserted: c950ctrl is 0 and outb() faults.

I believe it is simply not a multiport card. (info->multi == 1). ... ... confirmed by printks.

---
 drivers/serial/serial_cs.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/serial/serial_cs.c +2 -1
index 0ee7239..df85440 100644
@@ -146,7 +146,8 @@ static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
 {
 	struct serial_info *info = link->priv;
 
-	outb(12, info->c950ctrl + 1);
+	if (info->c950ctrl)
+		outb(12, info->c950ctrl + 1);
 }
 
 /* request_region? oxsemi branch does no request_region too... */
Signature · 1 line
1.6.5.7
maintainer Acked-by on v1 6/8
#8 lore raw

Re: [PATCH 6/8] serial: imx: bit &/| confusion

In reply to Greg Kroah-Hartman
Quoted 4 lines · Greg Kroah-Hartman

From: Roel Kluin <[email protected]>

Since UCR1_UARTEN is defined 1, the port was always treated as enabled.

Quoted 9 lines
Quoted 21 lines
---
 drivers/serial/imx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/serial/imx.c +1 -1
index 18130f1..60d665a 100644
@@ -1088,7 +1088,7 @@ imx_console_get_options(struct imx_port *sport, int *baud,
 			   int *parity, int *bits)
 {
 
-	if ( readl(sport->port.membase + UCR1) | UCR1_UARTEN ) {
+	if (readl(sport->port.membase + UCR1) & UCR1_UARTEN) {
 		/* ok, the port was enabled */
 		unsigned int ucr2, ubir,ubmr, uartclk;
 		unsigned int baud_raw;
Signature · 1 line
1.6.5.7
Signature · 4 lines
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |