<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/drivers/tty/serial/serial_core.c, branch v3.15</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>serial_core: fix uart PORT_UNKNOWN handling</title>
<updated>2014-04-24T22:38:22+00:00</updated>
<author>
<name>Thomas Pfaff</name>
<email>tpfaff@pcs.com</email>
</author>
<published>2014-04-23T10:33:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=7deb39ed8d9494ea541bcaa69b56036a94f79dc2'/>
<id>7deb39ed8d9494ea541bcaa69b56036a94f79dc2</id>
<content type='text'>
While porting a RS485 driver from 2.6.29 to 3.14, i noticed that the serial tty
driver could break it by using uart ports that it does not own :

1. uart_change_pm ist called during uart_open and calls the uart pm function
   without checking for PORT_UNKNOWN.
   The fix is to move uart_change_pm from uart_open to uart_port_startup.
2. The return code from the uart request_port call in uart_set_info is not
   handled properly, leading to the situation that the serial driver also
   thinks it owns the uart ports.
   This can triggered by doing following actions :

   setserial /dev/ttyS0 uart none    # release the uart ports
   modprobe lirc-serial              # or any other device that uses the uart
   setserial /dev/ttyS0 uart 16550   # gives no error and the uart tty driver
                                     # can use the ports as well

Signed-off-by: Thomas Pfaff &lt;tpfaff@pcs.com&gt;
Reviewed-by: Alan Cox &lt;alan@linux.intel.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While porting a RS485 driver from 2.6.29 to 3.14, i noticed that the serial tty
driver could break it by using uart ports that it does not own :

1. uart_change_pm ist called during uart_open and calls the uart pm function
   without checking for PORT_UNKNOWN.
   The fix is to move uart_change_pm from uart_open to uart_port_startup.
2. The return code from the uart request_port call in uart_set_info is not
   handled properly, leading to the situation that the serial driver also
   thinks it owns the uart ports.
   This can triggered by doing following actions :

   setserial /dev/ttyS0 uart none    # release the uart ports
   modprobe lirc-serial              # or any other device that uses the uart
   setserial /dev/ttyS0 uart 16550   # gives no error and the uart tty driver
                                     # can use the ports as well

Signed-off-by: Thomas Pfaff &lt;tpfaff@pcs.com&gt;
Reviewed-by: Alan Cox &lt;alan@linux.intel.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Fix pm imbalance on unbind</title>
<updated>2014-04-16T21:19:13+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@glider.be</email>
</author>
<published>2014-03-27T10:40:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=bf903c0c6ddfedec19ba92626ca30e98bfafbe08'/>
<id>bf903c0c6ddfedec19ba92626ca30e98bfafbe08</id>
<content type='text'>
When a serial port is closed, uart_close() takes care of shutting down the
hardware, and powering it down.

When a serial port is unbound while in use, uart_close() bypasses all of
this, as this is supposed to be done through uart_hangup() (invoked via
tty_vhangup() in uart_remove_one_port()).

However, uart_hangup() does not set the hardware's power state, leaving it
powered up.  This may also lead to unbounded nesting counts in clock and
power management, depending on their internal implementation.

Make sure to power down the port in uart_hangup(), except when the port is
used as a serial console.

For serial consoles, this operation must be postponed until after the port
becomes completely unused. This case is not fixed yet, as it depends on a
(future) fix for the tty-&gt;count vs. port-&gt;count imbalance on failed
uart_open().

After this, the module clock used by the sh-sci driver is disabled on
unbind while the serial port is in use.

Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@glider.be&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When a serial port is closed, uart_close() takes care of shutting down the
hardware, and powering it down.

When a serial port is unbound while in use, uart_close() bypasses all of
this, as this is supposed to be done through uart_hangup() (invoked via
tty_vhangup() in uart_remove_one_port()).

However, uart_hangup() does not set the hardware's power state, leaving it
powered up.  This may also lead to unbounded nesting counts in clock and
power management, depending on their internal implementation.

Make sure to power down the port in uart_hangup(), except when the port is
used as a serial console.

For serial consoles, this operation must be postponed until after the port
becomes completely unused. This case is not fixed yet, as it depends on a
(future) fix for the tty-&gt;count vs. port-&gt;count imbalance on failed
uart_open().

After this, the module clock used by the sh-sci driver is disabled on
unbind while the serial port is in use.

Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@glider.be&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Fix conditional start_tx on ring buffer not empty</title>
<updated>2014-04-16T21:17:43+00:00</updated>
<author>
<name>Seth Bollinger</name>
<email>sethb@digi.com</email>
</author>
<published>2014-03-25T17:55:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=717f3bbab3c7628736ef738fdbf3d9a28578c26c'/>
<id>717f3bbab3c7628736ef738fdbf3d9a28578c26c</id>
<content type='text'>
If the serial_core ring buffer empties just as the tty layer receives
an XOFF, then start_tx will never be called when the tty layer
receives an XON as the serial_core ring buffer is empty.  This will
possibly leave a few bytes trapped in the fifo for drivers that
disable the transmitter when flow controlled.

