All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/10] Add RS485 support to DW UART
@ 2022-04-26 12:24 Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support Ilpo Järvinen
                   ` (10 more replies)
  0 siblings, 11 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, linux-api

This patchset adds RS-485 support to the DW UART driver. The patchset
has two main parts. The first part adds HW support for RS-485 itself
in various modes of operation and the second part focuses on enabling
9th bit addressing mode that can be used on a multipoint RS-485
communications line.

To configure multipoint addressing, ADDRB flag is added to termios
and two new IOCTLs are added into serial core. Lukas Wunner brought up
during v1 review that if this addressing is only going to be used with
RS-485, doing it within rs485_config would avoid having to add those
IOCTLs. There was some counterexample w/o further details mentioned for
RS-232 usage by Andy Shevchenko. I left the IOCTL approach there but if
somebody has further input on this, please voice it as it is user-space
facing API.

I decided to rewrite the UART_CAP_NOTEMT patch from scratch myself
based on Uwe Kleine-König's earlier suggestion and include it to this
series. To make waiting for a single character easy and to avoid
storing it per purpose in the uart drivers, I decided to add
frame_time into uart_port. It turned out to beneficial also for serial
core which had to reverse calculate it from uart_port->timeout). I was
thinking of removing uart_port->timeout entirely and derive the value
timeout from frame_time and fifosize where needed but I was not sure
if that's ok to do lockingwise (not that fifosize is a variable that
is expected to change so maybe I'm just being too cautious).

Cc: linux-api@vger.kernel.org

v1 -> v2:
- Add uart_port->frame_time to avoid the need to store it per purpose
- Included NOTEMT patch rewritten from scratch
- Merge HW half & full-duplex patches
- Detect RS485 HW using RE_EN register write+read
- Removed SER_RS485_SW_RX_OR_TX
- Relocated/renamed RE polarity DT prop
- Use SER_RS485_RTS_ON_SEND rather than DT prop directly
- Removed DE polarity prop, it is still configurable but with rts one instead
- Make DE active-high by default in dwlib
- Don't unnecessarily clear DE/RE_EN for non-RS485 mode
- Prevent ADDRB and addrmode desync for RS485->RS232 transition
- Added ACPI enumeration doc
- Changed -EINVAL to -ENOTTY if no set/get_addr handler is present
- Clear ADDRB in set_termios of a few more drivers
- Added filtering for addresses to avoid them leaking into data stream
- Reworded comments & commit messages as requested

v2 -> v3:
- Change ADDRB to 0x20000000 which is free for all archs
- Added TIOCSADDR/GADDR to tty_compat_ioctl

v3 -> v4:
- defined DW_UART_ADDR_MASK instead of 0xff
- Adapt to UART_CAP_NOTEMT that already exists (is currently no-op)
- Corrected delay_rts_after_send conversion to nsec
- Make 8250 DMA code to use THRE & __stop_tx
- Add roughly one extra bit to stop_delay to prevent too early RTS deassert

v4 -> v5:
- rebased series to tty-testing

Ilpo Järvinen (10):
  serial: 8250_dwlib: RS485 HW half & full duplex support
  serial: 8250_dwlib: Implement SW half duplex support
  dt_bindings: rs485: Add receiver enable polarity
  ACPI / property: Document RS485 _DSD properties
  serial: termbits: ADDRB to indicate 9th bit addressing mode
  serial: General support for multipoint addresses
  serial: 8250: make saved LSR larger
  serial: 8250: create lsr_save_mask
  serial: 8250_lpss: Use 32-bit reads
  serial: 8250_dwlib: Support for 9th bit multipoint addressing

 .../devicetree/bindings/serial/rs485.yaml     |   5 +
 .../driver-api/serial/serial-rs485.rst        |  23 +-
 .../firmware-guide/acpi/enumeration.rst       |  25 ++
 arch/alpha/include/uapi/asm/ioctls.h          |   3 +
 arch/alpha/include/uapi/asm/termbits.h        |   1 +
 arch/mips/include/uapi/asm/ioctls.h           |   3 +
 arch/mips/include/uapi/asm/termbits.h         |   1 +
 arch/parisc/include/uapi/asm/ioctls.h         |   3 +
 arch/parisc/include/uapi/asm/termbits.h       |   1 +
 arch/powerpc/include/uapi/asm/ioctls.h        |   3 +
 arch/powerpc/include/uapi/asm/termbits.h      |   1 +
 arch/sh/include/uapi/asm/ioctls.h             |   3 +
 arch/sparc/include/uapi/asm/ioctls.h          |   3 +
 arch/sparc/include/uapi/asm/termbits.h        |   1 +
 arch/xtensa/include/uapi/asm/ioctls.h         |   3 +
 drivers/char/pcmcia/synclink_cs.c             |   2 +
 drivers/ipack/devices/ipoctal.c               |   2 +
 drivers/mmc/core/sdio_uart.c                  |   2 +
 drivers/net/usb/hso.c                         |   3 +-
 drivers/s390/char/tty3270.c                   |   3 +
 drivers/staging/greybus/uart.c                |   2 +
 drivers/tty/amiserial.c                       |   6 +-
 drivers/tty/moxa.c                            |   1 +
 drivers/tty/mxser.c                           |   1 +
 drivers/tty/serial/8250/8250_core.c           |   6 +-
 drivers/tty/serial/8250/8250_dwlib.c          | 232 +++++++++++++++++-
 drivers/tty/serial/8250/8250_dwlib.h          |   5 +
 drivers/tty/serial/8250/8250_lpss.c           |   2 +-
 drivers/tty/serial/8250/8250_port.c           |  14 +-
 drivers/tty/serial/serial_core.c              |  62 +++++
 drivers/tty/synclink_gt.c                     |   2 +
 drivers/tty/tty_io.c                          |   2 +
 drivers/tty/tty_ioctl.c                       |   2 +
 drivers/usb/class/cdc-acm.c                   |   2 +
 drivers/usb/serial/usb-serial.c               |   6 +-
 include/linux/serial_8250.h                   |   7 +-
 include/linux/serial_core.h                   |   6 +
 include/uapi/asm-generic/ioctls.h             |   3 +
 include/uapi/asm-generic/termbits.h           |   1 +
 include/uapi/linux/serial.h                   |   8 +
 net/bluetooth/rfcomm/tty.c                    |   2 +
 41 files changed, 445 insertions(+), 18 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 02/10] serial: 8250_dwlib: Implement SW half " Ilpo Järvinen
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, Raymond Tan

The Synopsys DesignWare UART can be configured to have HW support for
the RS485 protocol from IP version 4.0 onward. Add support for
hardware-controlled half duplex and full duplex modes.

HW will take care of managing DE and RE, the driver just gives it
permission to use either by setting both to 1.

To ask for full duplex mode, userspace sets SER_RS485_RX_DURING_TX flag
and HW will take care of the rest.

Set delay_rts_before_send and delay_rts_after_send to zero for now. The
granularity of that ABI is too coarse to be useful.

Co-developed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Co-developed-by: Raymond Tan <raymond.tan@intel.com>
Signed-off-by: Raymond Tan <raymond.tan@intel.com>
Co-developed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/tty/serial/8250/8250_dwlib.c | 82 ++++++++++++++++++++++++++++
 drivers/tty/serial/8250/8250_dwlib.h |  3 +
 2 files changed, 85 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index b3df6dee9ceb..05b73c8e75bc 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -2,18 +2,32 @@
 /* Synopsys DesignWare 8250 library. */
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/property.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
 
 #include "8250_dwlib.h"
 
 /* Offsets for the DesignWare specific registers */
+#define DW_UART_TCR	0xac /* Transceiver Control Register (RS485) */
+#define DW_UART_DE_EN	0xb0 /* Driver Output Enable Register */
+#define DW_UART_RE_EN	0xb4 /* Receiver Output Enable Register */
 #define DW_UART_DLF	0xc0 /* Divisor Latch Fraction Register */
 #define DW_UART_CPR	0xf4 /* Component Parameter Register */
 #define DW_UART_UCV	0xf8 /* UART Component Version */
 
+/* Transceiver Control Register bits */
+#define DW_UART_TCR_RS485_EN		BIT(0)
+#define DW_UART_TCR_RE_POL		BIT(1)
+#define DW_UART_TCR_DE_POL		BIT(2)
+#define DW_UART_TCR_XFER_MODE		GENMASK(4, 3)
+#define DW_UART_TCR_XFER_MODE_DE_DURING_RE	FIELD_PREP(DW_UART_TCR_XFER_MODE, 0)
+#define DW_UART_TCR_XFER_MODE_SW_DE_OR_RE	FIELD_PREP(DW_UART_TCR_XFER_MODE, 1)
+#define DW_UART_TCR_XFER_MODE_DE_OR_RE		FIELD_PREP(DW_UART_TCR_XFER_MODE, 2)
+
 /* Component Parameter Register bits */
 #define DW_UART_CPR_ABP_DATA_WIDTH	(3 << 0)
 #define DW_UART_CPR_AFCE_MODE		(1 << 4)
@@ -71,6 +85,70 @@ void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct
 }
 EXPORT_SYMBOL_GPL(dw8250_do_set_termios);
 
+static int dw8250_rs485_config(struct uart_port *p, struct serial_rs485 *rs485)
+{
+	u32 tcr;
+
+	tcr = dw8250_readl_ext(p, DW_UART_TCR);
+	tcr &= ~DW_UART_TCR_XFER_MODE;
+
+	if (rs485->flags & SER_RS485_ENABLED) {
+		/* Clear unsupported flags. */
+		rs485->flags &= SER_RS485_ENABLED | SER_RS485_RX_DURING_TX |
+				SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND;
+		tcr |= DW_UART_TCR_RS485_EN;
+
+		if (rs485->flags & SER_RS485_RX_DURING_TX) {
+			tcr |= DW_UART_TCR_XFER_MODE_DE_DURING_RE;
+		} else {
+			/* HW does not support same DE level for tx and rx */
+			if (!(rs485->flags & SER_RS485_RTS_ON_SEND) ==
+			    !(rs485->flags & SER_RS485_RTS_AFTER_SEND))
+				return -EINVAL;
+
+			tcr |= DW_UART_TCR_XFER_MODE_DE_OR_RE;
+		}
+		dw8250_writel_ext(p, DW_UART_DE_EN, 1);
+		dw8250_writel_ext(p, DW_UART_RE_EN, 1);
+	} else {
+		rs485->flags = 0;
+
+		tcr &= ~DW_UART_TCR_RS485_EN;
+	}
+
+	/* Reset to default polarity */
+	tcr |= DW_UART_TCR_DE_POL;
+	tcr &= ~DW_UART_TCR_RE_POL;
+
+	if (!(rs485->flags & SER_RS485_RTS_ON_SEND))
+		tcr &= ~DW_UART_TCR_DE_POL;
+	if (device_property_read_bool(p->dev, "rs485-rx-active-high"))
+		tcr |= DW_UART_TCR_RE_POL;
+
+	dw8250_writel_ext(p, DW_UART_TCR, tcr);
+
+	rs485->delay_rts_before_send = 0;
+	rs485->delay_rts_after_send = 0;
+
+	p->rs485 = *rs485;
+
+	return 0;
+}
+
+/*
+ * Tests if RE_EN register can have non-zero value to see if RS-485 HW support
+ * is present.
+ */
+static bool dw8250_detect_rs485_hw(struct uart_port *p)
+{
+	u32 reg;
+
+	dw8250_writel_ext(p, DW_UART_RE_EN, 1);
+	reg = dw8250_readl_ext(p, DW_UART_RE_EN);
+	dw8250_writel_ext(p, DW_UART_RE_EN, 0);
+	return reg;
+}
+
 void dw8250_setup_port(struct uart_port *p)
 {
 	struct dw8250_port_data *pd = p->private_data;
@@ -78,6 +156,10 @@ void dw8250_setup_port(struct uart_port *p)
 	struct uart_8250_port *up = up_to_u8250p(p);
 	u32 reg;
 
+	pd->hw_rs485_support = dw8250_detect_rs485_hw(p);
+	if (pd->hw_rs485_support)
+		p->rs485_config = dw8250_rs485_config;
+
 	/*
 	 * If the Component Version Register returns zero, we know that
 	 * ADDITIONAL_FEATURES are not enabled. No need to go any further.
diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
index b10e60a5d16a..055bfdc87985 100644
--- a/drivers/tty/serial/8250/8250_dwlib.h
+++ b/drivers/tty/serial/8250/8250_dwlib.h
@@ -20,6 +20,9 @@ struct dw8250_port_data {
 
 	/* Hardware configuration */
 	u8			dlf_size;
+
+	/* RS485 variables */
+	bool			hw_rs485_support;
 };
 
 struct dw8250_platform_data {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 02/10] serial: 8250_dwlib: Implement SW half duplex support
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 03/10] dt_bindings: rs485: Add receiver enable polarity Ilpo Järvinen
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, Eric Tremblay

This patch enables support for SW half-duplex mode using em485.

Cc: Eric Tremblay <etremblay@distech-controls.com>
Cc: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Tested-by: Vicente Bergas <vicencb@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/tty/serial/8250/8250_dwlib.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index 05b73c8e75bc..fbabfdd8c7b8 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -157,8 +157,14 @@ void dw8250_setup_port(struct uart_port *p)
 	u32 reg;
 
 	pd->hw_rs485_support = dw8250_detect_rs485_hw(p);
-	if (pd->hw_rs485_support)
+	if (pd->hw_rs485_support) {
 		p->rs485_config = dw8250_rs485_config;
+	} else {
+		p->rs485_config = serial8250_em485_config;
+		up->rs485_start_tx = serial8250_em485_start_tx;
+		up->rs485_stop_tx = serial8250_em485_stop_tx;
+	}
+	up->capabilities |= UART_CAP_NOTEMT;
 
 	/*
 	 * If the Component Version Register returns zero, we know that
@@ -194,7 +200,7 @@ void dw8250_setup_port(struct uart_port *p)
 		p->type = PORT_16550A;
 		p->flags |= UPF_FIXED_TYPE;
 		p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
-		up->capabilities = UART_CAP_FIFO;
+		up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT;
 	}
 
 	if (reg & DW_UART_CPR_AFCE_MODE)
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 03/10] dt_bindings: rs485: Add receiver enable polarity
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 02/10] serial: 8250_dwlib: Implement SW half " Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 04/10] ACPI / property: Document RS485 _DSD properties Ilpo Järvinen
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, devicetree, Rob Herring

Add polarity property for receiver enable. Some UARTs have separate
enable pins for tx (RTS or DE) and rx (RE). As most RS485 transceivers
have !RE pin, the default is active low in contrast to
rs485-rts-active-low that defaults to active high.

Cc: devicetree@vger.kernel.org
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 Documentation/devicetree/bindings/serial/rs485.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/rs485.yaml b/Documentation/devicetree/bindings/serial/rs485.yaml
index 0c9fa694f85c..f2c9c9fe6aa7 100644
--- a/Documentation/devicetree/bindings/serial/rs485.yaml
+++ b/Documentation/devicetree/bindings/serial/rs485.yaml
@@ -33,6 +33,11 @@ properties:
     description: drive RTS low when sending (default is high).
     $ref: /schemas/types.yaml#/definitions/flag
 
+  rs485-rx-active-high:
+    description: Polarity of receiver enable signal (when separate from RTS).
+      True indicates active high (default is low).
+    $ref: /schemas/types.yaml#/definitions/flag
+
   linux,rs485-enabled-at-boot-time:
     description: enables the rs485 feature at boot time. It can be disabled
       later with proper ioctl.
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 04/10] ACPI / property: Document RS485 _DSD properties
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
                   ` (2 preceding siblings ...)
  2022-04-26 12:24 ` [PATCH v5 03/10] dt_bindings: rs485: Add receiver enable polarity Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24   ` Ilpo Järvinen
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen

Document RS485 related properties returned from ACPI _DSD as device
properties.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 .../firmware-guide/acpi/enumeration.rst       | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/firmware-guide/acpi/enumeration.rst b/Documentation/firmware-guide/acpi/enumeration.rst
index 47fb4d6d4557..f584a6a0c5e3 100644
--- a/Documentation/firmware-guide/acpi/enumeration.rst
+++ b/Documentation/firmware-guide/acpi/enumeration.rst
@@ -390,6 +390,31 @@ descriptors once the device is released.
 See Documentation/firmware-guide/acpi/gpio-properties.rst for more information
 about the _DSD binding related to GPIOs.
 
+RS-485 support
+==============
+
+ACPI _DSD (Device Specific Data) can be used to describe RS-485 capability
+of UART.
+
+For example::
+
+	Device (DEV)
+	{
+		...
+
+		// ACPI 5.1 _DSD used for RS-485 capabilities
+		Name (_DSD, Package ()
+		{
+			ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+			Package ()
+			{
+				Package () {"rs485-rts-active-low", Zero},
+				Package () {"rs485-rx-active-high", Zero},
+				Package () {"rs485-rx-during-tx", Zero},
+			}
+		})
+		...
+
 MFD devices
 ===========
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support Ilpo Järvinen
@ 2022-04-26 12:24   ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 03/10] dt_bindings: rs485: Add receiver enable polarity Ilpo Järvinen
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, David S. Miller, sparclinux, Arnd Bergmann,
	linux-arch, linux-usb

Add ADDRB to termbits to indicate 9th bit addressing mode. This change
is necessary for supporting devices with RS485 multipoint addressing
[*]. A later patch in the patch series adds support for Synopsys
Designware UART capable for 9th bit addressing mode. In this mode, 9th
bit is used to indicate an address (byte) within the communication
line. The 9th bit addressing mode is selected using ADDRB introduced by
an earlier patch.

[*] Technically, RS485 is just an electronic spec and does not itself
specify the 9th bit addressing mode but 9th bit seems at least
"semi-standard" way to do addressing with RS485.

Cc: linux-api@vger.kernel.org
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 arch/alpha/include/uapi/asm/termbits.h   | 1 +
 arch/mips/include/uapi/asm/termbits.h    | 1 +
 arch/parisc/include/uapi/asm/termbits.h  | 1 +
 arch/powerpc/include/uapi/asm/termbits.h | 1 +
 arch/sparc/include/uapi/asm/termbits.h   | 1 +
 drivers/char/pcmcia/synclink_cs.c        | 2 ++
 drivers/ipack/devices/ipoctal.c          | 2 ++
 drivers/mmc/core/sdio_uart.c             | 2 ++
 drivers/net/usb/hso.c                    | 3 ++-
 drivers/s390/char/tty3270.c              | 3 +++
 drivers/staging/greybus/uart.c           | 2 ++
 drivers/tty/amiserial.c                  | 6 +++++-
 drivers/tty/moxa.c                       | 1 +
 drivers/tty/mxser.c                      | 1 +
 drivers/tty/serial/serial_core.c         | 2 ++
 drivers/tty/synclink_gt.c                | 2 ++
 drivers/tty/tty_ioctl.c                  | 2 ++
 drivers/usb/class/cdc-acm.c              | 2 ++
 drivers/usb/serial/usb-serial.c          | 6 ++++--
 include/uapi/asm-generic/termbits.h      | 1 +
 net/bluetooth/rfcomm/tty.c               | 2 ++
 21 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
