1. 26 3月, 2015 1 次提交
  2. 07 3月, 2015 2 次提交
  3. 03 2月, 2015 2 次提交
    • P
      serial: core: Rework hw-assisted flow control support · 391f93f2
      Peter Hurley 提交于
      hw-assisted flow control support was added to the serial core
      in v3.8 with commits,
      dba05832 ("SERIAL: core: add hardware assisted h/w flow control support")
      2cbacafd ("SERIAL: core: add hardware assisted s/w flow control support")
      9aba8d5b ("SERIAL: core: add throttle/unthrottle callbacks for hardware
                      assisted flow control")
      Since then, additional requirements for serial core support have arisen.
      Specifically,
      1. Separate tx and rx flow control settings for UARTs which only support
         tx flow control (ie., autoCTS).
      2. Disable sw-assisted CTS flow control in autoCTS mode
      3. Support for RTS flow control by serial core and userspace in autoRTS mode
      
      Distinguish mode from capability; introduce UPSTAT_AUTORTS, UPSTAT_AUTOCTS
      and UPSTAT_AUTOXOFF which, when set by the uart driver, enable serial core
      support for hw-assisted rx, hw-assisted tx and hw-assisted in-band/IXOFF
      rx flow control, respectively. [Note: hw-assisted in-band/IXON tx flow
      control does not require serial core support/intervention and can be
      enabled by the uart driver when required.]
      
      These modes must be set/reset in the driver's set_termios() method, based
      on termios settings, and thus can be safely queried in any context in which
      one of the port lock, port mutex or termios rwsem are held. Set these modes
      in the 2 in-tree drivers, omap-serial and 8250_omap, which currently
      use UPF_HARD_FLOW/UPF_SOFT_FLOW support.
      
      Retain UPF_HARD_FLOW and UPF_SOFT_FLOW as capabilities; re-define
      UPF_HARD_FLOW as both UPF_AUTO_RTS and UPF_AUTO_CTS to allow for distinct
      and separate rx and tx flow control capabilities.
      
      Disable sw-assisted CTS flow control when UPSTAT_AUTOCTS is enabled.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      391f93f2
    • P
      serial: core: Simplify console suspend logic in uart_suspend_port() · b164c972
      Peter Hurley 提交于
      When the uart port being suspended is a console and consoles are
      not suspending (kernel command line contains no_console_suspend),
      then no action is performed for that port, and the function can
      return early.
      
      If the function has not returned early, then one of the conditions
      is not true, so the expression
         (console_suspend_enabled || !uart_console(uport))
      must be true and can be eliminated.
      
      Similarly, the expression
         (console_suspend_enabled && uart_console(uport))
      simplifies to just uart_console(uport).
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      b164c972
  4. 03 1月, 2015 1 次提交
  5. 26 11月, 2014 1 次提交
  6. 07 11月, 2014 5 次提交
  7. 06 11月, 2014 11 次提交
    • P
      serial: core: Fix port count when uart_open() errors · 91b32f54
      Peter Hurley 提交于
      A port count mismatch occurs if mutex_lock_interruptible()
      exits uart_open() and the port has already been opened. This may
      prematurely close a port on an open tty. Since uart_close() is _always_
      called if uart_open() fails, the port count must be corrected if errors
      occur.
      
      Always increment the port count in uart_open(), regardless of errors;
      always decrement the port count in uart_close(). Note that
      tty_port_close_start() decrements the port count when uart_open()
      was successful.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      91b32f54
    • P
      serial: core: Remove extra locking in uart_write() · 64dbee31
      Peter Hurley 提交于
      uart_start() only claims the port->lock to call __uart_start(),
      which does the actual processing. Eliminate the extra acquire/release
      in uart_write(); call __uart_start() directly with port->lock already
      held.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      64dbee31
    • P
      serial: core: Colocate crucial structure linkage · 2b702b9b
      Peter Hurley 提交于
      The key function of uart_add_one_port() is to cross-reference the
      UART driver's port structure with the serial core's state table;
      keep the assignments together and document this crucial association.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2b702b9b
    • P
      serial: core: Remove redundant timeout assignments · 1f0afd16
      Peter Hurley 提交于
      tty_port_init() initializes close_delay and closing_wait to these
      same values; remove.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      1f0afd16
    • P
      serial: core: Unwrap >80 char line in uart_close() · 74866e75
      Peter Hurley 提交于
      The wrapped line looks wrong and out-of-place; leave it as
      >80 char line.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      74866e75
    • P
      serial: Fix locking for uart driver set_termios() method · 7c8ab967
      Peter Hurley 提交于
      The low-level uart driver may modify termios settings to override
      settings that are not compatible with the uart, such as CRTSCTS.
      Thus, callers of the low-level uart driver's set_termios() method must
      hold termios_rwsem write lock to prevent concurrent access to termios,
      in case such override occurs.
      
      The termios_rwsem lock requirement does not extend to console setup
      (ie., uart_set_options), as console setup cannot race with tty
      operations. Nor does this lock requirement extend to functions which
      cannot be concurrent with tty ioctls (ie., uart_port_startup() and
      uart_resume_port()).
      
      Further, always claim the port mutex to protect hardware
      re-reprogramming in the set_termios() uart driver method. Note this
      is unnecessary for console initialization in uart_set_options()
      which cannot be concurrent with other uart operations.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      7c8ab967
    • P
      serial: core: Flush ldisc after dropping port mutex in uart_close() · 2e758910
      Peter Hurley 提交于
      The tty buffers (and any line discipline buffers) must be flushed after
      the UART hardware has shutdown; otherwise, a racing open on the same
      tty may receive data from the previous session, which is a security
      hazard. However, holding the port mutex while flushing the line
      discipline buffers creates a lock inversion if the set_termios()
      handler takes the port mutex (as it does in the followup patch,
      'serial: Fix locking for uart driver set_termios method'.
      
      Flush the ldisc buffers after dropping the port mutex; the tty lock
      is still held which prevents a concurrent open() from advancing while
      flushing. Since no new rx data is possible after uart_shutdown() until
      a new open reinitializes the port, the later flush has no impact on
      what data is being discarded.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2e758910
    • P
      serial: Refactor uart_flush_buffer() from uart_close() · 479e9b94
      Peter Hurley 提交于
      In the context of the final tty & port close, flushing the tx
      ring buffer after the hardware has already been shutdown and
      the ring buffer freed is neither required nor desirable.
      
      uart_flush_buffer() performs 3 operations:
      1. Resets tx ring buffer indices, but the tx ring buffer has
         already been freed and the indices are reset if the port is
         re-opened.
      2. Calls uart driver's flush_buffer() method
         5 in-tree uart drivers define flush_buffer() methods:
           amba-pl011, atmel-serial, imx, serial-tegra, timbuart
         These have been refactored into the shutdown() method, if
         required.
      3. Kicks the ldisc for more writing, but this is undesirable.
         The file handle is being released; any waiting writer will
         will be kicked out by tty_release() with a warning. Further,
         the N_TTY ldisc may generate SIGIO for a file handle which
         is no longer valid.
      
      Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
      Cc: Russell King <linux@arm.linux.org.uk>
      Cc: Laxman Dewangan <ldewangan@nvidia.com>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      479e9b94
    • P
      serial: Fix sparse warnings in uart_throttle()/uart_unthrottle() · 91f189de
      Peter Hurley 提交于
      The struct uart_port.flags field is type upf_t, as are the matching
      bit definitions. Change local mask variable to type upf_t.
      
      Fixes sparse warnings:
      drivers/tty/serial/serial_core.c:620:22: warning: invalid assignment: |=
      drivers/tty/serial/serial_core.c:620:22:    left side has type unsigned int
      drivers/tty/serial/serial_core.c:620:22:    right side has type restricted upf_t
      drivers/tty/serial/serial_core.c:622:22: warning: invalid assignment: |=
      drivers/tty/serial/serial_core.c:622:22:    left side has type unsigned int
      drivers/tty/serial/serial_core.c:622:22:    right side has type restricted upf_t
      drivers/tty/serial/serial_core.c:624:17: warning: restricted upf_t degrades to integer
      drivers/tty/serial/serial_core.c:626:22: warning: invalid assignment: &=
      drivers/tty/serial/serial_core.c:626:22:    left side has type unsigned int
      drivers/tty/serial/serial_core.c:626:22:    right side has type restricted upf_t
      drivers/tty/serial/serial_core.c:629:20: warning: restricted upf_t degrades to integer
      drivers/tty/serial/serial_core.c:632:20: warning: restricted upf_t degrades to integer
      drivers/tty/serial/serial_core.c:643:22: warning: invalid assignment: |=
      drivers/tty/serial/serial_core.c:643:22:    left side has type unsigned int
      drivers/tty/serial/serial_core.c:643:22:    right side has type restricted upf_t
      drivers/tty/serial/serial_core.c:645:22: warning: invalid assignment: |=
      drivers/tty/serial/serial_core.c:645:22:    left side has type unsigned int
      drivers/tty/serial/serial_core.c:645:22:    right side has type restricted upf_t
      drivers/tty/serial/serial_core.c:647:17: warning: restricted upf_t degrades to integer
      drivers/tty/serial/serial_core.c:649:22: warning: invalid assignment: &=
      drivers/tty/serial/serial_core.c:649:22:    left side has type unsigned int
      drivers/tty/serial/serial_core.c:649:22:    right side has type restricted upf_t
      drivers/tty/serial/serial_core.c:652:20: warning: restricted upf_t degrades to integer
      drivers/tty/serial/serial_core.c:655:20: warning: restricted upf_t degrades to integer
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      91f189de
    • P
      serial: Fix upstat_t sparse warnings · d4260b51
      Peter Hurley 提交于
      Commit 299245a1,
      serial: core: Privatize modem status enable flags, introduced
      the upstat_t type and matching bit definitions. The purpose is to
      produce sparse warnings if the wrong bit definitions are used
      (by warning of implicit integer conversions).
      
      Fix implicit conversion to integer return type from uart_cts_enabled()
      and uart_dcd_enabled().
      
      Fixes the following sparse warnings:
      drivers/tty/serial/serial_core.c:63:30: warning: incorrect type in return expression (different base types)
      drivers/tty/serial/serial_core.c:63:30:    expected int
      drivers/tty/serial/serial_core.c:63:30:    got restricted upstat_t
      include/linux/serial_core.h:364:30: warning: incorrect type in return expression (different base types)
      include/linux/serial_core.h:364:30:    expected bool
      include/linux/serial_core.h:364:30:    got restricted upstat_t
      include/linux/serial_core.h:364:30: warning: incorrect type in return expression (different base types)
      include/linux/serial_core.h:364:30:    expected bool
      include/linux/serial_core.h:364:30:    got restricted upstat_t
      Reported-by: NFengguang Wu <fengguang.wu@intel.com>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      d4260b51
    • P
      serial: Fix divide-by-zero fault in uart_get_divisor() · 547039ec
      Peter Hurley 提交于
      uart_get_baud_rate() will return baud == 0 if the max rate is set
      to the "magic" 38400 rate and the SPD_* flags are also specified.
      On the first iteration, if the current baud rate is higher than the
      max, the baud rate is clamped at the max (which in the degenerate
      case is 38400). On the second iteration, the now-"magic" 38400 baud
      rate selects the possibly higher alternate baud rate indicated by
      the SPD_* flag. Since only two loop iterations are performed, the
      loop is exited, a kernel WARNING is generated and a baud rate of
      0 is returned.
      
      Reproducible with:
       setserial /dev/ttyS0 spd_hi base_baud 38400
      
      Only perform the "magic" 38400 -> SPD_* baud transform on the first
      loop iteration, which prevents the degenerate case from recognizing
      the clamped baud rate as the "magic" 38400 value.
      Reported-by: NRobert Święcki <robert@swiecki.net>
      Cc: <stable@vger.kernel.org> # all
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      547039ec
  8. 03 10月, 2014 1 次提交
  9. 29 9月, 2014 1 次提交
  10. 24 9月, 2014 4 次提交
  11. 09 9月, 2014 6 次提交
  12. 24 7月, 2014 1 次提交
  13. 18 7月, 2014 1 次提交
  14. 11 7月, 2014 3 次提交
    • P
      tty: serial: Fix termios/port flags mismatch · c18b55fd
      Peter Hurley 提交于
      Uart port drivers may reconfigure termios settings based on available
      hardware support; set/clear ASYNC_CTS_FLOW and ASYNC_CHECK_CD _after_
      calling the port driver's .set_termios method.
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      c18b55fd
    • P
      tty: Remove tty_hung_up_p() tests from tty drivers' open() · e359a4e3
      Peter Hurley 提交于
      Since at least before 2.6.30, it has not been possible to observe
      a hung up file pointer in a tty driver's open() method unless/until
      the driver open() releases the tty_lock() (eg., before blocking).
      
      This is because tty_open() adds the file pointer while holding
      the tty_lock() _and_ doesn't release the lock until after calling
      the tty driver's open() method. [ Before tty_lock(), this was
      lock_kernel(). ]
      
      Since __tty_hangup() first waits on the tty_lock() before
      enumerating and hanging up the open file pointers, either
      __tty_hangup() will wait for the tty_lock() or tty_open() will
      not yet have added the file pointer. For example,
      
      CPU 0                          |  CPU 1
                                     |
      tty_open                       |  __tty_hangup
        ..                           |    ..
        tty_lock                     |    ..
        tty_reopen                   |    tty_lock  / blocks
        ..                           |
        tty_add_file(tty, filp)      |
        ..                           |
        tty->ops->open(tty, filp)    |
          tty_port_open              |
            tty_port_block_til_ready |
              ..                     |
              while (1)              |
                ..                   |
                tty_unlock           |    / unblocks
                schedule             |    for each filp on tty->tty_files
                                     |      f_ops = tty_hung_up_fops;
                                     |    ..
                                     |    tty_unlock
                tty_lock             |
        ..                           |
        tty_unlock                   |
      
      Note that since tty_port_block_til_ready() and similar drop
      the tty_lock while blocking, when woken, the file pointer
      must then be tested for having been hung up.
      
      Also, fix bit-rotted drivers that used extra_count to track the
      port->count bump.
      
      CC: Mikael Starvik <starvik@axis.com>
      CC: Samuel Ortiz <samuel@sortiz.org>
      CC: "David S. Miller" <davem@davemloft.net>
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Acked-by: NJesper Nilsson <jesper.nilsson@axis.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      e359a4e3
    • P
      tty: Move tty->closing from port lock critical section · ddc7b758
      Peter Hurley 提交于
      tty->closing informs the line discipline that the hardware will
      be shutting down imminently, and to disable further input other
      than soft flow control (but to still allow additional output).
      
      However, the tty lock is the necessary lock for preventing
      concurrent changes to tty->closing. As shown by the call-tree
      audit [1] of functions that modify tty->closing, the tty lock
      is already held for those functions.
      
      [1]
      Call-tree audit of functions that modify tty->closing
      * does not include call tree to tty_port_close(), tty_port_close_start(),
        or tty_port_close_end() which is already documented in
        'tty: Document locking for tty_port_close{,start,end}' that shows
        callers to those 3 functions hold the tty lock
      
      tty_release()
        tty->ops->close() --+
                            |
      __tty_hangup()        |
        tty->ops->close() --+
                            |
              mp_close():drivers/staging/sb105x/sb_pci_mp.c
              dngc_tty_close():drivers/staging/dgnc/dgnc_tty.c
              dgap_tty_close():drivers/staging/dgap/dgap_tty.c
              dgrp_tty_close():drivers/staging/dgrp/dgrp_tty.c
              rp_close():drivers/tty/rocket.c
              hvsi_close():drivers/tty/hvc/hvsi.c
              rs_close():drivers/tty/serial/68328serial.c
              rs_close():drivers/tty/serial/crisv10.c
              uart_close():drivers/tty/serial/serial_core.c
              isdn_tty_close():drivers/isdn/i4l/isdn_tty.c
              tty3215_close():drivers/s390/char/con3215.c
      
      tty_open()
        tty_ldisc_setup() ----+
                              |
      __tty_hangup()          |
        tty_ldisc_hangup() ---+
                              |
      tty_set_ldisc() --------+
        tty_ldisc_restore() --+
                              |
                              +- tty_ldisc_open()
                                   ld->ops->open() --+
                                                     |
                                                     +- n_tty_open()
      Signed-off-by: NPeter Hurley <peter@hurleysoftware.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      ddc7b758