Signed-off-by: Seth Bollinger &lt;sethb@digi.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If the serial_core ring buffer empties just as the tty layer receives
an XOFF, then start_tx will never be called when the tty layer
receives an XON as the serial_core ring buffer is empty.  This will
possibly leave a few bytes trapped in the fifo for drivers that
disable the transmitter when flow controlled.

Signed-off-by: Seth Bollinger &lt;sethb@digi.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Avoid NULL pointer dereference in uart_close()</title>
<updated>2014-03-17T23:17:55+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@linux-m68k.org</email>
</author>
<published>2014-03-17T13:10:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=4ed94cd44039037980ce66c652b194ec21356268'/>
<id>4ed94cd44039037980ce66c652b194ec21356268</id>
<content type='text'>
When unbinding a serial driver that's being used as a serial console,
the kernel may crash with a NULL pointer dereference in a uart_*() function
called from uart_close () (e.g. uart_flush_buffer() or
uart_chars_in_buffer()).

To fix this, let uart_close() check for port-&gt;count == 0. If this is the
case, bail out early. Else tty_port_close_start() will make the port
counts inconsistent, printing out warnings like

    tty_port_close_start: tty-&gt;count = 1 port count = 0.

and

    tty_port_close_start: count = -1

and once uport == NULL, it will also crash.

Also fix the related crash in pr_debug() by checking for a non-NULL uport
first.

Detailed description:

On driver unbind, uart_remove_one_port() is called. Basically it;
  - marks the port dead,
  - calls tty_vhangup(),
  - sets state-&gt;uart_port = NULL.

What will happen depends on whether the port is just in use by e.g. getty,
or was also opened as a console.

A. If the tty was not opened as a console:

  - tty_vhangup() will (in __tty_hangup()):
      - mark all file descriptors for this tty hung up by pointing them to
	hung_up_tty_fops,
      - call uart_hangup(), which sets port-&gt;count to 0.

  - A subsequent uart_open() (this may be through /dev/ttyS*, or through
    /dev/console if this is a serial console) will fail with -ENXIO as the
    port was marked dead,
  - uart_close() after the failed uart_open() will return early, as
    tty_hung_up_p() (called from tty_port_close_start()) will notice it was
    hung up.

B. If the tty was also opened as a console:

  - tty_vhangup() will (in __tty_hangup()):
      - mark non-console file descriptors for this tty hung up by pointing
	them to hung_up_tty_fops,
      - NOT call uart_hangup(), but instead call uart_close() for every
        non-console file descriptor, so port-&gt;count will still have a
	non-zero value afterwards.

  - A subsequent uart_open() will fail with -ENXIO as the port was
    marked dead,
  - uart_close() after the failed uart_open() starts to misbehave:
      - tty_hung_up_p() will not notice it was hung up,
      - As port-&gt;count is non-zero, tty_port_close_start() will decrease
        port-&gt;count, making the tty and port counts inconsistent. Later,
	warnings like these will be printed:

	    tty_port_close_start: tty-&gt;count = 1 port count = 0.

	and
	    tty_port_close_start: count = -1

      - If all of this happens after state-&gt;uart_port was set to zero, a
        NULL pointer dereference will happen.

Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When unbinding a serial driver that's being used as a serial console,
the kernel may crash with a NULL pointer dereference in a uart_*() function
called from uart_close () (e.g. uart_flush_buffer() or
uart_chars_in_buffer()).

To fix this, let uart_close() check for port-&gt;count == 0. If this is the
case, bail out early. Else tty_port_close_start() will make the port
counts inconsistent, printing out warnings like

    tty_port_close_start: tty-&gt;count = 1 port count = 0.

and

    tty_port_close_start: count = -1

and once uport == NULL, it will also crash.

Also fix the related crash in pr_debug() by checking for a non-NULL uport
first.

Detailed description:

On driver unbind, uart_remove_one_port() is called. Basically it;
  - marks the port dead,
  - calls tty_vhangup(),
  - sets state-&gt;uart_port = NULL.

What will happen depends on whether the port is just in use by e.g. getty,
or was also opened as a console.

A. If the tty was not opened as a console:

  - tty_vhangup() will (in __tty_hangup()):
      - mark all file descriptors for this tty hung up by pointing them to
	hung_up_tty_fops,
      - call uart_hangup(), which sets port-&gt;count to 0.

  - A subsequent uart_open() (this may be through /dev/ttyS*, or through
    /dev/console if this is a serial console) will fail with -ENXIO as the
    port was marked dead,
  - uart_close() after the failed uart_open() will return early, as
    tty_hung_up_p() (called from tty_port_close_start()) will notice it was
    hung up.