index 4575ba34a0ea..0c123e715486 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -180,6 +180,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define ADDRB	004000000000		/* address bit */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
index dfeffba729b7..4732d31b0e4e 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -182,6 +182,7 @@ struct ktermios {
 #define	 B3500000 0010016
 #define	 B4000000 0010017
 #define CIBAUD	  002003600000	/* input baud rate */
+#define ADDRB	  004000000000	/* address bit */
 #define CMSPAR	  010000000000	/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000	/* flow control */
 
diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
index 40e920f8d683..d6bbd10d92ba 100644
--- a/arch/parisc/include/uapi/asm/termbits.h
+++ b/arch/parisc/include/uapi/asm/termbits.h
@@ -159,6 +159,7 @@ struct ktermios {
 #define  B3500000 0010016
 #define  B4000000 0010017
 #define CIBAUD    002003600000		/* input baud rate */
+#define ADDRB	  004000000000		/* address bit */
 #define CMSPAR    010000000000          /* mark or space (stick) parity */
 #define CRTSCTS   020000000000          /* flow control */
 
diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
index ed18bc61f63d..c6a033732f39 100644
--- a/arch/powerpc/include/uapi/asm/termbits.h
+++ b/arch/powerpc/include/uapi/asm/termbits.h
@@ -171,6 +171,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define ADDRB	004000000000		/* address bit */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
index ce5ad5d0f105..5eb1d547b5c4 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -201,6 +201,7 @@ struct ktermios {
 #define B3500000  0x00001012
 #define B4000000  0x00001013  */
 #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
+#define ADDRB	  0x20000000  /* address bit */
 #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 78baba55a8b5..d179b9b57a25 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	mgslpc_change_params(info, tty);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index 20d2b9ec1227..d66cc9683ebc 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -506,6 +506,8 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	struct ipoctal_channel *channel = tty->driver_data;
 	speed_t baud;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	cflag = tty->termios.c_cflag;
 
 	/* Disable and reset everything before change the setup */
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 414aa82abc39..f28075952f3e 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -867,6 +867,8 @@ static void sdio_uart_set_termios(struct tty_struct *tty,
 	if (sdio_uart_claim_func(port) != 0)
 		return;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	sdio_uart_change_speed(port, &tty->termios, old_termios);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index f8221a7acf62..056352618804 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1099,7 +1099,8 @@ static void _hso_serial_set_termios(struct tty_struct *tty)
 		~(CSIZE		/* no size */
 		| PARENB	/* disable parity bit */
 		| CBAUD		/* clear current baud rate */
-		| CBAUDEX);	/* clear current buad rate */
+		| CBAUDEX	/* clear current baud rate */
+		| ADDRB);	/* disable 9th (addr) bit */
 
 	tty->termios.c_cflag |= CS8;	/* character size 8 bits */
 
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 5c83f71c1d0e..253d2997a1d3 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1768,6 +1768,9 @@ tty3270_set_termios(struct tty_struct *tty, struct ktermios *old)
 	tp = tty->driver_data;
 	if (!tp)
 		return;
+
+	tty->termios.c_cflag &= ~ADDRB;
+
 	spin_lock_bh(&tp->view.lock);
 	if (L_ICANON(tty)) {
 		new = L_ECHO(tty) ? TF_INPUT: TF_INPUTN;
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index dc4ed0ff1ae2..83e73aefde0f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -487,6 +487,8 @@ static void gb_tty_set_termios(struct tty_struct *tty,
 	struct ktermios *termios = &tty->termios;
 	u8 newctrl = gb_tty->ctrlout;
 
+	termios->c_cflag &= ~ADDRB;
+
 	newline.rate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.format = termios->c_cflag & CSTOPB ?
 				GB_SERIAL_2_STOP_BITS : GB_SERIAL_1_STOP_BITS;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 533d02b38e02..3ca97007bd6e 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1175,7 +1175,11 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
-	unsigned int cflag = tty->termios.c_cflag;
+	unsigned int cflag;
+
+	tty->termios.c_cflag &= ~ADDRB;
+
+	cflag = tty->termios.c_cflag;
 
 	change_speed(tty, info, old_termios);
 
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index f3c72ab1476c..07cd88152d58 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -2050,6 +2050,7 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
 
 	ofsAddr = port->tableAddr;
 
+	termio->c_cflag &= ~ADDRB;
 	mode = termio->c_cflag & CSIZE;
 	if (mode == CS5)
 		mode = MX_CS5;
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 6ebd3e4ed859..79c542aca1c3 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -577,6 +577,7 @@ static void mxser_change_speed(struct tty_struct *tty, struct ktermios *old_term
 	struct mxser_port *info = tty->driver_data;
 	unsigned cflag, cval;
 
+	tty->termios.c_cflag &= ~ADDRB;
 	cflag = tty->termios.c_cflag;
 
 	if (mxser_set_baud(tty, tty_get_baud_rate(tty))) {
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 82a1770dd808..0f397e67eeb0 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1540,6 +1540,8 @@ static void uart_set_termios(struct tty_struct *tty,
 		goto out;
 	}
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	uart_change_speed(tty, state, old_termios);
 	/* reload cflag from termios; port driver may have overridden flags */
 	cflag = tty->termios.c_cflag;
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 9bc2a9265277..180f38f0f57a 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -714,6 +714,8 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
 	DBGINFO(("%s set_termios\n", tty->driver->name));
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	change_params(info);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index 63181925ec1a..934037d78868 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -319,6 +319,8 @@ unsigned char tty_get_frame_size(unsigned int cflag)
 		bits++;
 	if (cflag & PARENB)
 		bits++;
+	if (cflag & ADDRB)
+		bits++;
 
 	return bits;
 }
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9b9aea24d58c..fd246ec70da8 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1056,6 +1056,8 @@ static void acm_tty_set_termios(struct tty_struct *tty,
 	struct usb_cdc_line_coding newline;
 	int newctrl = acm->ctrlout;
 
+	termios->c_cflag &= ~ADDRB;
+
 	newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
 	newline.bParityType = termios->c_cflag & PARENB ?
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 24101bd7fcad..8d1d170eb7e6 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -525,10 +525,12 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 
 	dev_dbg(&port->dev, "%s\n", __func__);
 
-	if (port->serial->type->set_termios)
+	if (port->serial->type->set_termios) {
+		tty->termios.c_cflag &= ~ADDRB;
 		port->serial->type->set_termios(tty, port, old);
-	else
+	} else {
 		tty_termios_copy_hw(&tty->termios, old);
+	}
 }
 
 static int serial_break(struct tty_struct *tty, int break_state)
diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
index 2fbaf9ae89dd..e06eaa9cf8be 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -158,6 +158,7 @@ struct ktermios {
 #define  B3500000 0010016
 #define  B4000000 0010017
 #define CIBAUD	  002003600000	/* input baud rate */
+#define ADDRB	  004000000000	/* address bit */
 #define CMSPAR	  010000000000	/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000	/* flow control */
 
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index ebd78fdbd6e8..832e725f23ab 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -871,6 +871,8 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 	if (!dev || !dev->dlc || !dev->dlc->session)
 		return;
 
+	new->c_cflag &= ~ADDRB;
+
 	/* Handle turning off CRTSCTS */
 	if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
 		BT_DBG("Turning off CRTSCTS unsupported");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 12:24   ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Heikki Krogerus, heiko, James E.J. Bottomley, Paul Mackerras,
	sparclinux, Jiri Slaby, linux-arch, Helge Deller,
	Uwe Kleine-König, Ilpo Järvinen, Matt Turner,
	Arnd Bergmann, Johan Hovold, Vicente Bergas, Ivan Kokshaysky,
	Andy Shevchenko, Thomas Bogendoerfer, linux-parisc, linux-api,
	linux-usb, linux-mips, David S. Miller, Lukas Wunner,
	linux-alpha, linuxppc-dev, giulio.benetti

Add ADDRB to termbits to indicate 9th bit addressing mode. This change
is necessary for supporting devices with RS485 multipoint addressing
[*]. A later patch in the patch series adds support for Synopsys
Designware UART capable for 9th bit addressing mode. In this mode, 9th
bit is used to indicate an address (byte) within the communication
line. The 9th bit addressing mode is selected using ADDRB introduced by
an earlier patch.

[*] Technically, RS485 is just an electronic spec and does not itself
specify the 9th bit addressing mode but 9th bit seems at least
"semi-standard" way to do addressing with RS485.

Cc: linux-api@vger.kernel.org
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 arch/alpha/include/uapi/asm/termbits.h   | 1 +
 arch/mips/include/uapi/asm/termbits.h    | 1 +
 arch/parisc/include/uapi/asm/termbits.h  | 1 +
 arch/powerpc/include/uapi/asm/termbits.h | 1 +
 arch/sparc/include/uapi/asm/termbits.h   | 1 +
 drivers/char/pcmcia/synclink_cs.c        | 2 ++
 drivers/ipack/devices/ipoctal.c          | 2 ++
 drivers/mmc/core/sdio_uart.c             | 2 ++
 drivers/net/usb/hso.c                    | 3 ++-
 drivers/s390/char/tty3270.c              | 3 +++
 drivers/staging/greybus/uart.c           | 2 ++
 drivers/tty/amiserial.c                  | 6 +++++-
 drivers/tty/moxa.c                       | 1 +
 drivers/tty/mxser.c                      | 1 +
 drivers/tty/serial/serial_core.c         | 2 ++
 drivers/tty/synclink_gt.c                | 2 ++
 drivers/tty/tty_ioctl.c                  | 2 ++
 drivers/usb/class/cdc-acm.c              | 2 ++
 drivers/usb/serial/usb-serial.c          | 6 ++++--
 include/uapi/asm-generic/termbits.h      | 1 +
 net/bluetooth/rfcomm/tty.c               | 2 ++
 21 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
index 4575ba34a0ea..0c123e715486 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -180,6 +180,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define ADDRB	004000000000		/* address bit */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
index dfeffba729b7..4732d31b0e4e 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -182,6 +182,7 @@ struct ktermios {
 #define	 B3500000 0010016
 #define	 B4000000 0010017
 #define CIBAUD	  002003600000	/* input baud rate */
+#define ADDRB	  004000000000	/* address bit */
 #define CMSPAR	  010000000000	/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000	/* flow control */
 
diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
index 40e920f8d683..d6bbd10d92ba 100644
--- a/arch/parisc/include/uapi/asm/termbits.h
+++ b/arch/parisc/include/uapi/asm/termbits.h
@@ -159,6 +159,7 @@ struct ktermios {
 #define  B3500000 0010016
 #define  B4000000 0010017
 #define CIBAUD    002003600000		/* input baud rate */
+#define ADDRB	  004000000000		/* address bit */
 #define CMSPAR    010000000000          /* mark or space (stick) parity */
 #define CRTSCTS   020000000000          /* flow control */
 
diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
index ed18bc61f63d..c6a033732f39 100644
--- a/arch/powerpc/include/uapi/asm/termbits.h
+++ b/arch/powerpc/include/uapi/asm/termbits.h
@@ -171,6 +171,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define ADDRB	004000000000		/* address bit */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
index ce5ad5d0f105..5eb1d547b5c4 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -201,6 +201,7 @@ struct ktermios {
 #define B3500000  0x00001012
 #define B4000000  0x00001013  */
 #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
+#define ADDRB	  0x20000000  /* address bit */
 #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 78baba55a8b5..d179b9b57a25 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	mgslpc_change_params(info, tty);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index 20d2b9ec1227..d66cc9683ebc 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -506,6 +506,8 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	struct ipoctal_channel *channel = tty->driver_data;
 	speed_t baud;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	cflag = tty->termios.c_cflag;
 
 	/* Disable and reset everything before change the setup */
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 414aa82abc39..f28075952f3e 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -867,6 +867,8 @@ static void sdio_uart_set_termios(struct tty_struct *tty,
 	if (sdio_uart_claim_func(port) != 0)
 		return;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	sdio_uart_change_speed(port, &tty->termios, old_termios);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index f8221a7acf62..056352618804 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1099,7 +1099,8 @@ static void _hso_serial_set_termios(struct tty_struct *tty)
 		~(CSIZE		/* no size */
 		| PARENB	/* disable parity bit */
 		| CBAUD		/* clear current baud rate */
-		| CBAUDEX);	/* clear current buad rate */
+		| CBAUDEX	/* clear current baud rate */
+		| ADDRB);	/* disable 9th (addr) bit */
 
 	tty->termios.c_cflag |= CS8;	/* character size 8 bits */
 
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 5c83f71c1d0e..253d2997a1d3 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1768,6 +1768,9 @@ tty3270_set_termios(struct tty_struct *tty, struct ktermios *old)
 	tp = tty->driver_data;
 	if (!tp)
 		return;
+
+	tty->termios.c_cflag &= ~ADDRB;
+
 	spin_lock_bh(&tp->view.lock);
 	if (L_ICANON(tty)) {
 		new = L_ECHO(tty) ? TF_INPUT: TF_INPUTN;
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index dc4ed0ff1ae2..83e73aefde0f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -487,6 +487,8 @@ static void gb_tty_set_termios(struct tty_struct *tty,
 	struct ktermios *termios = &tty->termios;
 	u8 newctrl = gb_tty->ctrlout;
 
+	termios->c_cflag &= ~ADDRB;
+
 	newline.rate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.format = termios->c_cflag & CSTOPB ?
 				GB_SERIAL_2_STOP_BITS : GB_SERIAL_1_STOP_BITS;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 533d02b38e02..3ca97007bd6e 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1175,7 +1175,11 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
-	unsigned int cflag = tty->termios.c_cflag;
+	unsigned int cflag;
+
+	tty->termios.c_cflag &= ~ADDRB;
+
+	cflag = tty->termios.c_cflag;
 
 	change_speed(tty, info, old_termios);
 
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index f3c72ab1476c..07cd88152d58 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -2050,6 +2050,7 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
 
 	ofsAddr = port->tableAddr;
 
+	termio->c_cflag &= ~ADDRB;
 	mode = termio->c_cflag & CSIZE;
 	if (mode == CS5)
 		mode = MX_CS5;
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 6ebd3e4ed859..79c542aca1c3 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -577,6 +577,7 @@ static void mxser_change_speed(struct tty_struct *tty, struct ktermios *old_term
 	struct mxser_port *info = tty->driver_data;
 	unsigned cflag, cval;
 
+	tty->termios.c_cflag &= ~ADDRB;
 	cflag = tty->termios.c_cflag;
 
 	if (mxser_set_baud(tty, tty_get_baud_rate(tty))) {
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 82a1770dd808..0f397e67eeb0 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1540,6 +1540,8 @@ static void uart_set_termios(struct tty_struct *tty,
 		goto out;
 	}
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	uart_change_speed(tty, state, old_termios);
 	/* reload cflag from termios; port driver may have overridden flags */
 	cflag = tty->termios.c_cflag;
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 9bc2a9265277..180f38f0f57a 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -714,6 +714,8 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
 	DBGINFO(("%s set_termios\n", tty->driver->name));
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	change_params(info);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index 63181925ec1a..934037d78868 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -319,6 +319,8 @@ unsigned char tty_get_frame_size(unsigned int cflag)
 		bits++;
 	if (cflag & PARENB)
 		bits++;
+	if (cflag & ADDRB)
+		bits++;
 
 	return bits;
 }
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9b9aea24d58c..fd246ec70da8 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1056,6 +1056,8 @@ static void acm_tty_set_termios(struct tty_struct *tty,
 	struct usb_cdc_line_coding newline;
 	int newctrl = acm->ctrlout;
 
+	termios->c_cflag &= ~ADDRB;
+
 	newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
 	newline.bParityType = termios->c_cflag & PARENB ?
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 24101bd7fcad..8d1d170eb7e6 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -525,10 +525,12 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 
 	dev_dbg(&port->dev, "%s\n", __func__);
 
-	if (port->serial->type->set_termios)
+	if (port->serial->type->set_termios) {
+		tty->termios.c_cflag &= ~ADDRB;
 		port->serial->type->set_termios(tty, port, old);
-	else
+	} else {
 		tty_termios_copy_hw(&tty->termios, old);
+	}
 }
 
 static int serial_break(struct tty_struct *tty, int break_state)
diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
index 2fbaf9ae89dd..e06eaa9cf8be 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -158,6 +158,7 @@ struct ktermios {
 #define  B3500000 0010016
 #define  B4000000 0010017
 #define CIBAUD	  002003600000	/* input baud rate */
+#define ADDRB	  004000000000	/* address bit */
 #define CMSPAR	  010000000000	/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000	/* flow control */
 
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index ebd78fdbd6e8..832e725f23ab 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -871,6 +871,8 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 	if (!dev || !dev->dlc || !dev->dlc->session)
 		return;
 
+	new->c_cflag &= ~ADDRB;
+
 	/* Handle turning off CRTSCTS */
 	if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
 		BT_DBG("Turning off CRTSCTS unsupported");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 12:24   ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

Add ADDRB to termbits to indicate 9th bit addressing mode. This change
is necessary for supporting devices with RS485 multipoint addressing
[*]. A later patch in the patch series adds support for Synopsys
Designware UART capable for 9th bit addressing mode. In this mode, 9th
bit is used to indicate an address (byte) within the communication
line. The 9th bit addressing mode is selected using ADDRB introduced by
an earlier patch.

[*] Technically, RS485 is just an electronic spec and does not itself
specify the 9th bit addressing mode but 9th bit seems at least
"semi-standard" way to do addressing with RS485.

Cc: linux-api@vger.kernel.org
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 arch/alpha/include/uapi/asm/termbits.h   | 1 +
 arch/mips/include/uapi/asm/termbits.h    | 1 +
 arch/parisc/include/uapi/asm/termbits.h  | 1 +
 arch/powerpc/include/uapi/asm/termbits.h | 1 +
 arch/sparc/include/uapi/asm/termbits.h   | 1 +
 drivers/char/pcmcia/synclink_cs.c        | 2 ++
 drivers/ipack/devices/ipoctal.c          | 2 ++
 drivers/mmc/core/sdio_uart.c             | 2 ++
 drivers/net/usb/hso.c                    | 3 ++-
 drivers/s390/char/tty3270.c              | 3 +++
 drivers/staging/greybus/uart.c           | 2 ++
 drivers/tty/amiserial.c                  | 6 +++++-
 drivers/tty/moxa.c                       | 1 +
 drivers/tty/mxser.c                      | 1 +
 drivers/tty/serial/serial_core.c         | 2 ++
 drivers/tty/synclink_gt.c                | 2 ++
 drivers/tty/tty_ioctl.c                  | 2 ++
 drivers/usb/class/cdc-acm.c              | 2 ++
 drivers/usb/serial/usb-serial.c          | 6 ++++--
 include/uapi/asm-generic/termbits.h      | 1 +
 net/bluetooth/rfcomm/tty.c               | 2 ++
 21 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
index 4575ba34a0ea..0c123e715486 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -180,6 +180,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define ADDRB	004000000000		/* address bit */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
index dfeffba729b7..4732d31b0e4e 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -182,6 +182,7 @@ struct ktermios {
 #define	 B3500000 0010016
 #define	 B4000000 0010017
 #define CIBAUD	  002003600000	/* input baud rate */
+#define ADDRB	  004000000000	/* address bit */
 #define CMSPAR	  010000000000	/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000	/* flow control */
 
diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
index 40e920f8d683..d6bbd10d92ba 100644
--- a/arch/parisc/include/uapi/asm/termbits.h
+++ b/arch/parisc/include/uapi/asm/termbits.h
@@ -159,6 +159,7 @@ struct ktermios {
 #define  B3500000 0010016
 #define  B4000000 0010017
 #define CIBAUD    002003600000		/* input baud rate */
+#define ADDRB	  004000000000		/* address bit */
 #define CMSPAR    010000000000          /* mark or space (stick) parity */
 #define CRTSCTS   020000000000          /* flow control */
 
diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
index ed18bc61f63d..c6a033732f39 100644
--- a/arch/powerpc/include/uapi/asm/termbits.h
+++ b/arch/powerpc/include/uapi/asm/termbits.h
@@ -171,6 +171,7 @@ struct ktermios {
 #define HUPCL	00040000
 
 #define CLOCAL	00100000
+#define ADDRB	004000000000		/* address bit */
 #define CMSPAR	  010000000000		/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000		/* flow control */
 
diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
index ce5ad5d0f105..5eb1d547b5c4 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -201,6 +201,7 @@ struct ktermios {
 #define B3500000  0x00001012
 #define B4000000  0x00001013  */
 #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
+#define ADDRB	  0x20000000  /* address bit */
 #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
 #define CRTSCTS	  0x80000000  /* flow control */
 
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 78baba55a8b5..d179b9b57a25 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
 		== RELEVANT_IFLAG(old_termios->c_iflag)))
 	  return;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	mgslpc_change_params(info, tty);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c
index 20d2b9ec1227..d66cc9683ebc 100644
--- a/drivers/ipack/devices/ipoctal.c
+++ b/drivers/ipack/devices/ipoctal.c
@@ -506,6 +506,8 @@ static void ipoctal_set_termios(struct tty_struct *tty,
 	struct ipoctal_channel *channel = tty->driver_data;
 	speed_t baud;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	cflag = tty->termios.c_cflag;
 
 	/* Disable and reset everything before change the setup */
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 414aa82abc39..f28075952f3e 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -867,6 +867,8 @@ static void sdio_uart_set_termios(struct tty_struct *tty,
 	if (sdio_uart_claim_func(port) != 0)
 		return;
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	sdio_uart_change_speed(port, &tty->termios, old_termios);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index f8221a7acf62..056352618804 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1099,7 +1099,8 @@ static void _hso_serial_set_termios(struct tty_struct *tty)
 		~(CSIZE		/* no size */
 		| PARENB	/* disable parity bit */
 		| CBAUD		/* clear current baud rate */
-		| CBAUDEX);	/* clear current buad rate */
+		| CBAUDEX	/* clear current baud rate */
+		| ADDRB);	/* disable 9th (addr) bit */
 
 	tty->termios.c_cflag |= CS8;	/* character size 8 bits */
 
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 5c83f71c1d0e..253d2997a1d3 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -1768,6 +1768,9 @@ tty3270_set_termios(struct tty_struct *tty, struct ktermios *old)
 	tp = tty->driver_data;
 	if (!tp)
 		return;
+
+	tty->termios.c_cflag &= ~ADDRB;
+
 	spin_lock_bh(&tp->view.lock);
 	if (L_ICANON(tty)) {
 		new = L_ECHO(tty) ? TF_INPUT: TF_INPUTN;
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index dc4ed0ff1ae2..83e73aefde0f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -487,6 +487,8 @@ static void gb_tty_set_termios(struct tty_struct *tty,
 	struct ktermios *termios = &tty->termios;
 	u8 newctrl = gb_tty->ctrlout;
 
+	termios->c_cflag &= ~ADDRB;
+
 	newline.rate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.format = termios->c_cflag & CSTOPB ?
 				GB_SERIAL_2_STOP_BITS : GB_SERIAL_1_STOP_BITS;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 533d02b38e02..3ca97007bd6e 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1175,7 +1175,11 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
 	struct serial_state *info = tty->driver_data;
 	unsigned long flags;
-	unsigned int cflag = tty->termios.c_cflag;
+	unsigned int cflag;
+
+	tty->termios.c_cflag &= ~ADDRB;
+
+	cflag = tty->termios.c_cflag;
 
 	change_speed(tty, info, old_termios);
 
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c
index f3c72ab1476c..07cd88152d58 100644
--- a/drivers/tty/moxa.c
+++ b/drivers/tty/moxa.c
@@ -2050,6 +2050,7 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
 
 	ofsAddr = port->tableAddr;
 
+	termio->c_cflag &= ~ADDRB;
 	mode = termio->c_cflag & CSIZE;
 	if (mode == CS5)
 		mode = MX_CS5;
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 6ebd3e4ed859..79c542aca1c3 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -577,6 +577,7 @@ static void mxser_change_speed(struct tty_struct *tty, struct ktermios *old_term
 	struct mxser_port *info = tty->driver_data;
 	unsigned cflag, cval;
 
+	tty->termios.c_cflag &= ~ADDRB;
 	cflag = tty->termios.c_cflag;
 
 	if (mxser_set_baud(tty, tty_get_baud_rate(tty))) {
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 82a1770dd808..0f397e67eeb0 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1540,6 +1540,8 @@ static void uart_set_termios(struct tty_struct *tty,
 		goto out;
 	}
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	uart_change_speed(tty, state, old_termios);
 	/* reload cflag from termios; port driver may have overridden flags */
 	cflag = tty->termios.c_cflag;
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 9bc2a9265277..180f38f0f57a 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -714,6 +714,8 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
 	DBGINFO(("%s set_termios\n", tty->driver->name));
 
+	tty->termios.c_cflag &= ~ADDRB;
+
 	change_params(info);
 
 	/* Handle transition to B0 status */
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c
index 63181925ec1a..934037d78868 100644
--- a/drivers/tty/tty_ioctl.c
+++ b/drivers/tty/tty_ioctl.c
@@ -319,6 +319,8 @@ unsigned char tty_get_frame_size(unsigned int cflag)
 		bits++;
 	if (cflag & PARENB)
 		bits++;
+	if (cflag & ADDRB)
+		bits++;
 
 	return bits;
 }
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9b9aea24d58c..fd246ec70da8 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1056,6 +1056,8 @@ static void acm_tty_set_termios(struct tty_struct *tty,
 	struct usb_cdc_line_coding newline;
 	int newctrl = acm->ctrlout;
 
+	termios->c_cflag &= ~ADDRB;
+
 	newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty));
 	newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0;
 	newline.bParityType = termios->c_cflag & PARENB ?
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 24101bd7fcad..8d1d170eb7e6 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -525,10 +525,12 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 
 	dev_dbg(&port->dev, "%s\n", __func__);
 
-	if (port->serial->type->set_termios)
+	if (port->serial->type->set_termios) {
+		tty->termios.c_cflag &= ~ADDRB;
 		port->serial->type->set_termios(tty, port, old);
-	else
+	} else {
 		tty_termios_copy_hw(&tty->termios, old);
+	}
 }
 
 static int serial_break(struct tty_struct *tty, int break_state)
diff --git a/include/uapi/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
index 2fbaf9ae89dd..e06eaa9cf8be 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -158,6 +158,7 @@ struct ktermios {
 #define  B3500000 0010016
 #define  B4000000 0010017
 #define CIBAUD	  002003600000	/* input baud rate */
+#define ADDRB	  004000000000	/* address bit */
 #define CMSPAR	  010000000000	/* mark or space (stick) parity */
 #define CRTSCTS	  020000000000	/* flow control */
 
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index ebd78fdbd6e8..832e725f23ab 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -871,6 +871,8 @@ static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 	if (!dev || !dev->dlc || !dev->dlc->session)
 		return;
 
+	new->c_cflag &= ~ADDRB;
+
 	/* Handle turning off CRTSCTS */
 	if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
 		BT_DBG("Turning off CRTSCTS unsupported");
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 06/10] serial: General support for multipoint addresses
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support Ilpo Järvinen
@ 2022-04-26 12:24   ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 03/10] dt_bindings: rs485: Add receiver enable polarity Ilpo Järvinen
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, Yoshinori Sato, Rich Felker, linux-sh,
	David S. Miller, sparclinux, Chris Zankel, Max Filippov,
	linux-xtensa, Arnd Bergmann, linux-arch, linux-doc

Add generic support for serial multipoint addressing. Two new ioctls
are added. TIOCSADDR is used to indicate the destination/receive
address. TIOCGADDR returns the current address in use. The driver
should implement set_addr and get_addr to support addressing mode.

Adjust ADDRB clearing to happen only if driver does not provide
set_addr (=the driver doesn't support address mode).

This change is necessary for supporting devices with RS485 multipoint
addressing [*]. A following patch in the patch series adds support for
Synopsys Designware UART capable for 9th bit addressing mode. In this
mode, 9th bit is used to indicate an address (byte) within the
communication line. The 9th bit addressing mode is selected using ADDRB
introduced by the previous patch.

Transmit addresses / receiver filter are specified by setting the flags
SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
address, in the 9bit addressing mode it is sent out immediately with
the 9th bit set to 1. After that, the subsequent normal data bytes are
sent with 9th bit as 0 and they are intended to the device with the
given address. It is up to receiver to enforce the filter using
SER_ADDR_RECV. When userspace has supplied the receive address, the
driver is expected to handle the matching of the address and only data
with that address is forwarded to the user. Both SER_ADDR_DEST and
SER_ADDR_RECV can be given at the same time in a single call if the
addresses are the same.

The user can clear the receive filter with SER_ADDR_RECV_CLEAR.

[*] Technically, RS485 is just an electronic spec and does not itself
specify the 9th bit addressing mode but 9th bit seems at least
"semi-standard" way to do addressing with RS485.

Cc: linux-api@vger.kernel.org
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: linux-xtensa@linux-xtensa.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 .../driver-api/serial/serial-rs485.rst        | 23 ++++++-
 arch/alpha/include/uapi/asm/ioctls.h          |  3 +
 arch/mips/include/uapi/asm/ioctls.h           |  3 +
 arch/parisc/include/uapi/asm/ioctls.h         |  3 +
 arch/powerpc/include/uapi/asm/ioctls.h        |  3 +
 arch/sh/include/uapi/asm/ioctls.h             |  3 +
 arch/sparc/include/uapi/asm/ioctls.h          |  3 +
 arch/xtensa/include/uapi/asm/ioctls.h         |  3 +
 drivers/tty/serial/8250/8250_core.c           |  2 +
 drivers/tty/serial/serial_core.c              | 62 ++++++++++++++++++-
 drivers/tty/tty_io.c                          |  2 +
 include/linux/serial_core.h                   |  6 ++
 include/uapi/asm-generic/ioctls.h             |  3 +
 include/uapi/linux/serial.h                   |  8 +++
 14 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
index 6bc824f948f9..2f45f007fa5b 100644
--- a/Documentation/driver-api/serial/serial-rs485.rst
+++ b/Documentation/driver-api/serial/serial-rs485.rst
@@ -95,7 +95,28 @@ RS485 Serial Communications
 		/* Error handling. See errno. */
 	}
 
-5. References
+5. Multipoint Addressing
+========================
+
+   The Linux kernel provides serial_addr structure to handle addressing within
+   multipoint serial communications line such as RS485. 9th bit addressiong mode
+   is enabled by adding ADDRB flag in termios c_cflag.
+
+   Serial core calls device specific set/get_addr in response to TIOCSADDR and
+   TIOCGADDR ioctls with a pointer to serial_addr. Destination and receive
+   address can be specified using serial_addr flags field. Receive address may
+   also be cleared using flags. Once an address is set, the communication
+   can occur only with the particular device and other peers are filtered out.
+   It is left up to the receiver side to enforce the filtering.
+
+   Address flags:
+	- SER_ADDR_RECV: Receive (filter) address.
+	- SER_ADDR_RECV_CLEAR: Clear receive filter (only for TIOCSADDR).
+	- SER_ADDR_DEST: Destination address.
+
+   Note: not all devices supporting RS485 support multipoint addressing.
+
+6. References
 =============
 
  [1]	include/uapi/linux/serial.h
diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
index 971311605288..500cab3e1d6b 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -125,4 +125,7 @@
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* _ASM_ALPHA_IOCTLS_H */
diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
index 16aa8a766aec..3859dc46857e 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -96,6 +96,9 @@
 #define TIOCGISO7816	_IOR('T', 0x42, struct serial_iso7816)
 #define TIOCSISO7816	_IOWR('T', 0x43, struct serial_iso7816)
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY	0x5480		/* become controlling tty */
 #define TIOCGSOFTCAR	0x5481
diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
index 82d1148c6379..62337743db64 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -86,6 +86,9 @@
 #define TIOCSTOP	0x5462
 #define TIOCSLTC	0x5462
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
index 2c145da3b774..84fd69ac366a 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -120,4 +120,7 @@
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif	/* _ASM_POWERPC_IOCTLS_H */
diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
index 11866d4f60e1..f82966b7dba2 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -113,4 +113,7 @@
 #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* __ASM_SH_IOCTLS_H */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
index 7fd2f5873c9e..e44624c67c79 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -125,6 +125,9 @@
 #define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
 #define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Kernel definitions */
 
 /* Used for packet mode */
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
index 6d4a87296c95..759ca9377f2a 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -127,4 +127,7 @@
 #define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* _XTENSA_IOCTLS_H */
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 01d30f6ed8fb..f67bc3b76f65 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1008,6 +1008,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
 		uart->port.rs485	= up->port.rs485;
 		uart->rs485_start_tx	= up->rs485_start_tx;
 		uart->rs485_stop_tx	= up->rs485_stop_tx;
+		uart->port.set_addr	= up->port.set_addr;
+		uart->port.get_addr	= up->port.get_addr;
 		uart->dma		= up->dma;
 
 		/* Take tx_loadsz from fifosize if it wasn't set separately */
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0f397e67eeb0..5762987bf176 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1397,6 +1397,56 @@ static int uart_set_iso7816_config(struct uart_port *port,
 	return 0;
 }
 
+static int uart_set_addr(struct uart_port *port,
+			 struct serial_addr __user *serial_addr_user)
+{
+	struct serial_addr addr;
+	unsigned long flags;
+	int ret;
+
+	if (!port->set_addr)
+		return -ENOTTY;
+
+	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = port->set_addr(port, &addr);
+	spin_unlock_irqrestore(&port->lock, flags);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int uart_get_addr(struct uart_port *port,
+			 struct serial_addr __user *serial_addr_user)
+{
+	struct serial_addr addr;
+	unsigned long flags;
+	int ret;
+
+	if (!port->get_addr)
+		return -ENOTTY;
+
+	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = port->get_addr(port, &addr);
+	spin_unlock_irqrestore(&port->lock, flags);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
+		return -EFAULT;
+
+	return 0;
+}
+
 /*
  * Called via sys_ioctl.  We can use spin_lock_irq() here.
  */
@@ -1474,6 +1524,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
 	case TIOCGISO7816:
 		ret = uart_get_iso7816_config(state->uart_port, uarg);
 		break;
+
+	case TIOCSADDR:
+		ret = uart_set_addr(uport, uarg);
+		break;
+
+	case TIOCGADDR:
+		ret = uart_get_addr(uport, uarg);
+		break;
+
 	default:
 		if (uport->ops->ioctl)
 			ret = uport->ops->ioctl(uport, cmd, arg);
@@ -1540,7 +1599,8 @@ static void uart_set_termios(struct tty_struct *tty,
 		goto out;
 	}
 
-	tty->termios.c_cflag &= ~ADDRB;
+	if (!uport->set_addr)
+		tty->termios.c_cflag &= ~ADDRB;
 
 	uart_change_speed(tty, state, old_termios);
 	/* reload cflag from termios; port driver may have overridden flags */
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 8fec1d8648f5..ef22b95e9c79 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2885,6 +2885,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
 	case TIOCSERGETLSR:
 	case TIOCGRS485:
 	case TIOCSRS485:
+	case TIOCSADDR:
+	case TIOCGADDR:
 #ifdef TIOCGETP
 	case TIOCGETP:
 	case TIOCSETP:
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index cbd5070bc87f..2dd4c4d01c59 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -135,6 +135,12 @@ struct uart_port {
 						struct serial_rs485 *rs485);
 	int			(*iso7816_config)(struct uart_port *,
 						  struct serial_iso7816 *iso7816);
+
+	int			(*set_addr)(struct uart_port *p,
+					    struct serial_addr *addr);
+	int			(*get_addr)(struct uart_port *p,
+					    struct serial_addr *addr);
+
 	unsigned int		irq;			/* irq number */
 	unsigned long		irqflags;		/* irq flags  */
 	unsigned int		uartclk;		/* base uart clock */
diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
index cdc9f4ca8c27..689743366091 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -106,6 +106,9 @@
 # define FIOQSIZE	0x5460
 #endif
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index fa6b16e5fdd8..8cb785ea7087 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -149,4 +149,12 @@ struct serial_iso7816 {
 	__u32	reserved[5];
 };
 
+struct serial_addr {
+	__u32	flags;
+#define SER_ADDR_RECV			(1 << 0)
+#define SER_ADDR_RECV_CLEAR		(1 << 1)
+#define SER_ADDR_DEST			(1 << 2)
+	__u32	addr;
+};
+
 #endif /* _UAPI_LINUX_SERIAL_H */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 12:24   ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Heikki Krogerus, heiko, linux-sh, James E.J. Bottomley,
	Max Filippov, Rich Felker, Paul Mackerras, sparclinux,
	Jiri Slaby, linux-arch, Yoshinori Sato, Helge Deller, linux-doc,
	Uwe Kleine-König, Ilpo Järvinen, Matt Turner,
	linux-xtensa, Arnd Bergmann, Johan Hovold, Vicente Bergas,
	Ivan Kokshaysky, Andy Shevchenko, Chris Zankel,
	Thomas Bogendoerfer, linux-parisc, linux-api, linux-mips,
	David S. Miller, Lukas Wunner, linux-alpha, linuxppc-dev,
	giulio.benetti

Add generic support for serial multipoint addressing. Two new ioctls
are added. TIOCSADDR is used to indicate the destination/receive
address. TIOCGADDR returns the current address in use. The driver
should implement set_addr and get_addr to support addressing mode.

Adjust ADDRB clearing to happen only if driver does not provide
set_addr (=the driver doesn't support address mode).

This change is necessary for supporting devices with RS485 multipoint
addressing [*]. A following patch in the patch series adds support for
Synopsys Designware UART capable for 9th bit addressing mode. In this
mode, 9th bit is used to indicate an address (byte) within the
communication line. The 9th bit addressing mode is selected using ADDRB
introduced by the previous patch.

Transmit addresses / receiver filter are specified by setting the flags
SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
address, in the 9bit addressing mode it is sent out immediately with
the 9th bit set to 1. After that, the subsequent normal data bytes are
sent with 9th bit as 0 and they are intended to the device with the
given address. It is up to receiver to enforce the filter using
SER_ADDR_RECV. When userspace has supplied the receive address, the
driver is expected to handle the matching of the address and only data
with that address is forwarded to the user. Both SER_ADDR_DEST and
SER_ADDR_RECV can be given at the same time in a single call if the
addresses are the same.

The user can clear the receive filter with SER_ADDR_RECV_CLEAR.

[*] Technically, RS485 is just an electronic spec and does not itself
specify the 9th bit addressing mode but 9th bit seems at least
"semi-standard" way to do addressing with RS485.

Cc: linux-api@vger.kernel.org
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: linux-xtensa@linux-xtensa.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 .../driver-api/serial/serial-rs485.rst        | 23 ++++++-
 arch/alpha/include/uapi/asm/ioctls.h          |  3 +
 arch/mips/include/uapi/asm/ioctls.h           |  3 +
 arch/parisc/include/uapi/asm/ioctls.h         |  3 +
 arch/powerpc/include/uapi/asm/ioctls.h        |  3 +
 arch/sh/include/uapi/asm/ioctls.h             |  3 +
 arch/sparc/include/uapi/asm/ioctls.h          |  3 +
 arch/xtensa/include/uapi/asm/ioctls.h         |  3 +
 drivers/tty/serial/8250/8250_core.c           |  2 +
 drivers/tty/serial/serial_core.c              | 62 ++++++++++++++++++-
 drivers/tty/tty_io.c                          |  2 +
 include/linux/serial_core.h                   |  6 ++
 include/uapi/asm-generic/ioctls.h             |  3 +
 include/uapi/linux/serial.h                   |  8 +++
 14 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
index 6bc824f948f9..2f45f007fa5b 100644
--- a/Documentation/driver-api/serial/serial-rs485.rst
+++ b/Documentation/driver-api/serial/serial-rs485.rst
@@ -95,7 +95,28 @@ RS485 Serial Communications
 		/* Error handling. See errno. */
 	}
 
-5. References
+5. Multipoint Addressing
+========================
+
+   The Linux kernel provides serial_addr structure to handle addressing within
+   multipoint serial communications line such as RS485. 9th bit addressiong mode
+   is enabled by adding ADDRB flag in termios c_cflag.
+
+   Serial core calls device specific set/get_addr in response to TIOCSADDR and
+   TIOCGADDR ioctls with a pointer to serial_addr. Destination and receive
+   address can be specified using serial_addr flags field. Receive address may
+   also be cleared using flags. Once an address is set, the communication
+   can occur only with the particular device and other peers are filtered out.
+   It is left up to the receiver side to enforce the filtering.
+
+   Address flags:
+	- SER_ADDR_RECV: Receive (filter) address.
+	- SER_ADDR_RECV_CLEAR: Clear receive filter (only for TIOCSADDR).
+	- SER_ADDR_DEST: Destination address.
+
+   Note: not all devices supporting RS485 support multipoint addressing.
+
+6. References
 =============
 
  [1]	include/uapi/linux/serial.h
diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
index 971311605288..500cab3e1d6b 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -125,4 +125,7 @@
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* _ASM_ALPHA_IOCTLS_H */
diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
index 16aa8a766aec..3859dc46857e 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -96,6 +96,9 @@
 #define TIOCGISO7816	_IOR('T', 0x42, struct serial_iso7816)
 #define TIOCSISO7816	_IOWR('T', 0x43, struct serial_iso7816)
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY	0x5480		/* become controlling tty */
 #define TIOCGSOFTCAR	0x5481
diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
index 82d1148c6379..62337743db64 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -86,6 +86,9 @@
 #define TIOCSTOP	0x5462
 #define TIOCSLTC	0x5462
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
index 2c145da3b774..84fd69ac366a 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -120,4 +120,7 @@
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif	/* _ASM_POWERPC_IOCTLS_H */
diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
index 11866d4f60e1..f82966b7dba2 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -113,4 +113,7 @@
 #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* __ASM_SH_IOCTLS_H */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
index 7fd2f5873c9e..e44624c67c79 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -125,6 +125,9 @@
 #define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
 #define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Kernel definitions */
 
 /* Used for packet mode */
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
index 6d4a87296c95..759ca9377f2a 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -127,4 +127,7 @@
 #define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* _XTENSA_IOCTLS_H */
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 01d30f6ed8fb..f67bc3b76f65 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1008,6 +1008,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
 		uart->port.rs485	= up->port.rs485;
 		uart->rs485_start_tx	= up->rs485_start_tx;
 		uart->rs485_stop_tx	= up->rs485_stop_tx;
+		uart->port.set_addr	= up->port.set_addr;
+		uart->port.get_addr	= up->port.get_addr;
 		uart->dma		= up->dma;
 
 		/* Take tx_loadsz from fifosize if it wasn't set separately */
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0f397e67eeb0..5762987bf176 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1397,6 +1397,56 @@ static int uart_set_iso7816_config(struct uart_port *port,
 	return 0;
 }
 
+static int uart_set_addr(struct uart_port *port,
+			 struct serial_addr __user *serial_addr_user)
+{
+	struct serial_addr addr;
+	unsigned long flags;
+	int ret;
+
+	if (!port->set_addr)
+		return -ENOTTY;
+
+	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = port->set_addr(port, &addr);
+	spin_unlock_irqrestore(&port->lock, flags);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int uart_get_addr(struct uart_port *port,
+			 struct serial_addr __user *serial_addr_user)
+{
+	struct serial_addr addr;
+	unsigned long flags;
+	int ret;
+
+	if (!port->get_addr)
+		return -ENOTTY;
+
+	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = port->get_addr(port, &addr);
+	spin_unlock_irqrestore(&port->lock, flags);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
+		return -EFAULT;
+
+	return 0;
+}
+
 /*
  * Called via sys_ioctl.  We can use spin_lock_irq() here.
  */
@@ -1474,6 +1524,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
 	case TIOCGISO7816:
 		ret = uart_get_iso7816_config(state->uart_port, uarg);
 		break;
+
+	case TIOCSADDR:
+		ret = uart_set_addr(uport, uarg);
+		break;
+
+	case TIOCGADDR:
+		ret = uart_get_addr(uport, uarg);
+		break;
+
 	default:
 		if (uport->ops->ioctl)
 			ret = uport->ops->ioctl(uport, cmd, arg);
@@ -1540,7 +1599,8 @@ static void uart_set_termios(struct tty_struct *tty,
 		goto out;
 	}
 
-	tty->termios.c_cflag &= ~ADDRB;
+	if (!uport->set_addr)
+		tty->termios.c_cflag &= ~ADDRB;
 
 	uart_change_speed(tty, state, old_termios);
 	/* reload cflag from termios; port driver may have overridden flags */
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 8fec1d8648f5..ef22b95e9c79 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2885,6 +2885,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
 	case TIOCSERGETLSR:
 	case TIOCGRS485:
 	case TIOCSRS485:
+	case TIOCSADDR:
+	case TIOCGADDR:
 #ifdef TIOCGETP
 	case TIOCGETP:
 	case TIOCSETP:
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index cbd5070bc87f..2dd4c4d01c59 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -135,6 +135,12 @@ struct uart_port {
 						struct serial_rs485 *rs485);
 	int			(*iso7816_config)(struct uart_port *,
 						  struct serial_iso7816 *iso7816);
+
+	int			(*set_addr)(struct uart_port *p,
+					    struct serial_addr *addr);
+	int			(*get_addr)(struct uart_port *p,
+					    struct serial_addr *addr);
+
 	unsigned int		irq;			/* irq number */
 	unsigned long		irqflags;		/* irq flags  */
 	unsigned int		uartclk;		/* base uart clock */
diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
index cdc9f4ca8c27..689743366091 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -106,6 +106,9 @@
 # define FIOQSIZE	0x5460
 #endif
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index fa6b16e5fdd8..8cb785ea7087 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -149,4 +149,12 @@ struct serial_iso7816 {
 	__u32	reserved[5];
 };
 
+struct serial_addr {
+	__u32	flags;
+#define SER_ADDR_RECV			(1 << 0)
+#define SER_ADDR_RECV_CLEAR		(1 << 1)
+#define SER_ADDR_DEST			(1 << 2)
+	__u32	addr;
+};
+
 #endif /* _UAPI_LINUX_SERIAL_H */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 12:24   ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

Add generic support for serial multipoint addressing. Two new ioctls
are added. TIOCSADDR is used to indicate the destination/receive
address. TIOCGADDR returns the current address in use. The driver
should implement set_addr and get_addr to support addressing mode.

Adjust ADDRB clearing to happen only if driver does not provide
set_addr (=the driver doesn't support address mode).

This change is necessary for supporting devices with RS485 multipoint
addressing [*]. A following patch in the patch series adds support for
Synopsys Designware UART capable for 9th bit addressing mode. In this
mode, 9th bit is used to indicate an address (byte) within the
communication line. The 9th bit addressing mode is selected using ADDRB
introduced by the previous patch.

Transmit addresses / receiver filter are specified by setting the flags
SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
address, in the 9bit addressing mode it is sent out immediately with
the 9th bit set to 1. After that, the subsequent normal data bytes are
sent with 9th bit as 0 and they are intended to the device with the
given address. It is up to receiver to enforce the filter using
SER_ADDR_RECV. When userspace has supplied the receive address, the
driver is expected to handle the matching of the address and only data
with that address is forwarded to the user. Both SER_ADDR_DEST and
SER_ADDR_RECV can be given at the same time in a single call if the
addresses are the same.

The user can clear the receive filter with SER_ADDR_RECV_CLEAR.

[*] Technically, RS485 is just an electronic spec and does not itself
specify the 9th bit addressing mode but 9th bit seems at least
"semi-standard" way to do addressing with RS485.

Cc: linux-api@vger.kernel.org
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: linux-sh@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: sparclinux@vger.kernel.org
Cc: Chris Zankel <chris@zankel.net>
Cc: Max Filippov <jcmvbkbc@gmail.com>
Cc: linux-xtensa@linux-xtensa.org
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-arch@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 .../driver-api/serial/serial-rs485.rst        | 23 ++++++-
 arch/alpha/include/uapi/asm/ioctls.h          |  3 +
 arch/mips/include/uapi/asm/ioctls.h           |  3 +
 arch/parisc/include/uapi/asm/ioctls.h         |  3 +
 arch/powerpc/include/uapi/asm/ioctls.h        |  3 +
 arch/sh/include/uapi/asm/ioctls.h             |  3 +
 arch/sparc/include/uapi/asm/ioctls.h          |  3 +
 arch/xtensa/include/uapi/asm/ioctls.h         |  3 +
 drivers/tty/serial/8250/8250_core.c           |  2 +
 drivers/tty/serial/serial_core.c              | 62 ++++++++++++++++++-
 drivers/tty/tty_io.c                          |  2 +
 include/linux/serial_core.h                   |  6 ++
 include/uapi/asm-generic/ioctls.h             |  3 +
 include/uapi/linux/serial.h                   |  8 +++
 14 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
index 6bc824f948f9..2f45f007fa5b 100644
--- a/Documentation/driver-api/serial/serial-rs485.rst
+++ b/Documentation/driver-api/serial/serial-rs485.rst
@@ -95,7 +95,28 @@ RS485 Serial Communications
 		/* Error handling. See errno. */
 	}
 
-5. References
+5. Multipoint Addressing
+========================
+
+   The Linux kernel provides serial_addr structure to handle addressing within
+   multipoint serial communications line such as RS485. 9th bit addressiong mode
+   is enabled by adding ADDRB flag in termios c_cflag.
+
+   Serial core calls device specific set/get_addr in response to TIOCSADDR and
+   TIOCGADDR ioctls with a pointer to serial_addr. Destination and receive
+   address can be specified using serial_addr flags field. Receive address may
+   also be cleared using flags. Once an address is set, the communication
+   can occur only with the particular device and other peers are filtered out.
+   It is left up to the receiver side to enforce the filtering.
+
+   Address flags:
+	- SER_ADDR_RECV: Receive (filter) address.
+	- SER_ADDR_RECV_CLEAR: Clear receive filter (only for TIOCSADDR).
+	- SER_ADDR_DEST: Destination address.
+
+   Note: not all devices supporting RS485 support multipoint addressing.
+
+6. References
 =============
 
  [1]	include/uapi/linux/serial.h
diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
index 971311605288..500cab3e1d6b 100644
--- a/arch/alpha/include/uapi/asm/ioctls.h
+++ b/arch/alpha/include/uapi/asm/ioctls.h
@@ -125,4 +125,7 @@
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* _ASM_ALPHA_IOCTLS_H */
diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
index 16aa8a766aec..3859dc46857e 100644
--- a/arch/mips/include/uapi/asm/ioctls.h
+++ b/arch/mips/include/uapi/asm/ioctls.h
@@ -96,6 +96,9 @@
 #define TIOCGISO7816	_IOR('T', 0x42, struct serial_iso7816)
 #define TIOCSISO7816	_IOWR('T', 0x43, struct serial_iso7816)
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* I hope the range from 0x5480 on is free ... */
 #define TIOCSCTTY	0x5480		/* become controlling tty */
 #define TIOCGSOFTCAR	0x5481
diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
index 82d1148c6379..62337743db64 100644
--- a/arch/parisc/include/uapi/asm/ioctls.h
+++ b/arch/parisc/include/uapi/asm/ioctls.h
@@ -86,6 +86,9 @@
 #define TIOCSTOP	0x5462
 #define TIOCSLTC	0x5462
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
index 2c145da3b774..84fd69ac366a 100644
--- a/arch/powerpc/include/uapi/asm/ioctls.h
+++ b/arch/powerpc/include/uapi/asm/ioctls.h
@@ -120,4 +120,7 @@
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif	/* _ASM_POWERPC_IOCTLS_H */
diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
index 11866d4f60e1..f82966b7dba2 100644
--- a/arch/sh/include/uapi/asm/ioctls.h
+++ b/arch/sh/include/uapi/asm/ioctls.h
@@ -113,4 +113,7 @@
 #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* __ASM_SH_IOCTLS_H */
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
index 7fd2f5873c9e..e44624c67c79 100644
--- a/arch/sparc/include/uapi/asm/ioctls.h
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -125,6 +125,9 @@
 #define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
 #define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Kernel definitions */
 
 /* Used for packet mode */
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
index 6d4a87296c95..759ca9377f2a 100644
--- a/arch/xtensa/include/uapi/asm/ioctls.h
+++ b/arch/xtensa/include/uapi/asm/ioctls.h
@@ -127,4 +127,7 @@
 #define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 #endif /* _XTENSA_IOCTLS_H */
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 01d30f6ed8fb..f67bc3b76f65 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -1008,6 +1008,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
 		uart->port.rs485	= up->port.rs485;
 		uart->rs485_start_tx	= up->rs485_start_tx;
 		uart->rs485_stop_tx	= up->rs485_stop_tx;
+		uart->port.set_addr	= up->port.set_addr;
+		uart->port.get_addr	= up->port.get_addr;
 		uart->dma		= up->dma;
 
 		/* Take tx_loadsz from fifosize if it wasn't set separately */
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 0f397e67eeb0..5762987bf176 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -1397,6 +1397,56 @@ static int uart_set_iso7816_config(struct uart_port *port,
 	return 0;
 }
 
+static int uart_set_addr(struct uart_port *port,
+			 struct serial_addr __user *serial_addr_user)
+{
+	struct serial_addr addr;
+	unsigned long flags;
+	int ret;
+
+	if (!port->set_addr)
+		return -ENOTTY;
+
+	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = port->set_addr(port, &addr);
+	spin_unlock_irqrestore(&port->lock, flags);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int uart_get_addr(struct uart_port *port,
+			 struct serial_addr __user *serial_addr_user)
+{
+	struct serial_addr addr;
+	unsigned long flags;
+	int ret;
+
+	if (!port->get_addr)
+		return -ENOTTY;
+
+	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
+		return -EFAULT;
+
+	spin_lock_irqsave(&port->lock, flags);
+	ret = port->get_addr(port, &addr);
+	spin_unlock_irqrestore(&port->lock, flags);
+	if (ret)
+		return ret;
+
+	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
+		return -EFAULT;
+
+	return 0;
+}
+
 /*
  * Called via sys_ioctl.  We can use spin_lock_irq() here.
  */
@@ -1474,6 +1524,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
 	case TIOCGISO7816:
 		ret = uart_get_iso7816_config(state->uart_port, uarg);
 		break;
+
+	case TIOCSADDR:
+		ret = uart_set_addr(uport, uarg);
+		break;
+
+	case TIOCGADDR:
+		ret = uart_get_addr(uport, uarg);
+		break;
+
 	default:
 		if (uport->ops->ioctl)
 			ret = uport->ops->ioctl(uport, cmd, arg);
@@ -1540,7 +1599,8 @@ static void uart_set_termios(struct tty_struct *tty,
 		goto out;
 	}
 
-	tty->termios.c_cflag &= ~ADDRB;
+	if (!uport->set_addr)
+		tty->termios.c_cflag &= ~ADDRB;
 
 	uart_change_speed(tty, state, old_termios);
 	/* reload cflag from termios; port driver may have overridden flags */
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 8fec1d8648f5..ef22b95e9c79 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -2885,6 +2885,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
 	case TIOCSERGETLSR:
 	case TIOCGRS485:
 	case TIOCSRS485:
+	case TIOCSADDR:
+	case TIOCGADDR:
 #ifdef TIOCGETP
 	case TIOCGETP:
 	case TIOCSETP:
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index cbd5070bc87f..2dd4c4d01c59 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -135,6 +135,12 @@ struct uart_port {
 						struct serial_rs485 *rs485);
 	int			(*iso7816_config)(struct uart_port *,
 						  struct serial_iso7816 *iso7816);
+
+	int			(*set_addr)(struct uart_port *p,
+					    struct serial_addr *addr);
+	int			(*get_addr)(struct uart_port *p,
+					    struct serial_addr *addr);
+
 	unsigned int		irq;			/* irq number */
 	unsigned long		irqflags;		/* irq flags  */
 	unsigned int		uartclk;		/* base uart clock */
diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
index cdc9f4ca8c27..689743366091 100644
--- a/include/uapi/asm-generic/ioctls.h
+++ b/include/uapi/asm-generic/ioctls.h
@@ -106,6 +106,9 @@
 # define FIOQSIZE	0x5460
 #endif
 
+#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
+#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index fa6b16e5fdd8..8cb785ea7087 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -149,4 +149,12 @@ struct serial_iso7816 {
 	__u32	reserved[5];
 };
 
+struct serial_addr {
+	__u32	flags;
+#define SER_ADDR_RECV			(1 << 0)
+#define SER_ADDR_RECV_CLEAR		(1 << 1)
+#define SER_ADDR_DEST			(1 << 2)
+	__u32	addr;
+};
+
 #endif /* _UAPI_LINUX_SERIAL_H */
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 07/10] serial: 8250: make saved LSR larger
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
                   ` (5 preceding siblings ...)
  2022-04-26 12:24   ` Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 08/10] serial: 8250: create lsr_save_mask Ilpo Järvinen
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen

DW flags address received as BIT(8) in LSR. In order to not lose that
on read, enlarge lsr_saved_flags and adjust related call chains which
passed chars previously.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/tty/serial/8250/8250_port.c | 8 ++++----
 include/linux/serial_8250.h         | 6 +++---
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index b8d05a7dfcf9..aa76027b8acc 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1592,7 +1592,7 @@ static inline void __start_tx(struct uart_port *port)
 
 	if (serial8250_set_THRI(up)) {
 		if (up->bugs & UART_BUG_TXEN) {
-			unsigned char lsr;
+			unsigned int lsr;
 
 			lsr = serial_in(up, UART_LSR);
 			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
@@ -1748,7 +1748,7 @@ static void serial8250_enable_ms(struct uart_port *port)
 	serial8250_rpm_put(up);
 }
 
-void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr)
+void serial8250_read_char(struct uart_8250_port *up, unsigned int lsr)
 {
 	struct uart_port *port = &up->port;
 	unsigned char ch;
@@ -1815,7 +1815,7 @@ EXPORT_SYMBOL_GPL(serial8250_read_char);
  * value, and returns the remaining LSR bits not handled
  * by this Rx routine.
  */
-unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
+unsigned int serial8250_rx_chars(struct uart_8250_port *up, unsigned int lsr)
 {
 	struct uart_port *port = &up->port;
 	int max_count = 256;
@@ -1935,7 +1935,7 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
  */
 int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 {
-	unsigned char status;
+	unsigned int status;
 	struct uart_8250_port *up = up_to_u8250p(port);
 	bool skip_rx = false;
 	unsigned long flags;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index ff84a3ed10ea..921df4c60062 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -119,7 +119,7 @@ struct uart_8250_port {
 	 * be immediately processed.
 	 */
 #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
-	unsigned char		lsr_saved_flags;
+	u16			lsr_saved_flags;
 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
 	unsigned char		msr_saved_flags;
 
@@ -170,8 +170,8 @@ extern void serial8250_do_set_divisor(struct uart_port *port, unsigned int baud,
 				      unsigned int quot_frac);
 extern int fsl8250_handle_irq(struct uart_port *port);
 int serial8250_handle_irq(struct uart_port *port, unsigned int iir);
-unsigned char serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr);
-void serial8250_read_char(struct uart_8250_port *up, unsigned char lsr);
+unsigned int serial8250_rx_chars(struct uart_8250_port *up, unsigned int lsr);
+void serial8250_read_char(struct uart_8250_port *up, unsigned int lsr);
 void serial8250_tx_chars(struct uart_8250_port *up);
 unsigned int serial8250_modem_status(struct uart_8250_port *up);
 void serial8250_init_port(struct uart_8250_port *up);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 08/10] serial: 8250: create lsr_save_mask
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
                   ` (6 preceding siblings ...)
  2022-04-26 12:24 ` [PATCH v5 07/10] serial: 8250: make saved LSR larger Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 09/10] serial: 8250_lpss: Use 32-bit reads Ilpo Järvinen
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen

Allow drivers to alter LSR save mask.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/tty/serial/8250/8250_core.c | 4 +++-
 drivers/tty/serial/8250/8250_port.c | 6 +++---
 include/linux/serial_8250.h         | 1 +
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index f67bc3b76f65..7cb1267559d4 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -278,7 +278,7 @@ static void serial8250_backup_timeout(struct timer_list *t)
 	 * ia64 and parisc boxes.
 	 */
 	lsr = serial_in(up, UART_LSR);
-	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+	up->lsr_saved_flags |= lsr & up->lsr_save_mask;
 	if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
 	    (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
 	    (lsr & UART_LSR_THRE)) {
@@ -1097,6 +1097,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
 			ret = 0;
 		}
 
+		uart->lsr_save_mask = up->lsr_save_mask ?: LSR_SAVE_FLAGS;
+
 		/* Initialise interrupt backoff work if required */
 		if (up->overrun_backoff_time_ms > 0) {
 			uart->overrun_backoff_time_ms =
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index aa76027b8acc..9505d9d5b45c 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1595,7 +1595,7 @@ static inline void __start_tx(struct uart_port *port)
 			unsigned int lsr;
 
 			lsr = serial_in(up, UART_LSR);
-			up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+			up->lsr_saved_flags |= lsr & up->lsr_save_mask;
 			if (lsr & UART_LSR_THRE)
 				serial8250_tx_chars(up);
 		}
@@ -2027,7 +2027,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
 
 	spin_lock_irqsave(&port->lock, flags);
 	lsr = serial_port_in(port, UART_LSR);
-	up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+	up->lsr_saved_flags |= lsr & up->lsr_save_mask;
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	serial8250_rpm_put(up);
@@ -2105,7 +2105,7 @@ static void wait_for_lsr(struct uart_8250_port *up, int bits)
 	for (;;) {
 		status = serial_in(up, UART_LSR);
 
-		up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
+		up->lsr_saved_flags |= status & up->lsr_save_mask;
 
 		if ((status & bits) == bits)
 			break;
diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
index 921df4c60062..aff76ea22287 100644
--- a/include/linux/serial_8250.h
+++ b/include/linux/serial_8250.h
@@ -120,6 +120,7 @@ struct uart_8250_port {
 	 */
 #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
 	u16			lsr_saved_flags;
+	u16			lsr_save_mask;
 #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
 	unsigned char		msr_saved_flags;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 09/10] serial: 8250_lpss: Use 32-bit reads
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
                   ` (7 preceding siblings ...)
  2022-04-26 12:24 ` [PATCH v5 08/10] serial: 8250: create lsr_save_mask Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:24 ` [PATCH v5 10/10] serial: 8250_dwlib: Support for 9th bit multipoint addressing Ilpo Järvinen
  2022-04-26 12:49 ` [PATCH v5 00/10] Add RS485 support to DW UART Greg KH
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen

Use 32-bit reads in order to not lose higher bits of DW UART regs. This
change does not fix any known issue as the high bits are not used for
anything related to 8250 driver (dw8250_readl_ext and dw8250_writel_ext
used within the dwlib are already doing
readl/writel/ioread32be/iowrite32be anyway).

This change is necessary for the next patch that enables 9th bit
address mode. DW UART reports address frames with BIT(8) of LSR.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/tty/serial/8250/8250_lpss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_lpss.c b/drivers/tty/serial/8250/8250_lpss.c
index 0f5af061e0b4..4ba43bef9933 100644
--- a/drivers/tty/serial/8250/8250_lpss.c
+++ b/drivers/tty/serial/8250/8250_lpss.c
@@ -330,7 +330,7 @@ static int lpss8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	uart.port.irq = pci_irq_vector(pdev, 0);
 	uart.port.private_data = &lpss->data;
 	uart.port.type = PORT_16550A;
-	uart.port.iotype = UPIO_MEM;
+	uart.port.iotype = UPIO_MEM32;
 	uart.port.regshift = 2;
 	uart.port.uartclk = lpss->board->base_baud * 16;
 	uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH v5 10/10] serial: 8250_dwlib: Support for 9th bit multipoint addressing
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
                   ` (8 preceding siblings ...)
  2022-04-26 12:24 ` [PATCH v5 09/10] serial: 8250_lpss: Use 32-bit reads Ilpo Järvinen
@ 2022-04-26 12:24 ` Ilpo Järvinen
  2022-04-26 12:49 ` [PATCH v5 00/10] Add RS485 support to DW UART Greg KH
  10 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 12:24 UTC (permalink / raw)
  To: linux-serial, Greg KH
  Cc: Jiri Slaby, Lukas Wunner, Andy Shevchenko, Uwe Kleine-König,
	Vicente Bergas, Johan Hovold, heiko, giulio.benetti,
	Heikki Krogerus, Ilpo Järvinen, Raymond Tan,
	Lakshmi Sowjanya

This change adds 9th bit multipoint addressing mode for DW UART using
the new ioctls introduced in the previous change. 9th bit addressing
can be used only when HW RS485 is available.

Updating RAR (receive address register) is bit tricky because busy
indication is not be available when DW UART is strictly 16550
compatible, which is the case with the hardware I was testing with. RAR
should not be updated while receive is in progress which is now
achieved by deasserting RE and waiting for one frame (in case rx would
be in progress, the driver seems to have no way of knowing it w/o busy
indication).

Co-developed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Co-developed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Co-developed-by: Raymond Tan <raymond.tan@intel.com>
Signed-off-by: Raymond Tan <raymond.tan@intel.com>
Co-developed-by: Lakshmi Sowjanya <lakshmi.sowjanya.d@intel.com>
Signed-off-by: Lakshmi Sowjanya <lakshmi.sowjanya.d@intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
 drivers/tty/serial/8250/8250_dwlib.c | 142 +++++++++++++++++++++++++++
 drivers/tty/serial/8250/8250_dwlib.h |   2 +
 2 files changed, 144 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c
index fbabfdd8c7b8..f285311a9dd9 100644
--- a/drivers/tty/serial/8250/8250_dwlib.c
+++ b/drivers/tty/serial/8250/8250_dwlib.c
@@ -3,8 +3,10 @@
 
 #include <linux/bitops.h>
 #include <linux/bitfield.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/math.h>
 #include <linux/property.h>
 #include <linux/serial_8250.h>
 #include <linux/serial_core.h>
@@ -16,9 +18,18 @@
 #define DW_UART_DE_EN	0xb0 /* Driver Output Enable Register */
 #define DW_UART_RE_EN	0xb4 /* Receiver Output Enable Register */
 #define DW_UART_DLF	0xc0 /* Divisor Latch Fraction Register */
+#define DW_UART_RAR	0xc4 /* Receive Address Register */
+#define DW_UART_TAR	0xc8 /* Transmit Address Register */
+#define DW_UART_LCR_EXT	0xcc /* Line Extended Control Register */
 #define DW_UART_CPR	0xf4 /* Component Parameter Register */
 #define DW_UART_UCV	0xf8 /* UART Component Version */
 
+/* Receive / Transmit Address Register bits */
+#define DW_UART_ADDR_MASK		GENMASK(7, 0)
+
+/* Line Status Register bits */
+#define DW_UART_LSR_ADDR_RCVD		BIT(8)
+
 /* Transceiver Control Register bits */
 #define DW_UART_TCR_RS485_EN		BIT(0)
 #define DW_UART_TCR_RE_POL		BIT(1)
@@ -28,6 +39,12 @@
 #define DW_UART_TCR_XFER_MODE_SW_DE_OR_RE	FIELD_PREP(DW_UART_TCR_XFER_MODE, 1)
 #define DW_UART_TCR_XFER_MODE_DE_OR_RE		FIELD_PREP(DW_UART_TCR_XFER_MODE, 2)
 
+/* Line Extended Control Register bits */
+#define DW_UART_LCR_EXT_DLS_E		BIT(0)
+#define DW_UART_LCR_EXT_ADDR_MATCH	BIT(1)
+#define DW_UART_LCR_EXT_SEND_ADDR	BIT(2)
+#define DW_UART_LCR_EXT_TRANSMIT_MODE	BIT(3)
+
 /* Component Parameter Register bits */
 #define DW_UART_CPR_ABP_DATA_WIDTH	(3 << 0)
 #define DW_UART_CPR_AFCE_MODE		(1 << 4)
@@ -75,18 +92,132 @@ static void dw8250_set_divisor(struct uart_port *p, unsigned int baud,
 	serial8250_do_set_divisor(p, baud, quot, quot_frac);
 }
 
+/*
+ * Wait until re is de-asserted for sure. An ongoing receive will keep
+ * re asserted until end of frame. Without BUSY indication available,
+ * only available course of action is to wait for the time it takes to
+ * receive one frame (there might nothing to receive but w/o BUSY the
+ * driver cannot know).
+ */
+static void dw8250_wait_re_deassert(struct uart_port *p)
+{
+	udelay(p->frame_time);
+}
+
+static void dw8250_update_rar(struct uart_port *p, u32 addr)
+{
+	u32 re_en = dw8250_readl_ext(p, DW_UART_RE_EN);
+
+	/*
+	 * RAR shouldn't be changed while receiving. Thus, de-assert RE_EN
+	 * if asserted and wait.
+	 */
+	if (re_en)
+		dw8250_writel_ext(p, DW_UART_RE_EN, 0);
+	dw8250_wait_re_deassert(p);
+	dw8250_writel_ext(p, DW_UART_RAR, addr);
+	if (re_en)
+		dw8250_writel_ext(p, DW_UART_RE_EN, re_en);
+}
+
+static void dw8250_addrmode_setup(struct uart_port *p, bool enable_addrmode)
+{
+	struct dw8250_port_data *d = p->private_data;
+
+	if (enable_addrmode) {
+		/* Clear RAR & TAR of any previous values */
+		dw8250_writel_ext(p, DW_UART_RAR, 0);
+		dw8250_writel_ext(p, DW_UART_TAR, 0);
+		dw8250_writel_ext(p, DW_UART_LCR_EXT, DW_UART_LCR_EXT_DLS_E);
+	} else {
+		dw8250_writel_ext(p, DW_UART_LCR_EXT, 0);
+	}
+
+	d->addrmode = enable_addrmode;
+}
+
 void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, struct ktermios *old)
 {
+	struct dw8250_port_data *d = p->private_data;
+
 	p->status &= ~UPSTAT_AUTOCTS;
 	if (termios->c_cflag & CRTSCTS)
 		p->status |= UPSTAT_AUTOCTS;
 
+	if (!(p->rs485.flags & SER_RS485_ENABLED) || !d->hw_rs485_support)
+		termios->c_cflag &= ~ADDRB;
+
+	if (!old || (termios->c_cflag ^ old->c_cflag) & ADDRB)
+		dw8250_addrmode_setup(p, termios->c_cflag & ADDRB);
+
 	serial8250_do_set_termios(p, termios, old);
+
+	if (d->addrmode) {
+		p->ignore_status_mask |= DW_UART_LSR_ADDR_RCVD;
+		p->read_status_mask |= DW_UART_LSR_ADDR_RCVD;
+	}
 }
 EXPORT_SYMBOL_GPL(dw8250_do_set_termios);
 
+static int dw8250_rs485_set_addr(struct uart_port *p, struct serial_addr *addr)
+{
+	struct dw8250_port_data *d = p->private_data;
+	u32 lcr;
+
+	if (!(p->rs485.flags & SER_RS485_ENABLED) || !d->addrmode)
+		return -EINVAL;
+
+	addr->flags &= SER_ADDR_RECV | SER_ADDR_RECV_CLEAR | SER_ADDR_DEST;
+	if (!addr->flags)
+		return -EINVAL;
+
+	lcr = dw8250_readl_ext(p, DW_UART_LCR_EXT);
+	if (addr->flags & SER_ADDR_RECV) {
+		dw8250_update_rar(p, addr->addr & DW_UART_ADDR_MASK);
+		lcr |= DW_UART_LCR_EXT_ADDR_MATCH;
+		addr->flags &= ~SER_ADDR_RECV_CLEAR;
+	} else if (addr->flags & SER_ADDR_RECV_CLEAR) {
+		lcr &= DW_UART_LCR_EXT_ADDR_MATCH;
+	}
+	if (addr->flags & SER_ADDR_DEST) {
+		dw8250_writel_ext(p, DW_UART_TAR, addr->addr & DW_UART_ADDR_MASK);
+		lcr |= DW_UART_LCR_EXT_SEND_ADDR;
+	}
+	dw8250_writel_ext(p, DW_UART_LCR_EXT, lcr);
+
+	return 0;
+}
+
+static int dw8250_rs485_get_addr(struct uart_port *p, struct serial_addr *addr)
+{
+	struct dw8250_port_data *d = p->private_data;
+
+	if (!(p->rs485.flags & SER_RS485_ENABLED) || !d->addrmode)
+		return -EINVAL;
+
+	if (addr->flags == SER_ADDR_DEST) {
+		addr->addr = dw8250_readl_ext(p, DW_UART_TAR) & DW_UART_ADDR_MASK;
+		return 0;
+	}
+	if (addr->flags == SER_ADDR_RECV) {
+		u32 lcr = dw8250_readl_ext(p, DW_UART_LCR_EXT);
+
+		if (!(lcr & DW_UART_LCR_EXT_ADDR_MATCH)) {
+			addr->flags = SER_ADDR_RECV_CLEAR;
+			addr->addr = 0;
+		} else {
+			addr->addr = dw8250_readl_ext(p, DW_UART_RAR) & DW_UART_ADDR_MASK;
+		}
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
 static int dw8250_rs485_config(struct uart_port *p, struct serial_rs485 *rs485)
 {
+	struct dw8250_port_data *d = p->private_data;
 	u32 tcr;
 
 	tcr = dw8250_readl_ext(p, DW_UART_TCR);
@@ -111,6 +242,14 @@ static int dw8250_rs485_config(struct uart_port *p, struct serial_rs485 *rs485)
 		dw8250_writel_ext(p, DW_UART_DE_EN, 1);
 		dw8250_writel_ext(p, DW_UART_RE_EN, 1);
 	} else {
+		/*
+		 * Don't allow disabling RS485 when address mode is enabled.
+		 * Clearing address mode would require clearing ADDRB in
+		 * termios.
+		 */
+		if (d->addrmode)
+			return -EINVAL;
+
 		rs485->flags = 0;
 
 		tcr &= ~DW_UART_TCR_RS485_EN;
@@ -159,6 +298,9 @@ void dw8250_setup_port(struct uart_port *p)
 	pd->hw_rs485_support = dw8250_detect_rs485_hw(p);
 	if (pd->hw_rs485_support) {
 		p->rs485_config = dw8250_rs485_config;
+		p->set_addr = dw8250_rs485_set_addr;
+		p->get_addr = dw8250_rs485_get_addr;
+		up->lsr_save_mask = LSR_SAVE_FLAGS | DW_UART_LSR_ADDR_RCVD;
 	} else {
 		p->rs485_config = serial8250_em485_config;
 		up->rs485_start_tx = serial8250_em485_start_tx;
diff --git a/drivers/tty/serial/8250/8250_dwlib.h b/drivers/tty/serial/8250/8250_dwlib.h
index 055bfdc87985..4fc2e968afcd 100644
--- a/drivers/tty/serial/8250/8250_dwlib.h
+++ b/drivers/tty/serial/8250/8250_dwlib.h
@@ -23,6 +23,8 @@ struct dw8250_port_data {
 
 	/* RS485 variables */
 	bool			hw_rs485_support;
+	/* 9-bit framing (9th bit is address indicator) */
+	bool			addrmode;
 };
 
 struct dw8250_platform_data {
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 00/10] Add RS485 support to DW UART
  2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
                   ` (9 preceding siblings ...)
  2022-04-26 12:24 ` [PATCH v5 10/10] serial: 8250_dwlib: Support for 9th bit multipoint addressing Ilpo Järvinen
@ 2022-04-26 12:49 ` Greg KH
  10 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:49 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api

On Tue, Apr 26, 2022 at 03:24:38PM +0300, Ilpo Järvinen wrote:
> This patchset adds RS-485 support to the DW UART driver. The patchset
> has two main parts. The first part adds HW support for RS-485 itself
> in various modes of operation and the second part focuses on enabling
> 9th bit addressing mode that can be used on a multipoint RS-485
> communications line.
> 
> To configure multipoint addressing, ADDRB flag is added to termios
> and two new IOCTLs are added into serial core. Lukas Wunner brought up
> during v1 review that if this addressing is only going to be used with
> RS-485, doing it within rs485_config would avoid having to add those
> IOCTLs. There was some counterexample w/o further details mentioned for
> RS-232 usage by Andy Shevchenko. I left the IOCTL approach there but if
> somebody has further input on this, please voice it as it is user-space
> facing API.
> 
> I decided to rewrite the UART_CAP_NOTEMT patch from scratch myself
> based on Uwe Kleine-König's earlier suggestion and include it to this
> series. To make waiting for a single character easy and to avoid
> storing it per purpose in the uart drivers, I decided to add
> frame_time into uart_port. It turned out to beneficial also for serial
> core which had to reverse calculate it from uart_port->timeout). I was
> thinking of removing uart_port->timeout entirely and derive the value
> timeout from frame_time and fifosize where needed but I was not sure
> if that's ok to do lockingwise (not that fifosize is a variable that
> is expected to change so maybe I'm just being too cautious).

I've applied the first 4 now, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
  2022-04-26 12:24   ` Ilpo Järvinen
  (?)
@ 2022-04-26 12:52     ` Greg KH
  -1 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:52 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, David S. Miller, sparclinux, Arnd Bergmann,
	linux-arch, linux-usb

On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> is necessary for supporting devices with RS485 multipoint addressing
> [*]. A later patch in the patch series adds support for Synopsys
> Designware UART capable for 9th bit addressing mode. In this mode, 9th
> bit is used to indicate an address (byte) within the communication
> line. The 9th bit addressing mode is selected using ADDRB introduced by
> an earlier patch.
> 
> [*] Technically, RS485 is just an electronic spec and does not itself
> specify the 9th bit addressing mode but 9th bit seems at least
> "semi-standard" way to do addressing with RS485.
> 
> Cc: linux-api@vger.kernel.org
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: linux-alpha@vger.kernel.org
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: linux-mips@vger.kernel.org
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>  arch/alpha/include/uapi/asm/termbits.h   | 1 +
>  arch/mips/include/uapi/asm/termbits.h    | 1 +
>  arch/parisc/include/uapi/asm/termbits.h  | 1 +
>  arch/powerpc/include/uapi/asm/termbits.h | 1 +
>  arch/sparc/include/uapi/asm/termbits.h   | 1 +
>  drivers/char/pcmcia/synclink_cs.c        | 2 ++
>  drivers/ipack/devices/ipoctal.c          | 2 ++
>  drivers/mmc/core/sdio_uart.c             | 2 ++
>  drivers/net/usb/hso.c                    | 3 ++-
>  drivers/s390/char/tty3270.c              | 3 +++
>  drivers/staging/greybus/uart.c           | 2 ++
>  drivers/tty/amiserial.c                  | 6 +++++-
>  drivers/tty/moxa.c                       | 1 +
>  drivers/tty/mxser.c                      | 1 +
>  drivers/tty/serial/serial_core.c         | 2 ++
>  drivers/tty/synclink_gt.c                | 2 ++
>  drivers/tty/tty_ioctl.c                  | 2 ++
>  drivers/usb/class/cdc-acm.c              | 2 ++
>  drivers/usb/serial/usb-serial.c          | 6 ++++--
>  include/uapi/asm-generic/termbits.h      | 1 +
>  net/bluetooth/rfcomm/tty.c               | 2 ++
>  21 files changed, 40 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
> index 4575ba34a0ea..0c123e715486 100644
> --- a/arch/alpha/include/uapi/asm/termbits.h
> +++ b/arch/alpha/include/uapi/asm/termbits.h
> @@ -180,6 +180,7 @@ struct ktermios {
>  #define HUPCL	00040000
>  
>  #define CLOCAL	00100000
> +#define ADDRB	004000000000		/* address bit */
>  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000		/* flow control */
>  
> diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
> index dfeffba729b7..4732d31b0e4e 100644
> --- a/arch/mips/include/uapi/asm/termbits.h
> +++ b/arch/mips/include/uapi/asm/termbits.h
> @@ -182,6 +182,7 @@ struct ktermios {
>  #define	 B3500000 0010016
>  #define	 B4000000 0010017
>  #define CIBAUD	  002003600000	/* input baud rate */
> +#define ADDRB	  004000000000	/* address bit */
>  #define CMSPAR	  010000000000	/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000	/* flow control */
>  
> diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
> index 40e920f8d683..d6bbd10d92ba 100644
> --- a/arch/parisc/include/uapi/asm/termbits.h
> +++ b/arch/parisc/include/uapi/asm/termbits.h
> @@ -159,6 +159,7 @@ struct ktermios {
>  #define  B3500000 0010016
>  #define  B4000000 0010017
>  #define CIBAUD    002003600000		/* input baud rate */
> +#define ADDRB	  004000000000		/* address bit */

tabs where the rest were not?

>  #define CMSPAR    010000000000          /* mark or space (stick) parity */
>  #define CRTSCTS   020000000000          /* flow control */
>  
> diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> index ed18bc61f63d..c6a033732f39 100644
> --- a/arch/powerpc/include/uapi/asm/termbits.h
> +++ b/arch/powerpc/include/uapi/asm/termbits.h
> @@ -171,6 +171,7 @@ struct ktermios {
>  #define HUPCL	00040000
>  
>  #define CLOCAL	00100000
> +#define ADDRB	004000000000		/* address bit */
>  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000		/* flow control */
>  
> diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> index ce5ad5d0f105..5eb1d547b5c4 100644
> --- a/arch/sparc/include/uapi/asm/termbits.h
> +++ b/arch/sparc/include/uapi/asm/termbits.h
> @@ -201,6 +201,7 @@ struct ktermios {
>  #define B3500000  0x00001012
>  #define B4000000  0x00001013  */
>  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> +#define ADDRB	  0x20000000  /* address bit */
>  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
>  #define CRTSCTS	  0x80000000  /* flow control */

Why all the different values?  Can't we pick one and use it for all
arches?  Having these be different in different arches and userspace
should not be a thing for new fields, right?

> diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> index 78baba55a8b5..d179b9b57a25 100644
> --- a/drivers/char/pcmcia/synclink_cs.c
> +++ b/drivers/char/pcmcia/synclink_cs.c
> @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
>  		== RELEVANT_IFLAG(old_termios->c_iflag)))
>  	  return;
>  
> +	tty->termios.c_cflag &= ~ADDRB;

Having to do this for all drivers feels wrong.  It isn't needed for any
other flag, right?  That makes me really not like this change as it
feels very ackward and
yet-another-thing-a-serial-driver-has-to-remember.

And as you are wanting to pass this bit to userspace, where is that
documented?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 12:52     ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:52 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Heikki Krogerus, heiko, James E.J. Bottomley, Paul Mackerras,
	sparclinux, Jiri Slaby, linux-arch, Helge Deller, linux-serial,
	Uwe Kleine-König, Matt Turner, Arnd Bergmann, Johan Hovold,
	Vicente Bergas, Ivan Kokshaysky, Andy Shevchenko,
	Thomas Bogendoerfer, linux-parisc, linux-api, linux-usb,
	linux-mips, David S. Miller, Lukas Wunner, linux-alpha,
	linuxppc-dev, giulio.benetti

On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> is necessary for supporting devices with RS485 multipoint addressing
> [*]. A later patch in the patch series adds support for Synopsys
> Designware UART capable for 9th bit addressing mode. In this mode, 9th
> bit is used to indicate an address (byte) within the communication
> line. The 9th bit addressing mode is selected using ADDRB introduced by
> an earlier patch.
> 
> [*] Technically, RS485 is just an electronic spec and does not itself
> specify the 9th bit addressing mode but 9th bit seems at least
> "semi-standard" way to do addressing with RS485.
> 
> Cc: linux-api@vger.kernel.org
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: linux-alpha@vger.kernel.org
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: linux-mips@vger.kernel.org
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>  arch/alpha/include/uapi/asm/termbits.h   | 1 +
>  arch/mips/include/uapi/asm/termbits.h    | 1 +
>  arch/parisc/include/uapi/asm/termbits.h  | 1 +
>  arch/powerpc/include/uapi/asm/termbits.h | 1 +
>  arch/sparc/include/uapi/asm/termbits.h   | 1 +
>  drivers/char/pcmcia/synclink_cs.c        | 2 ++
>  drivers/ipack/devices/ipoctal.c          | 2 ++
>  drivers/mmc/core/sdio_uart.c             | 2 ++
>  drivers/net/usb/hso.c                    | 3 ++-
>  drivers/s390/char/tty3270.c              | 3 +++
>  drivers/staging/greybus/uart.c           | 2 ++
>  drivers/tty/amiserial.c                  | 6 +++++-
>  drivers/tty/moxa.c                       | 1 +
>  drivers/tty/mxser.c                      | 1 +
>  drivers/tty/serial/serial_core.c         | 2 ++
>  drivers/tty/synclink_gt.c                | 2 ++
>  drivers/tty/tty_ioctl.c                  | 2 ++
>  drivers/usb/class/cdc-acm.c              | 2 ++
>  drivers/usb/serial/usb-serial.c          | 6 ++++--
>  include/uapi/asm-generic/termbits.h      | 1 +
>  net/bluetooth/rfcomm/tty.c               | 2 ++
>  21 files changed, 40 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
> index 4575ba34a0ea..0c123e715486 100644
> --- a/arch/alpha/include/uapi/asm/termbits.h
> +++ b/arch/alpha/include/uapi/asm/termbits.h
> @@ -180,6 +180,7 @@ struct ktermios {
>  #define HUPCL	00040000
>  
>  #define CLOCAL	00100000
> +#define ADDRB	004000000000		/* address bit */
>  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000		/* flow control */
>  
> diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
> index dfeffba729b7..4732d31b0e4e 100644
> --- a/arch/mips/include/uapi/asm/termbits.h
> +++ b/arch/mips/include/uapi/asm/termbits.h
> @@ -182,6 +182,7 @@ struct ktermios {
>  #define	 B3500000 0010016
>  #define	 B4000000 0010017
>  #define CIBAUD	  002003600000	/* input baud rate */
> +#define ADDRB	  004000000000	/* address bit */
>  #define CMSPAR	  010000000000	/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000	/* flow control */
>  
> diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
> index 40e920f8d683..d6bbd10d92ba 100644
> --- a/arch/parisc/include/uapi/asm/termbits.h
> +++ b/arch/parisc/include/uapi/asm/termbits.h
> @@ -159,6 +159,7 @@ struct ktermios {
>  #define  B3500000 0010016
>  #define  B4000000 0010017
>  #define CIBAUD    002003600000		/* input baud rate */
> +#define ADDRB	  004000000000		/* address bit */

tabs where the rest were not?

>  #define CMSPAR    010000000000          /* mark or space (stick) parity */
>  #define CRTSCTS   020000000000          /* flow control */
>  
> diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> index ed18bc61f63d..c6a033732f39 100644
> --- a/arch/powerpc/include/uapi/asm/termbits.h
> +++ b/arch/powerpc/include/uapi/asm/termbits.h
> @@ -171,6 +171,7 @@ struct ktermios {
>  #define HUPCL	00040000
>  
>  #define CLOCAL	00100000
> +#define ADDRB	004000000000		/* address bit */
>  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000		/* flow control */
>  
> diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> index ce5ad5d0f105..5eb1d547b5c4 100644
> --- a/arch/sparc/include/uapi/asm/termbits.h
> +++ b/arch/sparc/include/uapi/asm/termbits.h
> @@ -201,6 +201,7 @@ struct ktermios {
>  #define B3500000  0x00001012
>  #define B4000000  0x00001013  */
>  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> +#define ADDRB	  0x20000000  /* address bit */
>  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
>  #define CRTSCTS	  0x80000000  /* flow control */

Why all the different values?  Can't we pick one and use it for all
arches?  Having these be different in different arches and userspace
should not be a thing for new fields, right?

> diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> index 78baba55a8b5..d179b9b57a25 100644
> --- a/drivers/char/pcmcia/synclink_cs.c
> +++ b/drivers/char/pcmcia/synclink_cs.c
> @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
>  		== RELEVANT_IFLAG(old_termios->c_iflag)))
>  	  return;
>  
> +	tty->termios.c_cflag &= ~ADDRB;

Having to do this for all drivers feels wrong.  It isn't needed for any
other flag, right?  That makes me really not like this change as it
feels very ackward and
yet-another-thing-a-serial-driver-has-to-remember.

And as you are wanting to pass this bit to userspace, where is that
documented?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 12:52     ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:52 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman

On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> is necessary for supporting devices with RS485 multipoint addressing
> [*]. A later patch in the patch series adds support for Synopsys
> Designware UART capable for 9th bit addressing mode. In this mode, 9th
> bit is used to indicate an address (byte) within the communication
> line. The 9th bit addressing mode is selected using ADDRB introduced by
> an earlier patch.
> 
> [*] Technically, RS485 is just an electronic spec and does not itself
> specify the 9th bit addressing mode but 9th bit seems at least
> "semi-standard" way to do addressing with RS485.
> 
> Cc: linux-api@vger.kernel.org
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: linux-alpha@vger.kernel.org
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: linux-mips@vger.kernel.org
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-usb@vger.kernel.org
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>  arch/alpha/include/uapi/asm/termbits.h   | 1 +
>  arch/mips/include/uapi/asm/termbits.h    | 1 +
>  arch/parisc/include/uapi/asm/termbits.h  | 1 +
>  arch/powerpc/include/uapi/asm/termbits.h | 1 +
>  arch/sparc/include/uapi/asm/termbits.h   | 1 +
>  drivers/char/pcmcia/synclink_cs.c        | 2 ++
>  drivers/ipack/devices/ipoctal.c          | 2 ++
>  drivers/mmc/core/sdio_uart.c             | 2 ++
>  drivers/net/usb/hso.c                    | 3 ++-
>  drivers/s390/char/tty3270.c              | 3 +++
>  drivers/staging/greybus/uart.c           | 2 ++
>  drivers/tty/amiserial.c                  | 6 +++++-
>  drivers/tty/moxa.c                       | 1 +
>  drivers/tty/mxser.c                      | 1 +
>  drivers/tty/serial/serial_core.c         | 2 ++
>  drivers/tty/synclink_gt.c                | 2 ++
>  drivers/tty/tty_ioctl.c                  | 2 ++
>  drivers/usb/class/cdc-acm.c              | 2 ++
>  drivers/usb/serial/usb-serial.c          | 6 ++++--
>  include/uapi/asm-generic/termbits.h      | 1 +
>  net/bluetooth/rfcomm/tty.c               | 2 ++
>  21 files changed, 40 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
> index 4575ba34a0ea..0c123e715486 100644
> --- a/arch/alpha/include/uapi/asm/termbits.h
> +++ b/arch/alpha/include/uapi/asm/termbits.h
> @@ -180,6 +180,7 @@ struct ktermios {
>  #define HUPCL	00040000
>  
>  #define CLOCAL	00100000
> +#define ADDRB	004000000000		/* address bit */
>  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000		/* flow control */
>  
> diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
> index dfeffba729b7..4732d31b0e4e 100644
> --- a/arch/mips/include/uapi/asm/termbits.h
> +++ b/arch/mips/include/uapi/asm/termbits.h
> @@ -182,6 +182,7 @@ struct ktermios {
>  #define	 B3500000 0010016
>  #define	 B4000000 0010017
>  #define CIBAUD	  002003600000	/* input baud rate */
> +#define ADDRB	  004000000000	/* address bit */
>  #define CMSPAR	  010000000000	/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000	/* flow control */
>  
> diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
> index 40e920f8d683..d6bbd10d92ba 100644
> --- a/arch/parisc/include/uapi/asm/termbits.h
> +++ b/arch/parisc/include/uapi/asm/termbits.h
> @@ -159,6 +159,7 @@ struct ktermios {
>  #define  B3500000 0010016
>  #define  B4000000 0010017
>  #define CIBAUD    002003600000		/* input baud rate */
> +#define ADDRB	  004000000000		/* address bit */

tabs where the rest were not?

>  #define CMSPAR    010000000000          /* mark or space (stick) parity */
>  #define CRTSCTS   020000000000          /* flow control */
>  
> diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> index ed18bc61f63d..c6a033732f39 100644
> --- a/arch/powerpc/include/uapi/asm/termbits.h
> +++ b/arch/powerpc/include/uapi/asm/termbits.h
> @@ -171,6 +171,7 @@ struct ktermios {
>  #define HUPCL	00040000
>  
>  #define CLOCAL	00100000
> +#define ADDRB	004000000000		/* address bit */
>  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
>  #define CRTSCTS	  020000000000		/* flow control */
>  
> diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> index ce5ad5d0f105..5eb1d547b5c4 100644
> --- a/arch/sparc/include/uapi/asm/termbits.h
> +++ b/arch/sparc/include/uapi/asm/termbits.h
> @@ -201,6 +201,7 @@ struct ktermios {
>  #define B3500000  0x00001012
>  #define B4000000  0x00001013  */
>  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> +#define ADDRB	  0x20000000  /* address bit */
>  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
>  #define CRTSCTS	  0x80000000  /* flow control */

Why all the different values?  Can't we pick one and use it for all
arches?  Having these be different in different arches and userspace
should not be a thing for new fields, right?

> diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> index 78baba55a8b5..d179b9b57a25 100644
> --- a/drivers/char/pcmcia/synclink_cs.c
> +++ b/drivers/char/pcmcia/synclink_cs.c
> @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
>  		== RELEVANT_IFLAG(old_termios->c_iflag)))
>  	  return;
>  
> +	tty->termios.c_cflag &= ~ADDRB;

Having to do this for all drivers feels wrong.  It isn't needed for any
other flag, right?  That makes me really not like this change as it
feels very ackward and
yet-another-thing-a-serial-driver-has-to-remember.

And as you are wanting to pass this bit to userspace, where is that
documented?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
  2022-04-26 12:24   ` Ilpo Järvinen
  (?)
@ 2022-04-26 12:56     ` Greg KH
  -1 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:56 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, Yoshinori Sato, Rich Felker, linux-sh,
	David S. Miller, sparclinux, Chris Zankel, Max Filippov,
	linux-xtensa, Arnd Bergmann, linux-arch, linux-doc

On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> Add generic support for serial multipoint addressing. Two new ioctls
> are added. TIOCSADDR is used to indicate the destination/receive
> address. TIOCGADDR returns the current address in use. The driver
> should implement set_addr and get_addr to support addressing mode.
> 
> Adjust ADDRB clearing to happen only if driver does not provide
> set_addr (=the driver doesn't support address mode).
> 
> This change is necessary for supporting devices with RS485 multipoint
> addressing [*]. A following patch in the patch series adds support for
> Synopsys Designware UART capable for 9th bit addressing mode. In this
> mode, 9th bit is used to indicate an address (byte) within the
> communication line. The 9th bit addressing mode is selected using ADDRB
> introduced by the previous patch.
> 
> Transmit addresses / receiver filter are specified by setting the flags
> SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> address, in the 9bit addressing mode it is sent out immediately with
> the 9th bit set to 1. After that, the subsequent normal data bytes are
> sent with 9th bit as 0 and they are intended to the device with the
> given address. It is up to receiver to enforce the filter using
> SER_ADDR_RECV. When userspace has supplied the receive address, the
> driver is expected to handle the matching of the address and only data
> with that address is forwarded to the user. Both SER_ADDR_DEST and
> SER_ADDR_RECV can be given at the same time in a single call if the
> addresses are the same.
> 
> The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> 
> [*] Technically, RS485 is just an electronic spec and does not itself
> specify the 9th bit addressing mode but 9th bit seems at least
> "semi-standard" way to do addressing with RS485.
> 
> Cc: linux-api@vger.kernel.org
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: linux-alpha@vger.kernel.org
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: linux-mips@vger.kernel.org
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: linux-sh@vger.kernel.org
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Cc: Chris Zankel <chris@zankel.net>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: linux-xtensa@linux-xtensa.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>  .../driver-api/serial/serial-rs485.rst        | 23 ++++++-
>  arch/alpha/include/uapi/asm/ioctls.h          |  3 +
>  arch/mips/include/uapi/asm/ioctls.h           |  3 +
>  arch/parisc/include/uapi/asm/ioctls.h         |  3 +
>  arch/powerpc/include/uapi/asm/ioctls.h        |  3 +
>  arch/sh/include/uapi/asm/ioctls.h             |  3 +
>  arch/sparc/include/uapi/asm/ioctls.h          |  3 +
>  arch/xtensa/include/uapi/asm/ioctls.h         |  3 +
>  drivers/tty/serial/8250/8250_core.c           |  2 +
>  drivers/tty/serial/serial_core.c              | 62 ++++++++++++++++++-
>  drivers/tty/tty_io.c                          |  2 +
>  include/linux/serial_core.h                   |  6 ++
>  include/uapi/asm-generic/ioctls.h             |  3 +
>  include/uapi/linux/serial.h                   |  8 +++
>  14 files changed, 125 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
> index 6bc824f948f9..2f45f007fa5b 100644
> --- a/Documentation/driver-api/serial/serial-rs485.rst
> +++ b/Documentation/driver-api/serial/serial-rs485.rst
> @@ -95,7 +95,28 @@ RS485 Serial Communications
>  		/* Error handling. See errno. */
>  	}
>  
> -5. References
> +5. Multipoint Addressing
> +========================
> +
> +   The Linux kernel provides serial_addr structure to handle addressing within
> +   multipoint serial communications line such as RS485. 9th bit addressiong mode
> +   is enabled by adding ADDRB flag in termios c_cflag.
> +
> +   Serial core calls device specific set/get_addr in response to TIOCSADDR and
> +   TIOCGADDR ioctls with a pointer to serial_addr. Destination and receive
> +   address can be specified using serial_addr flags field. Receive address may
> +   also be cleared using flags. Once an address is set, the communication
> +   can occur only with the particular device and other peers are filtered out.
> +   It is left up to the receiver side to enforce the filtering.
> +
> +   Address flags:
> +	- SER_ADDR_RECV: Receive (filter) address.
> +	- SER_ADDR_RECV_CLEAR: Clear receive filter (only for TIOCSADDR).
> +	- SER_ADDR_DEST: Destination address.
> +
> +   Note: not all devices supporting RS485 support multipoint addressing.
> +
> +6. References
>  =============
>  
>   [1]	include/uapi/linux/serial.h
> diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
> index 971311605288..500cab3e1d6b 100644
> --- a/arch/alpha/include/uapi/asm/ioctls.h
> +++ b/arch/alpha/include/uapi/asm/ioctls.h
> @@ -125,4 +125,7 @@
>  #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* _ASM_ALPHA_IOCTLS_H */
> diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
> index 16aa8a766aec..3859dc46857e 100644
> --- a/arch/mips/include/uapi/asm/ioctls.h
> +++ b/arch/mips/include/uapi/asm/ioctls.h
> @@ -96,6 +96,9 @@
>  #define TIOCGISO7816	_IOR('T', 0x42, struct serial_iso7816)
>  #define TIOCSISO7816	_IOWR('T', 0x43, struct serial_iso7816)
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* I hope the range from 0x5480 on is free ... */
>  #define TIOCSCTTY	0x5480		/* become controlling tty */
>  #define TIOCGSOFTCAR	0x5481
> diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
> index 82d1148c6379..62337743db64 100644
> --- a/arch/parisc/include/uapi/asm/ioctls.h
> +++ b/arch/parisc/include/uapi/asm/ioctls.h
> @@ -86,6 +86,9 @@
>  #define TIOCSTOP	0x5462
>  #define TIOCSLTC	0x5462
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Used for packet mode */
>  #define TIOCPKT_DATA		 0
>  #define TIOCPKT_FLUSHREAD	 1
> diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
> index 2c145da3b774..84fd69ac366a 100644
> --- a/arch/powerpc/include/uapi/asm/ioctls.h
> +++ b/arch/powerpc/include/uapi/asm/ioctls.h
> @@ -120,4 +120,7 @@
>  #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif	/* _ASM_POWERPC_IOCTLS_H */
> diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
> index 11866d4f60e1..f82966b7dba2 100644
> --- a/arch/sh/include/uapi/asm/ioctls.h
> +++ b/arch/sh/include/uapi/asm/ioctls.h
> @@ -113,4 +113,7 @@
>  #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* __ASM_SH_IOCTLS_H */
> diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
> index 7fd2f5873c9e..e44624c67c79 100644
> --- a/arch/sparc/include/uapi/asm/ioctls.h
> +++ b/arch/sparc/include/uapi/asm/ioctls.h
> @@ -125,6 +125,9 @@
>  #define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Kernel definitions */
>  
>  /* Used for packet mode */
> diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
> index 6d4a87296c95..759ca9377f2a 100644
> --- a/arch/xtensa/include/uapi/asm/ioctls.h
> +++ b/arch/xtensa/include/uapi/asm/ioctls.h
> @@ -127,4 +127,7 @@
>  #define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* _XTENSA_IOCTLS_H */
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index 01d30f6ed8fb..f67bc3b76f65 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -1008,6 +1008,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  		uart->port.rs485	= up->port.rs485;
>  		uart->rs485_start_tx	= up->rs485_start_tx;
>  		uart->rs485_stop_tx	= up->rs485_stop_tx;
> +		uart->port.set_addr	= up->port.set_addr;
> +		uart->port.get_addr	= up->port.get_addr;
>  		uart->dma		= up->dma;
>  
>  		/* Take tx_loadsz from fifosize if it wasn't set separately */
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index 0f397e67eeb0..5762987bf176 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -1397,6 +1397,56 @@ static int uart_set_iso7816_config(struct uart_port *port,
>  	return 0;
>  }
>  
> +static int uart_set_addr(struct uart_port *port,
> +			 struct serial_addr __user *serial_addr_user)
> +{
> +	struct serial_addr addr;
> +	unsigned long flags;
> +	int ret;
> +
> +	if (!port->set_addr)
> +		return -ENOTTY;
> +
> +	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
> +		return -EFAULT;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	ret = port->set_addr(port, &addr);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	if (ret)
> +		return ret;
> +
> +	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +static int uart_get_addr(struct uart_port *port,
> +			 struct serial_addr __user *serial_addr_user)
> +{
> +	struct serial_addr addr;
> +	unsigned long flags;
> +	int ret;
> +
> +	if (!port->get_addr)
> +		return -ENOTTY;
> +
> +	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
> +		return -EFAULT;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	ret = port->get_addr(port, &addr);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	if (ret)
> +		return ret;
> +
> +	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
>  /*
>   * Called via sys_ioctl.  We can use spin_lock_irq() here.
>   */
> @@ -1474,6 +1524,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
>  	case TIOCGISO7816:
>  		ret = uart_get_iso7816_config(state->uart_port, uarg);
>  		break;
> +
> +	case TIOCSADDR:
> +		ret = uart_set_addr(uport, uarg);
> +		break;
> +
> +	case TIOCGADDR:
> +		ret = uart_get_addr(uport, uarg);
> +		break;
> +
>  	default:
>  		if (uport->ops->ioctl)
>  			ret = uport->ops->ioctl(uport, cmd, arg);
> @@ -1540,7 +1599,8 @@ static void uart_set_termios(struct tty_struct *tty,
>  		goto out;
>  	}
>  
> -	tty->termios.c_cflag &= ~ADDRB;
> +	if (!uport->set_addr)
> +		tty->termios.c_cflag &= ~ADDRB;
>  
>  	uart_change_speed(tty, state, old_termios);
>  	/* reload cflag from termios; port driver may have overridden flags */
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index 8fec1d8648f5..ef22b95e9c79 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -2885,6 +2885,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
>  	case TIOCSERGETLSR:
>  	case TIOCGRS485:
>  	case TIOCSRS485:
> +	case TIOCSADDR:
> +	case TIOCGADDR:
>  #ifdef TIOCGETP
>  	case TIOCGETP:
>  	case TIOCSETP:
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index cbd5070bc87f..2dd4c4d01c59 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -135,6 +135,12 @@ struct uart_port {
>  						struct serial_rs485 *rs485);
>  	int			(*iso7816_config)(struct uart_port *,
>  						  struct serial_iso7816 *iso7816);
> +
> +	int			(*set_addr)(struct uart_port *p,
> +					    struct serial_addr *addr);
> +	int			(*get_addr)(struct uart_port *p,
> +					    struct serial_addr *addr);
> +
>  	unsigned int		irq;			/* irq number */
>  	unsigned long		irqflags;		/* irq flags  */
>  	unsigned int		uartclk;		/* base uart clock */
> diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
> index cdc9f4ca8c27..689743366091 100644
> --- a/include/uapi/asm-generic/ioctls.h
> +++ b/include/uapi/asm-generic/ioctls.h
> @@ -106,6 +106,9 @@
>  # define FIOQSIZE	0x5460
>  #endif
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Used for packet mode */
>  #define TIOCPKT_DATA		 0
>  #define TIOCPKT_FLUSHREAD	 1
> diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> index fa6b16e5fdd8..8cb785ea7087 100644
> --- a/include/uapi/linux/serial.h
> +++ b/include/uapi/linux/serial.h
> @@ -149,4 +149,12 @@ struct serial_iso7816 {
>  	__u32	reserved[5];
>  };
>  
> +struct serial_addr {
> +	__u32	flags;
> +#define SER_ADDR_RECV			(1 << 0)
> +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> +#define SER_ADDR_DEST			(1 << 2)

You never check for invalid flags being sent to the kernel, which means
this api can never change in the future to add new flags :(

And what about struct serial_rs485?  Shouldn't that be used here
instead?  Why do we need a new ioctl and structure?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 12:56     ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:56 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Heikki Krogerus, heiko, linux-sh, James E.J. Bottomley,
	Max Filippov, Rich Felker, Paul Mackerras, sparclinux,
	Jiri Slaby, linux-arch, Yoshinori Sato, Helge Deller, linux-doc,
	linux-serial, Uwe Kleine-König, Matt Turner, linux-xtensa,
	Arnd Bergmann, Johan Hovold, Vicente Bergas, Ivan Kokshaysky,
	Andy Shevchenko, Chris Zankel, Thomas Bogendoerfer, linux-parisc,
	linux-api, linux-mips, David S. Miller, Lukas Wunner,
	linux-alpha, linuxppc-dev, giulio.benetti

On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> Add generic support for serial multipoint addressing. Two new ioctls
> are added. TIOCSADDR is used to indicate the destination/receive
> address. TIOCGADDR returns the current address in use. The driver
> should implement set_addr and get_addr to support addressing mode.
> 
> Adjust ADDRB clearing to happen only if driver does not provide
> set_addr (=the driver doesn't support address mode).
> 
> This change is necessary for supporting devices with RS485 multipoint
> addressing [*]. A following patch in the patch series adds support for
> Synopsys Designware UART capable for 9th bit addressing mode. In this
> mode, 9th bit is used to indicate an address (byte) within the
> communication line. The 9th bit addressing mode is selected using ADDRB
> introduced by the previous patch.
> 
> Transmit addresses / receiver filter are specified by setting the flags
> SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> address, in the 9bit addressing mode it is sent out immediately with
> the 9th bit set to 1. After that, the subsequent normal data bytes are
> sent with 9th bit as 0 and they are intended to the device with the
> given address. It is up to receiver to enforce the filter using
> SER_ADDR_RECV. When userspace has supplied the receive address, the
> driver is expected to handle the matching of the address and only data
> with that address is forwarded to the user. Both SER_ADDR_DEST and
> SER_ADDR_RECV can be given at the same time in a single call if the
> addresses are the same.
> 
> The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> 
> [*] Technically, RS485 is just an electronic spec and does not itself
> specify the 9th bit addressing mode but 9th bit seems at least
> "semi-standard" way to do addressing with RS485.
> 
> Cc: linux-api@vger.kernel.org
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: linux-alpha@vger.kernel.org
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: linux-mips@vger.kernel.org
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: linux-sh@vger.kernel.org
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Cc: Chris Zankel <chris@zankel.net>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: linux-xtensa@linux-xtensa.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>  .../driver-api/serial/serial-rs485.rst        | 23 ++++++-
>  arch/alpha/include/uapi/asm/ioctls.h          |  3 +
>  arch/mips/include/uapi/asm/ioctls.h           |  3 +
>  arch/parisc/include/uapi/asm/ioctls.h         |  3 +
>  arch/powerpc/include/uapi/asm/ioctls.h        |  3 +
>  arch/sh/include/uapi/asm/ioctls.h             |  3 +
>  arch/sparc/include/uapi/asm/ioctls.h          |  3 +
>  arch/xtensa/include/uapi/asm/ioctls.h         |  3 +
>  drivers/tty/serial/8250/8250_core.c           |  2 +
>  drivers/tty/serial/serial_core.c              | 62 ++++++++++++++++++-
>  drivers/tty/tty_io.c                          |  2 +
>  include/linux/serial_core.h                   |  6 ++
>  include/uapi/asm-generic/ioctls.h             |  3 +
>  include/uapi/linux/serial.h                   |  8 +++
>  14 files changed, 125 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
> index 6bc824f948f9..2f45f007fa5b 100644
> --- a/Documentation/driver-api/serial/serial-rs485.rst
> +++ b/Documentation/driver-api/serial/serial-rs485.rst
> @@ -95,7 +95,28 @@ RS485 Serial Communications
>  		/* Error handling. See errno. */
>  	}
>  
> -5. References
> +5. Multipoint Addressing
> +========================
> +
> +   The Linux kernel provides serial_addr structure to handle addressing within
> +   multipoint serial communications line such as RS485. 9th bit addressiong mode
> +   is enabled by adding ADDRB flag in termios c_cflag.
> +
> +   Serial core calls device specific set/get_addr in response to TIOCSADDR and
> +   TIOCGADDR ioctls with a pointer to serial_addr. Destination and receive
> +   address can be specified using serial_addr flags field. Receive address may
> +   also be cleared using flags. Once an address is set, the communication
> +   can occur only with the particular device and other peers are filtered out.
> +   It is left up to the receiver side to enforce the filtering.
> +
> +   Address flags:
> +	- SER_ADDR_RECV: Receive (filter) address.
> +	- SER_ADDR_RECV_CLEAR: Clear receive filter (only for TIOCSADDR).
> +	- SER_ADDR_DEST: Destination address.
> +
> +   Note: not all devices supporting RS485 support multipoint addressing.
> +
> +6. References
>  =============
>  
>   [1]	include/uapi/linux/serial.h
> diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
> index 971311605288..500cab3e1d6b 100644
> --- a/arch/alpha/include/uapi/asm/ioctls.h
> +++ b/arch/alpha/include/uapi/asm/ioctls.h
> @@ -125,4 +125,7 @@
>  #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* _ASM_ALPHA_IOCTLS_H */
> diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
> index 16aa8a766aec..3859dc46857e 100644
> --- a/arch/mips/include/uapi/asm/ioctls.h
> +++ b/arch/mips/include/uapi/asm/ioctls.h
> @@ -96,6 +96,9 @@
>  #define TIOCGISO7816	_IOR('T', 0x42, struct serial_iso7816)
>  #define TIOCSISO7816	_IOWR('T', 0x43, struct serial_iso7816)
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* I hope the range from 0x5480 on is free ... */
>  #define TIOCSCTTY	0x5480		/* become controlling tty */
>  #define TIOCGSOFTCAR	0x5481
> diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
> index 82d1148c6379..62337743db64 100644
> --- a/arch/parisc/include/uapi/asm/ioctls.h
> +++ b/arch/parisc/include/uapi/asm/ioctls.h
> @@ -86,6 +86,9 @@
>  #define TIOCSTOP	0x5462
>  #define TIOCSLTC	0x5462
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Used for packet mode */
>  #define TIOCPKT_DATA		 0
>  #define TIOCPKT_FLUSHREAD	 1
> diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
> index 2c145da3b774..84fd69ac366a 100644
> --- a/arch/powerpc/include/uapi/asm/ioctls.h
> +++ b/arch/powerpc/include/uapi/asm/ioctls.h
> @@ -120,4 +120,7 @@
>  #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif	/* _ASM_POWERPC_IOCTLS_H */
> diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
> index 11866d4f60e1..f82966b7dba2 100644
> --- a/arch/sh/include/uapi/asm/ioctls.h
> +++ b/arch/sh/include/uapi/asm/ioctls.h
> @@ -113,4 +113,7 @@
>  #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* __ASM_SH_IOCTLS_H */
> diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
> index 7fd2f5873c9e..e44624c67c79 100644
> --- a/arch/sparc/include/uapi/asm/ioctls.h
> +++ b/arch/sparc/include/uapi/asm/ioctls.h
> @@ -125,6 +125,9 @@
>  #define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Kernel definitions */
>  
>  /* Used for packet mode */
> diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
> index 6d4a87296c95..759ca9377f2a 100644
> --- a/arch/xtensa/include/uapi/asm/ioctls.h
> +++ b/arch/xtensa/include/uapi/asm/ioctls.h
> @@ -127,4 +127,7 @@
>  #define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* _XTENSA_IOCTLS_H */
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index 01d30f6ed8fb..f67bc3b76f65 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -1008,6 +1008,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  		uart->port.rs485	= up->port.rs485;
>  		uart->rs485_start_tx	= up->rs485_start_tx;
>  		uart->rs485_stop_tx	= up->rs485_stop_tx;
> +		uart->port.set_addr	= up->port.set_addr;
> +		uart->port.get_addr	= up->port.get_addr;
>  		uart->dma		= up->dma;
>  
>  		/* Take tx_loadsz from fifosize if it wasn't set separately */
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index 0f397e67eeb0..5762987bf176 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -1397,6 +1397,56 @@ static int uart_set_iso7816_config(struct uart_port *port,
>  	return 0;
>  }
>  
> +static int uart_set_addr(struct uart_port *port,
> +			 struct serial_addr __user *serial_addr_user)
> +{
> +	struct serial_addr addr;
> +	unsigned long flags;
> +	int ret;
> +
> +	if (!port->set_addr)
> +		return -ENOTTY;
> +
> +	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
> +		return -EFAULT;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	ret = port->set_addr(port, &addr);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	if (ret)
> +		return ret;
> +
> +	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +static int uart_get_addr(struct uart_port *port,
> +			 struct serial_addr __user *serial_addr_user)
> +{
> +	struct serial_addr addr;
> +	unsigned long flags;
> +	int ret;
> +
> +	if (!port->get_addr)
> +		return -ENOTTY;
> +
> +	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
> +		return -EFAULT;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	ret = port->get_addr(port, &addr);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	if (ret)
> +		return ret;
> +
> +	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
>  /*
>   * Called via sys_ioctl.  We can use spin_lock_irq() here.
>   */
> @@ -1474,6 +1524,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
>  	case TIOCGISO7816:
>  		ret = uart_get_iso7816_config(state->uart_port, uarg);
>  		break;
> +
> +	case TIOCSADDR:
> +		ret = uart_set_addr(uport, uarg);
> +		break;
> +
> +	case TIOCGADDR:
> +		ret = uart_get_addr(uport, uarg);
> +		break;
> +
>  	default:
>  		if (uport->ops->ioctl)
>  			ret = uport->ops->ioctl(uport, cmd, arg);
> @@ -1540,7 +1599,8 @@ static void uart_set_termios(struct tty_struct *tty,
>  		goto out;
>  	}
>  
> -	tty->termios.c_cflag &= ~ADDRB;
> +	if (!uport->set_addr)
> +		tty->termios.c_cflag &= ~ADDRB;
>  
>  	uart_change_speed(tty, state, old_termios);
>  	/* reload cflag from termios; port driver may have overridden flags */
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index 8fec1d8648f5..ef22b95e9c79 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -2885,6 +2885,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
>  	case TIOCSERGETLSR:
>  	case TIOCGRS485:
>  	case TIOCSRS485:
> +	case TIOCSADDR:
> +	case TIOCGADDR:
>  #ifdef TIOCGETP
>  	case TIOCGETP:
>  	case TIOCSETP:
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index cbd5070bc87f..2dd4c4d01c59 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -135,6 +135,12 @@ struct uart_port {
>  						struct serial_rs485 *rs485);
>  	int			(*iso7816_config)(struct uart_port *,
>  						  struct serial_iso7816 *iso7816);
> +
> +	int			(*set_addr)(struct uart_port *p,
> +					    struct serial_addr *addr);
> +	int			(*get_addr)(struct uart_port *p,
> +					    struct serial_addr *addr);
> +
>  	unsigned int		irq;			/* irq number */
>  	unsigned long		irqflags;		/* irq flags  */
>  	unsigned int		uartclk;		/* base uart clock */
> diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
> index cdc9f4ca8c27..689743366091 100644
> --- a/include/uapi/asm-generic/ioctls.h
> +++ b/include/uapi/asm-generic/ioctls.h
> @@ -106,6 +106,9 @@
>  # define FIOQSIZE	0x5460
>  #endif
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Used for packet mode */
>  #define TIOCPKT_DATA		 0
>  #define TIOCPKT_FLUSHREAD	 1
> diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> index fa6b16e5fdd8..8cb785ea7087 100644
> --- a/include/uapi/linux/serial.h
> +++ b/include/uapi/linux/serial.h
> @@ -149,4 +149,12 @@ struct serial_iso7816 {
>  	__u32	reserved[5];
>  };
>  
> +struct serial_addr {
> +	__u32	flags;
> +#define SER_ADDR_RECV			(1 << 0)
> +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> +#define SER_ADDR_DEST			(1 << 2)

You never check for invalid flags being sent to the kernel, which means
this api can never change in the future to add new flags :(

And what about struct serial_rs485?  Shouldn't that be used here
instead?  Why do we need a new ioctl and structure?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 12:56     ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 12:56 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman

On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> Add generic support for serial multipoint addressing. Two new ioctls
> are added. TIOCSADDR is used to indicate the destination/receive
> address. TIOCGADDR returns the current address in use. The driver
> should implement set_addr and get_addr to support addressing mode.
> 
> Adjust ADDRB clearing to happen only if driver does not provide
> set_addr (=the driver doesn't support address mode).
> 
> This change is necessary for supporting devices with RS485 multipoint
> addressing [*]. A following patch in the patch series adds support for
> Synopsys Designware UART capable for 9th bit addressing mode. In this
> mode, 9th bit is used to indicate an address (byte) within the
> communication line. The 9th bit addressing mode is selected using ADDRB
> introduced by the previous patch.
> 
> Transmit addresses / receiver filter are specified by setting the flags
> SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> address, in the 9bit addressing mode it is sent out immediately with
> the 9th bit set to 1. After that, the subsequent normal data bytes are
> sent with 9th bit as 0 and they are intended to the device with the
> given address. It is up to receiver to enforce the filter using
> SER_ADDR_RECV. When userspace has supplied the receive address, the
> driver is expected to handle the matching of the address and only data
> with that address is forwarded to the user. Both SER_ADDR_DEST and
> SER_ADDR_RECV can be given at the same time in a single call if the
> addresses are the same.
> 
> The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> 
> [*] Technically, RS485 is just an electronic spec and does not itself
> specify the 9th bit addressing mode but 9th bit seems at least
> "semi-standard" way to do addressing with RS485.
> 
> Cc: linux-api@vger.kernel.org
> Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> Cc: Matt Turner <mattst88@gmail.com>
> Cc: linux-alpha@vger.kernel.org
> Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Cc: linux-mips@vger.kernel.org
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: linux-sh@vger.kernel.org
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: sparclinux@vger.kernel.org
> Cc: Chris Zankel <chris@zankel.net>
> Cc: Max Filippov <jcmvbkbc@gmail.com>
> Cc: linux-xtensa@linux-xtensa.org
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: linux-arch@vger.kernel.org
> Cc: linux-doc@vger.kernel.org
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
>  .../driver-api/serial/serial-rs485.rst        | 23 ++++++-
>  arch/alpha/include/uapi/asm/ioctls.h          |  3 +
>  arch/mips/include/uapi/asm/ioctls.h           |  3 +
>  arch/parisc/include/uapi/asm/ioctls.h         |  3 +
>  arch/powerpc/include/uapi/asm/ioctls.h        |  3 +
>  arch/sh/include/uapi/asm/ioctls.h             |  3 +
>  arch/sparc/include/uapi/asm/ioctls.h          |  3 +
>  arch/xtensa/include/uapi/asm/ioctls.h         |  3 +
>  drivers/tty/serial/8250/8250_core.c           |  2 +
>  drivers/tty/serial/serial_core.c              | 62 ++++++++++++++++++-
>  drivers/tty/tty_io.c                          |  2 +
>  include/linux/serial_core.h                   |  6 ++
>  include/uapi/asm-generic/ioctls.h             |  3 +
>  include/uapi/linux/serial.h                   |  8 +++
>  14 files changed, 125 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/driver-api/serial/serial-rs485.rst b/Documentation/driver-api/serial/serial-rs485.rst
> index 6bc824f948f9..2f45f007fa5b 100644
> --- a/Documentation/driver-api/serial/serial-rs485.rst
> +++ b/Documentation/driver-api/serial/serial-rs485.rst
> @@ -95,7 +95,28 @@ RS485 Serial Communications
>  		/* Error handling. See errno. */
>  	}
>  
> -5. References
> +5. Multipoint Addressing
> +========================
> +
> +   The Linux kernel provides serial_addr structure to handle addressing within
> +   multipoint serial communications line such as RS485. 9th bit addressiong mode
> +   is enabled by adding ADDRB flag in termios c_cflag.
> +
> +   Serial core calls device specific set/get_addr in response to TIOCSADDR and
> +   TIOCGADDR ioctls with a pointer to serial_addr. Destination and receive
> +   address can be specified using serial_addr flags field. Receive address may
> +   also be cleared using flags. Once an address is set, the communication
> +   can occur only with the particular device and other peers are filtered out.
> +   It is left up to the receiver side to enforce the filtering.
> +
> +   Address flags:
> +	- SER_ADDR_RECV: Receive (filter) address.
> +	- SER_ADDR_RECV_CLEAR: Clear receive filter (only for TIOCSADDR).
> +	- SER_ADDR_DEST: Destination address.
> +
> +   Note: not all devices supporting RS485 support multipoint addressing.
> +
> +6. References
>  =============
>  
>   [1]	include/uapi/linux/serial.h
> diff --git a/arch/alpha/include/uapi/asm/ioctls.h b/arch/alpha/include/uapi/asm/ioctls.h
> index 971311605288..500cab3e1d6b 100644
> --- a/arch/alpha/include/uapi/asm/ioctls.h
> +++ b/arch/alpha/include/uapi/asm/ioctls.h
> @@ -125,4 +125,7 @@
>  #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* _ASM_ALPHA_IOCTLS_H */
> diff --git a/arch/mips/include/uapi/asm/ioctls.h b/arch/mips/include/uapi/asm/ioctls.h
> index 16aa8a766aec..3859dc46857e 100644
> --- a/arch/mips/include/uapi/asm/ioctls.h
> +++ b/arch/mips/include/uapi/asm/ioctls.h
> @@ -96,6 +96,9 @@
>  #define TIOCGISO7816	_IOR('T', 0x42, struct serial_iso7816)
>  #define TIOCSISO7816	_IOWR('T', 0x43, struct serial_iso7816)
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* I hope the range from 0x5480 on is free ... */
>  #define TIOCSCTTY	0x5480		/* become controlling tty */
>  #define TIOCGSOFTCAR	0x5481
> diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h
> index 82d1148c6379..62337743db64 100644
> --- a/arch/parisc/include/uapi/asm/ioctls.h
> +++ b/arch/parisc/include/uapi/asm/ioctls.h
> @@ -86,6 +86,9 @@
>  #define TIOCSTOP	0x5462
>  #define TIOCSLTC	0x5462
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Used for packet mode */
>  #define TIOCPKT_DATA		 0
>  #define TIOCPKT_FLUSHREAD	 1
> diff --git a/arch/powerpc/include/uapi/asm/ioctls.h b/arch/powerpc/include/uapi/asm/ioctls.h
> index 2c145da3b774..84fd69ac366a 100644
> --- a/arch/powerpc/include/uapi/asm/ioctls.h
> +++ b/arch/powerpc/include/uapi/asm/ioctls.h
> @@ -120,4 +120,7 @@
>  #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif	/* _ASM_POWERPC_IOCTLS_H */
> diff --git a/arch/sh/include/uapi/asm/ioctls.h b/arch/sh/include/uapi/asm/ioctls.h
> index 11866d4f60e1..f82966b7dba2 100644
> --- a/arch/sh/include/uapi/asm/ioctls.h
> +++ b/arch/sh/include/uapi/asm/ioctls.h
> @@ -113,4 +113,7 @@
>  #define TIOCMIWAIT	_IO('T', 92) /* 0x545C */	/* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* __ASM_SH_IOCTLS_H */
> diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
> index 7fd2f5873c9e..e44624c67c79 100644
> --- a/arch/sparc/include/uapi/asm/ioctls.h
> +++ b/arch/sparc/include/uapi/asm/ioctls.h
> @@ -125,6 +125,9 @@
>  #define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Kernel definitions */
>  
>  /* Used for packet mode */
> diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h
> index 6d4a87296c95..759ca9377f2a 100644
> --- a/arch/xtensa/include/uapi/asm/ioctls.h
> +++ b/arch/xtensa/include/uapi/asm/ioctls.h
> @@ -127,4 +127,7 @@
>  #define TIOCMIWAIT	_IO('T', 92) /* wait for a change on serial input line(s) */
>  #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  #endif /* _XTENSA_IOCTLS_H */
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index 01d30f6ed8fb..f67bc3b76f65 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -1008,6 +1008,8 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  		uart->port.rs485	= up->port.rs485;
>  		uart->rs485_start_tx	= up->rs485_start_tx;
>  		uart->rs485_stop_tx	= up->rs485_stop_tx;
> +		uart->port.set_addr	= up->port.set_addr;
> +		uart->port.get_addr	= up->port.get_addr;
>  		uart->dma		= up->dma;
>  
>  		/* Take tx_loadsz from fifosize if it wasn't set separately */
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index 0f397e67eeb0..5762987bf176 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -1397,6 +1397,56 @@ static int uart_set_iso7816_config(struct uart_port *port,
>  	return 0;
>  }
>  
> +static int uart_set_addr(struct uart_port *port,
> +			 struct serial_addr __user *serial_addr_user)
> +{
> +	struct serial_addr addr;
> +	unsigned long flags;
> +	int ret;
> +
> +	if (!port->set_addr)
> +		return -ENOTTY;
> +
> +	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
> +		return -EFAULT;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	ret = port->set_addr(port, &addr);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	if (ret)
> +		return ret;
> +
> +	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
> +static int uart_get_addr(struct uart_port *port,
> +			 struct serial_addr __user *serial_addr_user)
> +{
> +	struct serial_addr addr;
> +	unsigned long flags;
> +	int ret;
> +
> +	if (!port->get_addr)
> +		return -ENOTTY;
> +
> +	if (copy_from_user(&addr, serial_addr_user, sizeof(*serial_addr_user)))
> +		return -EFAULT;
> +
> +	spin_lock_irqsave(&port->lock, flags);
> +	ret = port->get_addr(port, &addr);
> +	spin_unlock_irqrestore(&port->lock, flags);
> +	if (ret)
> +		return ret;
> +
> +	if (copy_to_user(serial_addr_user, &addr, sizeof(addr)))
> +		return -EFAULT;
> +
> +	return 0;
> +}
> +
>  /*
>   * Called via sys_ioctl.  We can use spin_lock_irq() here.
>   */
> @@ -1474,6 +1524,15 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
>  	case TIOCGISO7816:
>  		ret = uart_get_iso7816_config(state->uart_port, uarg);
>  		break;
> +
> +	case TIOCSADDR:
> +		ret = uart_set_addr(uport, uarg);
> +		break;
> +
> +	case TIOCGADDR:
> +		ret = uart_get_addr(uport, uarg);
> +		break;
> +
>  	default:
>  		if (uport->ops->ioctl)
>  			ret = uport->ops->ioctl(uport, cmd, arg);
> @@ -1540,7 +1599,8 @@ static void uart_set_termios(struct tty_struct *tty,
>  		goto out;
>  	}
>  
> -	tty->termios.c_cflag &= ~ADDRB;
> +	if (!uport->set_addr)
> +		tty->termios.c_cflag &= ~ADDRB;
>  
>  	uart_change_speed(tty, state, old_termios);
>  	/* reload cflag from termios; port driver may have overridden flags */
> diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
> index 8fec1d8648f5..ef22b95e9c79 100644
> --- a/drivers/tty/tty_io.c
> +++ b/drivers/tty/tty_io.c
> @@ -2885,6 +2885,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
>  	case TIOCSERGETLSR:
>  	case TIOCGRS485:
>  	case TIOCSRS485:
> +	case TIOCSADDR:
> +	case TIOCGADDR:
>  #ifdef TIOCGETP
>  	case TIOCGETP:
>  	case TIOCSETP:
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index cbd5070bc87f..2dd4c4d01c59 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -135,6 +135,12 @@ struct uart_port {
>  						struct serial_rs485 *rs485);
>  	int			(*iso7816_config)(struct uart_port *,
>  						  struct serial_iso7816 *iso7816);
> +
> +	int			(*set_addr)(struct uart_port *p,
> +					    struct serial_addr *addr);
> +	int			(*get_addr)(struct uart_port *p,
> +					    struct serial_addr *addr);
> +
>  	unsigned int		irq;			/* irq number */
>  	unsigned long		irqflags;		/* irq flags  */
>  	unsigned int		uartclk;		/* base uart clock */
> diff --git a/include/uapi/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
> index cdc9f4ca8c27..689743366091 100644
> --- a/include/uapi/asm-generic/ioctls.h
> +++ b/include/uapi/asm-generic/ioctls.h
> @@ -106,6 +106,9 @@
>  # define FIOQSIZE	0x5460
>  #endif
>  
> +#define TIOCSADDR	_IOWR('T', 0x63, struct serial_addr)
> +#define TIOCGADDR	_IOWR('T', 0x64, struct serial_addr)
> +
>  /* Used for packet mode */
>  #define TIOCPKT_DATA		 0
>  #define TIOCPKT_FLUSHREAD	 1
> diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> index fa6b16e5fdd8..8cb785ea7087 100644
> --- a/include/uapi/linux/serial.h
> +++ b/include/uapi/linux/serial.h
> @@ -149,4 +149,12 @@ struct serial_iso7816 {
>  	__u32	reserved[5];
>  };
>  
> +struct serial_addr {
> +	__u32	flags;
> +#define SER_ADDR_RECV			(1 << 0)
> +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> +#define SER_ADDR_DEST			(1 << 2)

You never check for invalid flags being sent to the kernel, which means
this api can never change in the future to add new flags :(

And what about struct serial_rs485?  Shouldn't that be used here
instead?  Why do we need a new ioctl and structure?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
  2022-04-26 12:52     ` Greg KH
  (?)
@ 2022-04-26 13:12       ` Ilpo Järvinen
  -1 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 13:12 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, David S. Miller, sparclinux, Arnd Bergmann,
	linux-arch, linux-usb

[-- Attachment #1: Type: text/plain, Size: 7351 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > is necessary for supporting devices with RS485 multipoint addressing
> > [*]. A later patch in the patch series adds support for Synopsys
> > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > bit is used to indicate an address (byte) within the communication
> > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > an earlier patch.
> > 
> > [*] Technically, RS485 is just an electronic spec and does not itself
> > specify the 9th bit addressing mode but 9th bit seems at least
> > "semi-standard" way to do addressing with RS485.
> > 
> > Cc: linux-api@vger.kernel.org
> > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > Cc: Matt Turner <mattst88@gmail.com>
> > Cc: linux-alpha@vger.kernel.org
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: linux-mips@vger.kernel.org
> > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: Helge Deller <deller@gmx.de>
> > Cc: linux-parisc@vger.kernel.org
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-usb@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > ---
> >  arch/alpha/include/uapi/asm/termbits.h   | 1 +
> >  arch/mips/include/uapi/asm/termbits.h    | 1 +
> >  arch/parisc/include/uapi/asm/termbits.h  | 1 +
> >  arch/powerpc/include/uapi/asm/termbits.h | 1 +
> >  arch/sparc/include/uapi/asm/termbits.h   | 1 +
> >  drivers/char/pcmcia/synclink_cs.c        | 2 ++
> >  drivers/ipack/devices/ipoctal.c          | 2 ++
> >  drivers/mmc/core/sdio_uart.c             | 2 ++
> >  drivers/net/usb/hso.c                    | 3 ++-
> >  drivers/s390/char/tty3270.c              | 3 +++
> >  drivers/staging/greybus/uart.c           | 2 ++
> >  drivers/tty/amiserial.c                  | 6 +++++-
> >  drivers/tty/moxa.c                       | 1 +
> >  drivers/tty/mxser.c                      | 1 +
> >  drivers/tty/serial/serial_core.c         | 2 ++
> >  drivers/tty/synclink_gt.c                | 2 ++
> >  drivers/tty/tty_ioctl.c                  | 2 ++
> >  drivers/usb/class/cdc-acm.c              | 2 ++
> >  drivers/usb/serial/usb-serial.c          | 6 ++++--
> >  include/uapi/asm-generic/termbits.h      | 1 +
> >  net/bluetooth/rfcomm/tty.c               | 2 ++
> >  21 files changed, 40 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
> > index 4575ba34a0ea..0c123e715486 100644
> > --- a/arch/alpha/include/uapi/asm/termbits.h
> > +++ b/arch/alpha/include/uapi/asm/termbits.h
> > @@ -180,6 +180,7 @@ struct ktermios {
> >  #define HUPCL	00040000
> >  
> >  #define CLOCAL	00100000
> > +#define ADDRB	004000000000		/* address bit */
> >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000		/* flow control */
> >  
> > diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
> > index dfeffba729b7..4732d31b0e4e 100644
> > --- a/arch/mips/include/uapi/asm/termbits.h
> > +++ b/arch/mips/include/uapi/asm/termbits.h
> > @@ -182,6 +182,7 @@ struct ktermios {
> >  #define	 B3500000 0010016
> >  #define	 B4000000 0010017
> >  #define CIBAUD	  002003600000	/* input baud rate */
> > +#define ADDRB	  004000000000	/* address bit */
> >  #define CMSPAR	  010000000000	/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000	/* flow control */
> >  
> > diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
> > index 40e920f8d683..d6bbd10d92ba 100644
> > --- a/arch/parisc/include/uapi/asm/termbits.h
> > +++ b/arch/parisc/include/uapi/asm/termbits.h
> > @@ -159,6 +159,7 @@ struct ktermios {
> >  #define  B3500000 0010016
> >  #define  B4000000 0010017
> >  #define CIBAUD    002003600000		/* input baud rate */
> > +#define ADDRB	  004000000000		/* address bit */
> 
> tabs where the rest were not?
> 
> >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> >  #define CRTSCTS   020000000000          /* flow control */
> >  
> > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > index ed18bc61f63d..c6a033732f39 100644
> > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > @@ -171,6 +171,7 @@ struct ktermios {
> >  #define HUPCL	00040000
> >  
> >  #define CLOCAL	00100000
> > +#define ADDRB	004000000000		/* address bit */
> >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000		/* flow control */
> >  
> > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > index ce5ad5d0f105..5eb1d547b5c4 100644
> > --- a/arch/sparc/include/uapi/asm/termbits.h
> > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > @@ -201,6 +201,7 @@ struct ktermios {
> >  #define B3500000  0x00001012
> >  #define B4000000  0x00001013  */
> >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > +#define ADDRB	  0x20000000  /* address bit */
> >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> >  #define CRTSCTS	  0x80000000  /* flow control */
> 
> Why all the different values?  Can't we pick one and use it for all
> arches?  Having these be different in different arches and userspace
> should not be a thing for new fields, right?
> 
> > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > index 78baba55a8b5..d179b9b57a25 100644
> > --- a/drivers/char/pcmcia/synclink_cs.c
> > +++ b/drivers/char/pcmcia/synclink_cs.c
> > @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
> >  		== RELEVANT_IFLAG(old_termios->c_iflag)))
> >  	  return;
> >  
> > +	tty->termios.c_cflag &= ~ADDRB;
> 
> Having to do this for all drivers feels wrong.  It isn't needed for any
> other flag, right?

My understanding is that it would be needed for other flags too, it's just 
that many drivers probably haven't cared enough. Some drivers certainly 
clear a few flags they don't support while others don't clear any but
it's also challenging to determine it which flags which driver supports. 
How bad the impact is per flag varies.

> That makes me really not like this change as it
> feels very ackward and
> yet-another-thing-a-serial-driver-has-to-remember.

It would be nice to have some mask for supported bits per driver. But it
will be challenging to add at this point and I'm far from sure I could get 
them right per driver even if carefully trying to.

> And as you are wanting to pass this bit to userspace, where is that
> documented?

Ah, I probably should add it to driver-api/serial/driver.rst too but ADDRB
is certainly mentioned alongside with other addressing mode documentation
I wrote for the later changes in this series.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 13:12       ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 13:12 UTC (permalink / raw)
  To: Greg KH
  Cc: Heikki Krogerus, heiko, James E.J. Bottomley, Paul Mackerras,
	sparclinux, Jiri Slaby, linux-arch, Helge Deller, linux-serial,
	Uwe Kleine-König, Matt Turner, Arnd Bergmann, Johan Hovold,
	Vicente Bergas, Ivan Kokshaysky, Andy Shevchenko,
	Thomas Bogendoerfer, linux-parisc, linux-api, linux-usb,
	linux-mips, David S. Miller, Lukas Wunner, linux-alpha,
	linuxppc-dev, giulio.benetti

[-- Attachment #1: Type: text/plain, Size: 7351 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > is necessary for supporting devices with RS485 multipoint addressing
> > [*]. A later patch in the patch series adds support for Synopsys
> > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > bit is used to indicate an address (byte) within the communication
> > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > an earlier patch.
> > 
> > [*] Technically, RS485 is just an electronic spec and does not itself
> > specify the 9th bit addressing mode but 9th bit seems at least
> > "semi-standard" way to do addressing with RS485.
> > 
> > Cc: linux-api@vger.kernel.org
> > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > Cc: Matt Turner <mattst88@gmail.com>
> > Cc: linux-alpha@vger.kernel.org
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: linux-mips@vger.kernel.org
> > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: Helge Deller <deller@gmx.de>
> > Cc: linux-parisc@vger.kernel.org
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-usb@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > ---
> >  arch/alpha/include/uapi/asm/termbits.h   | 1 +
> >  arch/mips/include/uapi/asm/termbits.h    | 1 +
> >  arch/parisc/include/uapi/asm/termbits.h  | 1 +
> >  arch/powerpc/include/uapi/asm/termbits.h | 1 +
> >  arch/sparc/include/uapi/asm/termbits.h   | 1 +
> >  drivers/char/pcmcia/synclink_cs.c        | 2 ++
> >  drivers/ipack/devices/ipoctal.c          | 2 ++
> >  drivers/mmc/core/sdio_uart.c             | 2 ++
> >  drivers/net/usb/hso.c                    | 3 ++-
> >  drivers/s390/char/tty3270.c              | 3 +++
> >  drivers/staging/greybus/uart.c           | 2 ++
> >  drivers/tty/amiserial.c                  | 6 +++++-
> >  drivers/tty/moxa.c                       | 1 +
> >  drivers/tty/mxser.c                      | 1 +
> >  drivers/tty/serial/serial_core.c         | 2 ++
> >  drivers/tty/synclink_gt.c                | 2 ++
> >  drivers/tty/tty_ioctl.c                  | 2 ++
> >  drivers/usb/class/cdc-acm.c              | 2 ++
> >  drivers/usb/serial/usb-serial.c          | 6 ++++--
> >  include/uapi/asm-generic/termbits.h      | 1 +
> >  net/bluetooth/rfcomm/tty.c               | 2 ++
> >  21 files changed, 40 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
> > index 4575ba34a0ea..0c123e715486 100644
> > --- a/arch/alpha/include/uapi/asm/termbits.h
> > +++ b/arch/alpha/include/uapi/asm/termbits.h
> > @@ -180,6 +180,7 @@ struct ktermios {
> >  #define HUPCL	00040000
> >  
> >  #define CLOCAL	00100000
> > +#define ADDRB	004000000000		/* address bit */
> >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000		/* flow control */
> >  
> > diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
> > index dfeffba729b7..4732d31b0e4e 100644
> > --- a/arch/mips/include/uapi/asm/termbits.h
> > +++ b/arch/mips/include/uapi/asm/termbits.h
> > @@ -182,6 +182,7 @@ struct ktermios {
> >  #define	 B3500000 0010016
> >  #define	 B4000000 0010017
> >  #define CIBAUD	  002003600000	/* input baud rate */
> > +#define ADDRB	  004000000000	/* address bit */
> >  #define CMSPAR	  010000000000	/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000	/* flow control */
> >  
> > diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
> > index 40e920f8d683..d6bbd10d92ba 100644
> > --- a/arch/parisc/include/uapi/asm/termbits.h
> > +++ b/arch/parisc/include/uapi/asm/termbits.h
> > @@ -159,6 +159,7 @@ struct ktermios {
> >  #define  B3500000 0010016
> >  #define  B4000000 0010017
> >  #define CIBAUD    002003600000		/* input baud rate */
> > +#define ADDRB	  004000000000		/* address bit */
> 
> tabs where the rest were not?
> 
> >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> >  #define CRTSCTS   020000000000          /* flow control */
> >  
> > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > index ed18bc61f63d..c6a033732f39 100644
> > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > @@ -171,6 +171,7 @@ struct ktermios {
> >  #define HUPCL	00040000
> >  
> >  #define CLOCAL	00100000
> > +#define ADDRB	004000000000		/* address bit */
> >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000		/* flow control */
> >  
> > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > index ce5ad5d0f105..5eb1d547b5c4 100644
> > --- a/arch/sparc/include/uapi/asm/termbits.h
> > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > @@ -201,6 +201,7 @@ struct ktermios {
> >  #define B3500000  0x00001012
> >  #define B4000000  0x00001013  */
> >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > +#define ADDRB	  0x20000000  /* address bit */
> >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> >  #define CRTSCTS	  0x80000000  /* flow control */
> 
> Why all the different values?  Can't we pick one and use it for all
> arches?  Having these be different in different arches and userspace
> should not be a thing for new fields, right?
> 
> > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > index 78baba55a8b5..d179b9b57a25 100644
> > --- a/drivers/char/pcmcia/synclink_cs.c
> > +++ b/drivers/char/pcmcia/synclink_cs.c
> > @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
> >  		== RELEVANT_IFLAG(old_termios->c_iflag)))
> >  	  return;
> >  
> > +	tty->termios.c_cflag &= ~ADDRB;
> 
> Having to do this for all drivers feels wrong.  It isn't needed for any
> other flag, right?

My understanding is that it would be needed for other flags too, it's just 
that many drivers probably haven't cared enough. Some drivers certainly 
clear a few flags they don't support while others don't clear any but
it's also challenging to determine it which flags which driver supports. 
How bad the impact is per flag varies.

> That makes me really not like this change as it
> feels very ackward and
> yet-another-thing-a-serial-driver-has-to-remember.

It would be nice to have some mask for supported bits per driver. But it
will be challenging to add at this point and I'm far from sure I could get 
them right per driver even if carefully trying to.

> And as you are wanting to pass this bit to userspace, where is that
> documented?

Ah, I probably should add it to driver-api/serial/driver.rst too but ADDRB
is certainly mentioned alongside with other addressing mode documentation
I wrote for the later changes in this series.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 13:12       ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 13:12 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

[-- Attachment #1: Type: text/plain, Size: 7511 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > is necessary for supporting devices with RS485 multipoint addressing
> > [*]. A later patch in the patch series adds support for Synopsys
> > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > bit is used to indicate an address (byte) within the communication
> > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > an earlier patch.
> > 
> > [*] Technically, RS485 is just an electronic spec and does not itself
> > specify the 9th bit addressing mode but 9th bit seems at least
> > "semi-standard" way to do addressing with RS485.
> > 
> > Cc: linux-api@vger.kernel.org
> > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > Cc: Matt Turner <mattst88@gmail.com>
> > Cc: linux-alpha@vger.kernel.org
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: linux-mips@vger.kernel.org
> > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: Helge Deller <deller@gmx.de>
> > Cc: linux-parisc@vger.kernel.org
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-usb@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > ---
> >  arch/alpha/include/uapi/asm/termbits.h   | 1 +
> >  arch/mips/include/uapi/asm/termbits.h    | 1 +
> >  arch/parisc/include/uapi/asm/termbits.h  | 1 +
> >  arch/powerpc/include/uapi/asm/termbits.h | 1 +
> >  arch/sparc/include/uapi/asm/termbits.h   | 1 +
> >  drivers/char/pcmcia/synclink_cs.c        | 2 ++
> >  drivers/ipack/devices/ipoctal.c          | 2 ++
> >  drivers/mmc/core/sdio_uart.c             | 2 ++
> >  drivers/net/usb/hso.c                    | 3 ++-
> >  drivers/s390/char/tty3270.c              | 3 +++
> >  drivers/staging/greybus/uart.c           | 2 ++
> >  drivers/tty/amiserial.c                  | 6 +++++-
> >  drivers/tty/moxa.c                       | 1 +
> >  drivers/tty/mxser.c                      | 1 +
> >  drivers/tty/serial/serial_core.c         | 2 ++
> >  drivers/tty/synclink_gt.c                | 2 ++
> >  drivers/tty/tty_ioctl.c                  | 2 ++
> >  drivers/usb/class/cdc-acm.c              | 2 ++
> >  drivers/usb/serial/usb-serial.c          | 6 ++++--
> >  include/uapi/asm-generic/termbits.h      | 1 +
> >  net/bluetooth/rfcomm/tty.c               | 2 ++
> >  21 files changed, 40 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/alpha/include/uapi/asm/termbits.h b/arch/alpha/include/uapi/asm/termbits.h
> > index 4575ba34a0ea..0c123e715486 100644
> > --- a/arch/alpha/include/uapi/asm/termbits.h
> > +++ b/arch/alpha/include/uapi/asm/termbits.h
> > @@ -180,6 +180,7 @@ struct ktermios {
> >  #define HUPCL	00040000
> >  
> >  #define CLOCAL	00100000
> > +#define ADDRB	004000000000		/* address bit */
> >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000		/* flow control */
> >  
> > diff --git a/arch/mips/include/uapi/asm/termbits.h b/arch/mips/include/uapi/asm/termbits.h
> > index dfeffba729b7..4732d31b0e4e 100644
> > --- a/arch/mips/include/uapi/asm/termbits.h
> > +++ b/arch/mips/include/uapi/asm/termbits.h
> > @@ -182,6 +182,7 @@ struct ktermios {
> >  #define	 B3500000 0010016
> >  #define	 B4000000 0010017
> >  #define CIBAUD	  002003600000	/* input baud rate */
> > +#define ADDRB	  004000000000	/* address bit */
> >  #define CMSPAR	  010000000000	/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000	/* flow control */
> >  
> > diff --git a/arch/parisc/include/uapi/asm/termbits.h b/arch/parisc/include/uapi/asm/termbits.h
> > index 40e920f8d683..d6bbd10d92ba 100644
> > --- a/arch/parisc/include/uapi/asm/termbits.h
> > +++ b/arch/parisc/include/uapi/asm/termbits.h
> > @@ -159,6 +159,7 @@ struct ktermios {
> >  #define  B3500000 0010016
> >  #define  B4000000 0010017
> >  #define CIBAUD    002003600000		/* input baud rate */
> > +#define ADDRB	  004000000000		/* address bit */
> 
> tabs where the rest were not?
> 
> >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> >  #define CRTSCTS   020000000000          /* flow control */
> >  
> > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > index ed18bc61f63d..c6a033732f39 100644
> > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > @@ -171,6 +171,7 @@ struct ktermios {
> >  #define HUPCL	00040000
> >  
> >  #define CLOCAL	00100000
> > +#define ADDRB	004000000000		/* address bit */
> >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> >  #define CRTSCTS	  020000000000		/* flow control */
> >  
> > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > index ce5ad5d0f105..5eb1d547b5c4 100644
> > --- a/arch/sparc/include/uapi/asm/termbits.h
> > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > @@ -201,6 +201,7 @@ struct ktermios {
> >  #define B3500000  0x00001012
> >  #define B4000000  0x00001013  */
> >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > +#define ADDRB	  0x20000000  /* address bit */
> >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> >  #define CRTSCTS	  0x80000000  /* flow control */
> 
> Why all the different values?  Can't we pick one and use it for all
> arches?  Having these be different in different arches and userspace
> should not be a thing for new fields, right?
> 
> > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > index 78baba55a8b5..d179b9b57a25 100644
> > --- a/drivers/char/pcmcia/synclink_cs.c
> > +++ b/drivers/char/pcmcia/synclink_cs.c
> > @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
> >  		== RELEVANT_IFLAG(old_termios->c_iflag)))
> >  	  return;
> >  
> > +	tty->termios.c_cflag &= ~ADDRB;
> 
> Having to do this for all drivers feels wrong.  It isn't needed for any
> other flag, right?

My understanding is that it would be needed for other flags too, it's just 
that many drivers probably haven't cared enough. Some drivers certainly 
clear a few flags they don't support while others don't clear any but
it's also challenging to determine it which flags which driver supports. 
How bad the impact is per flag varies.

> That makes me really not like this change as it
> feels very ackward and
> yet-another-thing-a-serial-driver-has-to-remember.

It would be nice to have some mask for supported bits per driver. But it
will be challenging to add at this point and I'm far from sure I could get 
them right per driver even if carefully trying to.

> And as you are wanting to pass this bit to userspace, where is that
> documented?

Ah, I probably should add it to driver-api/serial/driver.rst too but ADDRB
is certainly mentioned alongside with other addressing mode documentation
I wrote for the later changes in this series.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
  2022-04-26 12:56     ` Greg KH
  (?)
@ 2022-04-26 13:36       ` Ilpo Järvinen
  -1 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 13:36 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, Yoshinori Sato, Rich Felker, linux-sh,
	David S. Miller, sparclinux, Chris Zankel, Max Filippov,
	linux-xtensa, Arnd Bergmann, linux-arch, linux-doc

[-- Attachment #1: Type: text/plain, Size: 4705 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> > Add generic support for serial multipoint addressing. Two new ioctls
> > are added. TIOCSADDR is used to indicate the destination/receive
> > address. TIOCGADDR returns the current address in use. The driver
> > should implement set_addr and get_addr to support addressing mode.
> > 
> > Adjust ADDRB clearing to happen only if driver does not provide
> > set_addr (=the driver doesn't support address mode).
> > 
> > This change is necessary for supporting devices with RS485 multipoint
> > addressing [*]. A following patch in the patch series adds support for
> > Synopsys Designware UART capable for 9th bit addressing mode. In this
> > mode, 9th bit is used to indicate an address (byte) within the
> > communication line. The 9th bit addressing mode is selected using ADDRB
> > introduced by the previous patch.
> > 
> > Transmit addresses / receiver filter are specified by setting the flags
> > SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> > address, in the 9bit addressing mode it is sent out immediately with
> > the 9th bit set to 1. After that, the subsequent normal data bytes are
> > sent with 9th bit as 0 and they are intended to the device with the
> > given address. It is up to receiver to enforce the filter using
> > SER_ADDR_RECV. When userspace has supplied the receive address, the
> > driver is expected to handle the matching of the address and only data
> > with that address is forwarded to the user. Both SER_ADDR_DEST and
> > SER_ADDR_RECV can be given at the same time in a single call if the
> > addresses are the same.
> > 
> > The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> > 
> > [*] Technically, RS485 is just an electronic spec and does not itself
> > specify the 9th bit addressing mode but 9th bit seems at least
> > "semi-standard" way to do addressing with RS485.
> > 
> > Cc: linux-api@vger.kernel.org
> > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > Cc: Matt Turner <mattst88@gmail.com>
> > Cc: linux-alpha@vger.kernel.org
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: linux-mips@vger.kernel.org
> > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: Helge Deller <deller@gmx.de>
> > Cc: linux-parisc@vger.kernel.org
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> > Cc: Rich Felker <dalias@libc.org>
> > Cc: linux-sh@vger.kernel.org
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Cc: Chris Zankel <chris@zankel.net>
> > Cc: Max Filippov <jcmvbkbc@gmail.com>
> > Cc: linux-xtensa@linux-xtensa.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-doc@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > ---

> > diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> > index fa6b16e5fdd8..8cb785ea7087 100644
> > --- a/include/uapi/linux/serial.h
> > +++ b/include/uapi/linux/serial.h
> > @@ -149,4 +149,12 @@ struct serial_iso7816 {
> >  	__u32	reserved[5];
> >  };
> >  
> > +struct serial_addr {
> > +	__u32	flags;
> > +#define SER_ADDR_RECV			(1 << 0)
> > +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> > +#define SER_ADDR_DEST			(1 << 2)
> 
> You never check for invalid flags being sent to the kernel, which means
> this api can never change in the future to add new flags :(

Ok, so you mean the general level should to check
if (...->flags & ~(SER_ADDR_FLAGS_ALL))
	return -EINVAL;
?

There's some code in the driver that detects invalid flag combinations 
(in 10/10) but I guess it doesn't satisfies what you're after. It is 
similar to how serial_rs485 flags is handled, that is, clearing flags it 
didn't handle (when it can) and returning -EINVAL for impossible 
combinations such as getting both RECV and DEST addr at the same time.
I don't know if serial_rs485 flags is a good example at all, it certainly 
doesn't check whether bits are set where there's no flag defined.

> And what about struct serial_rs485?  Shouldn't that be used here
> instead?  Why do we need a new ioctl and structure?

It is possible (Lukas already mentioned that option too). It just means
this will be available only on RS485 which could well be enough but Andy 
mentioned he has in the past come across addressing mode also with some 
RS232 thing (he didn't remember details anymore and it could be 
insignificant for the real world of today).


-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 13:36       ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 13:36 UTC (permalink / raw)
  To: Greg KH
  Cc: Heikki Krogerus, heiko, linux-sh, James E.J. Bottomley,
	Max Filippov, Rich Felker, Paul Mackerras, sparclinux,
	Jiri Slaby, linux-arch, Yoshinori Sato, Helge Deller, linux-doc,
	linux-serial, Uwe Kleine-König, Matt Turner, linux-xtensa,
	Arnd Bergmann, Johan Hovold, Vicente Bergas, Ivan Kokshaysky,
	Andy Shevchenko, Chris Zankel, Thomas Bogendoerfer, linux-parisc,
	linux-api, linux-mips, David S. Miller, Lukas Wunner,
	linux-alpha, linuxppc-dev, giulio.benetti

[-- Attachment #1: Type: text/plain, Size: 4705 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> > Add generic support for serial multipoint addressing. Two new ioctls
> > are added. TIOCSADDR is used to indicate the destination/receive
> > address. TIOCGADDR returns the current address in use. The driver
> > should implement set_addr and get_addr to support addressing mode.
> > 
> > Adjust ADDRB clearing to happen only if driver does not provide
> > set_addr (=the driver doesn't support address mode).
> > 
> > This change is necessary for supporting devices with RS485 multipoint
> > addressing [*]. A following patch in the patch series adds support for
> > Synopsys Designware UART capable for 9th bit addressing mode. In this
> > mode, 9th bit is used to indicate an address (byte) within the
> > communication line. The 9th bit addressing mode is selected using ADDRB
> > introduced by the previous patch.
> > 
> > Transmit addresses / receiver filter are specified by setting the flags
> > SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> > address, in the 9bit addressing mode it is sent out immediately with
> > the 9th bit set to 1. After that, the subsequent normal data bytes are
> > sent with 9th bit as 0 and they are intended to the device with the
> > given address. It is up to receiver to enforce the filter using
> > SER_ADDR_RECV. When userspace has supplied the receive address, the
> > driver is expected to handle the matching of the address and only data
> > with that address is forwarded to the user. Both SER_ADDR_DEST and
> > SER_ADDR_RECV can be given at the same time in a single call if the
> > addresses are the same.
> > 
> > The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> > 
> > [*] Technically, RS485 is just an electronic spec and does not itself
> > specify the 9th bit addressing mode but 9th bit seems at least
> > "semi-standard" way to do addressing with RS485.
> > 
> > Cc: linux-api@vger.kernel.org
> > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > Cc: Matt Turner <mattst88@gmail.com>
> > Cc: linux-alpha@vger.kernel.org
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: linux-mips@vger.kernel.org
> > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: Helge Deller <deller@gmx.de>
> > Cc: linux-parisc@vger.kernel.org
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> > Cc: Rich Felker <dalias@libc.org>
> > Cc: linux-sh@vger.kernel.org
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Cc: Chris Zankel <chris@zankel.net>
> > Cc: Max Filippov <jcmvbkbc@gmail.com>
> > Cc: linux-xtensa@linux-xtensa.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-doc@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > ---

> > diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> > index fa6b16e5fdd8..8cb785ea7087 100644
> > --- a/include/uapi/linux/serial.h
> > +++ b/include/uapi/linux/serial.h
> > @@ -149,4 +149,12 @@ struct serial_iso7816 {
> >  	__u32	reserved[5];
> >  };
> >  
> > +struct serial_addr {
> > +	__u32	flags;
> > +#define SER_ADDR_RECV			(1 << 0)
> > +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> > +#define SER_ADDR_DEST			(1 << 2)
> 
> You never check for invalid flags being sent to the kernel, which means
> this api can never change in the future to add new flags :(

Ok, so you mean the general level should to check
if (...->flags & ~(SER_ADDR_FLAGS_ALL))
	return -EINVAL;
?

There's some code in the driver that detects invalid flag combinations 
(in 10/10) but I guess it doesn't satisfies what you're after. It is 
similar to how serial_rs485 flags is handled, that is, clearing flags it 
didn't handle (when it can) and returning -EINVAL for impossible 
combinations such as getting both RECV and DEST addr at the same time.
I don't know if serial_rs485 flags is a good example at all, it certainly 
doesn't check whether bits are set where there's no flag defined.

> And what about struct serial_rs485?  Shouldn't that be used here
> instead?  Why do we need a new ioctl and structure?

It is possible (Lukas already mentioned that option too). It just means
this will be available only on RS485 which could well be enough but Andy 
mentioned he has in the past come across addressing mode also with some 
RS232 thing (he didn't remember details anymore and it could be 
insignificant for the real world of today).


-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 13:36       ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 13:36 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

[-- Attachment #1: Type: text/plain, Size: 4810 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> > Add generic support for serial multipoint addressing. Two new ioctls
> > are added. TIOCSADDR is used to indicate the destination/receive
> > address. TIOCGADDR returns the current address in use. The driver
> > should implement set_addr and get_addr to support addressing mode.
> > 
> > Adjust ADDRB clearing to happen only if driver does not provide
> > set_addr (=the driver doesn't support address mode).
> > 
> > This change is necessary for supporting devices with RS485 multipoint
> > addressing [*]. A following patch in the patch series adds support for
> > Synopsys Designware UART capable for 9th bit addressing mode. In this
> > mode, 9th bit is used to indicate an address (byte) within the
> > communication line. The 9th bit addressing mode is selected using ADDRB
> > introduced by the previous patch.
> > 
> > Transmit addresses / receiver filter are specified by setting the flags
> > SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> > address, in the 9bit addressing mode it is sent out immediately with
> > the 9th bit set to 1. After that, the subsequent normal data bytes are
> > sent with 9th bit as 0 and they are intended to the device with the
> > given address. It is up to receiver to enforce the filter using
> > SER_ADDR_RECV. When userspace has supplied the receive address, the
> > driver is expected to handle the matching of the address and only data
> > with that address is forwarded to the user. Both SER_ADDR_DEST and
> > SER_ADDR_RECV can be given at the same time in a single call if the
> > addresses are the same.
> > 
> > The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> > 
> > [*] Technically, RS485 is just an electronic spec and does not itself
> > specify the 9th bit addressing mode but 9th bit seems at least
> > "semi-standard" way to do addressing with RS485.
> > 
> > Cc: linux-api@vger.kernel.org
> > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > Cc: Matt Turner <mattst88@gmail.com>
> > Cc: linux-alpha@vger.kernel.org
> > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > Cc: linux-mips@vger.kernel.org
> > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > Cc: Helge Deller <deller@gmx.de>
> > Cc: linux-parisc@vger.kernel.org
> > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> > Cc: Rich Felker <dalias@libc.org>
> > Cc: linux-sh@vger.kernel.org
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: sparclinux@vger.kernel.org
> > Cc: Chris Zankel <chris@zankel.net>
> > Cc: Max Filippov <jcmvbkbc@gmail.com>
> > Cc: linux-xtensa@linux-xtensa.org
> > Cc: Arnd Bergmann <arnd@arndb.de>
> > Cc: linux-arch@vger.kernel.org
> > Cc: linux-doc@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > ---

> > diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> > index fa6b16e5fdd8..8cb785ea7087 100644
> > --- a/include/uapi/linux/serial.h
> > +++ b/include/uapi/linux/serial.h
> > @@ -149,4 +149,12 @@ struct serial_iso7816 {
> >  	__u32	reserved[5];
> >  };
> >  
> > +struct serial_addr {
> > +	__u32	flags;
> > +#define SER_ADDR_RECV			(1 << 0)
> > +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> > +#define SER_ADDR_DEST			(1 << 2)
> 
> You never check for invalid flags being sent to the kernel, which means
> this api can never change in the future to add new flags :(

Ok, so you mean the general level should to check
if (...->flags & ~(SER_ADDR_FLAGS_ALL))
	return -EINVAL;
?

There's some code in the driver that detects invalid flag combinations 
(in 10/10) but I guess it doesn't satisfies what you're after. It is 
similar to how serial_rs485 flags is handled, that is, clearing flags it 
didn't handle (when it can) and returning -EINVAL for impossible 
combinations such as getting both RECV and DEST addr at the same time.
I don't know if serial_rs485 flags is a good example at all, it certainly 
doesn't check whether bits are set where there's no flag defined.

> And what about struct serial_rs485?  Shouldn't that be used here
> instead?  Why do we need a new ioctl and structure?

It is possible (Lukas already mentioned that option too). It just means
this will be available only on RS485 which could well be enough but Andy 
mentioned he has in the past come across addressing mode also with some 
RS232 thing (he didn't remember details anymore and it could be 
insignificant for the real world of today).


-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
  2022-04-26 13:36       ` Ilpo Järvinen
  (?)
@ 2022-04-26 13:58         ` Greg KH
  -1 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 13:58 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, Yoshinori Sato, Rich Felker, linux-sh,
	David S. Miller, sparclinux, Chris Zankel, Max Filippov,
	linux-xtensa, Arnd Bergmann, linux-arch, linux-doc

On Tue, Apr 26, 2022 at 04:36:49PM +0300, Ilpo Järvinen wrote:
> On Tue, 26 Apr 2022, Greg KH wrote:
> 
> > On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> > > Add generic support for serial multipoint addressing. Two new ioctls
> > > are added. TIOCSADDR is used to indicate the destination/receive
> > > address. TIOCGADDR returns the current address in use. The driver
> > > should implement set_addr and get_addr to support addressing mode.
> > > 
> > > Adjust ADDRB clearing to happen only if driver does not provide
> > > set_addr (=the driver doesn't support address mode).
> > > 
> > > This change is necessary for supporting devices with RS485 multipoint
> > > addressing [*]. A following patch in the patch series adds support for
> > > Synopsys Designware UART capable for 9th bit addressing mode. In this
> > > mode, 9th bit is used to indicate an address (byte) within the
> > > communication line. The 9th bit addressing mode is selected using ADDRB
> > > introduced by the previous patch.
> > > 
> > > Transmit addresses / receiver filter are specified by setting the flags
> > > SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> > > address, in the 9bit addressing mode it is sent out immediately with
> > > the 9th bit set to 1. After that, the subsequent normal data bytes are
> > > sent with 9th bit as 0 and they are intended to the device with the
> > > given address. It is up to receiver to enforce the filter using
> > > SER_ADDR_RECV. When userspace has supplied the receive address, the
> > > driver is expected to handle the matching of the address and only data
> > > with that address is forwarded to the user. Both SER_ADDR_DEST and
> > > SER_ADDR_RECV can be given at the same time in a single call if the
> > > addresses are the same.
> > > 
> > > The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> > > 
> > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > specify the 9th bit addressing mode but 9th bit seems at least
> > > "semi-standard" way to do addressing with RS485.
> > > 
> > > Cc: linux-api@vger.kernel.org
> > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > Cc: Matt Turner <mattst88@gmail.com>
> > > Cc: linux-alpha@vger.kernel.org
> > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > Cc: linux-mips@vger.kernel.org
> > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > Cc: Helge Deller <deller@gmx.de>
> > > Cc: linux-parisc@vger.kernel.org
> > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Paul Mackerras <paulus@samba.org>
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> > > Cc: Rich Felker <dalias@libc.org>
> > > Cc: linux-sh@vger.kernel.org
> > > Cc: "David S. Miller" <davem@davemloft.net>
> > > Cc: sparclinux@vger.kernel.org
> > > Cc: Chris Zankel <chris@zankel.net>
> > > Cc: Max Filippov <jcmvbkbc@gmail.com>
> > > Cc: linux-xtensa@linux-xtensa.org
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: linux-arch@vger.kernel.org
> > > Cc: linux-doc@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > ---
> 
> > > diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> > > index fa6b16e5fdd8..8cb785ea7087 100644
> > > --- a/include/uapi/linux/serial.h
> > > +++ b/include/uapi/linux/serial.h
> > > @@ -149,4 +149,12 @@ struct serial_iso7816 {
> > >  	__u32	reserved[5];
> > >  };
> > >  
> > > +struct serial_addr {
> > > +	__u32	flags;
> > > +#define SER_ADDR_RECV			(1 << 0)
> > > +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> > > +#define SER_ADDR_DEST			(1 << 2)
> > 
> > You never check for invalid flags being sent to the kernel, which means
> > this api can never change in the future to add new flags :(
> 
> Ok, so you mean the general level should to check
> if (...->flags & ~(SER_ADDR_FLAGS_ALL))
> 	return -EINVAL;
> ?

For any new kernel api you always have to ensure that no "extra" flags
or bits are set and reject it otherwise you can never add any more bits
or flags in the future.  This should be in the Documentation/ directory
for how to add new ioctls somewhere.

> There's some code in the driver that detects invalid flag combinations 
> (in 10/10) but I guess it doesn't satisfies what you're after. It is 
> similar to how serial_rs485 flags is handled, that is, clearing flags it 
> didn't handle (when it can) and returning -EINVAL for impossible 
> combinations such as getting both RECV and DEST addr at the same time.
> I don't know if serial_rs485 flags is a good example at all, it certainly 
> doesn't check whether bits are set where there's no flag defined.
> 
> > And what about struct serial_rs485?  Shouldn't that be used here
> > instead?  Why do we need a new ioctl and structure?
> 
> It is possible (Lukas already mentioned that option too). It just means
> this will be available only on RS485 which could well be enough but Andy 
> mentioned he has in the past come across addressing mode also with some 
> RS232 thing (he didn't remember details anymore and it could be 
> insignificant for the real world of today).

This is rs485 so let's keep it attached to that.  Lots of people do
their own custom addressing schemes on top of 232 but that's up to them
to support in userspace or as a line discipline.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 13:58         ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 13:58 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Heikki Krogerus, heiko, linux-sh, James E.J. Bottomley,
	Max Filippov, Rich Felker, Paul Mackerras, sparclinux,
	Jiri Slaby, linux-arch, Yoshinori Sato, Helge Deller, linux-doc,
	linux-serial, Uwe Kleine-König, Matt Turner, linux-xtensa,
	Arnd Bergmann, Johan Hovold, Vicente Bergas, Ivan Kokshaysky,
	Andy Shevchenko, Chris Zankel, Thomas Bogendoerfer, linux-parisc,
	linux-api, linux-mips, David S. Miller, Lukas Wunner,
	linux-alpha, linuxppc-dev, giulio.benetti

On Tue, Apr 26, 2022 at 04:36:49PM +0300, Ilpo Järvinen wrote:
> On Tue, 26 Apr 2022, Greg KH wrote:
> 
> > On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> > > Add generic support for serial multipoint addressing. Two new ioctls
> > > are added. TIOCSADDR is used to indicate the destination/receive
> > > address. TIOCGADDR returns the current address in use. The driver
> > > should implement set_addr and get_addr to support addressing mode.
> > > 
> > > Adjust ADDRB clearing to happen only if driver does not provide
> > > set_addr (=the driver doesn't support address mode).
> > > 
> > > This change is necessary for supporting devices with RS485 multipoint
> > > addressing [*]. A following patch in the patch series adds support for
> > > Synopsys Designware UART capable for 9th bit addressing mode. In this
> > > mode, 9th bit is used to indicate an address (byte) within the
> > > communication line. The 9th bit addressing mode is selected using ADDRB
> > > introduced by the previous patch.
> > > 
> > > Transmit addresses / receiver filter are specified by setting the flags
> > > SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> > > address, in the 9bit addressing mode it is sent out immediately with
> > > the 9th bit set to 1. After that, the subsequent normal data bytes are
> > > sent with 9th bit as 0 and they are intended to the device with the
> > > given address. It is up to receiver to enforce the filter using
> > > SER_ADDR_RECV. When userspace has supplied the receive address, the
> > > driver is expected to handle the matching of the address and only data
> > > with that address is forwarded to the user. Both SER_ADDR_DEST and
> > > SER_ADDR_RECV can be given at the same time in a single call if the
> > > addresses are the same.
> > > 
> > > The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> > > 
> > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > specify the 9th bit addressing mode but 9th bit seems at least
> > > "semi-standard" way to do addressing with RS485.
> > > 
> > > Cc: linux-api@vger.kernel.org
> > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > Cc: Matt Turner <mattst88@gmail.com>
> > > Cc: linux-alpha@vger.kernel.org
> > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > Cc: linux-mips@vger.kernel.org
> > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > Cc: Helge Deller <deller@gmx.de>
> > > Cc: linux-parisc@vger.kernel.org
> > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Paul Mackerras <paulus@samba.org>
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> > > Cc: Rich Felker <dalias@libc.org>
> > > Cc: linux-sh@vger.kernel.org
> > > Cc: "David S. Miller" <davem@davemloft.net>
> > > Cc: sparclinux@vger.kernel.org
> > > Cc: Chris Zankel <chris@zankel.net>
> > > Cc: Max Filippov <jcmvbkbc@gmail.com>
> > > Cc: linux-xtensa@linux-xtensa.org
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: linux-arch@vger.kernel.org
> > > Cc: linux-doc@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > ---
> 
> > > diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> > > index fa6b16e5fdd8..8cb785ea7087 100644
> > > --- a/include/uapi/linux/serial.h
> > > +++ b/include/uapi/linux/serial.h
> > > @@ -149,4 +149,12 @@ struct serial_iso7816 {
> > >  	__u32	reserved[5];
> > >  };
> > >  
> > > +struct serial_addr {
> > > +	__u32	flags;
> > > +#define SER_ADDR_RECV			(1 << 0)
> > > +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> > > +#define SER_ADDR_DEST			(1 << 2)
> > 
> > You never check for invalid flags being sent to the kernel, which means
> > this api can never change in the future to add new flags :(
> 
> Ok, so you mean the general level should to check
> if (...->flags & ~(SER_ADDR_FLAGS_ALL))
> 	return -EINVAL;
> ?

For any new kernel api you always have to ensure that no "extra" flags
or bits are set and reject it otherwise you can never add any more bits
or flags in the future.  This should be in the Documentation/ directory
for how to add new ioctls somewhere.

> There's some code in the driver that detects invalid flag combinations 
> (in 10/10) but I guess it doesn't satisfies what you're after. It is 
> similar to how serial_rs485 flags is handled, that is, clearing flags it 
> didn't handle (when it can) and returning -EINVAL for impossible 
> combinations such as getting both RECV and DEST addr at the same time.
> I don't know if serial_rs485 flags is a good example at all, it certainly 
> doesn't check whether bits are set where there's no flag defined.
> 
> > And what about struct serial_rs485?  Shouldn't that be used here
> > instead?  Why do we need a new ioctl and structure?
> 
> It is possible (Lukas already mentioned that option too). It just means
> this will be available only on RS485 which could well be enough but Andy 
> mentioned he has in the past come across addressing mode also with some 
> RS232 thing (he didn't remember details anymore and it could be 
> insignificant for the real world of today).

This is rs485 so let's keep it attached to that.  Lots of people do
their own custom addressing schemes on top of 232 but that's up to them
to support in userspace or as a line discipline.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 06/10] serial: General support for multipoint addresses
@ 2022-04-26 13:58         ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 13:58 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

On Tue, Apr 26, 2022 at 04:36:49PM +0300, Ilpo Järvinen wrote:
> On Tue, 26 Apr 2022, Greg KH wrote:
> 
> > On Tue, Apr 26, 2022 at 03:24:44PM +0300, Ilpo Järvinen wrote:
> > > Add generic support for serial multipoint addressing. Two new ioctls
> > > are added. TIOCSADDR is used to indicate the destination/receive
> > > address. TIOCGADDR returns the current address in use. The driver
> > > should implement set_addr and get_addr to support addressing mode.
> > > 
> > > Adjust ADDRB clearing to happen only if driver does not provide
> > > set_addr (=the driver doesn't support address mode).
> > > 
> > > This change is necessary for supporting devices with RS485 multipoint
> > > addressing [*]. A following patch in the patch series adds support for
> > > Synopsys Designware UART capable for 9th bit addressing mode. In this
> > > mode, 9th bit is used to indicate an address (byte) within the
> > > communication line. The 9th bit addressing mode is selected using ADDRB
> > > introduced by the previous patch.
> > > 
> > > Transmit addresses / receiver filter are specified by setting the flags
> > > SER_ADDR_DEST and/or SER_ADDR_RECV. When the user supplies the transmit
> > > address, in the 9bit addressing mode it is sent out immediately with
> > > the 9th bit set to 1. After that, the subsequent normal data bytes are
> > > sent with 9th bit as 0 and they are intended to the device with the
> > > given address. It is up to receiver to enforce the filter using
> > > SER_ADDR_RECV. When userspace has supplied the receive address, the
> > > driver is expected to handle the matching of the address and only data
> > > with that address is forwarded to the user. Both SER_ADDR_DEST and
> > > SER_ADDR_RECV can be given at the same time in a single call if the
> > > addresses are the same.
> > > 
> > > The user can clear the receive filter with SER_ADDR_RECV_CLEAR.
> > > 
> > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > specify the 9th bit addressing mode but 9th bit seems at least
> > > "semi-standard" way to do addressing with RS485.
> > > 
> > > Cc: linux-api@vger.kernel.org
> > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > Cc: Matt Turner <mattst88@gmail.com>
> > > Cc: linux-alpha@vger.kernel.org
> > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > Cc: linux-mips@vger.kernel.org
> > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > Cc: Helge Deller <deller@gmx.de>
> > > Cc: linux-parisc@vger.kernel.org
> > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Paul Mackerras <paulus@samba.org>
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> > > Cc: Rich Felker <dalias@libc.org>
> > > Cc: linux-sh@vger.kernel.org
> > > Cc: "David S. Miller" <davem@davemloft.net>
> > > Cc: sparclinux@vger.kernel.org
> > > Cc: Chris Zankel <chris@zankel.net>
> > > Cc: Max Filippov <jcmvbkbc@gmail.com>
> > > Cc: linux-xtensa@linux-xtensa.org
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: linux-arch@vger.kernel.org
> > > Cc: linux-doc@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > ---
> 
> > > diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
> > > index fa6b16e5fdd8..8cb785ea7087 100644
> > > --- a/include/uapi/linux/serial.h
> > > +++ b/include/uapi/linux/serial.h
> > > @@ -149,4 +149,12 @@ struct serial_iso7816 {
> > >  	__u32	reserved[5];
> > >  };
> > >  
> > > +struct serial_addr {
> > > +	__u32	flags;
> > > +#define SER_ADDR_RECV			(1 << 0)
> > > +#define SER_ADDR_RECV_CLEAR		(1 << 1)
> > > +#define SER_ADDR_DEST			(1 << 2)
> > 
> > You never check for invalid flags being sent to the kernel, which means
> > this api can never change in the future to add new flags :(
> 
> Ok, so you mean the general level should to check
> if (...->flags & ~(SER_ADDR_FLAGS_ALL))
> 	return -EINVAL;
> ?

For any new kernel api you always have to ensure that no "extra" flags
or bits are set and reject it otherwise you can never add any more bits
or flags in the future.  This should be in the Documentation/ directory
for how to add new ioctls somewhere.

> There's some code in the driver that detects invalid flag combinations 
> (in 10/10) but I guess it doesn't satisfies what you're after. It is 
> similar to how serial_rs485 flags is handled, that is, clearing flags it 
> didn't handle (when it can) and returning -EINVAL for impossible 
> combinations such as getting both RECV and DEST addr at the same time.
> I don't know if serial_rs485 flags is a good example at all, it certainly 
> doesn't check whether bits are set where there's no flag defined.
> 
> > And what about struct serial_rs485?  Shouldn't that be used here
> > instead?  Why do we need a new ioctl and structure?
> 
> It is possible (Lukas already mentioned that option too). It just means
> this will be available only on RS485 which could well be enough but Andy 
> mentioned he has in the past come across addressing mode also with some 
> RS232 thing (he didn't remember details anymore and it could be 
> insignificant for the real world of today).

This is rs485 so let's keep it attached to that.  Lots of people do
their own custom addressing schemes on top of 232 but that's up to them
to support in userspace or as a line discipline.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
  2022-04-26 13:12       ` Ilpo Järvinen
  (?)
@ 2022-04-26 14:01         ` Ilpo Järvinen
  -1 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 14:01 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Greg KH, linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, David S. Miller, sparclinux, Arnd Bergmann,
	linux-arch, linux-usb

[-- Attachment #1: Type: text/plain, Size: 5122 bytes --]

One additional thing below I missed on the first read.

On Tue, 26 Apr 2022, Ilpo Järvinen wrote:
> On Tue, 26 Apr 2022, Greg KH wrote:
> 
> > On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > > is necessary for supporting devices with RS485 multipoint addressing
> > > [*]. A later patch in the patch series adds support for Synopsys
> > > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > > bit is used to indicate an address (byte) within the communication
> > > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > > an earlier patch.
> > > 
> > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > specify the 9th bit addressing mode but 9th bit seems at least
> > > "semi-standard" way to do addressing with RS485.
> > > 
> > > Cc: linux-api@vger.kernel.org
> > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > Cc: Matt Turner <mattst88@gmail.com>
> > > Cc: linux-alpha@vger.kernel.org
> > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > Cc: linux-mips@vger.kernel.org
> > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > Cc: Helge Deller <deller@gmx.de>
> > > Cc: linux-parisc@vger.kernel.org
> > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Paul Mackerras <paulus@samba.org>
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: "David S. Miller" <davem@davemloft.net>
> > > Cc: sparclinux@vger.kernel.org
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: linux-arch@vger.kernel.org
> > > Cc: linux-usb@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > ---

> > >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> > >  #define CRTSCTS   020000000000          /* flow control */
> > >  
> > > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > > index ed18bc61f63d..c6a033732f39 100644
> > > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > > @@ -171,6 +171,7 @@ struct ktermios {
> > >  #define HUPCL	00040000
> > >  
> > >  #define CLOCAL	00100000
> > > +#define ADDRB	004000000000		/* address bit */
> > >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> > >  #define CRTSCTS	  020000000000		/* flow control */
> > >  
> > > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > > index ce5ad5d0f105..5eb1d547b5c4 100644
> > > --- a/arch/sparc/include/uapi/asm/termbits.h
> > > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > > @@ -201,6 +201,7 @@ struct ktermios {
> > >  #define B3500000  0x00001012
> > >  #define B4000000  0x00001013  */
> > >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > > +#define ADDRB	  0x20000000  /* address bit */
> > >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> > >  #define CRTSCTS	  0x80000000  /* flow control */
> > 
> > Why all the different values?  Can't we pick one and use it for all
> > arches?  Having these be different in different arches and userspace
> > should not be a thing for new fields, right?

ADDRB value is the same for all archs (it's just this octal vs hex 
notation I've followed as per the nearby defines within the same file
which makes them look different).

Should I perhaps add to my cleanup list conversion of all those octal ones 
to hex?

> > > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > > index 78baba55a8b5..d179b9b57a25 100644
> > > --- a/drivers/char/pcmcia/synclink_cs.c
> > > +++ b/drivers/char/pcmcia/synclink_cs.c
> > > @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
> > >  		== RELEVANT_IFLAG(old_termios->c_iflag)))
> > >  	  return;
> > >  
> > > +	tty->termios.c_cflag &= ~ADDRB;
> > 
> > Having to do this for all drivers feels wrong.  It isn't needed for any
> > other flag, right?
> 
> My understanding is that it would be needed for other flags too, it's just 
> that many drivers probably haven't cared enough. Some drivers certainly 
> clear a few flags they don't support while others don't clear any but
> it's also challenging to determine it which flags which driver supports. 
> How bad the impact is per flag varies.
> 
> > That makes me really not like this change as it
> > feels very ackward and
> > yet-another-thing-a-serial-driver-has-to-remember.
> 
> It would be nice to have some mask for supported bits per driver. But it
> will be challenging to add at this point and I'm far from sure I could get 
> them right per driver even if carefully trying to.
> 
> > And as you are wanting to pass this bit to userspace, where is that
> > documented?
> 
> Ah, I probably should add it to driver-api/serial/driver.rst too but ADDRB
> is certainly mentioned alongside with other addressing mode documentation
> I wrote for the later changes in this series.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 14:01         ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 14:01 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Heikki Krogerus, heiko, James E.J. Bottomley, Paul Mackerras,
	sparclinux, linux-api, Jiri Slaby, linux-arch, Helge Deller,
	linux-serial, Uwe Kleine-König, Matt Turner, Arnd Bergmann,
	Johan Hovold, Vicente Bergas, Ivan Kokshaysky, Andy Shevchenko,
	Thomas Bogendoerfer, linux-parisc, Greg KH, linux-usb,
	linux-mips, David S. Miller, Lukas Wunner, linux-alpha,
	linuxppc-dev, giulio.benetti

[-- Attachment #1: Type: text/plain, Size: 5122 bytes --]

One additional thing below I missed on the first read.

On Tue, 26 Apr 2022, Ilpo Järvinen wrote:
> On Tue, 26 Apr 2022, Greg KH wrote:
> 
> > On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > > is necessary for supporting devices with RS485 multipoint addressing
> > > [*]. A later patch in the patch series adds support for Synopsys
> > > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > > bit is used to indicate an address (byte) within the communication
> > > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > > an earlier patch.
> > > 
> > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > specify the 9th bit addressing mode but 9th bit seems at least
> > > "semi-standard" way to do addressing with RS485.
> > > 
> > > Cc: linux-api@vger.kernel.org
> > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > Cc: Matt Turner <mattst88@gmail.com>
> > > Cc: linux-alpha@vger.kernel.org
> > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > Cc: linux-mips@vger.kernel.org
> > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > Cc: Helge Deller <deller@gmx.de>
> > > Cc: linux-parisc@vger.kernel.org
> > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Paul Mackerras <paulus@samba.org>
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: "David S. Miller" <davem@davemloft.net>
> > > Cc: sparclinux@vger.kernel.org
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: linux-arch@vger.kernel.org
> > > Cc: linux-usb@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > ---

> > >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> > >  #define CRTSCTS   020000000000          /* flow control */
> > >  
> > > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > > index ed18bc61f63d..c6a033732f39 100644
> > > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > > @@ -171,6 +171,7 @@ struct ktermios {
> > >  #define HUPCL	00040000
> > >  
> > >  #define CLOCAL	00100000
> > > +#define ADDRB	004000000000		/* address bit */
> > >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> > >  #define CRTSCTS	  020000000000		/* flow control */
> > >  
> > > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > > index ce5ad5d0f105..5eb1d547b5c4 100644
> > > --- a/arch/sparc/include/uapi/asm/termbits.h
> > > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > > @@ -201,6 +201,7 @@ struct ktermios {
> > >  #define B3500000  0x00001012
> > >  #define B4000000  0x00001013  */
> > >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > > +#define ADDRB	  0x20000000  /* address bit */
> > >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> > >  #define CRTSCTS	  0x80000000  /* flow control */
> > 
> > Why all the different values?  Can't we pick one and use it for all
> > arches?  Having these be different in different arches and userspace
> > should not be a thing for new fields, right?

ADDRB value is the same for all archs (it's just this octal vs hex 
notation I've followed as per the nearby defines within the same file
which makes them look different).

Should I perhaps add to my cleanup list conversion of all those octal ones 
to hex?

> > > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > > index 78baba55a8b5..d179b9b57a25 100644
> > > --- a/drivers/char/pcmcia/synclink_cs.c
> > > +++ b/drivers/char/pcmcia/synclink_cs.c
> > > @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
> > >  		== RELEVANT_IFLAG(old_termios->c_iflag)))
> > >  	  return;
> > >  
> > > +	tty->termios.c_cflag &= ~ADDRB;
> > 
> > Having to do this for all drivers feels wrong.  It isn't needed for any
> > other flag, right?
> 
> My understanding is that it would be needed for other flags too, it's just 
> that many drivers probably haven't cared enough. Some drivers certainly 
> clear a few flags they don't support while others don't clear any but
> it's also challenging to determine it which flags which driver supports. 
> How bad the impact is per flag varies.
> 
> > That makes me really not like this change as it
> > feels very ackward and
> > yet-another-thing-a-serial-driver-has-to-remember.
> 
> It would be nice to have some mask for supported bits per driver. But it
> will be challenging to add at this point and I'm far from sure I could get 
> them right per driver even if carefully trying to.
> 
> > And as you are wanting to pass this bit to userspace, where is that
> > documented?
> 
> Ah, I probably should add it to driver-api/serial/driver.rst too but ADDRB
> is certainly mentioned alongside with other addressing mode documentation
> I wrote for the later changes in this series.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 14:01         ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 14:01 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Greg KH, linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller

[-- Attachment #1: Type: text/plain, Size: 5234 bytes --]

One additional thing below I missed on the first read.

On Tue, 26 Apr 2022, Ilpo Järvinen wrote:
> On Tue, 26 Apr 2022, Greg KH wrote:
> 
> > On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > > is necessary for supporting devices with RS485 multipoint addressing
> > > [*]. A later patch in the patch series adds support for Synopsys
> > > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > > bit is used to indicate an address (byte) within the communication
> > > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > > an earlier patch.
> > > 
> > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > specify the 9th bit addressing mode but 9th bit seems at least
> > > "semi-standard" way to do addressing with RS485.
> > > 
> > > Cc: linux-api@vger.kernel.org
> > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > Cc: Matt Turner <mattst88@gmail.com>
> > > Cc: linux-alpha@vger.kernel.org
> > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > Cc: linux-mips@vger.kernel.org
> > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > Cc: Helge Deller <deller@gmx.de>
> > > Cc: linux-parisc@vger.kernel.org
> > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > Cc: Paul Mackerras <paulus@samba.org>
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: "David S. Miller" <davem@davemloft.net>
> > > Cc: sparclinux@vger.kernel.org
> > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > Cc: linux-arch@vger.kernel.org
> > > Cc: linux-usb@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > ---

> > >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> > >  #define CRTSCTS   020000000000          /* flow control */
> > >  
> > > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > > index ed18bc61f63d..c6a033732f39 100644
> > > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > > @@ -171,6 +171,7 @@ struct ktermios {
> > >  #define HUPCL	00040000
> > >  
> > >  #define CLOCAL	00100000
> > > +#define ADDRB	004000000000		/* address bit */
> > >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> > >  #define CRTSCTS	  020000000000		/* flow control */
> > >  
> > > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > > index ce5ad5d0f105..5eb1d547b5c4 100644
> > > --- a/arch/sparc/include/uapi/asm/termbits.h
> > > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > > @@ -201,6 +201,7 @@ struct ktermios {
> > >  #define B3500000  0x00001012
> > >  #define B4000000  0x00001013  */
> > >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > > +#define ADDRB	  0x20000000  /* address bit */
> > >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> > >  #define CRTSCTS	  0x80000000  /* flow control */
> > 
> > Why all the different values?  Can't we pick one and use it for all
> > arches?  Having these be different in different arches and userspace
> > should not be a thing for new fields, right?

ADDRB value is the same for all archs (it's just this octal vs hex 
notation I've followed as per the nearby defines within the same file
which makes them look different).

Should I perhaps add to my cleanup list conversion of all those octal ones 
to hex?

> > > diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
> > > index 78baba55a8b5..d179b9b57a25 100644
> > > --- a/drivers/char/pcmcia/synclink_cs.c
> > > +++ b/drivers/char/pcmcia/synclink_cs.c
> > > @@ -2287,6 +2287,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
> > >  		== RELEVANT_IFLAG(old_termios->c_iflag)))
> > >  	  return;
> > >  
> > > +	tty->termios.c_cflag &= ~ADDRB;
> > 
> > Having to do this for all drivers feels wrong.  It isn't needed for any
> > other flag, right?
> 
> My understanding is that it would be needed for other flags too, it's just 
> that many drivers probably haven't cared enough. Some drivers certainly 
> clear a few flags they don't support while others don't clear any but
> it's also challenging to determine it which flags which driver supports. 
> How bad the impact is per flag varies.
> 
> > That makes me really not like this change as it
> > feels very ackward and
> > yet-another-thing-a-serial-driver-has-to-remember.
> 
> It would be nice to have some mask for supported bits per driver. But it
> will be challenging to add at this point and I'm far from sure I could get 
> them right per driver even if carefully trying to.
> 
> > And as you are wanting to pass this bit to userspace, where is that
> > documented?
> 
> Ah, I probably should add it to driver-api/serial/driver.rst too but ADDRB
> is certainly mentioned alongside with other addressing mode documentation
> I wrote for the later changes in this series.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
  2022-04-26 14:01         ` Ilpo Järvinen
  (?)
@ 2022-04-26 14:10           ` Greg KH
  -1 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 14:10 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, David S. Miller, sparclinux, Arnd Bergmann,
	linux-arch, linux-usb

On Tue, Apr 26, 2022 at 05:01:31PM +0300, Ilpo Järvinen wrote:
> One additional thing below I missed on the first read.
> 
> On Tue, 26 Apr 2022, Ilpo Järvinen wrote:
> > On Tue, 26 Apr 2022, Greg KH wrote:
> > 
> > > On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > > > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > > > is necessary for supporting devices with RS485 multipoint addressing
> > > > [*]. A later patch in the patch series adds support for Synopsys
> > > > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > > > bit is used to indicate an address (byte) within the communication
> > > > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > > > an earlier patch.
> > > > 
> > > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > > specify the 9th bit addressing mode but 9th bit seems at least
> > > > "semi-standard" way to do addressing with RS485.
> > > > 
> > > > Cc: linux-api@vger.kernel.org
> > > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > > Cc: Matt Turner <mattst88@gmail.com>
> > > > Cc: linux-alpha@vger.kernel.org
> > > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > > Cc: linux-mips@vger.kernel.org
> > > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > > Cc: Helge Deller <deller@gmx.de>
> > > > Cc: linux-parisc@vger.kernel.org
> > > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Paul Mackerras <paulus@samba.org>
> > > > Cc: linuxppc-dev@lists.ozlabs.org
> > > > Cc: "David S. Miller" <davem@davemloft.net>
> > > > Cc: sparclinux@vger.kernel.org
> > > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > > Cc: linux-arch@vger.kernel.org
> > > > Cc: linux-usb@vger.kernel.org
> > > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > > ---
> 
> > > >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> > > >  #define CRTSCTS   020000000000          /* flow control */
> > > >  
> > > > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > > > index ed18bc61f63d..c6a033732f39 100644
> > > > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > > > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > > > @@ -171,6 +171,7 @@ struct ktermios {
> > > >  #define HUPCL	00040000
> > > >  
> > > >  #define CLOCAL	00100000
> > > > +#define ADDRB	004000000000		/* address bit */
> > > >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> > > >  #define CRTSCTS	  020000000000		/* flow control */
> > > >  
> > > > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > > > index ce5ad5d0f105..5eb1d547b5c4 100644
> > > > --- a/arch/sparc/include/uapi/asm/termbits.h
> > > > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > > > @@ -201,6 +201,7 @@ struct ktermios {
> > > >  #define B3500000  0x00001012
> > > >  #define B4000000  0x00001013  */
> > > >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > > > +#define ADDRB	  0x20000000  /* address bit */
> > > >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> > > >  #define CRTSCTS	  0x80000000  /* flow control */
> > > 
> > > Why all the different values?  Can't we pick one and use it for all
> > > arches?  Having these be different in different arches and userspace
> > > should not be a thing for new fields, right?
> 
> ADDRB value is the same for all archs (it's just this octal vs hex 
> notation I've followed as per the nearby defines within the same file
> which makes them look different).
> 
> Should I perhaps add to my cleanup list conversion of all those octal ones 
> to hex?

Argh, yes, please, let's do that now, I totally missed that.  Will let
us see how to unify them as well.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 14:10           ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 14:10 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Heikki Krogerus, heiko, James E.J. Bottomley, Paul Mackerras,
	sparclinux, Jiri Slaby, linux-arch, Helge Deller, linux-serial,
	Uwe Kleine-König, Matt Turner, Arnd Bergmann, Johan Hovold,
	Vicente Bergas, Ivan Kokshaysky, Andy Shevchenko,
	Thomas Bogendoerfer, linux-parisc, linux-api, linux-usb,
	linux-mips, David S. Miller, Lukas Wunner, linux-alpha,
	linuxppc-dev, giulio.benetti

On Tue, Apr 26, 2022 at 05:01:31PM +0300, Ilpo Järvinen wrote:
> One additional thing below I missed on the first read.
> 
> On Tue, 26 Apr 2022, Ilpo Järvinen wrote:
> > On Tue, 26 Apr 2022, Greg KH wrote:
> > 
> > > On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > > > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > > > is necessary for supporting devices with RS485 multipoint addressing
> > > > [*]. A later patch in the patch series adds support for Synopsys
> > > > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > > > bit is used to indicate an address (byte) within the communication
> > > > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > > > an earlier patch.
> > > > 
> > > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > > specify the 9th bit addressing mode but 9th bit seems at least
> > > > "semi-standard" way to do addressing with RS485.
> > > > 
> > > > Cc: linux-api@vger.kernel.org
> > > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > > Cc: Matt Turner <mattst88@gmail.com>
> > > > Cc: linux-alpha@vger.kernel.org
> > > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > > Cc: linux-mips@vger.kernel.org
> > > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > > Cc: Helge Deller <deller@gmx.de>
> > > > Cc: linux-parisc@vger.kernel.org
> > > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Paul Mackerras <paulus@samba.org>
> > > > Cc: linuxppc-dev@lists.ozlabs.org
> > > > Cc: "David S. Miller" <davem@davemloft.net>
> > > > Cc: sparclinux@vger.kernel.org
> > > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > > Cc: linux-arch@vger.kernel.org
> > > > Cc: linux-usb@vger.kernel.org
> > > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > > ---
> 
> > > >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> > > >  #define CRTSCTS   020000000000          /* flow control */
> > > >  
> > > > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > > > index ed18bc61f63d..c6a033732f39 100644
> > > > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > > > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > > > @@ -171,6 +171,7 @@ struct ktermios {
> > > >  #define HUPCL	00040000
> > > >  
> > > >  #define CLOCAL	00100000
> > > > +#define ADDRB	004000000000		/* address bit */
> > > >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> > > >  #define CRTSCTS	  020000000000		/* flow control */
> > > >  
> > > > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > > > index ce5ad5d0f105..5eb1d547b5c4 100644
> > > > --- a/arch/sparc/include/uapi/asm/termbits.h
> > > > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > > > @@ -201,6 +201,7 @@ struct ktermios {
> > > >  #define B3500000  0x00001012
> > > >  #define B4000000  0x00001013  */
> > > >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > > > +#define ADDRB	  0x20000000  /* address bit */
> > > >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> > > >  #define CRTSCTS	  0x80000000  /* flow control */
> > > 
> > > Why all the different values?  Can't we pick one and use it for all
> > > arches?  Having these be different in different arches and userspace
> > > should not be a thing for new fields, right?
> 
> ADDRB value is the same for all archs (it's just this octal vs hex 
> notation I've followed as per the nearby defines within the same file
> which makes them look different).
> 
> Should I perhaps add to my cleanup list conversion of all those octal ones 
> to hex?

Argh, yes, please, let's do that now, I totally missed that.  Will let
us see how to unify them as well.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 14:10           ` Greg KH
  0 siblings, 0 replies; 40+ messages in thread
From: Greg KH @ 2022-04-26 14:10 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

On Tue, Apr 26, 2022 at 05:01:31PM +0300, Ilpo Järvinen wrote:
> One additional thing below I missed on the first read.
> 
> On Tue, 26 Apr 2022, Ilpo Järvinen wrote:
> > On Tue, 26 Apr 2022, Greg KH wrote:
> > 
> > > On Tue, Apr 26, 2022 at 03:24:43PM +0300, Ilpo Järvinen wrote:
> > > > Add ADDRB to termbits to indicate 9th bit addressing mode. This change
> > > > is necessary for supporting devices with RS485 multipoint addressing
> > > > [*]. A later patch in the patch series adds support for Synopsys
> > > > Designware UART capable for 9th bit addressing mode. In this mode, 9th
> > > > bit is used to indicate an address (byte) within the communication
> > > > line. The 9th bit addressing mode is selected using ADDRB introduced by
> > > > an earlier patch.
> > > > 
> > > > [*] Technically, RS485 is just an electronic spec and does not itself
> > > > specify the 9th bit addressing mode but 9th bit seems at least
> > > > "semi-standard" way to do addressing with RS485.
> > > > 
> > > > Cc: linux-api@vger.kernel.org
> > > > Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
> > > > Cc: Matt Turner <mattst88@gmail.com>
> > > > Cc: linux-alpha@vger.kernel.org
> > > > Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> > > > Cc: linux-mips@vger.kernel.org
> > > > Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> > > > Cc: Helge Deller <deller@gmx.de>
> > > > Cc: linux-parisc@vger.kernel.org
> > > > Cc: Michael Ellerman <mpe@ellerman.id.au>
> > > > Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > > > Cc: Paul Mackerras <paulus@samba.org>
> > > > Cc: linuxppc-dev@lists.ozlabs.org
> > > > Cc: "David S. Miller" <davem@davemloft.net>
> > > > Cc: sparclinux@vger.kernel.org
> > > > Cc: Arnd Bergmann <arnd@arndb.de>
> > > > Cc: linux-arch@vger.kernel.org
> > > > Cc: linux-usb@vger.kernel.org
> > > > Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > > > ---
> 
> > > >  #define CMSPAR    010000000000          /* mark or space (stick) parity */
> > > >  #define CRTSCTS   020000000000          /* flow control */
> > > >  
> > > > diff --git a/arch/powerpc/include/uapi/asm/termbits.h b/arch/powerpc/include/uapi/asm/termbits.h
> > > > index ed18bc61f63d..c6a033732f39 100644
> > > > --- a/arch/powerpc/include/uapi/asm/termbits.h
> > > > +++ b/arch/powerpc/include/uapi/asm/termbits.h
> > > > @@ -171,6 +171,7 @@ struct ktermios {
> > > >  #define HUPCL	00040000
> > > >  
> > > >  #define CLOCAL	00100000
> > > > +#define ADDRB	004000000000		/* address bit */
> > > >  #define CMSPAR	  010000000000		/* mark or space (stick) parity */
> > > >  #define CRTSCTS	  020000000000		/* flow control */
> > > >  
> > > > diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
> > > > index ce5ad5d0f105..5eb1d547b5c4 100644
> > > > --- a/arch/sparc/include/uapi/asm/termbits.h
> > > > +++ b/arch/sparc/include/uapi/asm/termbits.h
> > > > @@ -201,6 +201,7 @@ struct ktermios {
> > > >  #define B3500000  0x00001012
> > > >  #define B4000000  0x00001013  */
> > > >  #define CIBAUD	  0x100f0000  /* input baud rate (not used) */
> > > > +#define ADDRB	  0x20000000  /* address bit */
> > > >  #define CMSPAR	  0x40000000  /* mark or space (stick) parity */
> > > >  #define CRTSCTS	  0x80000000  /* flow control */
> > > 
> > > Why all the different values?  Can't we pick one and use it for all
> > > arches?  Having these be different in different arches and userspace
> > > should not be a thing for new fields, right?
> 
> ADDRB value is the same for all archs (it's just this octal vs hex 
> notation I've followed as per the nearby defines within the same file
> which makes them look different).
> 
> Should I perhaps add to my cleanup list conversion of all those octal ones 
> to hex?

Argh, yes, please, let's do that now, I totally missed that.  Will let
us see how to unify them as well.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
  2022-04-26 14:10           ` Greg KH
  (?)
@ 2022-04-26 16:29             ` Ilpo Järvinen
  -1 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 16:29 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc,
	Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras,
	linuxppc-dev, David S. Miller, sparclinux, Arnd Bergmann,
	linux-arch, linux-usb

[-- Attachment #1: Type: text/plain, Size: 905 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 05:01:31PM +0300, Ilpo Järvinen wrote:
> > 
> > ADDRB value is the same for all archs (it's just this octal vs hex 
> > notation I've followed as per the nearby defines within the same file
> > which makes them look different).
> > 
> > Should I perhaps add to my cleanup list conversion of all those octal ones 
> > to hex?
> 
> Argh, yes, please, let's do that now, I totally missed that.  Will let
> us see how to unify them as well.

Unifying them might turn out impractical, here's a rough idea now many
copies ... | uniq -c finds for the defines (based on more aggressively 
cleaned up lines than the patch will have):
     89 1
     74 2
     14 3
     58 4
     11 5
     54 6
There just tends to be 1 or 2 archs which are different from the others.

...I'll send the actual octal-to-hex patch once the arch builds complete.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 16:29             ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 16:29 UTC (permalink / raw)
  To: Greg KH
  Cc: Heikki Krogerus, heiko, James E.J. Bottomley, Paul Mackerras,
	sparclinux, Jiri Slaby, linux-arch, Helge Deller, linux-serial,
	Uwe Kleine-König, Matt Turner, Arnd Bergmann, Johan Hovold,
	Vicente Bergas, Ivan Kokshaysky, Andy Shevchenko,
	Thomas Bogendoerfer, linux-parisc, linux-api, linux-usb,
	linux-mips, David S. Miller, Lukas Wunner, linux-alpha,
	linuxppc-dev, giulio.benetti

[-- Attachment #1: Type: text/plain, Size: 905 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 05:01:31PM +0300, Ilpo Järvinen wrote:
> > 
> > ADDRB value is the same for all archs (it's just this octal vs hex 
> > notation I've followed as per the nearby defines within the same file
> > which makes them look different).
> > 
> > Should I perhaps add to my cleanup list conversion of all those octal ones 
> > to hex?
> 
> Argh, yes, please, let's do that now, I totally missed that.  Will let
> us see how to unify them as well.

Unifying them might turn out impractical, here's a rough idea now many
copies ... | uniq -c finds for the defines (based on more aggressively 
cleaned up lines than the patch will have):
     89 1
     74 2
     14 3
     58 4
     11 5
     54 6
There just tends to be 1 or 2 archs which are different from the others.

...I'll send the actual octal-to-hex patch once the arch builds complete.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode
@ 2022-04-26 16:29             ` Ilpo Järvinen
  0 siblings, 0 replies; 40+ messages in thread
From: Ilpo Järvinen @ 2022-04-26 16:29 UTC (permalink / raw)
  To: Greg KH
  Cc: linux-serial, Jiri Slaby, Lukas Wunner, Andy Shevchenko,
	Uwe Kleine-König, Vicente Bergas, Johan Hovold, heiko,
	giulio.benetti, Heikki Krogerus, linux-api, Ivan Kokshaysky,
	Matt Turner, linux-alpha, Thomas Bogendoerfer, linux-mips,
	James E.J. Bottomley, Helge Deller, linux-parisc

[-- Attachment #1: Type: text/plain, Size: 934 bytes --]

On Tue, 26 Apr 2022, Greg KH wrote:

> On Tue, Apr 26, 2022 at 05:01:31PM +0300, Ilpo Järvinen wrote:
> > 
> > ADDRB value is the same for all archs (it's just this octal vs hex 
> > notation I've followed as per the nearby defines within the same file
> > which makes them look different).
> > 
> > Should I perhaps add to my cleanup list conversion of all those octal ones 
> > to hex?
> 
> Argh, yes, please, let's do that now, I totally missed that.  Will let
> us see how to unify them as well.

Unifying them might turn out impractical, here's a rough idea now many
copies ... | uniq -c finds for the defines (based on more aggressively 
cleaned up lines than the patch will have):
     89 1
     74 2
     14 3
     58 4
     11 5
     54 6
There just tends to be 1 or 2 archs which are different from the others.

...I'll send the actual octal-to-hex patch once the arch builds complete.

-- 
 i.

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2022-04-26 16:38 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-26 12:24 [PATCH v5 00/10] Add RS485 support to DW UART Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 01/10] serial: 8250_dwlib: RS485 HW half & full duplex support Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 02/10] serial: 8250_dwlib: Implement SW half " Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 03/10] dt_bindings: rs485: Add receiver enable polarity Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 04/10] ACPI / property: Document RS485 _DSD properties Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode Ilpo Järvinen
2022-04-26 12:24   ` Ilpo Järvinen
2022-04-26 12:24   ` Ilpo Järvinen
2022-04-26 12:52   ` Greg KH
2022-04-26 12:52     ` Greg KH
2022-04-26 12:52     ` Greg KH
2022-04-26 13:12     ` Ilpo Järvinen
2022-04-26 13:12       ` Ilpo Järvinen
2022-04-26 13:12       ` Ilpo Järvinen
2022-04-26 14:01       ` Ilpo Järvinen
2022-04-26 14:01         ` Ilpo Järvinen
2022-04-26 14:01         ` Ilpo Järvinen
2022-04-26 14:10         ` Greg KH
2022-04-26 14:10           ` Greg KH
2022-04-26 14:10           ` Greg KH
2022-04-26 16:29           ` Ilpo Järvinen
2022-04-26 16:29             ` Ilpo Järvinen
2022-04-26 16:29             ` Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 06/10] serial: General support for multipoint addresses Ilpo Järvinen
2022-04-26 12:24   ` Ilpo Järvinen
2022-04-26 12:24   ` Ilpo Järvinen
2022-04-26 12:56   ` Greg KH
2022-04-26 12:56     ` Greg KH
2022-04-26 12:56     ` Greg KH
2022-04-26 13:36     ` Ilpo Järvinen
2022-04-26 13:36       ` Ilpo Järvinen
2022-04-26 13:36       ` Ilpo Järvinen
2022-04-26 13:58       ` Greg KH
2022-04-26 13:58         ` Greg KH
2022-04-26 13:58         ` Greg KH
2022-04-26 12:24 ` [PATCH v5 07/10] serial: 8250: make saved LSR larger Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 08/10] serial: 8250: create lsr_save_mask Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 09/10] serial: 8250_lpss: Use 32-bit reads Ilpo Järvinen
2022-04-26 12:24 ` [PATCH v5 10/10] serial: 8250_dwlib: Support for 9th bit multipoint addressing Ilpo Järvinen
2022-04-26 12:49 ` [PATCH v5 00/10] Add RS485 support to DW UART Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.