B. If the tty was also opened as a console:

  - tty_vhangup() will (in __tty_hangup()):
      - mark non-console file descriptors for this tty hung up by pointing
	them to hung_up_tty_fops,
      - NOT call uart_hangup(), but instead call uart_close() for every
        non-console file descriptor, so port-&gt;count will still have a
	non-zero value afterwards.

  - A subsequent uart_open() will fail with -ENXIO as the port was
    marked dead,
  - uart_close() after the failed uart_open() starts to misbehave:
      - tty_hung_up_p() will not notice it was hung up,
      - As port-&gt;count is non-zero, tty_port_close_start() will decrease
        port-&gt;count, making the tty and port counts inconsistent. Later,
	warnings like these will be printed:

	    tty_port_close_start: tty-&gt;count = 1 port count = 0.

	and
	    tty_port_close_start: count = -1

      - If all of this happens after state-&gt;uart_port was set to zero, a
        NULL pointer dereference will happen.

Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Get a reference for port-&gt;tty in uart_remove_one_port()</title>
<updated>2014-03-17T23:16:59+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@linux-m68k.org</email>
</author>
<published>2014-03-17T13:10:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=4c6d5b4d537fbdfa310295e7071c85b07783d245'/>
<id>4c6d5b4d537fbdfa310295e7071c85b07783d245</id>
<content type='text'>
Suggested-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Suggested-by: Peter Hurley &lt;peter@hurleysoftware.com&gt;
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Grammar s/ports/port's/</title>
<updated>2014-03-17T23:13:23+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@linux-m68k.org</email>
</author>
<published>2014-03-11T10:23:36+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=015355b70e074a8cc11da6ae4f82d45c5160358a'/>
<id>015355b70e074a8cc11da6ae4f82d45c5160358a</id>
<content type='text'>
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Cc: linux-serial@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Cc: linux-serial@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Spelling s/contro/control/</title>
<updated>2014-03-17T23:13:23+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@linux-m68k.org</email>
</author>
<published>2014-03-11T10:23:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=02088ca63b2de4f7eb575c46fc9ff3d60775b07f'/>
<id>02088ca63b2de4f7eb575c46fc9ff3d60775b07f</id>
<content type='text'>
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Cc: linux-serial@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Cc: linux-serial@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Unregister console in uart_remove_one_port()</title>
<updated>2014-03-01T00:39:38+00:00</updated>
<author>
<name>Geert Uytterhoeven</name>
<email>geert+renesas@linux-m68k.org</email>
</author>
<published>2014-02-28T13:21:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=5f5c9ae56c38942623f69c3e6dc6ec78e4da2076'/>
<id>5f5c9ae56c38942623f69c3e6dc6ec78e4da2076</id>
<content type='text'>
If the serial port being removed is used as a console, it must also be
unregistered from the console subsystem using unregister_console().

uart_ops.release_port() will release resources (e.g. iounmap() the serial
port registers), causing a crash on subsequent kernel output if the console
is still registered.

Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
If the serial port being removed is used as a console, it must also be
unregistered from the console subsystem using unregister_console().

uart_ops.release_port() will release resources (e.g. iounmap() the serial
port registers), causing a crash on subsequent kernel output if the console
is still registered.

Signed-off-by: Geert Uytterhoeven &lt;geert+renesas@linux-m68k.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial_core: Don't re-initialize a previously initialized spinlock.</title>
<updated>2013-12-09T00:44:21+00:00</updated>
<author>
<name>Randy Witt</name>
<email>rewitt@declaratino.com</email>
</author>
<published>2013-10-17T20:56:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=42b6a1baa3ec18de2eb15baa250da6203eeb2d39'/>
<id>42b6a1baa3ec18de2eb15baa250da6203eeb2d39</id>
<content type='text'>
The uart_set_options() code unconditionally initalizes the spinlock
on the port. This can cause a deadlock in some situations.

One instance that exposed the problem, was when writing to
/sys/module/kgdboc/parameters/kgdboc to use ttyS0 when the console
is already running on ttyS0. If the spinlock is re-initialized
while the lock is held due to output to the console, there
is a deadlock.

Assume the spinlock is initialized if the port is a console.

Signed-off-by: Randy Witt &lt;rewitt@declaratino.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The uart_set_options() code unconditionally initalizes the spinlock
on the port. This can cause a deadlock in some situations.

One instance that exposed the problem, was when writing to
/sys/module/kgdboc/parameters/kgdboc to use ttyS0 when the console
is already running on ttyS0. If the spinlock is re-initialized
while the lock is held due to output to the console, there
is a deadlock.

Assume the spinlock is initialized if the port is a console.

Signed-off-by: Randy Witt &lt;rewitt@declaratino.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>serial: report base_baud after initialization</title>
<updated>2013-07-26T23:03:05+00:00</updated>
<author>
<name>Kees Cook</name>
<email>keescook@chromium.org</email>
</author>
<published>2013-07-12T20:07:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=7d12b9769f39bec1630c6a1947e8615ce26c9a52'/>
<id>7d12b9769f39bec1630c6a1947e8615ce26c9a52</id>
<content type='text'>
Some serial ports will not use the standard base baud rate. Report
this after initialization so it might be discovered and used for early
console configuration.

Signed-off-by: Kees Cook &lt;keescook@chromium.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Some serial ports will not use the standard base baud rate. Report
this after initialization so it might be discovered and used for early
console configuration.

Signed-off-by: Kees Cook &lt;keescook@chromium.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
