[PATCH v5 7/7] PCI: Create helper to print TLP Header and Prefix Log

2024-05-14 Thread Ilpo Järvinen
Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log.
Print End-End Prefixes only if they are non-zero.

Consolidate the few places which currently print TLP using custom
formatting.

The first attempt used pr_cont() instead of building a string first but
it turns out pr_cont() is not compatible with pci_err() and prints on a
separate line. When I asked about this, Andy Shevchenko suggested
pr_cont() should not be used in the first place (to eventually get rid
of it) so pr_cont() is now replaced with building the string first.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.h  |  2 ++
 drivers/pci/pcie/aer.c | 10 ++
 drivers/pci/pcie/dpc.c |  5 +
 drivers/pci/pcie/tlp.c | 31 +++
 4 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 7afdd71f9026..45083e62892c 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -423,6 +423,8 @@ void aer_print_error(struct pci_dev *dev, struct 
aer_err_info *info);
 int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
  unsigned int tlp_len, struct pcie_tlp_log *log);
 unsigned int aer_tlp_log_len(struct pci_dev *dev);
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *log, const char *pfx);
 #endif /* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ecc1dea5a208..efb9e728fe94 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -664,12 +664,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev 
*pdev,
}
 }
 
-static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
-{
-   pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
-   t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
-}
-
 static void __aer_print_error(struct pci_dev *dev,
  struct aer_err_info *info)
 {
@@ -724,7 +718,7 @@ void aer_print_error(struct pci_dev *dev, struct 
aer_err_info *info)
__aer_print_error(dev, info);
 
if (info->tlp_header_valid)
-   __print_tlp_header(dev, >tlp);
+   pcie_print_tlp_log(dev, >tlp, "  ");
 
 out:
if (info->id && info->error_dev_num > 1 && info->id == id)
@@ -796,7 +790,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity,
aer->uncor_severity);
 
if (tlp_header_valid)
-   __print_tlp_header(dev, >header_log);
+   pcie_print_tlp_log(dev, >header_log, "  ");
 
trace_aer_event(dev_name(>dev), (status & ~mask),
aer_severity, tlp_header_valid, >header_log);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 5056cc6961ec..598f74384471 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -220,10 +220,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
  cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
  dpc_tlp_log_len(pdev), _log);
-   pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
-   tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
-   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, 
tlp_log.prefix[i]);
+   pcie_print_tlp_log(pdev, _log, "");
 
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index def9dd7b73e8..097ac8514e96 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -6,6 +6,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -76,3 +77,33 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, int 
where2,
 
return 0;
 }
+
+/**
+ * pcie_print_tlp_log - Print TLP Header / Prefix Log contents
+ * @dev: PCIe device
+ * @log: TLP Log structure
+ * @pfx: String prefix (for print out indentation)
+ *
+ * Prints TLP Header and Prefix Log information held by @log.
+ */
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *log, const char *pfx)
+{
+   char buf[(10 + 1) * (4 + ARRAY_SIZE(log->prefix)) + 14 + 1];
+   unsigned int i;
+   int len;
+
+   len = scnprintf(buf, sizeof(buf), "%#010x %#010x %#010x %#010x",
+   log->dw[0], log->dw[1], log->dw[2], log->dw[3]);
+
+   if (log->prefix[0])
+   len += scnprintf(buf + len, sizeof(buf) - len, " E-E 
Prefixes:");
+   for (i = 0; i < ARRAY_SIZE(log->prefix); i++) {
+   if (!log->prefix[i])
+   break;
+   len += scnprintf(buf + len, sizeof(buf) - len,
+" %#010x", log->prefix[i]);
+   }
+
+   pci_err(dev, "%sTLP Header: %s\n", pfx, buf);
+}
-- 
2.39.2



[PATCH v5 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-05-14 Thread Ilpo Järvinen
pcie_read_tlp_log() handles only 4 Header Log DWORDs but TLP Prefix Log
(PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.

Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
TLP Prefix Log. The relevant registers are formatted identically in AER
and DPC Capability, but has these variations:

a) The offsets of TLP Prefix Log registers vary.
b) DPC RP PIO TLP Prefix Log register can be < 4 DWORDs.

Therefore callers must pass the offset of the TLP Prefix Log register
and the entire length to pcie_read_tlp_log() to be able to read the
correct number of TLP Prefix DWORDs from the correct offset.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.h |  5 +++-
 drivers/pci/pcie/aer.c|  4 ++-
 drivers/pci/pcie/dpc.c| 13 +-
 drivers/pci/pcie/tlp.c| 49 +++
 include/linux/aer.h   |  1 +
 include/uapi/linux/pci_regs.h |  1 +
 6 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0e9917f8bf3f..7afdd71f9026 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -420,7 +420,9 @@ struct aer_err_info {
 int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 
-int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
+int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
+ unsigned int tlp_len, struct pcie_tlp_log *log);
+unsigned int aer_tlp_log_len(struct pci_dev *dev);
 #endif /* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
@@ -439,6 +441,7 @@ void pci_dpc_init(struct pci_dev *pdev);
 void dpc_process_error(struct pci_dev *pdev);
 pci_ers_result_t dpc_reset_link(struct pci_dev *pdev);
 bool pci_dpc_recovered(struct pci_dev *pdev);
+unsigned int dpc_tlp_log_len(struct pci_dev *dev);
 #else
 static inline void pci_save_dpc_state(struct pci_dev *dev) { }
 static inline void pci_restore_dpc_state(struct pci_dev *dev) { }
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ac6293c24976..ecc1dea5a208 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
 
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
-   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, 
>tlp);
+   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG,
+ aer + PCI_ERR_PREFIX_LOG,
+ aer_tlp_log_len(dev), >tlp);
}
}
 
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index a668820696dc..5056cc6961ec 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -190,7 +190,7 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
 static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 {
u16 cap = pdev->dpc_cap, dpc_status, first_error;
-   u32 status, mask, sev, syserr, exc, log, prefix;
+   u32 status, mask, sev, syserr, exc, log;
struct pcie_tlp_log tlp_log;
int i;
 
@@ -217,20 +217,19 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 
if (pdev->dpc_rp_log_size < 4)
goto clear_status;
-   pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG, _log);
+   pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
+ cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
+ dpc_tlp_log_len(pdev), _log);
pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
+   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
+   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, 
tlp_log.prefix[i]);
 
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, );
pci_err(pdev, "RP PIO ImpSpec Log %#010x\n", log);
 
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) {
-   pci_read_config_dword(pdev,
-   cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, 
);
-   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
-   }
  clear_status:
pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status);
 }
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 65ac7b5d8a87..def9dd7b73e8 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -11,26 +11,65 @@
 
 #include "../pci.h"
 
+/**
+ * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length
+ * @dev: PCIe device
+ *
+ * Return: TLP Header

[PATCH v5 5/7] PCI: Store # of supported End-End TLP Prefixes

2024-05-14 Thread Ilpo Järvinen
eetlp_prefix_path in the struct pci_dev tells if End-End TLP Prefixes
are supported by the path or not, the value is only calculated if
CONFIG_PCI_PASID is set.

The Max End-End TLP Prefixes field in the Device Capabilities Register
2 also tells how many (1-4) End-End TLP Prefixes are supported (PCIe r6
sec 7.5.3.15). The number of supported End-End Prefixes is useful for
reading correct number of DWORDs from TLP Prefix Log register in AER
capability (PCIe r6 sec 7.8.4.12).

Replace eetlp_prefix_path with eetlp_prefix_max and determine the
number of supported End-End Prefixes regardless of CONFIG_PCI_PASID so
that an upcoming commit generalizing TLP Prefix Log register reading
does not have to read extra DWORDs for End-End Prefixes that never will
be there.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/ats.c |  2 +-
 drivers/pci/probe.c   | 14 +-
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  1 +
 4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index c570892b2090..e13433dcfc82 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (WARN_ON(pdev->pasid_enabled))
return -EBUSY;
 
-   if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp)
+   if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp)
return -EINVAL;
 
if (!pasid)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 1325fbae2f28..02035b005a53 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2211,8 +2211,8 @@ static void pci_configure_relaxed_ordering(struct pci_dev 
*dev)
 
 static void pci_configure_eetlp_prefix(struct pci_dev *dev)
 {
-#ifdef CONFIG_PCI_PASID
struct pci_dev *bridge;
+   unsigned int eetlp_max;
int pcie_type;
u32 cap;
 
@@ -2224,15 +2224,19 @@ static void pci_configure_eetlp_prefix(struct pci_dev 
*dev)
return;
 
pcie_type = pci_pcie_type(dev);
+
+   eetlp_max = FIELD_GET(PCI_EXP_DEVCAP2_EE_PREFIX_MAX, cap);
+   /* 00b means 4 */
+   eetlp_max = eetlp_max ?: 4;
+
if (pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
pcie_type == PCI_EXP_TYPE_RC_END)
-   dev->eetlp_prefix_path = 1;
+   dev->eetlp_prefix_max = eetlp_max;
else {
bridge = pci_upstream_bridge(dev);
-   if (bridge && bridge->eetlp_prefix_path)
-   dev->eetlp_prefix_path = 1;
+   if (bridge && bridge->eetlp_prefix_max)
+   dev->eetlp_prefix_max = eetlp_max;
}
-#endif
 }
 
 static void pci_configure_serr(struct pci_dev *dev)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 16493426a04f..29c51325b1d9 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -397,7 +397,7 @@ struct pci_dev {
   supported from root to here */
 #endif
unsigned intpasid_no_tlp:1; /* PASID works without TLP 
Prefix */
-   unsigned inteetlp_prefix_path:1;/* End-to-End TLP Prefix */
+   unsigned inteetlp_prefix_max:3; /* Max # of End-End TLP 
Prefixes, 0=not supported */
 
pci_channel_state_t error_state;/* Current connectivity state */
struct device   dev;/* Generic device interface */
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index a39193213ff2..09e0c300c952 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -661,6 +661,7 @@
 #define  PCI_EXP_DEVCAP2_OBFF_MSG  0x0004 /* New message signaling */
 #define  PCI_EXP_DEVCAP2_OBFF_WAKE 0x0008 /* Re-use WAKE# for OBFF */
 #define  PCI_EXP_DEVCAP2_EE_PREFIX 0x0020 /* End-End TLP Prefix */
+#define  PCI_EXP_DEVCAP2_EE_PREFIX_MAX 0x00c0 /* Max End-End TLP Prefixes 
*/
 #define PCI_EXP_DEVCTL20x28/* Device Control 2 */
 #define  PCI_EXP_DEVCTL2_COMP_TIMEOUT  0x000f  /* Completion Timeout Value */
 #define  PCI_EXP_DEVCTL2_COMP_TMOUT_DIS0x0010  /* Completion Timeout 
Disable */
-- 
2.39.2



[PATCH v5 4/7] PCI: Use unsigned int i in pcie_read_tlp_log()

2024-05-14 Thread Ilpo Järvinen
Loop variable i counting from 0 upwards does not need to be signed so
make it unsigned int.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/tlp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 2bf15749cd31..65ac7b5d8a87 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -24,7 +24,8 @@
 int pcie_read_tlp_log(struct pci_dev *dev, int where,
  struct pcie_tlp_log *log)
 {
-   int i, ret;
+   unsigned int i;
+   int ret;
 
memset(log, 0, sizeof(*log));
 
-- 
2.39.2



[PATCH v5 3/7] PCI: Make pcie_read_tlp_log() signature same

2024-05-14 Thread Ilpo Järvinen
pcie_read_tlp_log()'s prototype and function signature diverged due to
changes made while applying.

Make the parameters of pcie_read_tlp_log() named identically.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/tlp.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 3f053cc62290..2bf15749cd31 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -15,22 +15,21 @@
  * pcie_read_tlp_log - read TLP Header Log
  * @dev: PCIe device
  * @where: PCI Config offset of TLP Header Log
- * @tlp_log: TLP Log structure to fill
+ * @log: TLP Log structure to fill
  *
- * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
+ * Fill @log from TLP Header Log registers, e.g., AER or DPC.
  *
  * Return: 0 on success and filled TLP Log structure, <0 on error.
  */
 int pcie_read_tlp_log(struct pci_dev *dev, int where,
- struct pcie_tlp_log *tlp_log)
+ struct pcie_tlp_log *log)
 {
int i, ret;
 
-   memset(tlp_log, 0, sizeof(*tlp_log));
+   memset(log, 0, sizeof(*log));
 
for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4,
-   _log->dw[i]);
+   ret = pci_read_config_dword(dev, where + i * 4, >dw[i]);
if (ret)
return pcibios_err_to_errno(ret);
}
-- 
2.39.2



[PATCH v5 2/7] PCI: Move TLP Log handling to own file

2024-05-14 Thread Ilpo Järvinen
TLP Log is PCIe feature and is processed only by AER and DPC.
Configwise, DPC depends AER being enabled. In lack of better place, the
TLP Log handling code was initially placed into pci.c but it can be
easily placed in a separate file.

Move TLP Log handling code to own file under pcie/ subdirectory and
include it only when AER is enabled.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.c | 27 ---
 drivers/pci/pci.h |  2 +-
 drivers/pci/pcie/Makefile |  2 +-
 drivers/pci/pcie/tlp.c| 39 +++
 4 files changed, 41 insertions(+), 29 deletions(-)
 create mode 100644 drivers/pci/pcie/tlp.c

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 54ab1d6b8e53..2cc875f60fef 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1066,33 +1066,6 @@ static void pci_enable_acs(struct pci_dev *dev)
pci_disable_acs_redir(dev);
 }
 
-/**
- * pcie_read_tlp_log - read TLP Header Log
- * @dev: PCIe device
- * @where: PCI Config offset of TLP Header Log
- * @tlp_log: TLP Log structure to fill
- *
- * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
- *
- * Return: 0 on success and filled TLP Log structure, <0 on error.
- */
-int pcie_read_tlp_log(struct pci_dev *dev, int where,
- struct pcie_tlp_log *tlp_log)
-{
-   int i, ret;
-
-   memset(tlp_log, 0, sizeof(*tlp_log));
-
-   for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4,
-   _log->dw[i]);
-   if (ret)
-   return pcibios_err_to_errno(ret);
-   }
-
-   return 0;
-}
-
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 9c968df86a92..0e9917f8bf3f 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -419,9 +419,9 @@ struct aer_err_info {
 
 int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
-#endif /* CONFIG_PCIEAER */
 
 int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
+#endif /* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
 /* Cached RCEC Endpoint Association */
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index 6461aa93fe76..591ef317 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -7,7 +7,7 @@ pcieportdrv-y   := portdrv.o rcec.o
 obj-$(CONFIG_PCIEPORTBUS)  += pcieportdrv.o
 
 obj-y  += aspm.o
-obj-$(CONFIG_PCIEAER)  += aer.o err.o
+obj-$(CONFIG_PCIEAER)  += aer.o err.o tlp.o
 obj-$(CONFIG_PCIEAER_INJECT)   += aer_inject.o
 obj-$(CONFIG_PCIE_PME) += pme.o
 obj-$(CONFIG_PCIE_DPC) += dpc.o
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
new file mode 100644
index ..3f053cc62290
--- /dev/null
+++ b/drivers/pci/pcie/tlp.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe TLP Log handling
+ *
+ * Copyright (C) 2024 Intel Corporation
+ */
+
+#include 
+#include 
+#include 
+
+#include "../pci.h"
+
+/**
+ * pcie_read_tlp_log - read TLP Header Log
+ * @dev: PCIe device
+ * @where: PCI Config offset of TLP Header Log
+ * @tlp_log: TLP Log structure to fill
+ *
+ * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
+ *
+ * Return: 0 on success and filled TLP Log structure, <0 on error.
+ */
+int pcie_read_tlp_log(struct pci_dev *dev, int where,
+ struct pcie_tlp_log *tlp_log)
+{
+   int i, ret;
+
+   memset(tlp_log, 0, sizeof(*tlp_log));
+
+   for (i = 0; i < 4; i++) {
+   ret = pci_read_config_dword(dev, where + i * 4,
+   _log->dw[i]);
+   if (ret)
+   return pcibios_err_to_errno(ret);
+   }
+
+   return 0;
+}
-- 
2.39.2



[PATCH v5 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem

2024-05-14 Thread Ilpo Järvinen
pcie_read_tlp_log() was exposed by the commit 0a5a46a6a61b ("PCI/AER:
Generalize TLP Header Log reading") but this is now considered a
mistake. No drivers outside of PCI subsystem should build their own
diagnostic logging but should rely on PCI core doing it for them.

There's currently one driver (ixgbe) doing it independently which was
the initial reason why the export was added but it was decided by the
PCI maintainer that it's something that should be eliminated.

Remove the unwanted EXPORT of pcie_read_tlp_log() and remove it from
include/linux/aer.h.

Link: https://lore.kernel.org/all/20240322193011.GA701027@bhelgaas/
Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.c   | 1 -
 drivers/pci/pci.h   | 4 
 include/linux/aer.h | 2 --
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e5f243dd4288..54ab1d6b8e53 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1092,7 +1092,6 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where,
 
return 0;
 }
-EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
 
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 17fed1846847..9c968df86a92 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -4,6 +4,8 @@
 
 #include 
 
+struct pcie_tlp_log;
+
 /* Number of possible devfns: 0.0 to 1f.7 inclusive */
 #define MAX_NR_DEVFNS 256
 
@@ -419,6 +421,8 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 #endif /* CONFIG_PCIEAER */
 
+int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
+
 #ifdef CONFIG_PCIEPORTBUS
 /* Cached RCEC Endpoint Association */
 struct rcec_ea {
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 4b97f38f3fcf..190a0a2061cd 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -37,8 +37,6 @@ struct aer_capability_regs {
u16 uncor_err_source;
 };
 
-int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
-
 #if defined(CONFIG_PCIEAER)
 int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
 int pcie_aer_is_native(struct pci_dev *dev);
-- 
2.39.2



[PATCH v5 0/7] PCI: Consolidate TLP Log reading and printing

2024-05-14 Thread Ilpo Järvinen
This series has the remaining patches of the AER & DPC TLP Log handling
consolidation and now includes a few minor improvements to the earlier
accepted TLP Logging code.

v5:
- Fix build with AER=y and DPC=n
- Match kerneldoc and function parameter name

v4:
- Added patches:
- Remove EXPORT of pcie_read_tlp_log()
- Moved code to pcie/tlp.c and build only with AER enabled
- Match variables in prototype and function
- int -> unsigned int conversion
- eetlp_prefix_max into own patch
- struct pcie_tlp_log param consistently called "log" within tlp.c
- Moved function prototypes into drivers/pci/pci.h
- Describe AER/DPC differences more clearly in one commit message

v3:
- Small rewording in a commit message

v2:
- Don't add EXPORT()s
- Don't include igxbe changes
- Don't use pr_cont() as it's incompatible with pci_err() and according
  to Andy Shevchenko should not be used in the first place

Ilpo Järvinen (7):
  PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem
  PCI: Move TLP Log handling to own file
  PCI: Make pcie_read_tlp_log() signature same
  PCI: Use unsigned int i in pcie_read_tlp_log()
  PCI: Store # of supported End-End TLP Prefixes
  PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  PCI: Create helper to print TLP Header and Prefix Log

 drivers/pci/ats.c |   2 +-
 drivers/pci/pci.c |  28 -
 drivers/pci/pci.h |   9 +++
 drivers/pci/pcie/Makefile |   2 +-
 drivers/pci/pcie/aer.c|  14 ++---
 drivers/pci/pcie/dpc.c|  14 ++---
 drivers/pci/pcie/tlp.c| 109 ++
 drivers/pci/probe.c   |  14 +++--
 include/linux/aer.h   |   3 +-
 include/linux/pci.h   |   2 +-
 include/uapi/linux/pci_regs.h |   2 +
 11 files changed, 143 insertions(+), 56 deletions(-)
 create mode 100644 drivers/pci/pcie/tlp.c

-- 
2.39.2



Re: [PATCH v4 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-05-10 Thread Ilpo Järvinen
On Fri, 10 May 2024, Ilpo Järvinen wrote:

> pcie_read_tlp_log() handles only 4 Header Log DWORDs but TLP Prefix Log
> (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.
> 
> Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
> TLP Prefix Log. The relevant registers are formatted identically in AER
> and DPC Capability, but has these variations:
> 
> a) The offsets of TLP Prefix Log registers vary.
> b) DPC RP PIO TLP Prefix Log register can be < 4 DWORDs.
> 
> Therefore callers must pass the offset of the TLP Prefix Log register
> and the entire length to pcie_read_tlp_log() to be able to read the
> correct number of TLP Prefix DWORDs from the correct offset.
> 
> Signed-off-by: Ilpo Järvinen 
> ---
>  drivers/pci/pci.h |  5 +++-
>  drivers/pci/pcie/aer.c|  4 ++-
>  drivers/pci/pcie/dpc.c| 13 +-
>  drivers/pci/pcie/tlp.c| 47 +++
>  include/linux/aer.h   |  1 +
>  include/uapi/linux/pci_regs.h |  1 +
>  6 files changed, 57 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
> index 0e9917f8bf3f..3d9034d89be8 100644
> --- a/drivers/pci/pci.h
> +++ b/drivers/pci/pci.h
> @@ -420,7 +420,10 @@ struct aer_err_info {
>  int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info 
> *info);
>  void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
>  
> -int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
> *log);
> +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
> +   unsigned int tlp_len, struct pcie_tlp_log *log);
> +unsigned int aer_tlp_log_len(struct pci_dev *dev);
> +unsigned int dpc_tlp_log_len(struct pci_dev *dev);
>  #endif   /* CONFIG_PCIEAER */
>  
>  #ifdef CONFIG_PCIEPORTBUS
> diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
> index 65ac7b5d8a87..3615ca520c9a 100644
> --- a/drivers/pci/pcie/tlp.c
> +++ b/drivers/pci/pcie/tlp.c
> @@ -11,26 +11,63 @@
>  
>  #include "../pci.h"
>  
> +/**
> + * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length
> + * @dev: PCIe device
> + *
> + * Return: TLP Header/Prefix Log length
> + */
> +unsigned int aer_tlp_log_len(struct pci_dev *dev)
> +{
> + return 4 + dev->eetlp_prefix_max;
> +}
> +
> +/**
> + * dpc_tlp_log_len - Calculates DPC RP PIO TLP Header/Prefix Log length
> + * @dev: PCIe device
> + *
> + * Return: TLP Header/Prefix Log length
> + */
> +unsigned int dpc_tlp_log_len(struct pci_dev *pdev)
> +{
> + /* Remove ImpSpec Log register from the count */
> + if (pdev->dpc_rp_log_size >= 5)

Scratch this. LKP's randconfig build seems to have caught this failing to 
build when AER is enabled but DPC is not because this member doesn't exist 
w/o DPC.

> + return pdev->dpc_rp_log_size - 1;
> +
> + return pdev->dpc_rp_log_size;
> +}


-- 
 i.


[PATCH v4 5/7] PCI: Store # of supported End-End TLP Prefixes

2024-05-10 Thread Ilpo Järvinen
eetlp_prefix_path in the struct pci_dev tells if End-End TLP Prefixes
are supported by the path or not, the value is only calculated if
CONFIG_PCI_PASID is set.

The Max End-End TLP Prefixes field in the Device Capabilities Register
2 also tells how many (1-4) End-End TLP Prefixes are supported (PCIe r6
sec 7.5.3.15). The number of supported End-End Prefixes is useful for
reading correct number of DWORDs from TLP Prefix Log register in AER
capability (PCIe r6 sec 7.8.4.12).

Replace eetlp_prefix_path with eetlp_prefix_max and determine the
number of supported End-End Prefixes regardless of CONFIG_PCI_PASID so
that an upcoming commit generalizing TLP Prefix Log register reading
does not have to read extra DWORDs for End-End Prefixes that never will
be there.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/ats.c |  2 +-
 drivers/pci/probe.c   | 14 +-
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  1 +
 4 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index c570892b2090..e13433dcfc82 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (WARN_ON(pdev->pasid_enabled))
return -EBUSY;
 
-   if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp)
+   if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp)
return -EINVAL;
 
if (!pasid)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 1325fbae2f28..02035b005a53 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2211,8 +2211,8 @@ static void pci_configure_relaxed_ordering(struct pci_dev 
*dev)
 
 static void pci_configure_eetlp_prefix(struct pci_dev *dev)
 {
-#ifdef CONFIG_PCI_PASID
struct pci_dev *bridge;
+   unsigned int eetlp_max;
int pcie_type;
u32 cap;
 
@@ -2224,15 +2224,19 @@ static void pci_configure_eetlp_prefix(struct pci_dev 
*dev)
return;
 
pcie_type = pci_pcie_type(dev);
+
+   eetlp_max = FIELD_GET(PCI_EXP_DEVCAP2_EE_PREFIX_MAX, cap);
+   /* 00b means 4 */
+   eetlp_max = eetlp_max ?: 4;
+
if (pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
pcie_type == PCI_EXP_TYPE_RC_END)
-   dev->eetlp_prefix_path = 1;
+   dev->eetlp_prefix_max = eetlp_max;
else {
bridge = pci_upstream_bridge(dev);
-   if (bridge && bridge->eetlp_prefix_path)
-   dev->eetlp_prefix_path = 1;
+   if (bridge && bridge->eetlp_prefix_max)
+   dev->eetlp_prefix_max = eetlp_max;
}
-#endif
 }
 
 static void pci_configure_serr(struct pci_dev *dev)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 16493426a04f..29c51325b1d9 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -397,7 +397,7 @@ struct pci_dev {
   supported from root to here */
 #endif
unsigned intpasid_no_tlp:1; /* PASID works without TLP 
Prefix */
-   unsigned inteetlp_prefix_path:1;/* End-to-End TLP Prefix */
+   unsigned inteetlp_prefix_max:3; /* Max # of End-End TLP 
Prefixes, 0=not supported */
 
pci_channel_state_t error_state;/* Current connectivity state */
struct device   dev;/* Generic device interface */
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index a39193213ff2..09e0c300c952 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -661,6 +661,7 @@
 #define  PCI_EXP_DEVCAP2_OBFF_MSG  0x0004 /* New message signaling */
 #define  PCI_EXP_DEVCAP2_OBFF_WAKE 0x0008 /* Re-use WAKE# for OBFF */
 #define  PCI_EXP_DEVCAP2_EE_PREFIX 0x0020 /* End-End TLP Prefix */
+#define  PCI_EXP_DEVCAP2_EE_PREFIX_MAX 0x00c0 /* Max End-End TLP Prefixes 
*/
 #define PCI_EXP_DEVCTL20x28/* Device Control 2 */
 #define  PCI_EXP_DEVCTL2_COMP_TIMEOUT  0x000f  /* Completion Timeout Value */
 #define  PCI_EXP_DEVCTL2_COMP_TMOUT_DIS0x0010  /* Completion Timeout 
Disable */
-- 
2.39.2



[PATCH v4 2/7] PCI: Move TLP Log handling to own file

2024-05-10 Thread Ilpo Järvinen
TLP Log is PCIe feature and is processed only by AER and DPC.
Configwise, DPC depends AER being enabled. In lack of better place, the
TLP Log handling code was initially placed into pci.c but it can be
easily placed in a separate file.

Move TLP Log handling code to own file under pcie/ subdirectory and
include it only when AER is enabled.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.c | 27 ---
 drivers/pci/pci.h |  2 +-
 drivers/pci/pcie/Makefile |  2 +-
 drivers/pci/pcie/tlp.c| 39 +++
 4 files changed, 41 insertions(+), 29 deletions(-)
 create mode 100644 drivers/pci/pcie/tlp.c

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 54ab1d6b8e53..2cc875f60fef 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1066,33 +1066,6 @@ static void pci_enable_acs(struct pci_dev *dev)
pci_disable_acs_redir(dev);
 }
 
-/**
- * pcie_read_tlp_log - read TLP Header Log
- * @dev: PCIe device
- * @where: PCI Config offset of TLP Header Log
- * @tlp_log: TLP Log structure to fill
- *
- * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
- *
- * Return: 0 on success and filled TLP Log structure, <0 on error.
- */
-int pcie_read_tlp_log(struct pci_dev *dev, int where,
- struct pcie_tlp_log *tlp_log)
-{
-   int i, ret;
-
-   memset(tlp_log, 0, sizeof(*tlp_log));
-
-   for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4,
-   _log->dw[i]);
-   if (ret)
-   return pcibios_err_to_errno(ret);
-   }
-
-   return 0;
-}
-
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 9c968df86a92..0e9917f8bf3f 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -419,9 +419,9 @@ struct aer_err_info {
 
 int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
-#endif /* CONFIG_PCIEAER */
 
 int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
+#endif /* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
 /* Cached RCEC Endpoint Association */
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index 6461aa93fe76..591ef317 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -7,7 +7,7 @@ pcieportdrv-y   := portdrv.o rcec.o
 obj-$(CONFIG_PCIEPORTBUS)  += pcieportdrv.o
 
 obj-y  += aspm.o
-obj-$(CONFIG_PCIEAER)  += aer.o err.o
+obj-$(CONFIG_PCIEAER)  += aer.o err.o tlp.o
 obj-$(CONFIG_PCIEAER_INJECT)   += aer_inject.o
 obj-$(CONFIG_PCIE_PME) += pme.o
 obj-$(CONFIG_PCIE_DPC) += dpc.o
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
new file mode 100644
index ..3f053cc62290
--- /dev/null
+++ b/drivers/pci/pcie/tlp.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PCIe TLP Log handling
+ *
+ * Copyright (C) 2024 Intel Corporation
+ */
+
+#include 
+#include 
+#include 
+
+#include "../pci.h"
+
+/**
+ * pcie_read_tlp_log - read TLP Header Log
+ * @dev: PCIe device
+ * @where: PCI Config offset of TLP Header Log
+ * @tlp_log: TLP Log structure to fill
+ *
+ * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
+ *
+ * Return: 0 on success and filled TLP Log structure, <0 on error.
+ */
+int pcie_read_tlp_log(struct pci_dev *dev, int where,
+ struct pcie_tlp_log *tlp_log)
+{
+   int i, ret;
+
+   memset(tlp_log, 0, sizeof(*tlp_log));
+
+   for (i = 0; i < 4; i++) {
+   ret = pci_read_config_dword(dev, where + i * 4,
+   _log->dw[i]);
+   if (ret)
+   return pcibios_err_to_errno(ret);
+   }
+
+   return 0;
+}
-- 
2.39.2



[PATCH v4 1/7] PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem

2024-05-10 Thread Ilpo Järvinen
pcie_read_tlp_log() was exposed by the commit 0a5a46a6a61b ("PCI/AER:
Generalize TLP Header Log reading") but this is now considered a
mistake. No drivers outside of PCI subsystem should build their own
diagnostic logging but should rely on PCI core doing it for them.

There's currently one driver (ixgbe) doing it independently which was
the initial reason why the export was added but it was decided by the
PCI maintainer that it's something that should be eliminated.

Remove the unwanted EXPORT of pcie_read_tlp_log() and remove it from
include/linux/aer.h.

Link: https://lore.kernel.org/all/20240322193011.GA701027@bhelgaas/
Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.c   | 1 -
 drivers/pci/pci.h   | 4 
 include/linux/aer.h | 2 --
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e5f243dd4288..54ab1d6b8e53 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1092,7 +1092,6 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where,
 
return 0;
 }
-EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
 
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 17fed1846847..9c968df86a92 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -4,6 +4,8 @@
 
 #include 
 
+struct pcie_tlp_log;
+
 /* Number of possible devfns: 0.0 to 1f.7 inclusive */
 #define MAX_NR_DEVFNS 256
 
@@ -419,6 +421,8 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 #endif /* CONFIG_PCIEAER */
 
+int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
+
 #ifdef CONFIG_PCIEPORTBUS
 /* Cached RCEC Endpoint Association */
 struct rcec_ea {
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 4b97f38f3fcf..190a0a2061cd 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -37,8 +37,6 @@ struct aer_capability_regs {
u16 uncor_err_source;
 };
 
-int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
-
 #if defined(CONFIG_PCIEAER)
 int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
 int pcie_aer_is_native(struct pci_dev *dev);
-- 
2.39.2



[PATCH v4 0/7] PCI: Consolidate TLP Log reading and printing

2024-05-10 Thread Ilpo Järvinen
This series has the remaining patches of the AER & DPC TLP Log handling
consolidation and now includes a few minor improvements to the earlier
accepted TLP Logging code.

v4:
- Added patches:
- Remove EXPORT of pcie_read_tlp_log()
- Moved code to pcie/tlp.c and build only with AER enabled
- Match variables in prototype and function
- int -> unsigned int conversion
- eetlp_prefix_max into own patch
- struct pcie_tlp_log param consistently called "log" within tlp.c
- Moved function prototypes into drivers/pci/pci.h
- Describe AER/DPC differences more clearly in one commit message

v3:
- Small rewording in a commit message

v2:
- Don't add EXPORT()s
- Don't include igxbe changes
- Don't use pr_cont() as it's incompatible with pci_err() and according
  to Andy Shevchenko should not be used in the first place

Ilpo Järvinen (7):
  PCI: Don't expose pcie_read_tlp_log() outside of PCI subsystem
  PCI: Move TLP Log handling to own file
  PCI: Make pcie_read_tlp_log() signature same
  PCI: Use unsigned int i in pcie_read_tlp_log()
  PCI: Store # of supported End-End TLP Prefixes
  PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  PCI: Create helper to print TLP Header and Prefix Log

 drivers/pci/ats.c |   2 +-
 drivers/pci/pci.c |  28 -
 drivers/pci/pci.h |   9 +++
 drivers/pci/pcie/Makefile |   2 +-
 drivers/pci/pcie/aer.c|  14 ++---
 drivers/pci/pcie/dpc.c|  14 ++---
 drivers/pci/pcie/tlp.c| 107 ++
 drivers/pci/probe.c   |  14 +++--
 include/linux/aer.h   |   3 +-
 include/linux/pci.h   |   2 +-
 include/uapi/linux/pci_regs.h |   2 +
 11 files changed, 141 insertions(+), 56 deletions(-)
 create mode 100644 drivers/pci/pcie/tlp.c

-- 
2.39.2



[PATCH v4 7/7] PCI: Create helper to print TLP Header and Prefix Log

2024-05-10 Thread Ilpo Järvinen
Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log.
Print End-End Prefixes only if they are non-zero.

Consolidate the few places which currently print TLP using custom
formatting.

The first attempt used pr_cont() instead of building a string first but
it turns out pr_cont() is not compatible with pci_err() and prints on a
separate line. When I asked about this, Andy Shevchenko suggested
pr_cont() should not be used in the first place (to eventually get rid
of it) so pr_cont() is now replaced with building the string first.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.h  |  2 ++
 drivers/pci/pcie/aer.c | 10 ++
 drivers/pci/pcie/dpc.c |  5 +
 drivers/pci/pcie/tlp.c | 31 +++
 4 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3d9034d89be8..bf13d2fc4bb7 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -424,6 +424,8 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, int 
where2,
  unsigned int tlp_len, struct pcie_tlp_log *log);
 unsigned int aer_tlp_log_len(struct pci_dev *dev);
 unsigned int dpc_tlp_log_len(struct pci_dev *dev);
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *log, const char *pfx);
 #endif /* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ecc1dea5a208..efb9e728fe94 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -664,12 +664,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev 
*pdev,
}
 }
 
-static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
-{
-   pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
-   t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
-}
-
 static void __aer_print_error(struct pci_dev *dev,
  struct aer_err_info *info)
 {
@@ -724,7 +718,7 @@ void aer_print_error(struct pci_dev *dev, struct 
aer_err_info *info)
__aer_print_error(dev, info);
 
if (info->tlp_header_valid)
-   __print_tlp_header(dev, >tlp);
+   pcie_print_tlp_log(dev, >tlp, "  ");
 
 out:
if (info->id && info->error_dev_num > 1 && info->id == id)
@@ -796,7 +790,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity,
aer->uncor_severity);
 
if (tlp_header_valid)
-   __print_tlp_header(dev, >header_log);
+   pcie_print_tlp_log(dev, >header_log, "  ");
 
trace_aer_event(dev_name(>dev), (status & ~mask),
aer_severity, tlp_header_valid, >header_log);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 5056cc6961ec..598f74384471 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -220,10 +220,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
  cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
  dpc_tlp_log_len(pdev), _log);
-   pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
-   tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
-   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, 
tlp_log.prefix[i]);
+   pcie_print_tlp_log(pdev, _log, "");
 
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 3615ca520c9a..59a28485696f 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -6,6 +6,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -74,3 +75,33 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, int 
where2,
 
return 0;
 }
+
+/**
+ * pcie_print_tlp_log - Print TLP Header / Prefix Log contents
+ * @dev: PCIe device
+ * @log: TLP Log structure
+ * @pfx: String prefix (for print out indentation)
+ *
+ * Prints TLP Header and Prefix Log information held by @log.
+ */
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *log, const char *pfx)
+{
+   char buf[(10 + 1) * (4 + ARRAY_SIZE(log->prefix)) + 14 + 1];
+   unsigned int i;
+   int len;
+
+   len = scnprintf(buf, sizeof(buf), "%#010x %#010x %#010x %#010x",
+   log->dw[0], log->dw[1], log->dw[2], log->dw[3]);
+
+   if (log->prefix[0])
+   len += scnprintf(buf + len, sizeof(buf) - len, " E-E 
Prefixes:");
+   for (i = 0; i < ARRAY_SIZE(log->prefix); i++) {
+   if (!log->prefix[i])
+   break;
+   len += scnprintf(buf + len, sizeof(buf) - len,
+" %#010x", log->prefix[i]);
+   }
+
+   pci_err(dev, "%sTLP Header: %s\n", pfx, buf);
+}
-- 
2.39.2



[PATCH v4 6/7] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-05-10 Thread Ilpo Järvinen
pcie_read_tlp_log() handles only 4 Header Log DWORDs but TLP Prefix Log
(PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.

Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
TLP Prefix Log. The relevant registers are formatted identically in AER
and DPC Capability, but has these variations:

a) The offsets of TLP Prefix Log registers vary.
b) DPC RP PIO TLP Prefix Log register can be < 4 DWORDs.

Therefore callers must pass the offset of the TLP Prefix Log register
and the entire length to pcie_read_tlp_log() to be able to read the
correct number of TLP Prefix DWORDs from the correct offset.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.h |  5 +++-
 drivers/pci/pcie/aer.c|  4 ++-
 drivers/pci/pcie/dpc.c| 13 +-
 drivers/pci/pcie/tlp.c| 47 +++
 include/linux/aer.h   |  1 +
 include/uapi/linux/pci_regs.h |  1 +
 6 files changed, 57 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 0e9917f8bf3f..3d9034d89be8 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -420,7 +420,10 @@ struct aer_err_info {
 int aer_get_device_error_info(struct pci_dev *dev, struct aer_err_info *info);
 void aer_print_error(struct pci_dev *dev, struct aer_err_info *info);
 
-int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*log);
+int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
+ unsigned int tlp_len, struct pcie_tlp_log *log);
+unsigned int aer_tlp_log_len(struct pci_dev *dev);
+unsigned int dpc_tlp_log_len(struct pci_dev *dev);
 #endif /* CONFIG_PCIEAER */
 
 #ifdef CONFIG_PCIEPORTBUS
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ac6293c24976..ecc1dea5a208 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
 
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
-   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, 
>tlp);
+   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG,
+ aer + PCI_ERR_PREFIX_LOG,
+ aer_tlp_log_len(dev), >tlp);
}
}
 
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index a668820696dc..5056cc6961ec 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -190,7 +190,7 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
 static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 {
u16 cap = pdev->dpc_cap, dpc_status, first_error;
-   u32 status, mask, sev, syserr, exc, log, prefix;
+   u32 status, mask, sev, syserr, exc, log;
struct pcie_tlp_log tlp_log;
int i;
 
@@ -217,20 +217,19 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 
if (pdev->dpc_rp_log_size < 4)
goto clear_status;
-   pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG, _log);
+   pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
+ cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
+ dpc_tlp_log_len(pdev), _log);
pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
+   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
+   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, 
tlp_log.prefix[i]);
 
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, );
pci_err(pdev, "RP PIO ImpSpec Log %#010x\n", log);
 
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) {
-   pci_read_config_dword(pdev,
-   cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, 
);
-   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
-   }
  clear_status:
pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, status);
 }
diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 65ac7b5d8a87..3615ca520c9a 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -11,26 +11,63 @@
 
 #include "../pci.h"
 
+/**
+ * aer_tlp_log_len - Calculates AER Capability TLP Header/Prefix Log length
+ * @dev: PCIe device
+ *
+ * Return: TLP Header/Prefix Log length
+ */
+unsigned int aer_tlp_log_len(struct pci_dev *dev)
+{
+   return 4 + dev->eetlp_prefix_max;
+}
+
+/**
+ * dpc_tlp_log_len - Calculates DPC RP PIO TLP Header/Prefix Log length
+ * @dev: PCIe device
+ *
+ * Return: TLP Header/Prefix Log length
+ */
+unsigned int dpc_tlp_log_len(struct pci_dev *pdev)
+{
+   /* Remove Imp

[PATCH v4 4/7] PCI: Use unsigned int i in pcie_read_tlp_log()

2024-05-10 Thread Ilpo Järvinen
Loop variable i counting from 0 upwards does not need to be signed so
make it unsigned int.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/tlp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 2bf15749cd31..65ac7b5d8a87 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -24,7 +24,8 @@
 int pcie_read_tlp_log(struct pci_dev *dev, int where,
  struct pcie_tlp_log *log)
 {
-   int i, ret;
+   unsigned int i;
+   int ret;
 
memset(log, 0, sizeof(*log));
 
-- 
2.39.2



[PATCH v4 3/7] PCI: Make pcie_read_tlp_log() signature same

2024-05-10 Thread Ilpo Järvinen
pcie_read_tlp_log()'s prototype and function signature diverged due to
changes made while applying.

Make the parameters of pcie_read_tlp_log() named identically.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/tlp.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/pcie/tlp.c b/drivers/pci/pcie/tlp.c
index 3f053cc62290..2bf15749cd31 100644
--- a/drivers/pci/pcie/tlp.c
+++ b/drivers/pci/pcie/tlp.c
@@ -15,22 +15,21 @@
  * pcie_read_tlp_log - read TLP Header Log
  * @dev: PCIe device
  * @where: PCI Config offset of TLP Header Log
- * @tlp_log: TLP Log structure to fill
+ * @log: TLP Log structure to fill
  *
- * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
+ * Fill @log from TLP Header Log registers, e.g., AER or DPC.
  *
  * Return: 0 on success and filled TLP Log structure, <0 on error.
  */
 int pcie_read_tlp_log(struct pci_dev *dev, int where,
- struct pcie_tlp_log *tlp_log)
+ struct pcie_tlp_log *log)
 {
int i, ret;
 
-   memset(tlp_log, 0, sizeof(*tlp_log));
+   memset(log, 0, sizeof(*log));
 
for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4,
-   _log->dw[i]);
+   ret = pci_read_config_dword(dev, where + i * 4, >dw[i]);
if (ret)
return pcibios_err_to_errno(ret);
}
-- 
2.39.2



Re: [PATCH v3 1/2] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-05-06 Thread Ilpo Järvinen
On Fri, 3 May 2024, Bjorn Helgaas wrote:

> On Fri, Apr 12, 2024 at 04:36:34PM +0300, Ilpo Järvinen wrote:
> > pcie_read_tlp_log() handles only 4 TLP Header Log DWORDs but TLP Prefix
> > Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.
> > 
> > Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
> > TLP Prefix Log. The layout of relevant registers in AER and DPC
> > Capability is not identical because the offsets of TLP Header Log and
> > TLP Prefix Log vary so the callers must pass the offsets to
> > pcie_read_tlp_log().
> 
> I think the layouts of the Header Log and the TLP Prefix Log *are*
> identical, but they are at different offsets in the AER Capability vs
> the DPC Capability.  Lukas and I have both stumbled over this.

I'll try to reword it once again.

The way it's spec'ed, there actually also a small difference in sizes too 
(PCIe r6 7.9.14.13 says DPC one can be < 4 DWs whereas AER on is always 4 
DWs regardless of the number of supported E-E Prefixes) so I'll just 
rewrite it so it doesn't focus just on the offset.

> Similar and more comments at:
> https://lore.kernel.org/r/20240322193011.GA701027@bhelgaas

I'm really sorry, I missed those comments and only focused on that ixgbe 
part.

> > Convert eetlp_prefix_path into integer called eetlp_prefix_max and
> > make is available also when CONFIG_PCI_PASID is not configured to
> > be able to determine the number of E-E Prefixes.
> 
> s/make is/make it/
> 
> I think this could be a separate patch.

Sure, I can make it own patch.

> > --- a/include/linux/aer.h
> > +++ b/include/linux/aer.h
> > @@ -20,6 +20,7 @@ struct pci_dev;
> >  
> >  struct pcie_tlp_log {
> > u32 dw[4];
> > +   u32 prefix[4];
> >  };
> >  
> >  struct aer_capability_regs {
> > @@ -37,7 +38,9 @@ struct aer_capability_regs {
> > u16 uncor_err_source;
> >  };
> >  
> > -int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
> > *log);
> > +int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
> > + unsigned int tlp_len, struct pcie_tlp_log *log);
> > +unsigned int aer_tlp_log_len(struct pci_dev *dev);
> 
> I think it was a mistake to expose pcie_read_tlp_log() outside
> drivers/pci, and I don't think we should expose aer_tlp_log_len()
> either.

Ah, my intention was to remove the exposure but I only ended up removing 
the actual EXPORT and didn't realize I should have also moved the 
prototype into another header.

I'll add also a patch to remove pcie_read_tlp_log() EXPORT too but I'm 
wondering now whether I should also move these function(s) into 
pcie/aer.c (or somewhere else that is only build if AER is enabled) since 
there won't be callers ourside of AER/DPC?

> We might be stuck with exposing struct pcie_tlp_log since it looks
> like ras_event.h uses it.

Yes.

-- 
 i.

[PATCH 1/2] PCI/ERR: Cleanup misleading indentation inside if conditions

2024-04-29 Thread Ilpo Järvinen
A few if conditions align misleadingly with the following code block.
The checks are really cascading NULL checks that fit into 80 chars so
remove newlines in between and realign to the if condition indent.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/err.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/pcie/err.c b/drivers/pci/pcie/err.c
index 705893b5f7b0..31090770fffc 100644
--- a/drivers/pci/pcie/err.c
+++ b/drivers/pci/pcie/err.c
@@ -116,9 +116,7 @@ static int report_mmio_enabled(struct pci_dev *dev, void 
*data)
 
device_lock(>dev);
pdrv = dev->driver;
-   if (!pdrv ||
-   !pdrv->err_handler ||
-   !pdrv->err_handler->mmio_enabled)
+   if (!pdrv || !pdrv->err_handler || !pdrv->err_handler->mmio_enabled)
goto out;
 
err_handler = pdrv->err_handler;
@@ -137,9 +135,7 @@ static int report_slot_reset(struct pci_dev *dev, void 
*data)
 
device_lock(>dev);
pdrv = dev->driver;
-   if (!pdrv ||
-   !pdrv->err_handler ||
-   !pdrv->err_handler->slot_reset)
+   if (!pdrv || !pdrv->err_handler || !pdrv->err_handler->slot_reset)
goto out;
 
err_handler = pdrv->err_handler;
@@ -158,9 +154,7 @@ static int report_resume(struct pci_dev *dev, void *data)
device_lock(>dev);
pdrv = dev->driver;
if (!pci_dev_set_io_state(dev, pci_channel_io_normal) ||
-   !pdrv ||
-   !pdrv->err_handler ||
-   !pdrv->err_handler->resume)
+   !pdrv || !pdrv->err_handler || !pdrv->err_handler->resume)
goto out;
 
err_handler = pdrv->err_handler;
-- 
2.39.2



[PATCH v3 2/2] PCI: Create helper to print TLP Header and Prefix Log

2024-04-12 Thread Ilpo Järvinen
Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log.
Print End-End Prefixes only if they are non-zero.

Consolidate the few places which currently print TLP using custom
formatting.

The first attempt used pr_cont() instead of building a string first but
it turns out pr_cont() is not compatible with pci_err() but prints on a
separate line. When I asked about this, Andy Shevchenko suggested
pr_cont() should not be used in the first place (to eventually get rid
of it) so pr_cont() is now replaced with building the string first.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.c  | 32 
 drivers/pci/pcie/aer.c | 10 ++
 drivers/pci/pcie/dpc.c |  5 +
 include/linux/aer.h|  2 ++
 4 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index af230e6e5557..54d4872d14b8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -9,6 +9,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1116,6 +1117,37 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, 
int where2,
 }
 EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
 
+/**
+ * pcie_print_tlp_log - Print TLP Header / Prefix Log contents
+ * @dev:   PCIe device
+ * @tlp_log:   TLP Log structure
+ * @pfx:   Internal string prefix (for indentation)
+ *
+ * Prints TLP Header and Prefix Log information held by @tlp_log.
+ */
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *tlp_log, const char *pfx)
+{
+   char buf[(10 + 1) * (4 + ARRAY_SIZE(tlp_log->prefix)) + 14 + 1];
+   unsigned int i;
+   int len;
+
+   len = scnprintf(buf, sizeof(buf), "%#010x %#010x %#010x %#010x",
+   tlp_log->dw[0], tlp_log->dw[1], tlp_log->dw[2],
+   tlp_log->dw[3]);
+
+   if (tlp_log->prefix[0])
+   len += scnprintf(buf + len, sizeof(buf) - len, " E-E 
Prefixes:");
+   for (i = 0; i < ARRAY_SIZE(tlp_log->prefix); i++) {
+   if (!tlp_log->prefix[i])
+   break;
+   len += scnprintf(buf + len, sizeof(buf) - len,
+" %#010x", tlp_log->prefix[i]);
+   }
+
+   pci_err(dev, "%sTLP Header: %s\n", pfx, buf);
+}
+
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ecc1dea5a208..efb9e728fe94 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -664,12 +664,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev 
*pdev,
}
 }
 
-static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
-{
-   pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
-   t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
-}
-
 static void __aer_print_error(struct pci_dev *dev,
  struct aer_err_info *info)
 {
@@ -724,7 +718,7 @@ void aer_print_error(struct pci_dev *dev, struct 
aer_err_info *info)
__aer_print_error(dev, info);
 
if (info->tlp_header_valid)
-   __print_tlp_header(dev, >tlp);
+   pcie_print_tlp_log(dev, >tlp, "  ");
 
 out:
if (info->id && info->error_dev_num > 1 && info->id == id)
@@ -796,7 +790,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity,
aer->uncor_severity);
 
if (tlp_header_valid)
-   __print_tlp_header(dev, >header_log);
+   pcie_print_tlp_log(dev, >header_log, "  ");
 
trace_aer_event(dev_name(>dev), (status & ~mask),
aer_severity, tlp_header_valid, >header_log);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 80b1456f95fe..3f8e3b6c7948 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -229,10 +229,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
  cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
  dpc_tlp_log_len(pdev), _log);
-   pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
-   tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
-   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, 
tlp_log.prefix[i]);
+   pcie_print_tlp_log(pdev, _log, "");
 
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 2484056feb8d..1e8c61deca65 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -41,6 +41,8 @@ struct aer_capability_regs {
 int pcie_

[PATCH v3 1/2] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-04-12 Thread Ilpo Järvinen
pcie_read_tlp_log() handles only 4 TLP Header Log DWORDs but TLP Prefix
Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.

Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
TLP Prefix Log. The layout of relevant registers in AER and DPC
Capability is not identical because the offsets of TLP Header Log and
TLP Prefix Log vary so the callers must pass the offsets to
pcie_read_tlp_log().

Convert eetlp_prefix_path into integer called eetlp_prefix_max and
make is available also when CONFIG_PCI_PASID is not configured to
be able to determine the number of E-E Prefixes.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/ats.c |  2 +-
 drivers/pci/pci.c | 34 --
 drivers/pci/pcie/aer.c|  4 +++-
 drivers/pci/pcie/dpc.c| 22 +++---
 drivers/pci/probe.c   | 14 +-
 include/linux/aer.h   |  5 -
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  2 ++
 8 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index c570892b2090..e13433dcfc82 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (WARN_ON(pdev->pasid_enabled))
return -EBUSY;
 
-   if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp)
+   if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp)
return -EINVAL;
 
if (!pasid)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e5f243dd4288..af230e6e5557 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1066,26 +1066,48 @@ static void pci_enable_acs(struct pci_dev *dev)
pci_disable_acs_redir(dev);
 }
 
+/**
+ * aer_tlp_log_len - Calculates TLP Header/Prefix Log length
+ * @dev:   PCIe device
+ *
+ * Return: TLP Header/Prefix Log length
+ */
+unsigned int aer_tlp_log_len(struct pci_dev *dev)
+{
+   return 4 + dev->eetlp_prefix_max;
+}
+
 /**
  * pcie_read_tlp_log - read TLP Header Log
  * @dev: PCIe device
  * @where: PCI Config offset of TLP Header Log
+ * @where2: PCI Config offset of TLP Prefix Log
+ * @tlp_len: TLP Log length (in DWORDs)
  * @tlp_log: TLP Log structure to fill
  *
  * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
  *
  * Return: 0 on success and filled TLP Log structure, <0 on error.
  */
-int pcie_read_tlp_log(struct pci_dev *dev, int where,
- struct pcie_tlp_log *tlp_log)
+int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
+ unsigned int tlp_len, struct pcie_tlp_log *tlp_log)
 {
-   int i, ret;
+   unsigned int i;
+   int off, ret;
+   u32 *to;
 
memset(tlp_log, 0, sizeof(*tlp_log));
 
-   for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4,
-   _log->dw[i]);
+   for (i = 0; i < tlp_len; i++) {
+   if (i < 4) {
+   to = _log->dw[i];
+   off = where + i * 4;
+   } else {
+   to = _log->prefix[i - 4];
+   off = where2 + (i - 4) * 4;
+   }
+
+   ret = pci_read_config_dword(dev, off, to);
if (ret)
return pcibios_err_to_errno(ret);
}
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ac6293c24976..ecc1dea5a208 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
 
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
-   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, 
>tlp);
+   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG,
+ aer + PCI_ERR_PREFIX_LOG,
+ aer_tlp_log_len(dev), >tlp);
}
}
 
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index a668820696dc..80b1456f95fe 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -187,10 +187,19 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
return ret;
 }
 
+static unsigned int dpc_tlp_log_len(struct pci_dev *pdev)
+{
+   /* Remove ImpSpec Log register from the count */
+   if (pdev->dpc_rp_log_size >= 5)
+   return pdev->dpc_rp_log_size - 1;
+
+   return pdev->dpc_rp_log_size;
+}
+
 static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 {
u16 cap = pdev->dpc_cap, dpc_status, first_error;
-   u32 status, mask, sev, syserr, exc, log, prefix;
+   u32 status, mask, sev, syserr, exc, log;
struct pcie_tlp_log tlp_log;
  

[PATCH v3 0/2] PCI: Consolidate TLP Log reading and printing

2024-04-12 Thread Ilpo Järvinen
This series has the remaining patches of the AER & DPC TLP Log handling
consolidation.

v3:
- Small rewording in a commit message

v2:
- Don't add EXPORT()s
- Don't include igxbe changes
- Don't use pr_cont() as it's incompatible with pci_err() and according
  to Andy Shevchenko should not be used in the first place

Ilpo Järvinen (2):
  PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  PCI: Create helper to print TLP Header and Prefix Log

 drivers/pci/ats.c |  2 +-
 drivers/pci/pci.c | 66 +++
 drivers/pci/pcie/aer.c| 14 +++-
 drivers/pci/pcie/dpc.c| 23 +++-
 drivers/pci/probe.c   | 14 +---
 include/linux/aer.h   |  7 +++-
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  2 ++
 8 files changed, 98 insertions(+), 32 deletions(-)

-- 
2.39.2



Re: [PATCH v2 1/2] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-04-04 Thread Ilpo Järvinen
On Thu, 4 Apr 2024, Lukas Wunner wrote:

> On Wed, Apr 03, 2024 at 01:02:05PM +0300, Ilpo Järvinen wrote:
> > pcie_read_tlp_log() handles only 4 TLP Header Log DWORDs but TLP Prefix
> > Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.
> > 
> > Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
> > TLP Prefix Log. The layout of relevant registers in AER and DPC
> > Capability is not identical but the offsets of TLP Header Log and TLP
> ^^^   ^^^
> Somehow this doesn't seem to make sense.  Is the "not" perhaps wrong here?

Hi Lukas,

How about changing it into plural and adding a comma:

The layouts of relevant registers in AER and DPC Capabilities are not 
identical, but ...

Does that sound better?

> > Prefix Log vary so the callers must pass the offsets to
> > pcie_read_tlp_log().


-- 
 i.


[PATCH v2 2/2] PCI: Create helper to print TLP Header and Prefix Log

2024-04-03 Thread Ilpo Järvinen
Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log.
Print End-End Prefixes only if they are non-zero.

Consolidate the few places which currently print TLP using custom
formatting.

The first attempt used pr_cont() instead of building a string first but
it turns out pr_cont() is not compatible with pci_err() but prints on a
separate line. When I asked about this, Andy Shevchenko suggested
pr_cont() should not be used in the first place (to eventually get rid
of it) so pr_cont() is now replaced with building the string first.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pci.c  | 32 
 drivers/pci/pcie/aer.c | 10 ++
 drivers/pci/pcie/dpc.c |  5 +
 include/linux/aer.h|  2 ++
 4 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index af230e6e5557..54d4872d14b8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -9,6 +9,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1116,6 +1117,37 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, 
int where2,
 }
 EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
 
+/**
+ * pcie_print_tlp_log - Print TLP Header / Prefix Log contents
+ * @dev:   PCIe device
+ * @tlp_log:   TLP Log structure
+ * @pfx:   Internal string prefix (for indentation)
+ *
+ * Prints TLP Header and Prefix Log information held by @tlp_log.
+ */
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *tlp_log, const char *pfx)
+{
+   char buf[(10 + 1) * (4 + ARRAY_SIZE(tlp_log->prefix)) + 14 + 1];
+   unsigned int i;
+   int len;
+
+   len = scnprintf(buf, sizeof(buf), "%#010x %#010x %#010x %#010x",
+   tlp_log->dw[0], tlp_log->dw[1], tlp_log->dw[2],
+   tlp_log->dw[3]);
+
+   if (tlp_log->prefix[0])
+   len += scnprintf(buf + len, sizeof(buf) - len, " E-E 
Prefixes:");
+   for (i = 0; i < ARRAY_SIZE(tlp_log->prefix); i++) {
+   if (!tlp_log->prefix[i])
+   break;
+   len += scnprintf(buf + len, sizeof(buf) - len,
+" %#010x", tlp_log->prefix[i]);
+   }
+
+   pci_err(dev, "%sTLP Header: %s\n", pfx, buf);
+}
+
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ecc1dea5a208..efb9e728fe94 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -664,12 +664,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev 
*pdev,
}
 }
 
-static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
-{
-   pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
-   t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
-}
-
 static void __aer_print_error(struct pci_dev *dev,
  struct aer_err_info *info)
 {
@@ -724,7 +718,7 @@ void aer_print_error(struct pci_dev *dev, struct 
aer_err_info *info)
__aer_print_error(dev, info);
 
if (info->tlp_header_valid)
-   __print_tlp_header(dev, >tlp);
+   pcie_print_tlp_log(dev, >tlp, "  ");
 
 out:
if (info->id && info->error_dev_num > 1 && info->id == id)
@@ -796,7 +790,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity,
aer->uncor_severity);
 
if (tlp_header_valid)
-   __print_tlp_header(dev, >header_log);
+   pcie_print_tlp_log(dev, >header_log, "  ");
 
trace_aer_event(dev_name(>dev), (status & ~mask),
aer_severity, tlp_header_valid, >header_log);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 80b1456f95fe..3f8e3b6c7948 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -229,10 +229,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
  cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
  dpc_tlp_log_len(pdev), _log);
-   pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
-   tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
-   pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, 
tlp_log.prefix[i]);
+   pcie_print_tlp_log(pdev, _log, "");
 
if (pdev->dpc_rp_log_size < 5)
goto clear_status;
diff --git a/include/linux/aer.h b/include/linux/aer.h
index 2484056feb8d..1e8c61deca65 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -41,6 +41,8 @@ struct aer_capability_regs {
 int pcie_

[PATCH v2 1/2] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-04-03 Thread Ilpo Järvinen
pcie_read_tlp_log() handles only 4 TLP Header Log DWORDs but TLP Prefix
Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.

Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
TLP Prefix Log. The layout of relevant registers in AER and DPC
Capability is not identical but the offsets of TLP Header Log and TLP
Prefix Log vary so the callers must pass the offsets to
pcie_read_tlp_log().

Convert eetlp_prefix_path into integer called eetlp_prefix_max and
make is available also when CONFIG_PCI_PASID is not configured to
be able to determine the number of E-E Prefixes.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/ats.c |  2 +-
 drivers/pci/pci.c | 34 --
 drivers/pci/pcie/aer.c|  4 +++-
 drivers/pci/pcie/dpc.c| 22 +++---
 drivers/pci/probe.c   | 14 +-
 include/linux/aer.h   |  5 -
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  2 ++
 8 files changed, 63 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index c570892b2090..e13433dcfc82 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (WARN_ON(pdev->pasid_enabled))
return -EBUSY;
 
-   if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp)
+   if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp)
return -EINVAL;
 
if (!pasid)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e5f243dd4288..af230e6e5557 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1066,26 +1066,48 @@ static void pci_enable_acs(struct pci_dev *dev)
pci_disable_acs_redir(dev);
 }
 
+/**
+ * aer_tlp_log_len - Calculates TLP Header/Prefix Log length
+ * @dev:   PCIe device
+ *
+ * Return: TLP Header/Prefix Log length
+ */
+unsigned int aer_tlp_log_len(struct pci_dev *dev)
+{
+   return 4 + dev->eetlp_prefix_max;
+}
+
 /**
  * pcie_read_tlp_log - read TLP Header Log
  * @dev: PCIe device
  * @where: PCI Config offset of TLP Header Log
+ * @where2: PCI Config offset of TLP Prefix Log
+ * @tlp_len: TLP Log length (in DWORDs)
  * @tlp_log: TLP Log structure to fill
  *
  * Fill @tlp_log from TLP Header Log registers, e.g., AER or DPC.
  *
  * Return: 0 on success and filled TLP Log structure, <0 on error.
  */
-int pcie_read_tlp_log(struct pci_dev *dev, int where,
- struct pcie_tlp_log *tlp_log)
+int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
+ unsigned int tlp_len, struct pcie_tlp_log *tlp_log)
 {
-   int i, ret;
+   unsigned int i;
+   int off, ret;
+   u32 *to;
 
memset(tlp_log, 0, sizeof(*tlp_log));
 
-   for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4,
-   _log->dw[i]);
+   for (i = 0; i < tlp_len; i++) {
+   if (i < 4) {
+   to = _log->dw[i];
+   off = where + i * 4;
+   } else {
+   to = _log->prefix[i - 4];
+   off = where2 + (i - 4) * 4;
+   }
+
+   ret = pci_read_config_dword(dev, off, to);
if (ret)
return pcibios_err_to_errno(ret);
}
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ac6293c24976..ecc1dea5a208 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
 
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
-   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, 
>tlp);
+   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG,
+ aer + PCI_ERR_PREFIX_LOG,
+ aer_tlp_log_len(dev), >tlp);
}
}
 
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index a668820696dc..80b1456f95fe 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -187,10 +187,19 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
return ret;
 }
 
+static unsigned int dpc_tlp_log_len(struct pci_dev *pdev)
+{
+   /* Remove ImpSpec Log register from the count */
+   if (pdev->dpc_rp_log_size >= 5)
+   return pdev->dpc_rp_log_size - 1;
+
+   return pdev->dpc_rp_log_size;
+}
+
 static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 {
u16 cap = pdev->dpc_cap, dpc_status, first_error;
-   u32 status, mask, sev, syserr, exc, log, prefix;
+   u32 status, mask, sev, syserr, exc, log;
struct pcie_tlp_log tlp_log;
  

[PATCH v2 0/2] PCI: Consolidate TLP Log reading and printing

2024-04-03 Thread Ilpo Järvinen
This series has the remaining patches of the AER & DPC TLP Log handling
consolidation.

v2:
- Don't add EXPORT()s
- Don't include igxbe changes
- Don't use pr_cont() as it's incompatible with pci_err() and according
  to Andy Shevchenko should not be used in the first place

Ilpo Järvinen (2):
  PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  PCI: Create helper to print TLP Header and Prefix Log

 drivers/pci/ats.c |  2 +-
 drivers/pci/pci.c | 66 +++
 drivers/pci/pcie/aer.c| 14 +++-
 drivers/pci/pcie/dpc.c| 23 +++-
 drivers/pci/probe.c   | 14 +---
 include/linux/aer.h   |  7 +++-
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  2 ++
 8 files changed, 98 insertions(+), 32 deletions(-)

-- 
2.39.2



Re: [PATCH 0/4] PCI: Consolidate TLP Log reading and printing

2024-03-22 Thread Ilpo Järvinen
On Mon, 11 Mar 2024, Ilpo Järvinen wrote:

> On Fri, 8 Mar 2024, Bjorn Helgaas wrote:
> 
> > On Tue, Feb 06, 2024 at 03:57:13PM +0200, Ilpo Järvinen wrote:
> > > This series consolidates AER & DPC TLP Log handling code. Helpers are
> > > added for reading and printing the TLP Log and the format is made to
> > > include E-E Prefixes in both cases (previously only one DPC RP PIO
> > > displayed the E-E Prefixes).
> > > 
> > > I'd appreciate if people familiar with ixgbe could check the error
> > > handling conversion within the driver is correct.
> > > 
> > > Ilpo Järvinen (4):
> > >   PCI/AER: Cleanup register variable
> > >   PCI: Generalize TLP Header Log reading
> > 
> > I applied these first two to pci/aer for v6.9, thanks, these are all
> > nice improvements!
> > 
> > I postponed the ixgbe part for now because I think we should get an
> > ack from those maintainers or just send it to them since it subtly
> > changes the error and device removal checking there.
> 
> Okay, I'll make sure they're separated properly for the remaining patches 
> (I was already planning on doing that separation and posting v2 to avoid 
> their input blocking the changed but you beat me to it).
> 
> > >   PCI: Add TLP Prefix reading into pcie_read_tlp_log()
> > >   PCI: Create helper to print TLP Header and Prefix Log
> > 
> > I'll respond to these with some minor comments.
> 
> Did you forget to send those comments?

Ping.

I still haven't received those comments for patches 3 & 4.

-- 
 i.


Re: [PATCH 0/4] PCI: Consolidate TLP Log reading and printing

2024-03-11 Thread Ilpo Järvinen
On Fri, 8 Mar 2024, Bjorn Helgaas wrote:

> On Tue, Feb 06, 2024 at 03:57:13PM +0200, Ilpo Järvinen wrote:
> > This series consolidates AER & DPC TLP Log handling code. Helpers are
> > added for reading and printing the TLP Log and the format is made to
> > include E-E Prefixes in both cases (previously only one DPC RP PIO
> > displayed the E-E Prefixes).
> > 
> > I'd appreciate if people familiar with ixgbe could check the error
> > handling conversion within the driver is correct.
> > 
> > Ilpo Järvinen (4):
> >   PCI/AER: Cleanup register variable
> >   PCI: Generalize TLP Header Log reading
> 
> I applied these first two to pci/aer for v6.9, thanks, these are all
> nice improvements!
> 
> I postponed the ixgbe part for now because I think we should get an
> ack from those maintainers or just send it to them since it subtly
> changes the error and device removal checking there.

Okay, I'll make sure they're separated properly for the remaining patches 
(I was already planning on doing that separation and posting v2 to avoid 
their input blocking the changed but you beat me to it).

> >   PCI: Add TLP Prefix reading into pcie_read_tlp_log()
> >   PCI: Create helper to print TLP Header and Prefix Log
> 
> I'll respond to these with some minor comments.

Did you forget to send those comments?


-- 
 i.


Re: [PATCH 0/4] PCI: Consolidate TLP Log reading and printing

2024-02-07 Thread Ilpo Järvinen
Adding Cc Quigshun which I ended up forgotting despite thinking it at one 
point.

-- 
 i.

On Tue, 6 Feb 2024, Ilpo Järvinen wrote:

> This series consolidates AER & DPC TLP Log handling code. Helpers are
> added for reading and printing the TLP Log and the format is made to
> include E-E Prefixes in both cases (previously only one DPC RP PIO
> displayed the E-E Prefixes).
> 
> I'd appreciate if people familiar with ixgbe could check the error
> handling conversion within the driver is correct.
> 
> Ilpo Järvinen (4):
>   PCI/AER: Cleanup register variable
>   PCI: Generalize TLP Header Log reading
>   PCI: Add TLP Prefix reading into pcie_read_tlp_log()
>   PCI: Create helper to print TLP Header and Prefix Log
> 
>  drivers/firmware/efi/cper.c   |  4 +-
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 39 +++--
>  drivers/pci/ats.c |  2 +-
>  drivers/pci/pci.c | 79 +++
>  drivers/pci/pci.h |  2 +-
>  drivers/pci/pcie/aer.c| 28 ++-
>  drivers/pci/pcie/dpc.c| 31 
>  drivers/pci/probe.c   | 14 ++--
>  include/linux/aer.h   | 16 ++--
>  include/linux/pci.h   |  2 +-
>  include/ras/ras_event.h   | 10 +--
>  include/uapi/linux/pci_regs.h |  2 +
>  12 files changed, 145 insertions(+), 84 deletions(-)
> 
> 

[PATCH 4/4] PCI: Create helper to print TLP Header and Prefix Log

2024-02-06 Thread Ilpo Järvinen
Add pcie_print_tlp_log() helper to print TLP Header and Prefix Log.
Print End-End Prefixes only if they are non-zero.

Consolidate the few places which currently print TLP using custom
formatting.

Signed-off-by: Ilpo Järvinen 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  4 +--
 drivers/pci/pci.c | 28 +++
 drivers/pci/pcie/aer.c| 10 ++-
 drivers/pci/pcie/dpc.c|  5 +---
 include/linux/aer.h   |  2 ++
 5 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 6ce720726a1a..73eabf3215e5 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -11355,8 +11355,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct 
pci_dev *pdev,
 
vf = FIELD_GET(0x7F, req_id);
e_dev_err("VF %d has caused a PCIe error\n", vf);
-   e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: %8.8x\tdw3: 
%8.8x\n",
- tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], 
tlp_log.dw[3]);
+   pcie_print_tlp_log(pdev, _log, "");
+
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
device_id = IXGBE_82599_VF_DEVICE_ID;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 268a5b9f1dff..d7974d25ae44 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -9,6 +9,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1118,6 +1119,33 @@ int pcie_read_tlp_log(struct pci_dev *dev, int where, 
int where2,
 }
 EXPORT_SYMBOL_GPL(pcie_read_tlp_log);
 
+/**
+ * pcie_print_tlp_log - Print TLP Header / Prefix Log contents
+ * @dev:   PCIe device
+ * @tlp_log:   TLP Log structure
+ * @pfx:   Internal string prefix (for indentation)
+ *
+ * Prints TLP Header and Prefix Log information held by @tlp_log.
+ */
+void pcie_print_tlp_log(const struct pci_dev *dev,
+   const struct pcie_tlp_log *tlp_log, const char *pfx)
+{
+   unsigned int i;
+
+   pci_err(dev, "%sTLP Header: %#010x %#010x %#010x %#010x",
+   pfx, tlp_log->dw[0], tlp_log->dw[1], tlp_log->dw[2], 
tlp_log->dw[3]);
+
+   if (tlp_log->prefix[0])
+   pr_cont(" E-E Prefixes:");
+   for (i = 0; i < ARRAY_SIZE(tlp_log->prefix); i++) {
+   if (!tlp_log->prefix[i])
+   break;
+   pr_cont(" %#010x", tlp_log->prefix[i]);
+   }
+   pr_cont("\n");
+}
+EXPORT_SYMBOL_GPL(pcie_print_tlp_log);
+
 /**
  * pci_restore_bars - restore a device's BAR values (e.g. after wake-up)
  * @dev: PCI device to have its BARs restored
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ecc1dea5a208..efb9e728fe94 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -664,12 +664,6 @@ static void pci_rootport_aer_stats_incr(struct pci_dev 
*pdev,
}
 }
 
-static void __print_tlp_header(struct pci_dev *dev, struct pcie_tlp_log *t)
-{
-   pci_err(dev, "  TLP Header: %08x %08x %08x %08x\n",
-   t->dw[0], t->dw[1], t->dw[2], t->dw[3]);
-}
-
 static void __aer_print_error(struct pci_dev *dev,
  struct aer_err_info *info)
 {
@@ -724,7 +718,7 @@ void aer_print_error(struct pci_dev *dev, struct 
aer_err_info *info)
__aer_print_error(dev, info);
 
if (info->tlp_header_valid)
-   __print_tlp_header(dev, >tlp);
+   pcie_print_tlp_log(dev, >tlp, "  ");
 
 out:
if (info->id && info->error_dev_num > 1 && info->id == id)
@@ -796,7 +790,7 @@ void pci_print_aer(struct pci_dev *dev, int aer_severity,
aer->uncor_severity);
 
if (tlp_header_valid)
-   __print_tlp_header(dev, >header_log);
+   pcie_print_tlp_log(dev, >header_log, "  ");
 
trace_aer_event(dev_name(>dev), (status & ~mask),
aer_severity, tlp_header_valid, >header_log);
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index f384d0b02aa0..9c93871fbe37 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -229,10 +229,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
pcie_read_tlp_log(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
  cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
  dpc_tlp_log_len(pdev), _log);
-   pci_err(pdev, "TLP Header: %#010x %#010x %#010x %#010x\n",
-   tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], tlp_log.dw[3]);
-   for (i = 0; i < pdev->dpc_rp_log_size - 5; i++)
-   pci_err

[PATCH 3/4] PCI: Add TLP Prefix reading into pcie_read_tlp_log()

2024-02-06 Thread Ilpo Järvinen
pcie_read_tlp_log() handles only 4 TLP Header Log DWORDs but TLP Prefix
Log (PCIe r6.1 secs 7.8.4.12 & 7.9.14.13) may also be present.

Generalize pcie_read_tlp_log() and struct pcie_tlp_log to handle also
TLP Prefix Log. The layout of relevant registers in AER and DPC
Capability is not identical but the offsets of TLP Header Log and TLP
Prefix Log vary so the callers must pass the offsets to
pcie_read_tlp_log().

Convert eetlp_prefix_path into integer called eetlp_prefix_max and
make is available also when CONFIG_PCI_PASID is not configured to
be able to determine the number of E-E Prefixes.

Signed-off-by: Ilpo Järvinen 
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  4 +-
 drivers/pci/ats.c |  2 +-
 drivers/pci/pci.c | 37 ---
 drivers/pci/pcie/aer.c|  4 +-
 drivers/pci/pcie/dpc.c| 22 +++
 drivers/pci/probe.c   | 14 ---
 include/linux/aer.h   |  5 ++-
 include/linux/pci.h   |  2 +-
 include/uapi/linux/pci_regs.h |  2 +
 9 files changed, 69 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 5fdf37968b2d..6ce720726a1a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -11336,7 +11336,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct 
pci_dev *pdev,
if (!pos)
goto skip_bad_vf_detection;
 
-   ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG, _log);
+   ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG,
+   pos + PCI_ERR_PREFIX_LOG,
+   aer_tlp_log_len(pdev), _log);
if (ret < 0) {
ixgbe_check_cfg_remove(hw, pdev);
goto skip_bad_vf_detection;
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index c570892b2090..e13433dcfc82 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -377,7 +377,7 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
if (WARN_ON(pdev->pasid_enabled))
return -EBUSY;
 
-   if (!pdev->eetlp_prefix_path && !pdev->pasid_no_tlp)
+   if (!pdev->eetlp_prefix_max && !pdev->pasid_no_tlp)
return -EINVAL;
 
if (!pasid)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0152f0144eec..268a5b9f1dff 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1068,23 +1068,48 @@ static void pci_enable_acs(struct pci_dev *dev)
 }
 
 /**
- * pcie_read_tlp_log - Reads TLP Header Log
+ * aer_tlp_log_len - Calculates TLP Header/Prefix Log length
+ * @dev:   PCIe device
+ *
+ * Return: TLP Header/Prefix Log length
+ */
+unsigned int aer_tlp_log_len(struct pci_dev *dev)
+{
+   return 4 + dev->eetlp_prefix_max;
+}
+EXPORT_SYMBOL_GPL(aer_tlp_log_len);
+
+/**
+ * pcie_read_tlp_log - Reads TLP Header and Prefix Log
  * @dev:   PCIe device
  * @where: PCI Config offset of TLP Header Log
+ * @where2:PCI Config offset of TLP Prefix Log
+ * @tlp_len:   TLP Log length (in DWORDs)
  * @tlp_log:   TLP Log structure to fill
  *
- * Fills @tlp_log from TLP Header Log registers.
+ * Fills @tlp_log from TLP Header and Prefix Log registers.
  *
  * Return: 0 on success and filled TLP Log structure, <0 on error.
  */
-int pcie_read_tlp_log(struct pci_dev *dev, int where, struct pcie_tlp_log 
*tlp_log)
+int pcie_read_tlp_log(struct pci_dev *dev, int where, int where2,
+ unsigned int tlp_len, struct pcie_tlp_log *tlp_log)
 {
-   int i, ret;
+   unsigned int i;
+   int off, ret;
+   u32 *to;
 
memset(tlp_log, 0, sizeof(*tlp_log));
 
-   for (i = 0; i < 4; i++) {
-   ret = pci_read_config_dword(dev, where + i * 4, 
_log->dw[i]);
+   for (i = 0; i < tlp_len; i++) {
+   if (i < 4) {
+   to = _log->dw[i];
+   off = where + i * 4;
+   } else {
+   to = _log->prefix[i - 4];
+   off = where2 + (i - 4) * 4;
+   }
+
+   ret = pci_read_config_dword(dev, off, to);
if (ret)
return pcibios_err_to_errno(ret);
}
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ac6293c24976..ecc1dea5a208 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1245,7 +1245,9 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
 
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
-   pcie_read_tlp_log(dev, aer + PCI_ERR_HEADER_LOG, 
>tlp);
+   pcie_read_tlp_log(dev, aer + PCI_ERR_HEA

[PATCH 2/4] PCI: Generalize TLP Header Log reading

2024-02-06 Thread Ilpo Järvinen
Both AER and DPC RP PIO provide TLP Header Log registers (PCIe r6.1
secs 7.8.4 & 7.9.14) to convey error diagnostics but the struct is
named after AER as the struct aer_header_log_regs. Also, not all places
that handle TLP Header Log use the struct and the struct members are
named individually.

Generalize the struct name and members, and use it consistently where
TLP Header Log is being handled so that a pcie_read_tlp_log() helper
can be easily added.

Signed-off-by: Ilpo Järvinen 
---
 drivers/firmware/efi/cper.c   |  4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 37 +--
 drivers/pci/pci.c | 26 +
 drivers/pci/pci.h |  2 +-
 drivers/pci/pcie/aer.c| 14 ++-
 drivers/pci/pcie/dpc.c| 14 ++-
 include/linux/aer.h   | 11 +++---
 include/ras/ras_event.h   | 10 ++---
 8 files changed, 56 insertions(+), 62 deletions(-)

diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 35c37f667781..d3f98161171e 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -445,8 +445,8 @@ static void cper_print_pcie(const char *pfx, const struct 
cper_sec_pcie *pcie,
printk("%saer_uncor_severity: 0x%08x\n",
   pfx, aer->uncor_severity);
printk("%sTLP Header: %08x %08x %08x %08x\n", pfx,
-  aer->header_log.dw0, aer->header_log.dw1,
-  aer->header_log.dw2, aer->header_log.dw3);
+  aer->header_log.dw[0], aer->header_log.dw[1],
+  aer->header_log.dw[2], aer->header_log.dw[3]);
}
 }
 
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 
b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index bd541527c8c7..5fdf37968b2d 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Copyright(c) 1999 - 2018 Intel Corporation. */
 
+#include 
 #include 
 #include 
 #include 
@@ -391,22 +392,6 @@ u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg)
return value;
 }
 
-#ifdef CONFIG_PCI_IOV
-static u32 ixgbe_read_pci_cfg_dword(struct ixgbe_hw *hw, u32 reg)
-{
-   struct ixgbe_adapter *adapter = hw->back;
-   u32 value;
-
-   if (ixgbe_removed(hw->hw_addr))
-   return IXGBE_FAILED_READ_CFG_DWORD;
-   pci_read_config_dword(adapter->pdev, reg, );
-   if (value == IXGBE_FAILED_READ_CFG_DWORD &&
-   ixgbe_check_cfg_remove(hw, adapter->pdev))
-   return IXGBE_FAILED_READ_CFG_DWORD;
-   return value;
-}
-#endif /* CONFIG_PCI_IOV */
-
 void ixgbe_write_pci_cfg_word(struct ixgbe_hw *hw, u32 reg, u16 value)
 {
struct ixgbe_adapter *adapter = hw->back;
@@ -11332,8 +11317,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct 
pci_dev *pdev,
 #ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = >hw;
struct pci_dev *bdev, *vfdev;
-   u32 dw0, dw1, dw2, dw3;
-   int vf, pos;
+   struct pcie_tlp_log tlp_log;
+   int vf, pos, ret;
u16 req_id, pf_func;
 
if (adapter->hw.mac.type == ixgbe_mac_82598EB ||
@@ -11351,14 +11336,13 @@ static pci_ers_result_t 
ixgbe_io_error_detected(struct pci_dev *pdev,
if (!pos)
goto skip_bad_vf_detection;
 
-   dw0 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG);
-   dw1 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 4);
-   dw2 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 8);
-   dw3 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 12);
-   if (ixgbe_removed(hw->hw_addr))
+   ret = pcie_read_tlp_log(pdev, pos + PCI_ERR_HEADER_LOG, _log);
+   if (ret < 0) {
+   ixgbe_check_cfg_remove(hw, pdev);
goto skip_bad_vf_detection;
+   }
 
-   req_id = dw1 >> 16;
+   req_id = tlp_log.dw[1] >> 16;
/* On the 82599 if bit 7 of the requestor ID is set then it's a VF */
if (!(req_id & 0x0080))
goto skip_bad_vf_detection;
@@ -11369,9 +11353,8 @@ static pci_ers_result_t ixgbe_io_error_detected(struct 
pci_dev *pdev,
 
vf = FIELD_GET(0x7F, req_id);
e_dev_err("VF %d has caused a PCIe error\n", vf);
-   e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: "
-   "%8.8x\tdw3: %8.8x\n",
-   dw0, dw1, dw2, dw3);
+   e_dev_err("TLP: dw0: %8.8x\tdw1: %8.8x\tdw2: %8.8x\tdw3: 
%8.8x\n",
+ tlp_log.dw[0], tlp_log.dw[1], tlp_log.dw[2], 
tlp_log.dw[3]);
switch (adapter->hw.mac.type) {
case ixgbe

[PATCH 1/4] PCI/AER: Cleanup register variable

2024-02-06 Thread Ilpo Järvinen
Use u32 for PCIe Capability register variable and name it aercc
(Advanced Error Capabilities and Control register, PCIe r6.1 sec
7.8.4.7) instead of temp.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/aer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index 05fc30bb5134..e31e6a9a7773 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1210,7 +1210,7 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
 {
int type = pci_pcie_type(dev);
int aer = dev->aer_cap;
-   int temp;
+   u32 aercc;
 
/* Must reset in this function */
info->status = 0;
@@ -1241,8 +1241,8 @@ int aer_get_device_error_info(struct pci_dev *dev, struct 
aer_err_info *info)
return 0;
 
/* Get First Error Pointer */
-   pci_read_config_dword(dev, aer + PCI_ERR_CAP, );
-   info->first_error = PCI_ERR_CAP_FEP(temp);
+   pci_read_config_dword(dev, aer + PCI_ERR_CAP, );
+   info->first_error = PCI_ERR_CAP_FEP(aercc);
 
if (info->status & AER_LOG_TLP_MASKS) {
info->tlp_header_valid = 1;
-- 
2.39.2



[PATCH 0/4] PCI: Consolidate TLP Log reading and printing

2024-02-06 Thread Ilpo Järvinen
This series consolidates AER & DPC TLP Log handling code. Helpers are
added for reading and printing the TLP Log and the format is made to
include E-E Prefixes in both cases (previously only one DPC RP PIO
displayed the E-E Prefixes).

I'd appreciate if people familiar with ixgbe could check the error
handling conversion within the driver is correct.

Ilpo Järvinen (4):
  PCI/AER: Cleanup register variable
  PCI: Generalize TLP Header Log reading
  PCI: Add TLP Prefix reading into pcie_read_tlp_log()
  PCI: Create helper to print TLP Header and Prefix Log

 drivers/firmware/efi/cper.c   |  4 +-
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 39 +++--
 drivers/pci/ats.c |  2 +-
 drivers/pci/pci.c | 79 +++
 drivers/pci/pci.h |  2 +-
 drivers/pci/pcie/aer.c| 28 ++-
 drivers/pci/pcie/dpc.c| 31 
 drivers/pci/probe.c   | 14 ++--
 include/linux/aer.h   | 16 ++--
 include/linux/pci.h   |  2 +-
 include/ras/ras_event.h   | 10 +--
 include/uapi/linux/pci_regs.h |  2 +
 12 files changed, 145 insertions(+), 84 deletions(-)

-- 
2.39.2



Re: [PATCH 1/1] PCI/DPC: Fix TLP Prefix register reading offset

2024-01-22 Thread Ilpo Järvinen
On Fri, 19 Jan 2024, Bjorn Helgaas wrote:

> On Thu, Jan 18, 2024 at 01:08:15PM +0200, Ilpo Järvinen wrote:
> > The TLP Prefix Log Register consists of multiple DWORDs (PCIe r6.1 sec
> > 7.9.14.13) but the loop in dpc_process_rp_pio_error() keeps reading
> > from the first DWORD. Add the iteration count based offset calculation
> > into the config read.
> 
> So IIUC the user-visible bug is that we print only the first PIO TLP
> Prefix (duplicated several times), and we never print the second,
> third, etc Prefixes, right?

Yes.

> I wish we could print them all in a single pci_err(), as we do for the
> TLP Header Log, instead of dribbling them out one by one.

I've also done some work towards consolidating AER and DPC TLP 
Header/Prefix Log handling which is when I found this bug (the reading 
side is already done but printing is still pending).

> > Fixes: f20c4ea49ec4 ("PCI/DPC: Add eDPC support")
> > Signed-off-by: Ilpo Järvinen 

-- 
 i.

[PATCH 1/1] PCI/DPC: Fix TLP Prefix register reading offset

2024-01-18 Thread Ilpo Järvinen
The TLP Prefix Log Register consists of multiple DWORDs (PCIe r6.1 sec
7.9.14.13) but the loop in dpc_process_rp_pio_error() keeps reading
from the first DWORD. Add the iteration count based offset calculation
into the config read.

Fixes: f20c4ea49ec4 ("PCI/DPC: Add eDPC support")
Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/dpc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 94111e438241..e5d7c12854fa 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -234,7 +234,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 
for (i = 0; i < pdev->dpc_rp_log_size - 5; i++) {
pci_read_config_dword(pdev,
-   cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, );
+   cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG + i * 4, 
);
pci_err(pdev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
}
  clear_status:
-- 
2.39.2



[PATCH 2/6] powerpc/fsl-pci: Use PCI_HEADER_TYPE_MASK instead of literal

2023-11-24 Thread Ilpo Järvinen
Replace 0x7f literals with PCI_HEADER_TYPE_MASK.

Signed-off-by: Ilpo Järvinen 
---
 arch/powerpc/sysdev/fsl_pci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 3868483fbe29..ef7707ea0db7 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -54,7 +54,7 @@ static void quirk_fsl_pcie_early(struct pci_dev *dev)
 
/* if we aren't in host mode don't bother */
pci_read_config_byte(dev, PCI_HEADER_TYPE, _type);
-   if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
+   if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
return;
 
dev->class = PCI_CLASS_BRIDGE_PCI_NORMAL;
@@ -581,7 +581,7 @@ static int fsl_add_bridge(struct platform_device *pdev, int 
is_primary)
hose->ops = _indirect_pcie_ops;
/* For PCIE read HEADER_TYPE to identify controller mode */
early_read_config_byte(hose, 0, 0, PCI_HEADER_TYPE, _type);
-   if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE)
+   if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE)
goto no_bridge;
 
} else {
-- 
2.30.2



[PATCH 6/7] PCI/DPC: Use defines with DPC reason fields

2023-10-18 Thread Ilpo Järvinen
Add new defines for DPC reason fields and use them instead of literals.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/dpc.c| 27 +--
 include/uapi/linux/pci_regs.h |  6 ++
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 0048a11bd119..94111e438241 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -274,20 +274,27 @@ void dpc_process_error(struct pci_dev *pdev)
pci_info(pdev, "containment event, status:%#06x source:%#06x\n",
 status, source);
 
-   reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN) >> 1;
-   ext_reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT) >> 5;
+   reason = status & PCI_EXP_DPC_STATUS_TRIGGER_RSN;
+   ext_reason = status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT;
pci_warn(pdev, "%s detected\n",
-(reason == 0) ? "unmasked uncorrectable error" :
-(reason == 1) ? "ERR_NONFATAL" :
-(reason == 2) ? "ERR_FATAL" :
-(ext_reason == 0) ? "RP PIO error" :
-(ext_reason == 1) ? "software trigger" :
-"reserved error");
+(reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR) ?
+"unmasked uncorrectable error" :
+(reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE) ?
+"ERR_NONFATAL" :
+(reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE) ?
+"ERR_FATAL" :
+(ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO) ?
+"RP PIO error" :
+(ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER) ?
+"software trigger" :
+"reserved error");
 
/* show RP PIO error detail information */
-   if (pdev->dpc_rp_extensions && reason == 3 && ext_reason == 0)
+   if (pdev->dpc_rp_extensions &&
+   reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT &&
+   ext_reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO)
dpc_process_rp_pio_error(pdev);
-   else if (reason == 0 &&
+   else if (reason == PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR &&
 dpc_get_aer_uncorrect_severity(pdev, ) &&
 aer_get_device_error_info(pdev, )) {
aer_print_error(pdev, );
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 2d6df02a4b93..c4d67ceae20d 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -1044,9 +1044,15 @@
 #define PCI_EXP_DPC_STATUS 0x08/* DPC Status */
 #define  PCI_EXP_DPC_STATUS_TRIGGER0x0001 /* Trigger Status */
 #define  PCI_EXP_DPC_STATUS_TRIGGER_RSN0x0006 /* Trigger Reason */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR  0x /* DPC due to unmasked 
uncorrectable error */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE0x0002 /* DPC due to receiving 
ERR_NONFATAL */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE 0x0004 /* DPC due to receiving 
ERR_FATAL */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT 0x0006 /* Reason in Trig Reason 
Extension field */
 #define  PCI_EXP_DPC_STATUS_INTERRUPT  0x0008 /* Interrupt Status */
 #define  PCI_EXP_DPC_RP_BUSY   0x0010 /* Root Port Busy */
 #define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO 0x  /* DPC due to 
RP PIO error */
+#define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER 0x0020  /* DPC due to 
DPC SW Trigger bit */
 #define  PCI_EXP_DPC_RP_PIO_FEP0x1f00 /* Root Port PIO 
First Error Pointer */
 
 #define PCI_EXP_DPC_SOURCE_ID   0x0A   /* DPC Source Identifier */
-- 
2.30.2



[PATCH 5/7] PCI/DPC: Use defined fields with DPC_CTL register

2023-10-18 Thread Ilpo Järvinen
Instead of using a literal to clear bits, add PCI_EXP_DPC_CTL_EN_MASK
and use the usual pattern to modify a bitfield.

While at it, rearrange RMW code more logically together.

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/pcie/dpc.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index a5c259ada9ea..0048a11bd119 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -18,6 +18,9 @@
 #include "portdrv.h"
 #include "../pci.h"
 
+#define PCI_EXP_DPC_CTL_EN_MASK(PCI_EXP_DPC_CTL_EN_FATAL | \
+PCI_EXP_DPC_CTL_EN_NONFATAL)
+
 static const char * const rp_pio_error_string[] = {
"Configuration Request received UR Completion",  /* Bit Position 0  */
"Configuration Request received CA Completion",  /* Bit Position 1  */
@@ -369,12 +372,13 @@ static int dpc_probe(struct pcie_device *dev)
}
 
pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CAP, );
-   pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, );
 
-   ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_FATAL | 
PCI_EXP_DPC_CTL_INT_EN;
+   pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, );
+   ctl &= ~PCI_EXP_DPC_CTL_EN_MASK;
+   ctl |= PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN;
pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl);
-   pci_info(pdev, "enabled with IRQ %d\n", dev->irq);
 
+   pci_info(pdev, "enabled with IRQ %d\n", dev->irq);
pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c 
PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
 cap & PCI_EXP_DPC_IRQ, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
 FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP),
-- 
2.30.2



[PATCH 4/7] PCI/DPC: Use FIELD_GET()

2023-10-18 Thread Ilpo Järvinen
From: Bjorn Helgaas 

Use FIELD_GET() to remove dependencies on the field position, i.e., the
shift value. No functional change intended.

Signed-off-by: Ilpo Järvinen 
Signed-off-by: Bjorn Helgaas 
---
 drivers/pci/pcie/dpc.c| 5 +++--
 drivers/pci/quirks.c  | 2 +-
 include/uapi/linux/pci_regs.h | 1 +
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 3ceed8e3de41..a5c259ada9ea 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -9,6 +9,7 @@
 #define dev_fmt(fmt) "DPC: " fmt
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -202,7 +203,7 @@ static void dpc_process_rp_pio_error(struct pci_dev *pdev)
 
/* Get First Error Pointer */
pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, _status);
-   first_error = (dpc_status & 0x1f00) >> 8;
+   first_error = FIELD_GET(PCI_EXP_DPC_RP_PIO_FEP, dpc_status);
 
for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) {
if ((status & ~mask) & (1 << i))
@@ -338,7 +339,7 @@ void pci_dpc_init(struct pci_dev *pdev)
/* Quirks may set dpc_rp_log_size if device or firmware is buggy */
if (!pdev->dpc_rp_log_size) {
pdev->dpc_rp_log_size =
-   (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
+   FIELD_GET(PCI_EXP_DPC_RP_PIO_LOG_SIZE, cap);
if (pdev->dpc_rp_log_size < 4 || pdev->dpc_rp_log_size > 9) {
pci_err(pdev, "RP PIO log size %u is invalid\n",
pdev->dpc_rp_log_size);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index eeec1d6f9023..a9fdc2e3f110 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -6154,7 +6154,7 @@ static void dpc_log_size(struct pci_dev *dev)
if (!(val & PCI_EXP_DPC_CAP_RP_EXT))
return;
 
-   if (!((val & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8)) {
+   if (FIELD_GET(PCI_EXP_DPC_RP_PIO_LOG_SIZE, val) == 0) {
pci_info(dev, "Overriding RP PIO Log Size to 4\n");
dev->dpc_rp_log_size = 4;
}
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 495f0ae4ecd5..2d6df02a4b93 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -1047,6 +1047,7 @@
 #define  PCI_EXP_DPC_STATUS_INTERRUPT  0x0008 /* Interrupt Status */
 #define  PCI_EXP_DPC_RP_BUSY   0x0010 /* Root Port Busy */
 #define  PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
+#define  PCI_EXP_DPC_RP_PIO_FEP0x1f00 /* Root Port PIO 
First Error Pointer */
 
 #define PCI_EXP_DPC_SOURCE_ID   0x0A   /* DPC Source Identifier */
 
-- 
2.30.2



[PATCH 3/7] PCI: hotplug: Use FIELD_GET/PREP()

2023-10-18 Thread Ilpo Järvinen
Instead of handcrafted shifts to handle register fields, use
FIELD_GET/FIELD_PREP().

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/hotplug/pciehp_core.c | 3 ++-
 drivers/pci/hotplug/pciehp_hpc.c  | 5 +++--
 drivers/pci/hotplug/pnv_php.c | 3 ++-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_core.c 
b/drivers/pci/hotplug/pciehp_core.c
index 4042d87d539d..ddd55ad97a58 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -20,6 +20,7 @@
 #define pr_fmt(fmt) "pciehp: " fmt
 #define dev_fmt pr_fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -103,7 +104,7 @@ static int set_attention_status(struct hotplug_slot 
*hotplug_slot, u8 status)
struct pci_dev *pdev = ctrl->pcie->port;
 
if (status)
-   status <<= PCI_EXP_SLTCTL_ATTN_IND_SHIFT;
+   status = FIELD_PREP(PCI_EXP_SLTCTL_AIC, status);
else
status = PCI_EXP_SLTCTL_ATTN_IND_OFF;
 
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index fd713abdfb9f..b1d0a1b3917d 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -14,6 +14,7 @@
 
 #define dev_fmt(fmt) "pciehp: " fmt
 
+#include 
 #include 
 #include 
 #include 
@@ -484,7 +485,7 @@ int pciehp_set_raw_indicator_status(struct hotplug_slot 
*hotplug_slot,
struct pci_dev *pdev = ctrl_dev(ctrl);
 
pci_config_pm_runtime_get(pdev);
-   pcie_write_cmd_nowait(ctrl, status << 6,
+   pcie_write_cmd_nowait(ctrl, FIELD_PREP(PCI_EXP_SLTCTL_AIC, status),
  PCI_EXP_SLTCTL_AIC | PCI_EXP_SLTCTL_PIC);
pci_config_pm_runtime_put(pdev);
return 0;
@@ -1028,7 +1029,7 @@ struct controller *pcie_init(struct pcie_device *dev)
PCI_EXP_SLTSTA_DLLSC | PCI_EXP_SLTSTA_PDC);
 
ctrl_info(ctrl, "Slot #%d AttnBtn%c PwrCtrl%c MRL%c AttnInd%c PwrInd%c 
HotPlug%c Surprise%c Interlock%c NoCompl%c IbPresDis%c LLActRep%c%s\n",
-   (slot_cap & PCI_EXP_SLTCAP_PSN) >> 19,
+   FIELD_GET(PCI_EXP_SLTCAP_PSN, slot_cap),
FLAG(slot_cap, PCI_EXP_SLTCAP_ABP),
FLAG(slot_cap, PCI_EXP_SLTCAP_PCP),
FLAG(slot_cap, PCI_EXP_SLTCAP_MRLSP),
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 881d420637bf..694349be9d0a 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -5,6 +5,7 @@
  * Copyright Gavin Shan, IBM Corporation 2016.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -731,7 +732,7 @@ static int pnv_php_enable_msix(struct pnv_php_slot 
*php_slot)
 
/* Check hotplug MSIx entry is in range */
pcie_capability_read_word(pdev, PCI_EXP_FLAGS, _flag);
-   entry.entry = (pcie_flag & PCI_EXP_FLAGS_IRQ) >> 9;
+   entry.entry = FIELD_GET(PCI_EXP_FLAGS_IRQ, pcie_flag);
if (entry.entry >= nr_entries)
return -ERANGE;
 
-- 
2.30.2



[PATCH 3/3] PCI: Use PCI_HEADER_TYPE_* instead of literals

2023-10-03 Thread Ilpo Järvinen
Replace literals under drivers/pci/ with PCI_HEADER_TYPE_MASK,
PCI_HEADER_TYPE_NORMAL, and PCI_HEADER_TYPE_MFD.

While at it, replace !! boolean conversion with FIELD_GET().

Signed-off-by: Ilpo Järvinen 
---
 drivers/pci/controller/dwc/pci-layerscape.c   |  2 +-
 .../controller/mobiveil/pcie-mobiveil-host.c  |  2 +-
 drivers/pci/controller/pcie-iproc.c   |  2 +-
 drivers/pci/controller/pcie-rcar-ep.c |  2 +-
 drivers/pci/controller/pcie-rcar-host.c   |  2 +-
 drivers/pci/controller/vmd.c  |  2 +-
 drivers/pci/hotplug/cpqphp_ctrl.c |  6 ++---
 drivers/pci/hotplug/cpqphp_pci.c  | 22 +--
 drivers/pci/hotplug/ibmphp.h  |  5 +++--
 drivers/pci/hotplug/ibmphp_pci.c  |  2 +-
 drivers/pci/pci.c |  2 +-
 drivers/pci/quirks.c  |  6 ++---
 12 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-layerscape.c 
b/drivers/pci/controller/dwc/pci-layerscape.c
index ed5fb492fe08..69a4aa5cfc20 100644
--- a/drivers/pci/controller/dwc/pci-layerscape.c
+++ b/drivers/pci/controller/dwc/pci-layerscape.c
@@ -41,7 +41,7 @@ static bool ls_pcie_is_bridge(struct ls_pcie *pcie)
u32 header_type;
 
header_type = ioread8(pci->dbi_base + PCI_HEADER_TYPE);
-   header_type &= 0x7f;
+   header_type &= PCI_HEADER_TYPE_MASK;
 
return header_type == PCI_HEADER_TYPE_BRIDGE;
 }
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c 
b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index 45b97a4b14db..32951f7d6d6d 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -539,7 +539,7 @@ static bool mobiveil_pcie_is_bridge(struct mobiveil_pcie 
*pcie)
u32 header_type;
 
header_type = mobiveil_csr_readb(pcie, PCI_HEADER_TYPE);
-   header_type &= 0x7f;
+   header_type &= PCI_HEADER_TYPE_MASK;
 
return header_type == PCI_HEADER_TYPE_BRIDGE;
 }
diff --git a/drivers/pci/controller/pcie-iproc.c 
b/drivers/pci/controller/pcie-iproc.c
index bd1c98b68851..97f739a2c9f8 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -783,7 +783,7 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
 
/* make sure we are not in EP mode */
iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, _type);
-   if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
+   if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE) {
dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
return -EFAULT;
}
diff --git a/drivers/pci/controller/pcie-rcar-ep.c 
b/drivers/pci/controller/pcie-rcar-ep.c
index f9682df1da61..7034c0ff23d0 100644
--- a/drivers/pci/controller/pcie-rcar-ep.c
+++ b/drivers/pci/controller/pcie-rcar-ep.c
@@ -43,7 +43,7 @@ static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ENDPOINT << 4);
-   rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
+   rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
   PCI_HEADER_TYPE_NORMAL);
 
/* Write out the physical slot number = 0 */
diff --git a/drivers/pci/controller/pcie-rcar-host.c 
b/drivers/pci/controller/pcie-rcar-host.c
index 88975e40ee2f..bf7cc0b6a695 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -460,7 +460,7 @@ static int rcar_pcie_hw_init(struct rcar_pcie *pcie)
rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
-   rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
+   rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
PCI_HEADER_TYPE_BRIDGE);
 
/* Enable data link layer active state reporting */
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index d5b97a6aae56..cc2422963a34 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -527,7 +527,7 @@ static void vmd_domain_reset(struct vmd_dev *vmd)
 
hdr_type = readb(base + PCI_HEADER_TYPE);
 
-   functions = (hdr_type & 0x80) ? 8 : 1;
+   functions = (hdr_type & PCI_HEADER_TYPE_MFD) ? 8 : 1;
for (fn = 0; fn < functions; fn++) {
base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus,
PCI_DEVFN(dev, fn), 0);
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c 
b/drivers/pci/hotplug/cpqphp_ctrl.c
index e429ecddc8fe..c01968ef0bd7 100644
--

[PATCH 2/3] PCI: Add PCI_HEADER_TYPE_MFD pci_regs.h

2023-10-03 Thread Ilpo Järvinen
Add PCI_HEADER_TYPE_MFD into pci_regs.h to be able to replace
literals in the code.

Signed-off-by: Ilpo Järvinen 
---
 include/uapi/linux/pci_regs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index e5f558d96493..06df65f11c39 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -80,6 +80,7 @@
 #define  PCI_HEADER_TYPE_NORMAL0
 #define  PCI_HEADER_TYPE_BRIDGE1
 #define  PCI_HEADER_TYPE_CARDBUS   2
+#define  PCI_HEADER_TYPE_MFD   0x80/* Multi-Function Device 
(possible) */
 
 #define PCI_BIST   0x0f/* 8 bits */
 #define  PCI_BIST_CODE_MASK0x0f/* Return result */
-- 
2.30.2



[PATCH 1/3] PCI: vmd: Correct PCI Header Type Register's MFD bit check

2023-10-03 Thread Ilpo Järvinen
vmd_domain_reset() attempts to find whether the device may contain
multiple functions by checking 0x80 (Multi-Function Device), however,
the hdr_type variable has already been masked with PCI_HEADER_TYPE_MASK
so the check can never true.

To fix the issue, don't mask the read with PCI_HEADER_TYPE_MASK.

Fixes: 6aab5622296b ("PCI: vmd: Clean up domain before enumeration")
Signed-off-by: Ilpo Järvinen 
Cc: Nirmal Patel 
---
 drivers/pci/controller/vmd.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index e718a816d481..d5b97a6aae56 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -525,8 +525,7 @@ static void vmd_domain_reset(struct vmd_dev *vmd)
base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus,
PCI_DEVFN(dev, 0), 0);
 
-   hdr_type = readb(base + PCI_HEADER_TYPE) &
-PCI_HEADER_TYPE_MASK;
+   hdr_type = readb(base + PCI_HEADER_TYPE);
 
functions = (hdr_type & 0x80) ? 8 : 1;
for (fn = 0; fn < functions; fn++) {
-- 
2.30.2



[PATCH 0/3] PCI: PCI_HEADER_TYPE bugfix & cleanups

2023-10-03 Thread Ilpo Järvinen
One bugfix and cleanups for PCI_HEADER_TYPE_* literals.

This series only covers what's within drivers/pci/. I'd have patches
for other subsystems too but I decided to wait with them until
PCI_HEADER_TYPE_MFD is in Linus' tree (to keep the series receipient
count reasonable, the rest can IMO go through the subsystem specific
trees once the define is there).

Ilpo Järvinen (3):
  PCI: vmd: Correct PCI Header Type Register's MFD bit check
  PCI: Add PCI_HEADER_TYPE_MFD pci_regs.h
  PCI: Use PCI_HEADER_TYPE_* instead of literals

 drivers/pci/controller/dwc/pci-layerscape.c   |  2 +-
 .../controller/mobiveil/pcie-mobiveil-host.c  |  2 +-
 drivers/pci/controller/pcie-iproc.c   |  2 +-
 drivers/pci/controller/pcie-rcar-ep.c |  2 +-
 drivers/pci/controller/pcie-rcar-host.c   |  2 +-
 drivers/pci/controller/vmd.c  |  5 ++---
 drivers/pci/hotplug/cpqphp_ctrl.c |  6 ++---
 drivers/pci/hotplug/cpqphp_pci.c  | 22 +--
 drivers/pci/hotplug/ibmphp.h  |  5 +++--
 drivers/pci/hotplug/ibmphp_pci.c  |  2 +-
 drivers/pci/pci.c |  2 +-
 drivers/pci/quirks.c  |  6 ++---
 include/uapi/linux/pci_regs.h |  1 +
 13 files changed, 30 insertions(+), 29 deletions(-)

-- 
2.30.2



Re: [PATCH tty v1 00/74] serial: wrappers for uart port lock

2023-09-15 Thread Ilpo Järvinen
On Thu, 14 Sep 2023, John Ogness wrote:

> When a serial port is used for kernel console output, then all
> modifications to the UART registers which are done from other contexts,
> e.g. getty, termios, are interference points for the kernel console.
> 
> So far this has been ignored and the printk output is based on the
> principle of hope. The rework of the console infrastructure which aims to
> support threaded and atomic consoles, requires to mark sections which
> modify the UART registers as unsafe. This allows the atomic write function
> to make informed decisions and eventually to restore operational state. It
> also allows to prevent the regular UART code from modifying UART registers
> while printk output is in progress.

Hi John,

Would this also be useful to enable printing to console while under port's 
lock (by postponing the output until the lock is released)?

E.g., 8250_dw.c has had this commented out since the dawn on time:
/*
 * FIXME: this deadlocks if port->lock is already held
 * dev_err(p->dev, "Couldn't set LCR to %d\n", value);
 */

-- 
 i.


> All modifications of UART registers are guarded by the UART port lock,
> which provides an obvious synchronization point with the console
> infrastructure.
> 
> Provide and use wrapper functions for spin_[un]lock*(port->lock)
> invocations so that the console mechanics can be applied later on at a
> single place and does not require to copy the same logic all over the
> drivers.
> 
> Patch 1 adds the wrapper functions.
> 
> Patches 2-74 switch all uart port locking call sites to use the new
> wrappers. These patches were automatically generated using coccinelle.
> The 2 used coccinelle scripts are included below and executed as
> follows:
> 
> $ spatch --sp-file uartlock-1.cocci $FILE
> $ spatch --sp-file uartlock-2.cocci --recursive-includes $FILE
> 
> This series brings no functional change.
> 
> Patches 2-74 contain identical commit message bodies. Feel free to
> fold them into a single commit if that seems more reasonable.
> 
> Thomas Gleixner (74):
>   serial: core: Provide port lock wrappers
>   serial: core: Use lock wrappers
>   serial: 21285: Use port lock wrappers
>   serial: 8250_aspeed_vuart: Use port lock wrappers
>   serial: 8250_bcm7271: Use port lock wrappers
>   serial: 8250: Use port lock wrappers
>   serial: 8250_dma: Use port lock wrappers
>   serial: 8250_dw: Use port lock wrappers
>   serial: 8250_exar: Use port lock wrappers
>   serial: 8250_fsl: Use port lock wrappers
>   serial: 8250_mtk: Use port lock wrappers
>   serial: 8250_omap: Use port lock wrappers
>   serial: 8250_pci1: Use port lock wrappers
>   serial: altera_jtaguart: Use port lock wrappers
>   serial: altera_uart: Use port lock wrappers
>   serial: amba-pl010: Use port lock wrappers
>   serial: amba-pl011: Use port lock wrappers
>   serial: apb: Use port lock wrappers
>   serial: ar933x: Use port lock wrappers
>   serial: arc_uart: Use port lock wrappers
>   serial: atmel: Use port lock wrappers
>   serial: bcm63xx-uart: Use port lock wrappers
>   serial: cpm_uart: Use port lock wrappers
>   serial: digicolor: Use port lock wrappers
>   serial: dz: Use port lock wrappers
>   serial: linflexuart: Use port lock wrappers
>   serial: fsl_lpuart: Use port lock wrappers
>   serial: icom: Use port lock wrappers
>   serial: imx: Use port lock wrappers
>   serial: ip22zilog: Use port lock wrappers
>   serial: jsm: Use port lock wrappers
>   serial: liteuart: Use port lock wrappers
>   serial: lpc32xx_hs: Use port lock wrappers
>   serial: ma35d1: Use port lock wrappers
>   serial: mcf: Use port lock wrappers
>   serial: men_z135_uart: Use port lock wrappers
>   serial: meson: Use port lock wrappers
>   serial: milbeaut_usio: Use port lock wrappers
>   serial: mpc52xx: Use port lock wrappers
>   serial: mps2-uart: Use port lock wrappers
>   serial: msm: Use port lock wrappers
>   serial: mvebu-uart: Use port lock wrappers
>   serial: omap: Use port lock wrappers
>   serial: owl: Use port lock wrappers
>   serial: pch: Use port lock wrappers
>   serial: pic32: Use port lock wrappers
>   serial: pmac_zilog: Use port lock wrappers
>   serial: pxa: Use port lock wrappers
>   serial: qcom-geni: Use port lock wrappers
>   serial: rda: Use port lock wrappers
>   serial: rp2: Use port lock wrappers
>   serial: sa1100: Use port lock wrappers
>   serial: samsung_tty: Use port lock wrappers
>   serial: sb1250-duart: Use port lock wrappers
>   serial: sc16is7xx: Use port lock wrappers
>   serial: tegra: Use port lock wrappers
>   serial: core: Use port lock wrappers
>   serial: mctrl_gpio: Use port lock wrappers
>   serial: txx9: Use port lock wrappers
>   serial: sh-sci: Use port lock wrappers
>   serial: sifive: Use port lock wrappers
>   serial: sprd: Use port lock wrappers
>   serial: st-asc: Use port lock wrappers
>   serial: stm32: Use port lock wrappers
>   serial: sunhv: Use port lock wrappers
>   serial: sunplus-uart: Use port lock 

Re: [PATCH v3 2/2] serial: 8250: Apply FSL workarounds also without SERIAL_8250_CONSOLE

2023-06-05 Thread Ilpo Järvinen
On Mon, 5 Jun 2023, Uwe Kleine-König wrote:

> Hello Ilpo,
> 
> On Mon, Jun 05, 2023 at 04:44:08PM +0300, Ilpo Järvinen wrote:
> > On Mon, 5 Jun 2023, Uwe Kleine-König wrote:
> > > On Mon, Jun 05, 2023 at 04:22:55PM +0300, Ilpo Järvinen wrote:
> > > > On Mon, 5 Jun 2023, Uwe Kleine-König wrote:
> > > > 
> > > > > The need to handle the FSL variant of 8250 in a special way is also
> > > > > present without console support. So soften the dependency for
> > > > > SERIAL_8250_FSL accordingly. Note that with the 8250 driver compiled 
> > > > > as
> > > > > a module, some devices still might not make use of the needed
> > > > > workarounds. That affects the ports instantiated in
> > > > > arch/powerpc/kernel/legacy_serial.c.
> > > > > 
> > > > > This issue was identified by Dominik Andreas Schorpp.
> > > > > 
> > > > > To cope for CONFIG_SERIAL_8250=m + CONFIG_SERIAL_8250_FSL=y, 
> > > > > 8250_fsl.o
> > > > > must be put in the same compilation unit as 8250_port.o because the
> > > > > latter defines some functions needed in the former and so 8250_fsl.o
> > > > > must not be built-in if 8250_port.o is available in a module.
> > > > > 
> > > > > Acked-by: Ilpo Järvinen 
> > > > > Link: 
> > > > > https://lore.kernel.org/r/20230531083230.2702181-1-u.kleine-koe...@pengutronix.de
> > > > > Signed-off-by: Uwe Kleine-König 
> > > > > ---
> > > > >  drivers/tty/serial/8250/Kconfig  | 2 +-
> > > > >  drivers/tty/serial/8250/Makefile | 2 +-
> > > > >  2 files changed, 2 insertions(+), 2 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/tty/serial/8250/Kconfig 
> > > > > b/drivers/tty/serial/8250/Kconfig
> > > > > index 5313aa31930f..10c09b19c871 100644
> > > > > --- a/drivers/tty/serial/8250/Kconfig
> > > > > +++ b/drivers/tty/serial/8250/Kconfig
> > > > > @@ -378,7 +378,7 @@ config SERIAL_8250_BCM2835AUX
> > > > >  
> > > > >  config SERIAL_8250_FSL
> > > > >   bool "Freescale 16550 UART support" if COMPILE_TEST && !(PPC || 
> > > > > ARM || ARM64)
> > > > > - depends on SERIAL_8250_CONSOLE
> > > > > + depends on SERIAL_8250
> > > > 
> > > > Just one additional thought: After the adding the arch side 
> > > > workaround/hack, SERIAL_8250_FSL could become a tristate?
> > > 
> > > I see no benefit for a module separate from 8250_base.ko. There are
> > > dependencies in both directions between 8250_port.o and 8250_fsl.o[1].
> > > So in my book a bool SERIAL_8250_FSL that modifies 8250_base.ko (with
> > > SERIAL_8250=m) is fine.
> > > 
> > > Best regards
> > > Uwe
> > > 
> > > [1] 8250_port.o uses fsl8250_handle_irq() from 8250_fsl.o
> > 
> > Is that after some fix which isn't in tty-next? I see only these:
> > 
> > $ git grep -l fsl8250_handle_irq
> > arch/powerpc/kernel/legacy_serial.c
> > drivers/tty/serial/8250/8250_fsl.c
> > drivers/tty/serial/8250/8250_of.c
> > include/linux/serial_8250.h
> > 
> > No users of fsl8250_handle_irq in 8250_port.c.
> 
> Ah right, I was too quick:
> 
>   8250_of.o uses fsl8250_handle_irq() from 8250_fsl.o
>   8250_fsl.o uses serial8250_modem_status() from 8250_port.o (which is in 
> 8250_base.o)
> 
> 
> However linking 8250_fsl.o in 8250_of.o isn't a good solution either as
> 8250_fsl.o should also be available with CONFIG_SERIAL_OF_PLATFORM
> disabled to provide the ACPI driver. And as 8250_of.o already depends on
> 8250_port.o (e.g. via serial8250_em485_config()) adding 8250_fsl.o
> together with 8250_port.o into 8250_base.ko is fine and doesn't add new
> dependencies.

So we have dependencies one-way only:

8250_port

/\|\
\
8250_fsl \
 /
/\  /

8250_of

There's no loop here, both they be indepedent modules and configured 
independently (with a correct IS_*() in 8250_of.c).

-- 
 i.


Re: [PATCH v3 2/2] serial: 8250: Apply FSL workarounds also without SERIAL_8250_CONSOLE

2023-06-05 Thread Ilpo Järvinen
On Mon, 5 Jun 2023, Uwe Kleine-König wrote:

> On Mon, Jun 05, 2023 at 04:22:55PM +0300, Ilpo Järvinen wrote:
> > On Mon, 5 Jun 2023, Uwe Kleine-König wrote:
> > 
> > > The need to handle the FSL variant of 8250 in a special way is also
> > > present without console support. So soften the dependency for
> > > SERIAL_8250_FSL accordingly. Note that with the 8250 driver compiled as
> > > a module, some devices still might not make use of the needed
> > > workarounds. That affects the ports instantiated in
> > > arch/powerpc/kernel/legacy_serial.c.
> > > 
> > > This issue was identified by Dominik Andreas Schorpp.
> > > 
> > > To cope for CONFIG_SERIAL_8250=m + CONFIG_SERIAL_8250_FSL=y, 8250_fsl.o
> > > must be put in the same compilation unit as 8250_port.o because the
> > > latter defines some functions needed in the former and so 8250_fsl.o
> > > must not be built-in if 8250_port.o is available in a module.
> > > 
> > > Acked-by: Ilpo Järvinen 
> > > Link: 
> > > https://lore.kernel.org/r/20230531083230.2702181-1-u.kleine-koe...@pengutronix.de
> > > Signed-off-by: Uwe Kleine-König 
> > > ---
> > >  drivers/tty/serial/8250/Kconfig  | 2 +-
> > >  drivers/tty/serial/8250/Makefile | 2 +-
> > >  2 files changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/tty/serial/8250/Kconfig 
> > > b/drivers/tty/serial/8250/Kconfig
> > > index 5313aa31930f..10c09b19c871 100644
> > > --- a/drivers/tty/serial/8250/Kconfig
> > > +++ b/drivers/tty/serial/8250/Kconfig
> > > @@ -378,7 +378,7 @@ config SERIAL_8250_BCM2835AUX
> > >  
> > >  config SERIAL_8250_FSL
> > >   bool "Freescale 16550 UART support" if COMPILE_TEST && !(PPC || ARM || 
> > > ARM64)
> > > - depends on SERIAL_8250_CONSOLE
> > > + depends on SERIAL_8250
> > 
> > Just one additional thought: After the adding the arch side 
> > workaround/hack, SERIAL_8250_FSL could become a tristate?
> 
> I see no benefit for a module separate from 8250_base.ko. There are
> dependencies in both directions between 8250_port.o and 8250_fsl.o[1].
> So in my book a bool SERIAL_8250_FSL that modifies 8250_base.ko (with
> SERIAL_8250=m) is fine.
> 
> Best regards
> Uwe
> 
> [1] 8250_port.o uses fsl8250_handle_irq() from 8250_fsl.o

Is that after some fix which isn't in tty-next? I see only these:

$ git grep -l fsl8250_handle_irq
arch/powerpc/kernel/legacy_serial.c
drivers/tty/serial/8250/8250_fsl.c
drivers/tty/serial/8250/8250_of.c
include/linux/serial_8250.h

No users of fsl8250_handle_irq in 8250_port.c.

-- 
 i.

>, and 8250_fsl.o uses serial8250_modem_status from 8250_port.o.


Re: [PATCH v3 2/2] serial: 8250: Apply FSL workarounds also without SERIAL_8250_CONSOLE

2023-06-05 Thread Ilpo Järvinen
On Mon, 5 Jun 2023, Uwe Kleine-König wrote:

> The need to handle the FSL variant of 8250 in a special way is also
> present without console support. So soften the dependency for
> SERIAL_8250_FSL accordingly. Note that with the 8250 driver compiled as
> a module, some devices still might not make use of the needed
> workarounds. That affects the ports instantiated in
> arch/powerpc/kernel/legacy_serial.c.
> 
> This issue was identified by Dominik Andreas Schorpp.
> 
> To cope for CONFIG_SERIAL_8250=m + CONFIG_SERIAL_8250_FSL=y, 8250_fsl.o
> must be put in the same compilation unit as 8250_port.o because the
> latter defines some functions needed in the former and so 8250_fsl.o
> must not be built-in if 8250_port.o is available in a module.
> 
> Acked-by: Ilpo Järvinen 
> Link: 
> https://lore.kernel.org/r/20230531083230.2702181-1-u.kleine-koe...@pengutronix.de
> Signed-off-by: Uwe Kleine-König 
> ---
>  drivers/tty/serial/8250/Kconfig  | 2 +-
>  drivers/tty/serial/8250/Makefile | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index 5313aa31930f..10c09b19c871 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -378,7 +378,7 @@ config SERIAL_8250_BCM2835AUX
>  
>  config SERIAL_8250_FSL
>   bool "Freescale 16550 UART support" if COMPILE_TEST && !(PPC || ARM || 
> ARM64)
> - depends on SERIAL_8250_CONSOLE
> + depends on SERIAL_8250

Just one additional thought: After the adding the arch side 
workaround/hack, SERIAL_8250_FSL could become a tristate?

(1/2 might need a small change to take into account that it can now be a 
module).

>   default PPC || ARM || ARM64
>   help
> Selecting this option enables a workaround for a break-detection
> diff --git a/drivers/tty/serial/8250/Makefile 
> b/drivers/tty/serial/8250/Makefile
> index 4fc2fc1f41b6..8824ba5295b6 100644
> --- a/drivers/tty/serial/8250/Makefile
> +++ b/drivers/tty/serial/8250/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_SERIAL_8250)   += 8250.o 8250_base.o
>  8250_base-$(CONFIG_SERIAL_8250_DMA)  += 8250_dma.o
>  8250_base-$(CONFIG_SERIAL_8250_DWLIB)+= 8250_dwlib.o
>  8250_base-$(CONFIG_SERIAL_8250_FINTEK)   += 8250_fintek.o
> +8250_base-$(CONFIG_SERIAL_8250_FSL)  += 8250_fsl.o
>  8250_base-$(CONFIG_SERIAL_8250_PCILIB)   += 8250_pcilib.o
>  obj-$(CONFIG_SERIAL_8250_PARISC) += 8250_parisc.o
>  obj-$(CONFIG_SERIAL_8250_PCI)+= 8250_pci.o
> @@ -28,7 +29,6 @@ obj-$(CONFIG_SERIAL_8250_BOCA)  += 8250_boca.o
>  obj-$(CONFIG_SERIAL_8250_EXAR_ST16C554)  += 8250_exar_st16c554.o
>  obj-$(CONFIG_SERIAL_8250_HUB6)   += 8250_hub6.o
>  obj-$(CONFIG_SERIAL_8250_PCI1)   += 8250_pci1.o
> -obj-$(CONFIG_SERIAL_8250_FSL)+= 8250_fsl.o
>  obj-$(CONFIG_SERIAL_8250_MEN_MCB)+= 8250_men_mcb.o
>  obj-$(CONFIG_SERIAL_8250_DFL)+= 8250_dfl.o
>  obj-$(CONFIG_SERIAL_8250_DW) += 8250_dw.o

-- 
 i.


[PATCH 1/2] serial: ucc_uart: Use uart_circ_empty()

2023-03-20 Thread Ilpo Järvinen
Use uart_circ_empty() rather than open coding it.

Signed-off-by: Ilpo Järvinen 
---
 drivers/tty/serial/ucc_uart.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 32c7a5b43f8e..e6bd1256a4e7 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -366,15 +366,14 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
/* Pick next descriptor and fill from buffer */
bdp = qe_port->tx_cur;
 
-   while (!(ioread16be(>status) & BD_SC_READY) &&
-  (xmit->tail != xmit->head)) {
+   while (!(ioread16be(>status) & BD_SC_READY) && 
!uart_circ_empty(xmit)) {
count = 0;
p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
while (count < qe_port->tx_fifosize) {
*p++ = xmit->buf[xmit->tail];
uart_xmit_advance(port, 1);
count++;
-   if (xmit->head == xmit->tail)
+   if (uart_circ_empty(xmit))
break;
}
 
-- 
2.30.2



[PATCH v4 11/12] tty: Call ->dtr_rts() parameter active consistently

2023-01-17 Thread Ilpo Järvinen
Convert various parameter names for ->dtr_rts() and related functions
from onoff, on, and raise to active.

Reviewed-by: Jiri Slaby 
Acked-by: Ulf Hansson  # For MMC
Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c | 6 +++---
 drivers/mmc/core/sdio_uart.c  | 6 +++---
 drivers/staging/greybus/uart.c| 4 ++--
 drivers/tty/amiserial.c   | 4 ++--
 drivers/tty/hvc/hvc_console.h | 2 +-
 drivers/tty/hvc/hvc_iucv.c| 6 +++---
 drivers/tty/mxser.c   | 4 ++--
 drivers/tty/n_gsm.c   | 4 ++--
 drivers/tty/serial/serial_core.c  | 8 
 drivers/tty/synclink_gt.c | 4 ++--
 drivers/usb/class/cdc-acm.c   | 4 ++--
 include/linux/tty_port.h  | 4 ++--
 12 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 46a0b586d234..1577eba6fe0e 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, bool onoff);
+static void dtr_rts(struct tty_port *port, bool active);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,13 +2442,13 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, bool onoff)
+static void dtr_rts(struct tty_port *port, bool active)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
 
spin_lock_irqsave(>lock, flags);
-   if (onoff)
+   if (active)
info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
else
info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index c6b4b2b2a4b2..50536fe59f1a 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -542,20 +542,20 @@ static bool uart_carrier_raised(struct tty_port *tport)
 /**
  * uart_dtr_rts-port helper to set uart signals
  * @tport: tty port to be updated
- * @onoff: set to turn on DTR/RTS
+ * @active: set to turn on DTR/RTS
  *
  * Called by the tty port helpers when the modem signals need to be
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, bool onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool active)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (!onoff)
+   if (!active)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 92d49740d5a4..20a34599859f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, bool on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool active)
 {
struct gb_tty *gb_tty;
u8 newctrl;
@@ -709,7 +709,7 @@ static void gb_tty_dtr_rts(struct tty_port *port, bool on)
gb_tty = container_of(port, struct gb_tty, port);
newctrl = gb_tty->ctrlout;
 
-   if (on)
+   if (active)
newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
else
newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 29d4c554f6b8..d7515d61659e 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,13 +1459,13 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, bool raise)
+static void amiga_dtr_rts(struct tty_port *port, bool active)
 {
struct serial_state *info = container_of(port, struct serial_state,
tport);
unsigned long flags;
 
-   if (raise)
+   if (active)
info->MCR |= SER_DTR|SER_RTS;
else
info->MCR &= ~(SER_DTR|SER_RTS);
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index 6d3428bf868f..9668f821db01 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -66,7 +66,7 @@ struct hv_ops {
int (*tiocmset)(struct hvc_struct *hp, unsigned int set, unsigned int 
clear);
 
/* Callbacks to handle tty por

[PATCH v4 07/12] tty: Convert ->dtr_rts() to take bool argument

2023-01-17 Thread Ilpo Järvinen
Convert the raise/on parameter in ->dtr_rts() to bool through the
callchain. The parameter is used like bool. In USB serial, there
remains a few implicit bool -> larger type conversions because some
devices use u8 in their control messages.

In moxa_tiocmget(), dtr variable was reused for line status which
requires int so use a separate variable for status.

Reviewed-by: Jiri Slaby 
Acked-by: Ulf Hansson  # For MMC
Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c |  4 +--
 drivers/mmc/core/sdio_uart.c  |  4 +--
 drivers/staging/greybus/uart.c|  2 +-
 drivers/tty/amiserial.c   |  2 +-
 drivers/tty/hvc/hvc_console.c |  4 +--
 drivers/tty/hvc/hvc_console.h |  2 +-
 drivers/tty/hvc/hvc_iucv.c|  4 +--
 drivers/tty/moxa.c| 54 ---
 drivers/tty/mxser.c   |  2 +-
 drivers/tty/n_gsm.c   |  2 +-
 drivers/tty/serial/serial_core.c  |  8 ++---
 drivers/tty/synclink_gt.c |  2 +-
 drivers/tty/tty_port.c|  4 +--
 drivers/usb/class/cdc-acm.c   |  2 +-
 drivers/usb/serial/usb-serial.c   |  2 +-
 include/linux/tty_port.h  |  4 +--
 16 files changed, 52 insertions(+), 50 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 4391138e1b8a..46a0b586d234 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, int onoff);
+static void dtr_rts(struct tty_port *port, bool onoff);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,7 +2442,7 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, int onoff)
+static void dtr_rts(struct tty_port *port, bool onoff)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 47f58258d8ff..c6b4b2b2a4b2 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -548,14 +548,14 @@ static bool uart_carrier_raised(struct tty_port *tport)
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, int onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool onoff)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (onoff == 0)
+   if (!onoff)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 90ff07f2cbf7..92d49740d5a4 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, int on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool on)
 {
struct gb_tty *gb_tty;
u8 newctrl;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 01c4fd3ce7c8..29d4c554f6b8 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,7 +1459,7 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, int raise)
+static void amiga_dtr_rts(struct tty_port *port, bool raise)
 {
struct serial_state *info = container_of(port, struct serial_state,
tport);
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index a683e21df19c..10c10cfdf92a 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -376,7 +376,7 @@ static int hvc_open(struct tty_struct *tty, struct file * 
filp)
/* We are ready... raise DTR/RTS */
if (C_BAUD(tty))
if (hp->ops->dtr_rts)
-   hp->ops->dtr_rts(hp, 1);
+   hp->ops->dtr_rts(hp, true);
tty_port_set_initialized(>port, true);
}
 
@@ -406,7 +406,7 @@ static void hvc_close(struct tty_struct *tty, struct file * 
filp)
 
if (C_HUPCL(tty))
if (hp->ops->dtr_rts)
-   hp->ops->dtr_rts(hp, 0);
+   hp->ops->dtr_rts(hp, false);
 
if (hp->ops->notifier_del)
hp->ops->n

[PATCH v3 11/13] tty/serial: Call ->dtr_rts() parameter active consistently

2023-01-11 Thread Ilpo Järvinen
Convert various parameter names for ->dtr_rts() and related functions
from onoff, on, and raise to active.

Reviewed-by: Jiri Slaby 
Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c | 6 +++---
 drivers/mmc/core/sdio_uart.c  | 6 +++---
 drivers/staging/greybus/uart.c| 4 ++--
 drivers/tty/amiserial.c   | 4 ++--
 drivers/tty/hvc/hvc_console.h | 2 +-
 drivers/tty/hvc/hvc_iucv.c| 6 +++---
 drivers/tty/mxser.c   | 4 ++--
 drivers/tty/n_gsm.c   | 4 ++--
 drivers/tty/serial/serial_core.c  | 8 
 drivers/tty/synclink_gt.c | 4 ++--
 include/linux/tty_port.h  | 4 ++--
 include/linux/usb/serial.h| 2 +-
 12 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 46a0b586d234..1577eba6fe0e 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, bool onoff);
+static void dtr_rts(struct tty_port *port, bool active);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,13 +2442,13 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, bool onoff)
+static void dtr_rts(struct tty_port *port, bool active)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
 
spin_lock_irqsave(>lock, flags);
-   if (onoff)
+   if (active)
info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
else
info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index c6b4b2b2a4b2..50536fe59f1a 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -542,20 +542,20 @@ static bool uart_carrier_raised(struct tty_port *tport)
 /**
  * uart_dtr_rts-port helper to set uart signals
  * @tport: tty port to be updated
- * @onoff: set to turn on DTR/RTS
+ * @active: set to turn on DTR/RTS
  *
  * Called by the tty port helpers when the modem signals need to be
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, bool onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool active)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (!onoff)
+   if (!active)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 92d49740d5a4..20a34599859f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, bool on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool active)
 {
struct gb_tty *gb_tty;
u8 newctrl;
@@ -709,7 +709,7 @@ static void gb_tty_dtr_rts(struct tty_port *port, bool on)
gb_tty = container_of(port, struct gb_tty, port);
newctrl = gb_tty->ctrlout;
 
-   if (on)
+   if (active)
newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
else
newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 29d4c554f6b8..d7515d61659e 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,13 +1459,13 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, bool raise)
+static void amiga_dtr_rts(struct tty_port *port, bool active)
 {
struct serial_state *info = container_of(port, struct serial_state,
tport);
unsigned long flags;
 
-   if (raise)
+   if (active)
info->MCR |= SER_DTR|SER_RTS;
else
info->MCR &= ~(SER_DTR|SER_RTS);
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index 6d3428bf868f..9668f821db01 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -66,7 +66,7 @@ struct hv_ops {
int (*tiocmset)(struct hvc_struct *hp, unsigned int set, unsigned int 
clear);
 
/* Callbacks to handle tty ports */
-   void (*dtr_rts)(s

[PATCH v3 07/13] tty: Convert ->dtr_rts() to take bool argument

2023-01-11 Thread Ilpo Järvinen
Convert the raise/on parameter in ->dtr_rts() to bool through the
callchain. The parameter is used like bool. In USB serial, there
remains a few implicit bool -> larger type conversions because some
devices use u8 in their control messages.

In moxa_tiocmget(), dtr variable was reused for line status which
requires int so use a separate variable for status.

Reviewed-by: Jiri Slaby 
Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c|  4 +--
 drivers/mmc/core/sdio_uart.c |  4 +--
 drivers/staging/greybus/uart.c   |  2 +-
 drivers/tty/amiserial.c  |  2 +-
 drivers/tty/hvc/hvc_console.c|  4 +--
 drivers/tty/hvc/hvc_console.h|  2 +-
 drivers/tty/hvc/hvc_iucv.c   |  4 +--
 drivers/tty/moxa.c   | 54 ++--
 drivers/tty/mxser.c  |  2 +-
 drivers/tty/n_gsm.c  |  2 +-
 drivers/tty/serial/serial_core.c |  8 ++---
 drivers/tty/synclink_gt.c|  2 +-
 drivers/tty/tty_port.c   |  4 +--
 drivers/usb/class/cdc-acm.c  |  2 +-
 drivers/usb/serial/ch341.c   |  2 +-
 drivers/usb/serial/cp210x.c  |  4 +--
 drivers/usb/serial/cypress_m8.c  |  6 ++--
 drivers/usb/serial/digi_acceleport.c |  6 ++--
 drivers/usb/serial/f81232.c  |  2 +-
 drivers/usb/serial/f81534.c  |  2 +-
 drivers/usb/serial/ftdi_sio.c|  2 +-
 drivers/usb/serial/ipw.c |  2 +-
 drivers/usb/serial/keyspan.c |  2 +-
 drivers/usb/serial/keyspan_pda.c |  2 +-
 drivers/usb/serial/mct_u232.c|  4 +--
 drivers/usb/serial/mxuport.c |  2 +-
 drivers/usb/serial/pl2303.c  |  2 +-
 drivers/usb/serial/quatech2.c|  2 +-
 drivers/usb/serial/sierra.c  |  2 +-
 drivers/usb/serial/spcp8x5.c |  2 +-
 drivers/usb/serial/ssu100.c  |  2 +-
 drivers/usb/serial/upd78f0730.c  |  6 ++--
 drivers/usb/serial/usb-serial.c  |  2 +-
 drivers/usb/serial/usb-wwan.h|  2 +-
 drivers/usb/serial/usb_wwan.c|  2 +-
 drivers/usb/serial/xr_serial.c   |  6 ++--
 include/linux/tty_port.h |  4 +--
 include/linux/usb/serial.h   |  2 +-
 38 files changed, 84 insertions(+), 82 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 4391138e1b8a..46a0b586d234 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, int onoff);
+static void dtr_rts(struct tty_port *port, bool onoff);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,7 +2442,7 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, int onoff)
+static void dtr_rts(struct tty_port *port, bool onoff)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 47f58258d8ff..c6b4b2b2a4b2 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -548,14 +548,14 @@ static bool uart_carrier_raised(struct tty_port *tport)
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, int onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool onoff)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (onoff == 0)
+   if (!onoff)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 90ff07f2cbf7..92d49740d5a4 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, int on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool on)
 {
struct gb_tty *gb_tty;
u8 newctrl;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 01c4fd3ce7c8..29d4c554f6b8 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,7 +1459,7 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, int raise)
+static void amiga_dtr_rts(struct tty_port *port, bool raise)
 {
struct serial_state *info = container_of(port,

[PATCH v2 11/13] tty/serial: Call ->dtr_rts() parameter active consistently

2023-01-10 Thread Ilpo Järvinen
Convert various parameter names for ->dtr_rts() and related functions
from onoff, on, and raise to active.

Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c | 6 +++---
 drivers/mmc/core/sdio_uart.c  | 6 +++---
 drivers/staging/greybus/uart.c| 4 ++--
 drivers/tty/amiserial.c   | 4 ++--
 drivers/tty/hvc/hvc_console.h | 2 +-
 drivers/tty/hvc/hvc_iucv.c| 6 +++---
 drivers/tty/mxser.c   | 4 ++--
 drivers/tty/n_gsm.c   | 4 ++--
 drivers/tty/serial/serial_core.c  | 8 
 drivers/tty/synclink_gt.c | 4 ++--
 include/linux/tty_port.h  | 4 ++--
 include/linux/usb/serial.h| 2 +-
 12 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 46a0b586d234..1577eba6fe0e 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, bool onoff);
+static void dtr_rts(struct tty_port *port, bool active);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,13 +2442,13 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, bool onoff)
+static void dtr_rts(struct tty_port *port, bool active)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
 
spin_lock_irqsave(>lock, flags);
-   if (onoff)
+   if (active)
info->serial_signals |= SerialSignal_RTS | SerialSignal_DTR;
else
info->serial_signals &= ~(SerialSignal_RTS | SerialSignal_DTR);
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index c6b4b2b2a4b2..50536fe59f1a 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -542,20 +542,20 @@ static bool uart_carrier_raised(struct tty_port *tport)
 /**
  * uart_dtr_rts-port helper to set uart signals
  * @tport: tty port to be updated
- * @onoff: set to turn on DTR/RTS
+ * @active: set to turn on DTR/RTS
  *
  * Called by the tty port helpers when the modem signals need to be
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, bool onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool active)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (!onoff)
+   if (!active)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 92d49740d5a4..20a34599859f 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, bool on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool active)
 {
struct gb_tty *gb_tty;
u8 newctrl;
@@ -709,7 +709,7 @@ static void gb_tty_dtr_rts(struct tty_port *port, bool on)
gb_tty = container_of(port, struct gb_tty, port);
newctrl = gb_tty->ctrlout;
 
-   if (on)
+   if (active)
newctrl |= (GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
else
newctrl &= ~(GB_UART_CTRL_DTR | GB_UART_CTRL_RTS);
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 29d4c554f6b8..d7515d61659e 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,13 +1459,13 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, bool raise)
+static void amiga_dtr_rts(struct tty_port *port, bool active)
 {
struct serial_state *info = container_of(port, struct serial_state,
tport);
unsigned long flags;
 
-   if (raise)
+   if (active)
info->MCR |= SER_DTR|SER_RTS;
else
info->MCR &= ~(SER_DTR|SER_RTS);
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index 6d3428bf868f..9668f821db01 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -66,7 +66,7 @@ struct hv_ops {
int (*tiocmset)(struct hvc_struct *hp, unsigned int set, unsigned int 
clear);
 
/* Callbacks to handle tty ports */
-   void (*dtr_rts)(struct hvc_struct *hp, bool ra

[PATCH v2 07/13] tty: Convert ->dtr_rts() to take bool argument

2023-01-10 Thread Ilpo Järvinen
Convert the raise/on parameter in ->dtr_rts() to bool through the
callchain. The parameter is used like bool. In USB serial, there
remains a few implicit bool -> larger type conversions because some
devices use u8 in their control messages.

In moxa_tiocmget(), dtr variable was reused for line status which
requires int so use a separate variable for status.

Reviewed-by: Jiri Slaby 
Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c|  4 +--
 drivers/mmc/core/sdio_uart.c |  4 +--
 drivers/staging/greybus/uart.c   |  2 +-
 drivers/tty/amiserial.c  |  2 +-
 drivers/tty/hvc/hvc_console.c|  4 +--
 drivers/tty/hvc/hvc_console.h|  2 +-
 drivers/tty/hvc/hvc_iucv.c   |  4 +--
 drivers/tty/moxa.c   | 52 +++-
 drivers/tty/mxser.c  |  2 +-
 drivers/tty/n_gsm.c  |  2 +-
 drivers/tty/serial/serial_core.c |  8 ++---
 drivers/tty/synclink_gt.c|  2 +-
 drivers/tty/tty_port.c   |  4 +--
 drivers/usb/class/cdc-acm.c  |  2 +-
 drivers/usb/serial/ch341.c   |  2 +-
 drivers/usb/serial/cp210x.c  |  4 +--
 drivers/usb/serial/cypress_m8.c  |  6 ++--
 drivers/usb/serial/digi_acceleport.c |  6 ++--
 drivers/usb/serial/f81232.c  |  2 +-
 drivers/usb/serial/f81534.c  |  2 +-
 drivers/usb/serial/ftdi_sio.c|  2 +-
 drivers/usb/serial/ipw.c |  2 +-
 drivers/usb/serial/keyspan.c |  2 +-
 drivers/usb/serial/keyspan_pda.c |  2 +-
 drivers/usb/serial/mct_u232.c|  4 +--
 drivers/usb/serial/mxuport.c |  2 +-
 drivers/usb/serial/pl2303.c  |  2 +-
 drivers/usb/serial/quatech2.c|  2 +-
 drivers/usb/serial/sierra.c  |  2 +-
 drivers/usb/serial/spcp8x5.c |  2 +-
 drivers/usb/serial/ssu100.c  |  2 +-
 drivers/usb/serial/upd78f0730.c  |  6 ++--
 drivers/usb/serial/usb-serial.c  |  2 +-
 drivers/usb/serial/usb-wwan.h|  2 +-
 drivers/usb/serial/usb_wwan.c|  2 +-
 drivers/usb/serial/xr_serial.c   |  6 ++--
 include/linux/tty_port.h |  4 +--
 include/linux/usb/serial.h   |  2 +-
 38 files changed, 83 insertions(+), 81 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 4391138e1b8a..46a0b586d234 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, int onoff);
+static void dtr_rts(struct tty_port *port, bool onoff);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,7 +2442,7 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, int onoff)
+static void dtr_rts(struct tty_port *port, bool onoff)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 47f58258d8ff..c6b4b2b2a4b2 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -548,14 +548,14 @@ static bool uart_carrier_raised(struct tty_port *tport)
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, int onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool onoff)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (onoff == 0)
+   if (!onoff)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 90ff07f2cbf7..92d49740d5a4 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, int on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool on)
 {
struct gb_tty *gb_tty;
u8 newctrl;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 01c4fd3ce7c8..29d4c554f6b8 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,7 +1459,7 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, int raise)
+static void amiga_dtr_rts(struct tty_port *port, bool raise)
 {
struct serial_state *info = container_of(port,

Re: [PATCH 07/10] tty: Convert ->dtr_rts() to take bool argument

2023-01-05 Thread Ilpo Järvinen
On Thu, 5 Jan 2023, Jiri Slaby wrote:

> On 04. 01. 23, 16:15, Ilpo Järvinen wrote:
> > Convert the raise/on parameter in ->dtr_rts() to bool through the
> > callchain. The parameter is used like bool. In USB serial, there
> > remains a few implicit bool -> larger type conversions because some
> > devices use u8 in their control messages.
> 
> Reviewed-by: Jiri Slaby 
> 
> > Signed-off-by: Ilpo Järvinen 
> > ---
> ...
> > --- a/drivers/char/pcmcia/synclink_cs.c
> > +++ b/drivers/char/pcmcia/synclink_cs.c
> > @@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
> >   static void tx_timeout(struct timer_list *t);
> > static bool carrier_raised(struct tty_port *port);
> > -static void dtr_rts(struct tty_port *port, int onoff);
> > +static void dtr_rts(struct tty_port *port, bool onoff);
> 
> Not anything for this patch, but having this dubbed "onoff" instead of "on"
> makes it really confusing.
> 
> > --- a/drivers/mmc/core/sdio_uart.c
> > +++ b/drivers/mmc/core/sdio_uart.c
> > @@ -548,14 +548,14 @@ static bool uart_carrier_raised(struct tty_port
> > *tport)
> >*adjusted during an open, close and hangup.
> >*/
> >   -static void uart_dtr_rts(struct tty_port *tport, int onoff)
> > +static void uart_dtr_rts(struct tty_port *tport, bool onoff)
> >   {
> > struct sdio_uart_port *port =
> > container_of(tport, struct sdio_uart_port, port);
> > int ret = sdio_uart_claim_func(port);
> > if (ret)
> > return;
> > -   if (onoff == 0)
> > +   if (!onoff)
> > sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
> > else
> > sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
> 
> Especially here. What does "!onoff" mean? If it were:
> 
> if (on)
>   sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
> else
>   sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
> 
> it would be a lot more clear.
> 
> > --- a/drivers/tty/amiserial.c
> > +++ b/drivers/tty/amiserial.c
> > @@ -1459,7 +1459,7 @@ static bool amiga_carrier_raised(struct tty_port
> > *port)
> > return !(ciab.pra & SER_DCD);
> >   }
> >   -static void amiga_dtr_rts(struct tty_port *port, int raise)
> > +static void amiga_dtr_rts(struct tty_port *port, bool raise)
> 
> Or "raise". That makes sense too and we call it as such in
> tty_port_operations:
> 
> > --- a/include/linux/tty_port.h
> > +++ b/include/linux/tty_port.h
> ...
> > @@ -32,7 +32,7 @@ struct tty_struct;
> >*/
> >   struct tty_port_operations {
> > bool (*carrier_raised)(struct tty_port *port);
> > -   void (*dtr_rts)(struct tty_port *port, int raise);
> > +   void (*dtr_rts)(struct tty_port *port, bool raise);
> > void (*shutdown)(struct tty_port *port);
> > int (*activate)(struct tty_port *port, struct tty_struct *tty);
> > void (*destruct)(struct tty_port *port);
> 
> Care to fix that up too?

Sure. I noticed they were inconsistent but it didn't feel like changing 
the name "while at it" would be good as this is long already. I think I'll 
make another patch out of the name changes.

-- 
 i.

[PATCH 07/10] tty: Convert ->dtr_rts() to take bool argument

2023-01-04 Thread Ilpo Järvinen
Convert the raise/on parameter in ->dtr_rts() to bool through the
callchain. The parameter is used like bool. In USB serial, there
remains a few implicit bool -> larger type conversions because some
devices use u8 in their control messages.

Signed-off-by: Ilpo Järvinen 
---
 drivers/char/pcmcia/synclink_cs.c|  4 ++--
 drivers/mmc/core/sdio_uart.c |  4 ++--
 drivers/staging/greybus/uart.c   |  2 +-
 drivers/tty/amiserial.c  |  2 +-
 drivers/tty/hvc/hvc_console.c|  4 ++--
 drivers/tty/hvc/hvc_console.h|  2 +-
 drivers/tty/hvc/hvc_iucv.c   |  4 ++--
 drivers/tty/moxa.c   | 16 
 drivers/tty/mxser.c  |  2 +-
 drivers/tty/n_gsm.c  |  2 +-
 drivers/tty/serial/serial_core.c |  8 
 drivers/tty/synclink_gt.c|  2 +-
 drivers/tty/tty_port.c   |  4 ++--
 drivers/usb/class/cdc-acm.c  |  2 +-
 drivers/usb/serial/ch341.c   |  2 +-
 drivers/usb/serial/cp210x.c  |  4 ++--
 drivers/usb/serial/cypress_m8.c  |  6 +++---
 drivers/usb/serial/digi_acceleport.c |  6 +++---
 drivers/usb/serial/f81232.c  |  2 +-
 drivers/usb/serial/f81534.c  |  2 +-
 drivers/usb/serial/ftdi_sio.c|  2 +-
 drivers/usb/serial/ipw.c |  2 +-
 drivers/usb/serial/keyspan.c |  2 +-
 drivers/usb/serial/keyspan_pda.c |  2 +-
 drivers/usb/serial/mct_u232.c|  4 ++--
 drivers/usb/serial/mxuport.c |  2 +-
 drivers/usb/serial/pl2303.c  |  2 +-
 drivers/usb/serial/quatech2.c|  2 +-
 drivers/usb/serial/sierra.c  |  2 +-
 drivers/usb/serial/spcp8x5.c |  2 +-
 drivers/usb/serial/ssu100.c  |  2 +-
 drivers/usb/serial/upd78f0730.c  |  6 +++---
 drivers/usb/serial/usb-serial.c  |  2 +-
 drivers/usb/serial/usb-wwan.h|  2 +-
 drivers/usb/serial/usb_wwan.c|  2 +-
 drivers/usb/serial/xr_serial.c   |  6 +++---
 include/linux/tty_port.h |  4 ++--
 include/linux/usb/serial.h   |  2 +-
 38 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/drivers/char/pcmcia/synclink_cs.c 
b/drivers/char/pcmcia/synclink_cs.c
index 4391138e1b8a..46a0b586d234 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -378,7 +378,7 @@ static void async_mode(MGSLPC_INFO *info);
 static void tx_timeout(struct timer_list *t);
 
 static bool carrier_raised(struct tty_port *port);
-static void dtr_rts(struct tty_port *port, int onoff);
+static void dtr_rts(struct tty_port *port, bool onoff);
 
 #if SYNCLINK_GENERIC_HDLC
 #define dev_to_port(D) (dev_to_hdlc(D)->priv)
@@ -2442,7 +2442,7 @@ static bool carrier_raised(struct tty_port *port)
return info->serial_signals & SerialSignal_DCD;
 }
 
-static void dtr_rts(struct tty_port *port, int onoff)
+static void dtr_rts(struct tty_port *port, bool onoff)
 {
MGSLPC_INFO *info = container_of(port, MGSLPC_INFO, port);
unsigned long flags;
diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c
index 47f58258d8ff..c6b4b2b2a4b2 100644
--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -548,14 +548,14 @@ static bool uart_carrier_raised(struct tty_port *tport)
  * adjusted during an open, close and hangup.
  */
 
-static void uart_dtr_rts(struct tty_port *tport, int onoff)
+static void uart_dtr_rts(struct tty_port *tport, bool onoff)
 {
struct sdio_uart_port *port =
container_of(tport, struct sdio_uart_port, port);
int ret = sdio_uart_claim_func(port);
if (ret)
return;
-   if (onoff == 0)
+   if (!onoff)
sdio_uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
else
sdio_uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 90ff07f2cbf7..92d49740d5a4 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -701,7 +701,7 @@ static int gb_tty_ioctl(struct tty_struct *tty, unsigned 
int cmd,
return -ENOIOCTLCMD;
 }
 
-static void gb_tty_dtr_rts(struct tty_port *port, int on)
+static void gb_tty_dtr_rts(struct tty_port *port, bool on)
 {
struct gb_tty *gb_tty;
u8 newctrl;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 01c4fd3ce7c8..29d4c554f6b8 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -1459,7 +1459,7 @@ static bool amiga_carrier_raised(struct tty_port *port)
return !(ciab.pra & SER_DCD);
 }
 
-static void amiga_dtr_rts(struct tty_port *port, int raise)
+static void amiga_dtr_rts(struct tty_port *port, bool raise)
 {
struct serial_state *info = container_of(port, struct serial_state,
tport);
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index a683e21df19c..10c10cfdf92a 

[PATCH 42/44] serial: ucc_uart: Use uart_xmit_advance()

2022-10-19 Thread Ilpo Järvinen
Take advantage of the new uart_xmit_advance() helper.

Signed-off-by: Ilpo Järvinen 
---
 drivers/tty/serial/ucc_uart.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 82cf14dd3d43..b09b6496ee3e 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -372,8 +372,7 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
while (count < qe_port->tx_fifosize) {
*p++ = xmit->buf[xmit->tail];
-   xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-   port->icount.tx++;
+   uart_xmit_advance(port, 1);
count++;
if (xmit->head == xmit->tail)
break;
-- 
2.30.2



[PATCH 26/44] serial: pmac_zilog: Use uart_xmit_advance()

2022-10-19 Thread Ilpo Järvinen
Take advantage of the new uart_xmit_advance() helper.

Signed-off-by: Ilpo Järvinen 
---
 drivers/tty/serial/pmac_zilog.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index fe2e4ec423f7..13668ffdb1e7 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -410,8 +410,7 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
write_zsdata(uap, xmit->buf[xmit->tail]);
zssync(uap);
 
-   xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-   uap->port.icount.tx++;
+   uart_xmit_advance(>port, 1);
 
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(>port);
@@ -627,8 +626,7 @@ static void pmz_start_tx(struct uart_port *port)
return;
write_zsdata(uap, xmit->buf[xmit->tail]);
zssync(uap);
-   xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-   port->icount.tx++;
+   uart_xmit_advance(port, 1);
 
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(>port);
-- 
2.30.2



[PATCH v2 1/5] serial: ucc_uart: Remove custom frame size calculation

2022-08-30 Thread Ilpo Järvinen
The number of bits can be calculated using tty_get_frame_size(), no
need for the driver to do it on its own.

Also remove a comment on number of bits that doesn't match the code nor
the comment on ucc_uart_pram's rx_length ("minus 1" part differs). That
comment seems a verbatim copy of that in cpm_uart/cpm_uart_core.c
anyway so perhaps it was just copied over w/o much thinking.

Reviewed-by: Andy Shevchenko 
Signed-off-by: Ilpo Järvinen 
---
 drivers/tty/serial/ucc_uart.c | 15 +--
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 3cc9ef08455c..7331964163c5 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -853,13 +853,6 @@ static void qe_uart_set_termios(struct uart_port *port,
u16 upsmr = ioread16be(>upsmr);
struct ucc_uart_pram __iomem *uccup = qe_port->uccup;
u16 supsmr = ioread16be(>supsmr);
-   u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */
-
-   /* Character length programmed into the mode register is the
-* sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
-* 1 or 2 stop bits, minus 1.
-* The value 'bits' counts this for us.
-*/
 
/* byte size */
upsmr &= UCC_UART_UPSMR_CL_MASK;
@@ -869,22 +862,18 @@ static void qe_uart_set_termios(struct uart_port *port,
case CS5:
upsmr |= UCC_UART_UPSMR_CL_5;
supsmr |= UCC_UART_SUPSMR_CL_5;
-   char_length += 5;
break;
case CS6:
upsmr |= UCC_UART_UPSMR_CL_6;
supsmr |= UCC_UART_SUPSMR_CL_6;
-   char_length += 6;
break;
case CS7:
upsmr |= UCC_UART_UPSMR_CL_7;
supsmr |= UCC_UART_SUPSMR_CL_7;
-   char_length += 7;
break;
default:/* case CS8 */
upsmr |= UCC_UART_UPSMR_CL_8;
supsmr |= UCC_UART_SUPSMR_CL_8;
-   char_length += 8;
break;
}
 
@@ -892,13 +881,11 @@ static void qe_uart_set_termios(struct uart_port *port,
if (termios->c_cflag & CSTOPB) {
upsmr |= UCC_UART_UPSMR_SL;
supsmr |= UCC_UART_SUPSMR_SL;
-   char_length++;  /* + SL */
}
 
if (termios->c_cflag & PARENB) {
upsmr |= UCC_UART_UPSMR_PEN;
supsmr |= UCC_UART_SUPSMR_PEN;
-   char_length++;  /* + PEN */
 
if (!(termios->c_cflag & PARODD)) {
upsmr &= ~(UCC_UART_UPSMR_RPM_MASK |
@@ -953,7 +940,7 @@ static void qe_uart_set_termios(struct uart_port *port,
iowrite16be(upsmr, >upsmr);
if (soft_uart) {
iowrite16be(supsmr, >supsmr);
-   iowrite8(char_length, >rx_length);
+   iowrite8(tty_get_frame_size(termios->c_cflag), 
>rx_length);
 
/* Soft-UART requires a 1X multiplier for TX */
qe_setbrg(qe_port->us_info.rx_clock, baud, 16);
-- 
2.30.2



[PATCH 1/5] serial: ucc_uart: Remove custom frame size calculation

2022-08-25 Thread Ilpo Järvinen
The number of bits can be calculated using tty_get_frame_size(), no
need for the driver to do it on its own.

Also remove a comment on number of bits that doesn't match the code nor
the comment on ucc_uart_pram's rx_length ("minus 1" part differs). That
comment seems a verbatim copy of that in cpm_uart/cpm_uart_core.c
anyway so perhaps it was just copied over w/o much thinking.

Signed-off-by: Ilpo Järvinen 
---
 drivers/tty/serial/ucc_uart.c | 15 +--
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
index 3cc9ef08455c..7331964163c5 100644
--- a/drivers/tty/serial/ucc_uart.c
+++ b/drivers/tty/serial/ucc_uart.c
@@ -853,13 +853,6 @@ static void qe_uart_set_termios(struct uart_port *port,
u16 upsmr = ioread16be(>upsmr);
struct ucc_uart_pram __iomem *uccup = qe_port->uccup;
u16 supsmr = ioread16be(>supsmr);
-   u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */
-
-   /* Character length programmed into the mode register is the
-* sum of: 1 start bit, number of data bits, 0 or 1 parity bit,
-* 1 or 2 stop bits, minus 1.
-* The value 'bits' counts this for us.
-*/
 
/* byte size */
upsmr &= UCC_UART_UPSMR_CL_MASK;
@@ -869,22 +862,18 @@ static void qe_uart_set_termios(struct uart_port *port,
case CS5:
upsmr |= UCC_UART_UPSMR_CL_5;
supsmr |= UCC_UART_SUPSMR_CL_5;
-   char_length += 5;
break;
case CS6:
upsmr |= UCC_UART_UPSMR_CL_6;
supsmr |= UCC_UART_SUPSMR_CL_6;
-   char_length += 6;
break;
case CS7:
upsmr |= UCC_UART_UPSMR_CL_7;
supsmr |= UCC_UART_SUPSMR_CL_7;
-   char_length += 7;
break;
default:/* case CS8 */
upsmr |= UCC_UART_UPSMR_CL_8;
supsmr |= UCC_UART_SUPSMR_CL_8;
-   char_length += 8;
break;
}
 
@@ -892,13 +881,11 @@ static void qe_uart_set_termios(struct uart_port *port,
if (termios->c_cflag & CSTOPB) {
upsmr |= UCC_UART_UPSMR_SL;
supsmr |= UCC_UART_SUPSMR_SL;
-   char_length++;  /* + SL */
}
 
if (termios->c_cflag & PARENB) {
upsmr |= UCC_UART_UPSMR_PEN;
supsmr |= UCC_UART_SUPSMR_PEN;
-   char_length++;  /* + PEN */
 
if (!(termios->c_cflag & PARODD)) {
upsmr &= ~(UCC_UART_UPSMR_RPM_MASK |
@@ -953,7 +940,7 @@ static void qe_uart_set_termios(struct uart_port *port,
iowrite16be(upsmr, >upsmr);
if (soft_uart) {
iowrite16be(supsmr, >supsmr);
-   iowrite8(char_length, >rx_length);
+   iowrite8(tty_get_frame_size(termios->c_cflag), 
>rx_length);
 
/* Soft-UART requires a 1X multiplier for TX */
qe_setbrg(qe_port->us_info.rx_clock, baud, 16);
-- 
2.30.2



[PATCH 6/8] serial: Make ->set_termios() old ktermios const

2022-08-16 Thread Ilpo Järvinen
There should be no reason to adjust old ktermios which is going to get
discarded anyway.

Signed-off-by: Ilpo Järvinen 
---
 drivers/tty/serial/21285.c  |  2 +-
 drivers/tty/serial/8250/8250_bcm7271.c  |  2 +-
 drivers/tty/serial/8250/8250_dw.c   |  2 +-
 drivers/tty/serial/8250/8250_dwlib.c|  3 ++-
 drivers/tty/serial/8250/8250_dwlib.h|  2 +-
 drivers/tty/serial/8250/8250_fintek.c   |  2 +-
 drivers/tty/serial/8250/8250_lpss.c |  2 +-
 drivers/tty/serial/8250/8250_mid.c  |  5 ++---
 drivers/tty/serial/8250/8250_mtk.c  |  2 +-
 drivers/tty/serial/8250/8250_omap.c |  2 +-
 drivers/tty/serial/8250/8250_port.c |  6 +++---
 drivers/tty/serial/altera_jtaguart.c|  4 ++--
 drivers/tty/serial/altera_uart.c|  2 +-
 drivers/tty/serial/amba-pl010.c |  2 +-
 drivers/tty/serial/amba-pl011.c |  4 ++--
 drivers/tty/serial/apbuart.c|  2 +-
 drivers/tty/serial/ar933x_uart.c|  2 +-
 drivers/tty/serial/arc_uart.c   |  2 +-
 drivers/tty/serial/atmel_serial.c   |  5 +++--
 drivers/tty/serial/bcm63xx_uart.c   |  5 ++---
 drivers/tty/serial/clps711x.c   |  2 +-
 drivers/tty/serial/cpm_uart/cpm_uart_core.c |  2 +-
 drivers/tty/serial/digicolor-usart.c|  2 +-
 drivers/tty/serial/dz.c |  2 +-
 drivers/tty/serial/fsl_linflexuart.c|  2 +-
 drivers/tty/serial/fsl_lpuart.c |  4 ++--
 drivers/tty/serial/icom.c   |  5 ++---
 drivers/tty/serial/imx.c|  2 +-
 drivers/tty/serial/ip22zilog.c  |  2 +-
 drivers/tty/serial/jsm/jsm_tty.c|  4 ++--
 drivers/tty/serial/lantiq.c |  4 ++--
 drivers/tty/serial/liteuart.c   |  2 +-
 drivers/tty/serial/lpc32xx_hs.c |  2 +-
 drivers/tty/serial/max3100.c|  2 +-
 drivers/tty/serial/max310x.c|  2 +-
 drivers/tty/serial/mcf.c|  2 +-
 drivers/tty/serial/men_z135_uart.c  |  4 ++--
 drivers/tty/serial/meson_uart.c |  2 +-
 drivers/tty/serial/milbeaut_usio.c  |  3 ++-
 drivers/tty/serial/mpc52xx_uart.c   | 12 ++--
 drivers/tty/serial/mps2-uart.c  |  2 +-
 drivers/tty/serial/msm_serial.c |  2 +-
 drivers/tty/serial/mux.c|  2 +-
 drivers/tty/serial/mvebu-uart.c |  2 +-
 drivers/tty/serial/mxs-auart.c  |  2 +-
 drivers/tty/serial/omap-serial.c|  2 +-
 drivers/tty/serial/owl-uart.c   |  2 +-
 drivers/tty/serial/pch_uart.c   |  3 ++-
 drivers/tty/serial/pic32_uart.c |  2 +-
 drivers/tty/serial/pmac_zilog.c |  4 ++--
 drivers/tty/serial/pxa.c|  2 +-
 drivers/tty/serial/qcom_geni_serial.c   |  3 ++-
 drivers/tty/serial/rda-uart.c   |  2 +-
 drivers/tty/serial/rp2.c|  5 ++---
 drivers/tty/serial/sa1100.c |  2 +-
 drivers/tty/serial/samsung_tty.c|  2 +-
 drivers/tty/serial/sb1250-duart.c   |  2 +-
 drivers/tty/serial/sc16is7xx.c  |  2 +-
 drivers/tty/serial/sccnxp.c |  3 ++-
 drivers/tty/serial/serial-tegra.c   |  3 ++-
 drivers/tty/serial/serial_core.c|  2 +-
 drivers/tty/serial/serial_txx9.c|  2 +-
 drivers/tty/serial/sh-sci.c |  2 +-
 drivers/tty/serial/sifive.c |  2 +-
 drivers/tty/serial/sprd_serial.c|  5 ++---
 drivers/tty/serial/st-asc.c |  2 +-
 drivers/tty/serial/stm32-usart.c|  2 +-
 drivers/tty/serial/sunhv.c  |  2 +-
 drivers/tty/serial/sunplus-uart.c   |  2 +-
 drivers/tty/serial/sunsab.c |  2 +-
 drivers/tty/serial/sunsu.c  |  2 +-
 drivers/tty/serial/sunzilog.c   |  2 +-
 drivers/tty/serial/tegra-tcu.c  |  2 +-
 drivers/tty/serial/timbuart.c   |  4 ++--
 drivers/tty/serial/uartlite.c   |  5 +++--
 drivers/tty/serial/ucc_uart.c   |  3 ++-
 drivers/tty/serial/vt8500_serial.c  |  2 +-
 drivers/tty/serial/xilinx_uartps.c  |  3 ++-
 drivers/tty/serial/zs.c |  2 +-
 drivers/tty/tty_ioctl.c |  2 +-
 include/linux/serial_8250.h |  4 ++--
 include/linux/serial_core.h |  6 +++---
 82 files changed, 117 insertions(+), 112 deletions(-)

diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c
index 7520cc02fd4d..2f17bf4b221e 100644
--- a/drivers/tty/serial/21285.c
+++ b/drivers/tty/serial/21285.c
@@ -243,7 +243,7 @@ static void serial21285_shutdown(struct uart_port *port)
 
 static void
 serial21285_set_termios(struct uart_port *port, struct ktermios *termios,
-   struct ktermios *old

Re: [PATCH 1/3] termbits.h: create termbits-common.h for identical bits

2022-05-09 Thread Ilpo Järvinen
On Mon, 9 May 2022, Helge Deller wrote:

> Hello Ilpo,
> 
> On 5/9/22 11:34, Ilpo Järvinen wrote:
> > Some defines are the same across all archs. Move the most obvious
> > intersection to termbits-common.h.
> 
> I like your cleanup patches, but in this specific one, does it makes sense
> to split up together-belonging constants, e.g.
> 
> > diff --git a/arch/parisc/include/uapi/asm/termbits.h 
> > b/arch/parisc/include/uapi/asm/termbits.h
> > index 6017ee08f099..7f74a822b7ea 100644
> > --- a/arch/parisc/include/uapi/asm/termbits.h
> > +++ b/arch/parisc/include/uapi/asm/termbits.h
> > @@ -61,31 +61,15 @@ struct ktermios {
> >
> >
> >  /* c_iflag bits */
> > -#define IGNBRK 0x1
> > -#define BRKINT 0x2
> > -#define IGNPAR 0x4
> > -#define PARMRK 0x8
> > -#define INPCK  0x00010
> > -#define ISTRIP 0x00020
> > -#define INLCR  0x00040
> > -#define IGNCR  0x00080
> > -#define ICRNL  0x00100
> >  #define IUCLC  0x00200
> >  #define IXON   0x00400
> > -#define IXANY  0x00800
> >  #define IXOFF  0x01000
> >  #define IMAXBEL0x04000
> >  #define IUTF8  0x08000
> 
> In the hunk above you leave IUCLC, IXON, IXOFF... because they seem unique to 
> parisc.
> The other defines are then taken from generic header.
> Although this is correct, it leaves single values alone, which make it hard 
> to verify
> because you don't see the full list of values in one place.

While I too am fine either way, I don't think these are as strongly 
grouped as you seem to imply. There's no big advantage in having as much 
as possible within the same file. If somebody is looking for the meaning 
of these, these headers are no match when compared e.g. with stty manpage.

For c_iflag, the break, parity and cr related "groups" within c_iflag are 
moving completely to common header.

IXANY is probably only one close to borderline whether it kind of belongs 
to the same group as IXON/IXOFF (which both by chance both remained on the 
same side in the split). I don't think it does strongly enough to warrant 
keeping them next to each other but I'm open what opinions others have on 
it.

The rest in c_iflag don't seem to be strongly tied/grouped to the other 
defines within c_iflag. They're just bits that appear next/close to each 
other but are not tied by any significant meaning-based connection.

C_oflag is more messy. I exercised grouping based judgement with c_oflag 
where only the defines with all bits as zero would have moved to the 
common header breaking the groups very badly. That is, only CR0 would have 
moved and CR1-3 remained in arch headers, etc. which made no sense to do. 
One could argue, that since ONLCR (and perhaps CRDLY) are not moving, no 
other cr related defines should move either.

> > @@ -112,24 +96,6 @@ struct ktermios {
> >
> >  /* c_cflag bit meaning */
> >  #define CBAUD  0x100f
> > -#define  B00x  /* hang up */
> > -#define  B50   0x0001
> > -#define  B75   0x0002
> > -#define  B110  0x0003
> > -#define  B134  0x0004
> > -#define  B150  0x0005
> > -#define  B200  0x0006
> > -#define  B300  0x0007
> > -#define  B600  0x0008
> > -#define  B1200 0x0009
> > -#define  B1800 0x000a
> > -#define  B2400 0x000b
> > -#define  B4800 0x000c
> > -#define  B9600 0x000d
> > -#define  B192000x000e
> > -#define  B384000x000f
> > -#define EXTA B19200
> > -#define EXTB B38400
> 
> Here all baud values are dropped and will be taken from generic header, 
> which is good. 
> 
> That said, I think it's good to move away the second hunk,
> but maybe we should keep the first as is?
> 
> It's just a thought. Either way, I'm fine your patch if that's the
> way which is decided to go for all platforms.

Yes, lets wait and see what the others think.

Thanks for taking a look!

-- 
 i.


[PATCH 3/3] termbits.h: Remove posix_types.h include

2022-05-09 Thread Ilpo Järvinen
Nothing in termbits seems to require anything from linux/posix_types.h.

Signed-off-by: Ilpo Järvinen 
---
 arch/alpha/include/uapi/asm/termbits.h  | 2 --
 arch/mips/include/uapi/asm/termbits.h   | 2 --
 arch/parisc/include/uapi/asm/termbits.h | 2 --
 arch/sparc/include/uapi/asm/termbits.h  | 2 --
 include/uapi/asm-generic/termbits.h | 2 --
 5 files changed, 10 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h 
b/arch/alpha/include/uapi/asm/termbits.h
index 735e9ffe2795..f1290b22072b 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -2,8 +2,6 @@
 #ifndef _ALPHA_TERMBITS_H
 #define _ALPHA_TERMBITS_H
 
-#include 
-
 #include 
 
 typedef unsigned int   tcflag_t;
diff --git a/arch/mips/include/uapi/asm/termbits.h 
b/arch/mips/include/uapi/asm/termbits.h
index 8fa3e79d4f94..1eb60903d6f0 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -11,8 +11,6 @@
 #ifndef _ASM_TERMBITS_H
 #define _ASM_TERMBITS_H
 
-#include 
-
 #include 
 
 typedef unsigned int   tcflag_t;
diff --git a/arch/parisc/include/uapi/asm/termbits.h 
b/arch/parisc/include/uapi/asm/termbits.h
index d72c5ebf3a3a..3a8938d26fb4 100644
--- a/arch/parisc/include/uapi/asm/termbits.h
+++ b/arch/parisc/include/uapi/asm/termbits.h
@@ -2,8 +2,6 @@
 #ifndef __ARCH_PARISC_TERMBITS_H__
 #define __ARCH_PARISC_TERMBITS_H__
 
-#include 
-
 #include 
 
 typedef unsigned int   tcflag_t;
diff --git a/arch/sparc/include/uapi/asm/termbits.h 
b/arch/sparc/include/uapi/asm/termbits.h
index cfcc4e07ce51..4321322701fc 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -2,8 +2,6 @@
 #ifndef _UAPI_SPARC_TERMBITS_H
 #define _UAPI_SPARC_TERMBITS_H
 
-#include 
-
 #include 
 
 #if defined(__sparc__) && defined(__arch64__)
diff --git a/include/uapi/asm-generic/termbits.h 
b/include/uapi/asm-generic/termbits.h
index c92179563289..890ef29053e2 100644
--- a/include/uapi/asm-generic/termbits.h
+++ b/include/uapi/asm-generic/termbits.h
@@ -2,8 +2,6 @@
 #ifndef __ASM_GENERIC_TERMBITS_H
 #define __ASM_GENERIC_TERMBITS_H
 
-#include 
-
 #include 
 
 typedef unsigned int   tcflag_t;
-- 
2.30.2



[PATCH 2/3] termbits.h: Align lines & format

2022-05-09 Thread Ilpo Järvinen
- Align c_cc defines.
- Remove extra newlines.
- Realign & adjust number of leading zeros.
- Reorder c_cflag defines to ascending order
- Make comment ending shorted (=remove period and one extra space from
  the comments in mips).

Co-developed-by: Arnd Bergmann 
Signed-off-by: Arnd Bergmann 
Signed-off-by: Ilpo Järvinen 
---
 arch/alpha/include/uapi/asm/termbits.h   | 130 +-
 arch/mips/include/uapi/asm/termbits.h| 156 ++---
 arch/parisc/include/uapi/asm/termbits.h  |  77 +--
 arch/powerpc/include/uapi/asm/termbits.h | 100 +++---
 arch/sparc/include/uapi/asm/termbits.h   | 168 +++
 include/uapi/asm-generic/termbits.h  |  76 +-
 6 files changed, 346 insertions(+), 361 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h 
b/arch/alpha/include/uapi/asm/termbits.h
index 3c7a9afc4333..735e9ffe2795 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -53,60 +53,58 @@ struct ktermios {
 };
 
 /* c_cc characters */
-#define VEOF 0
-#define VEOL 1
-#define VEOL2 2
-#define VERASE 3
-#define VWERASE 4
-#define VKILL 5
-#define VREPRINT 6
-#define VSWTC 7
-#define VINTR 8
-#define VQUIT 9
-#define VSUSP 10
-#define VSTART 12
-#define VSTOP 13
-#define VLNEXT 14
-#define VDISCARD 15
-#define VMIN 16
-#define VTIME 17
+#define VEOF0
+#define VEOL1
+#define VEOL2   2
+#define VERASE  3
+#define VWERASE 4
+#define VKILL   5
+#define VREPRINT6
+#define VSWTC   7
+#define VINTR   8
+#define VQUIT   9
+#define VSUSP  10
+#define VSTART 12
+#define VSTOP  13
+#define VLNEXT 14
+#define VDISCARD   15
+#define VMIN   16
+#define VTIME  17
 
 /* c_iflag bits */
-#define IXON   0x00200
-#define IXOFF  0x00400
-#define IUCLC  0x01000
-#define IMAXBEL0x02000
-#define IUTF8  0x04000
+#define IXON   0x0200
+#define IXOFF  0x0400
+#define IUCLC  0x1000
+#define IMAXBEL0x2000
+#define IUTF8  0x4000
 
 /* c_oflag bits */
 #define ONLCR  0x2
 #define OLCUC  0x4
-
-
-#define NLDLY  0x000300
-#define   NL0  0x00
-#define   NL1  0x000100
-#define   NL2  0x000200
-#define   NL3  0x000300
-#define TABDLY 0x000c00
-#define   TAB0 0x00
-#define   TAB1 0x000400
-#define   TAB2 0x000800
-#define   TAB3 0x000c00
-#define CRDLY  0x003000
-#define   CR0  0x00
-#define   CR1  0x001000
-#define   CR2  0x002000
-#define   CR3  0x003000
-#define FFDLY  0x004000
-#define   FF0  0x00
-#define   FF1  0x004000
-#define BSDLY  0x008000
-#define   BS0  0x00
-#define   BS1  0x008000
-#define VTDLY  0x01
-#define   VT0  0x00
-#define   VT1  0x01
+#define NLDLY  0x00300
+#define   NL0  0x0
+#define   NL1  0x00100
+#define   NL2  0x00200
+#define   NL3  0x00300
+#define TABDLY 0x00c00
+#define   TAB0 0x0
+#define   TAB1 0x00400
+#define   TAB2 0x00800
+#define   TAB3 0x00c00
+#define CRDLY  0x03000
+#define   CR0  0x0
+#define   CR1  0x01000
+#define   CR2  0x02000
+#define   CR3  0x03000
+#define FFDLY  0x04000
+#define   FF0  0x0
+#define   FF1  0x04000
+#define BSDLY  0x08000
+#define   BS0  0x0
+#define   BS1  0x08000
+#define VTDLY  0x1
+#define   VT0  0x0
+#define   VT1  0x1
 /*
  * Should be equivalent to TAB3, see description of TAB3 in
  * POSIX.1-2008, Ch. 11.2.3 "Output Modes"
@@ -116,38 +114,34 @@ struct ktermios {
 /* c_cflag bit meaning */
 #define CBAUD  0x001f
 #define CBAUDEX0x
-#define  B576000x0010
-#define  B115200   0x0011
-#define  B230400   0x0012
-#define  B460800   0x0013
-#define  B50   0x0014
-#define  B576000   0x0015
-#define  B921600   0x0016
-#define B100   0x0017
-#define B1152000   0x0018
-#define B150   0x0019
-#define B200   0x001a
-#define B250   0x001b
-#define B300   0x001c
-#define B350   0x001d
-#define B400   0x001e
 #define BOTHER 0x001f
-
+#define B57600 0x0010
+#defineB115200 0x0011
+#defineB230400 0x0012
+#defineB460800 0x0013
+#defineB50 0x0014
+#defineB576000 0x0015
+#defineB921600 0x0016
+#define   B100 0x0017
+#define   B1152000 0x0018
+#define   B150 0x0019
+#define   B200 0x001a
+#define   B250 0x001b
+#define   B300 0x001c
+#define   B350 0x001d
+#define   B400 0x001e
 #define CSIZE  0x0300
 #define   CS5  0x
 #define   CS6  0x0100
 #define   CS7  0x0200
 #define   CS8  0x0300
-
 #define CSTOPB 0x0400
 #define CREAD  0x0800
 #define PARENB 

[PATCH 1/3] termbits.h: create termbits-common.h for identical bits

2022-05-09 Thread Ilpo Järvinen
Some defines are the same across all archs. Move the most obvious
intersection to termbits-common.h.

Signed-off-by: Ilpo Järvinen 
---
 arch/alpha/include/uapi/asm/termbits.h | 52 +
 arch/mips/include/uapi/asm/termbits.h  | 53 +-
 arch/parisc/include/uapi/asm/termbits.h| 54 +-
 arch/powerpc/include/uapi/asm/termbits.h   | 52 +
 arch/sparc/include/uapi/asm/termbits.h | 53 +-
 include/uapi/asm-generic/termbits-common.h | 65 ++
 include/uapi/asm-generic/termbits.h| 53 +-
 7 files changed, 76 insertions(+), 306 deletions(-)
 create mode 100644 include/uapi/asm-generic/termbits-common.h

diff --git a/arch/alpha/include/uapi/asm/termbits.h 
b/arch/alpha/include/uapi/asm/termbits.h
index 30dc7ff777b8..3c7a9afc4333 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -4,8 +4,8 @@
 
 #include 
 
-typedef unsigned char  cc_t;
-typedef unsigned int   speed_t;
+#include 
+
 typedef unsigned int   tcflag_t;
 
 /*
@@ -72,33 +72,17 @@ struct ktermios {
 #define VTIME 17
 
 /* c_iflag bits */
-#define IGNBRK 0x1
-#define BRKINT 0x2
-#define IGNPAR 0x4
-#define PARMRK 0x8
-#define INPCK  0x00010
-#define ISTRIP 0x00020
-#define INLCR  0x00040
-#define IGNCR  0x00080
-#define ICRNL  0x00100
 #define IXON   0x00200
 #define IXOFF  0x00400
-#define IXANY  0x00800
 #define IUCLC  0x01000
 #define IMAXBEL0x02000
 #define IUTF8  0x04000
 
 /* c_oflag bits */
-#define OPOST  0x1
 #define ONLCR  0x2
 #define OLCUC  0x4
 
-#define OCRNL  0x8
-#define ONOCR  0x00010
-#define ONLRET 0x00020
 
-#define OFILL  0x40
-#define OFDEL  0x80
 #define NLDLY  0x000300
 #define   NL0  0x00
 #define   NL1  0x000100
@@ -131,24 +115,6 @@ struct ktermios {
 
 /* c_cflag bit meaning */
 #define CBAUD  0x001f
-#define  B00x  /* hang up */
-#define  B50   0x0001
-#define  B75   0x0002
-#define  B110  0x0003
-#define  B134  0x0004
-#define  B150  0x0005
-#define  B200  0x0006
-#define  B300  0x0007
-#define  B600  0x0008
-#define  B1200 0x0009
-#define  B1800 0x000a
-#define  B2400 0x000b
-#define  B4800 0x000c
-#define  B9600 0x000d
-#define  B192000x000e
-#define  B384000x000f
-#define EXTA B19200
-#define EXTB B38400
 #define CBAUDEX0x
 #define  B576000x0010
 #define  B115200   0x0011
@@ -180,11 +146,8 @@ struct ktermios {
 #define HUPCL  0x4000
 
 #define CLOCAL 0x8000
-#define CMSPAR 0x4000  /* mark or space (stick) parity */
-#define CRTSCTS0x8000  /* flow control */
 
 #define CIBAUD 0x1f
-#define IBSHIFT16
 
 /* c_lflag bits */
 #define ISIG   0x0080
@@ -204,17 +167,6 @@ struct ktermios {
 #define IEXTEN 0x0400
 #define EXTPROC0x1000
 
-/* Values for the ACTION argument to `tcflow'.  */
-#defineTCOOFF  0
-#defineTCOON   1
-#defineTCIOFF  2
-#defineTCION   3
-
-/* Values for the QUEUE_SELECTOR argument to `tcflush'.  */
-#defineTCIFLUSH0
-#defineTCOFLUSH1
-#defineTCIOFLUSH   2
-
 /* Values for the OPTIONAL_ACTIONS argument to `tcsetattr'.  */
 #defineTCSANOW 0
 #defineTCSADRAIN   1
diff --git a/arch/mips/include/uapi/asm/termbits.h 
b/arch/mips/include/uapi/asm/termbits.h
index d1315ccdb39a..b33f514315ce 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -13,8 +13,8 @@
 
 #include 
 
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
+#include 
+
 typedef unsigned int tcflag_t;
 
 /*
@@ -80,31 +80,15 @@ struct ktermios {
 #define VEOL   17  /* End-of-line character [ICANON].  */
 
 /* c_iflag bits */
-#define IGNBRK 0x1 /* Ignore break condition.  */
-#define BRKINT 0x2 /* Signal interrupt on break.  */
-#define IGNPAR 0x4 /* Ignore characters with parity errors.  */
-#define PARMRK 0x8 /* Mark parity and framing errors.  */
-#define INPCK  0x00010 /* Enable input parity check.  */
-#define ISTRIP 0x00020 /* Strip 8th bit off characters.  */
-#define INLCR  0x00040 /* Map NL to CR on input.  */
-#define IGNCR  0x00080 /* Ignore CR.  */
-#define ICRNL  0x00100 /* Map CR to NL on input.  */
 #define IUCLC  0x00200 /* Map upper case to lower case on input.  */
 #define IXON   0x00400 /* Enable start/stop output control.  */
-#define IXANY  0x00800 /* Any character will restart after stop.  */
 #define IXOFF

[PATCH 0/3] termbits.h: Further improvements

2022-05-09 Thread Ilpo Järvinen
Again, I prefer Greg to take these through his tty tree.

Changes done by this serie:

1) Create termbits-common.h for the most obvious termbits.h intersection.
2) Reformat some lines that remain in termbits.h files.
3) Don't include posix_types.h unnecessarily.

Please do check I got the uapi include things done correctly! That is,
that including using asm-generic/termbits-common.h path is the preferred
approach for a header file that is not supposed to be overridden by the
arch specific header files and that mandatory-y is not required for
termbits-common.h.

Unfortunately I couldn't move also tcflag_t into termbits-common.h due
to the way it is being defined for sparc. However, by the looks of how
the type for tcflag_t is being chosen there, having just unsigned int
might work also for sparc?

Ilpo Järvinen (3):
  termbits.h: create termbits-common.h for identical bits
  termbits.h: Align lines & format
  termbits.h: Remove posix_types.h include

 arch/alpha/include/uapi/asm/termbits.h | 182 ++---
 arch/mips/include/uapi/asm/termbits.h  | 209 ---
 arch/parisc/include/uapi/asm/termbits.h| 131 
 arch/powerpc/include/uapi/asm/termbits.h   | 152 +-
 arch/sparc/include/uapi/asm/termbits.h | 223 -
 include/uapi/asm-generic/termbits-common.h |  65 ++
 include/uapi/asm-generic/termbits.h| 129 
 7 files changed, 418 insertions(+), 673 deletions(-)
 create mode 100644 include/uapi/asm-generic/termbits-common.h

-- 
2.30.2



Re: [PATCH 1/1] termbits: Convert octal defines to hex

2022-05-05 Thread Ilpo Järvinen
On Wed, 4 May 2022, Arnd Bergmann wrote:

> On Wed, May 4, 2022 at 10:33 AM Ilpo Järvinen
>  wrote:
> > On Wed, 4 May 2022, Arnd Bergmann wrote:
> > > On Wed, May 4, 2022 at 9:20 AM Ilpo Järvinen 
> > >  wrote:
> > > >
> > > After applying the patch locally, I still see a bunch of whitespace
> > > differences in the
> > > changed lines if I run
> > >
> > > vimdiff arch/*/include/uapi/asm/termbits.h 
> > > include/uapi/asm-generic/termbits.h
> > >
> > > I think this mostly because you left the sparc version alone (it already
> > > uses hex constants), but it may be nice to edit this a little more to
> > > make the actual differences stick out more.
> >
> > I took a look on further harmonizing, however, it turned out to be not
> > that simple. This is basically the pipeline I use to further cleanup the
> > differences and remove comments if you want to play yourself, just remove
> > stages from the tail to get the intermediate datas (gawk is required for
> > --non-decimal-data):
> 
> I've played around with it some more to adjust the number of leading
> zeroes and the type of whitespace. This is what I ended up with on top
> of your patch: https://pastebin.com/raw/pkDPaKN1
> 
> Feel free to fold it into yours.

Ok thanks. With that it seems to go a bit beyond octal to hex conversion 
so I'll make a series out of it. The series will also introduce 
include/uapi/asm-generic/termbits-common.h for the most obvious 
intersection.


-- 
 i.


Re: [PATCH 1/1] termbits: Convert octal defines to hex

2022-05-04 Thread Ilpo Järvinen
On Wed, 4 May 2022, Arnd Bergmann wrote:

> On Wed, May 4, 2022 at 9:20 AM Ilpo Järvinen
>  wrote:
> >
> > Many archs have termbits.h as octal numbers. It makes hard for humans
> > to parse the magnitude of large numbers correctly and to compare with
> > hex ones of the same define.
> >
> > Convert octal values to hex.
> >
> > First step is an automated conversion with:
> >
> > for i in $(git ls-files | grep 'termbits\.h'); do
> > awk --non-decimal-data '/^#define\s+[A-Z][A-Z0-9]*\s+0[0-9]/ {
> > l=int(((length($3) - 1) * 3 + 3) / 4);
> > repl = sprintf("0x%0" l "x", $3);
> > print gensub(/[^[:blank:]]+/, repl, 3);
> > next} {print}' $i > $i~;
> > mv $i~ $i;
> > done
> >
> > On top of that, some manual processing on alignment and number of zeros.
> > In addition, small tweaks to formatting of a few comments on the same
> > lines.
> >
> > Signed-off-by: Ilpo Järvinen 
> 
> Good idea!
> 
> I assume you already checked if additional file contents can be shared across
> architectures? I think I've tried in the past but didn't really get
> anywhere with
> that.
> 
> After applying the patch locally, I still see a bunch of whitespace
> differences in the
> changed lines if I run
> 
> vimdiff arch/*/include/uapi/asm/termbits.h include/uapi/asm-generic/termbits.h
> 
> I think this mostly because you left the sparc version alone (it already
> uses hex constants), but it may be nice to edit this a little more to
> make the actual differences stick out more.

I took a look on further harmonizing, however, it turned out to be not 
that simple. This is basically the pipeline I use to further cleanup the 
differences and remove comments if you want to play yourself, just remove 
stages from the tail to get the intermediate datas (gawk is required for 
--non-decimal-data):

$ git ls-files | grep 'termbits\.h' | xargs grep -h -e '#define' | awk 
--non-decimal-data '{if (NF < 3) {next}; printf("#define %s\t0x%08x\n", $2, 
$3)}' | sort | uniq -c | sort | awk '{print $1}' | uniq -c
 82 1
 74 2
 14 3
 58 4
 11 5
 54 6

So only 54 are the same for all archs (non-numeric defines such as EXT[AB] 
will appear as 0x0 but at least those two seem the same across archs 
anyway):
  6 #define B0  0x
  6 #define B1100x0003
  6 #define B1200   0x0009
  6 #define B1340x0004
  6 #define B1500x0005
  6 #define B1800   0x000a
  6 #define B19200  0x000e
  6 #define B2000x0006
  6 #define B2400   0x000b
  6 #define B3000x0007
  6 #define B38400  0x000f
  6 #define B4800   0x000c
  6 #define B50 0x0001
  6 #define B6000x0008
  6 #define B75 0x0002
  6 #define B9600   0x000d
  6 #define BRKINT  0x0002
  6 #define BS0 0x
  6 #define CMSPAR  0x4000
  6 #define CR0 0x
  6 #define CRTSCTS 0x8000
  6 #define CS5 0x
  6 #define ECHO0x0008
  6 #define EXTA0x
  6 #define EXTB0x
  6 #define FF0 0x
  6 #define IBSHIFT 0x0010
  6 #define ICRNL   0x0100
  6 #define IGNBRK  0x0001
  6 #define IGNCR   0x0080
  6 #define IGNPAR  0x0004
  6 #define INLCR   0x0040
  6 #define INPCK   0x0010
  6 #define ISTRIP  0x0020
  6 #define IXANY   0x0800
  6 #define NL0 0x
  6 #define NL1 0x0100
  6 #define OCRNL   0x0008
  6 #define OFDEL   0x0080
  6 #define OFILL   0x0040
  6 #define ONLRET  0x0020
  6 #define ONOCR   0x0010
  6 #define OPOST   0x0001
  6 #define PARMRK  0x0008
  6 #define TAB00x
  6 #define TCIFLUSH0x
  6 #define TCIOFF  0x0002
  6 #define TCIOFLUSH   0x0002
  6 #define TCION   0x0003
  6 #define TCOFLUSH0x0001
  6 #define TCOOFF  0x
  6 #define TCOON   0x0001
  6 #define TCSANOW 0x
  6 #define VT0 0x

Sadly for the others, it just tends to be that one or two are different 
from the rest.



-- 
 i.


[PATCH 1/1] termbits: Convert octal defines to hex

2022-05-04 Thread Ilpo Järvinen
Many archs have termbits.h as octal numbers. It makes hard for humans
to parse the magnitude of large numbers correctly and to compare with
hex ones of the same define.

Convert octal values to hex.

First step is an automated conversion with:

for i in $(git ls-files | grep 'termbits\.h'); do
awk --non-decimal-data '/^#define\s+[A-Z][A-Z0-9]*\s+0[0-9]/ {
l=int(((length($3) - 1) * 3 + 3) / 4);
repl = sprintf("0x%0" l "x", $3);
print gensub(/[^[:blank:]]+/, repl, 3);
next} {print}' $i > $i~;
mv $i~ $i;
done

On top of that, some manual processing on alignment and number of zeros.
In addition, small tweaks to formatting of a few comments on the same 
lines.

Signed-off-by: Ilpo Järvinen 
---

I prefer this to go in though Greg's tty tree.

 arch/alpha/include/uapi/asm/termbits.h   | 202 ++---
 arch/mips/include/uapi/asm/termbits.h| 222 +++
 arch/parisc/include/uapi/asm/termbits.h  | 220 +++---
 arch/powerpc/include/uapi/asm/termbits.h | 202 ++---
 include/uapi/asm-generic/termbits.h  | 220 +++---
 5 files changed, 533 insertions(+), 533 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h 
b/arch/alpha/include/uapi/asm/termbits.h
index 4575ba34a0ea..30dc7ff777b8 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -72,57 +72,57 @@ struct ktermios {
 #define VTIME 17
 
 /* c_iflag bits */
-#define IGNBRK 001
-#define BRKINT 002
-#define IGNPAR 004
-#define PARMRK 010
-#define INPCK  020
-#define ISTRIP 040
-#define INLCR  100
-#define IGNCR  200
-#define ICRNL  400
-#define IXON   0001000
-#define IXOFF  0002000
-#define IXANY  0004000
-#define IUCLC  001
-#define IMAXBEL002
-#define IUTF8  004
+#define IGNBRK 0x1
+#define BRKINT 0x2
+#define IGNPAR 0x4
+#define PARMRK 0x8
+#define INPCK  0x00010
+#define ISTRIP 0x00020
+#define INLCR  0x00040
+#define IGNCR  0x00080
+#define ICRNL  0x00100
+#define IXON   0x00200
+#define IXOFF  0x00400
+#define IXANY  0x00800
+#define IUCLC  0x01000
+#define IMAXBEL0x02000
+#define IUTF8  0x04000
 
 /* c_oflag bits */
-#define OPOST  001
-#define ONLCR  002
-#define OLCUC  004
-
-#define OCRNL  010
-#define ONOCR  020
-#define ONLRET 040
-
-#define OFILL  0100
-#define OFDEL  0200
-#define NLDLY  1400
-#define   NL0  
-#define   NL1  0400
-#define   NL2  1000
-#define   NL3  1400
-#define TABDLY 6000
-#define   TAB0 
-#define   TAB1 2000
-#define   TAB2 4000
-#define   TAB3 6000
-#define CRDLY  0003
-#define   CR0  
-#define   CR1  0001
-#define   CR2  0002
-#define   CR3  0003
-#define FFDLY  0004
-#define   FF0  
-#define   FF1  0004
-#define BSDLY  0010
-#define   BS0  
-#define   BS1  0010
-#define VTDLY  0020
-#define   VT0  
-#define   VT1  0020
+#define OPOST  0x1
+#define ONLCR  0x2
+#define OLCUC  0x4
+
+#define OCRNL  0x8
+#define ONOCR  0x00010
+#define ONLRET 0x00020
+
+#define OFILL  0x40
+#define OFDEL  0x80
+#define NLDLY  0x000300
+#define   NL0  0x00
+#define   NL1  0x000100
+#define   NL2  0x000200
+#define   NL3  0x000300
+#define TABDLY 0x000c00
+#define   TAB0 0x00
+#define   TAB1 0x000400
+#define   TAB2 0x000800
+#define   TAB3 0x000c00
+#define CRDLY  0x003000
+#define   CR0  0x00
+#define   CR1  0x001000
+#define   CR2  0x002000
+#define   CR3  0x003000
+#define FFDLY  0x004000
+#define   FF0  0x00
+#define   FF1  0x004000
+#define BSDLY  0x008000
+#define   BS0  0x00
+#define   BS1  0x008000
+#define VTDLY  0x01
+#define   VT0  0x00
+#define   VT1  0x01
 /*
  * Should be equivalent to TAB3, see description of TAB3 in
  * POSIX.1-2008, Ch. 11.2.3 "Output Modes"
@@ -130,60 +130,60 @@ struct ktermios {
 #define XTABS  TAB3
 
 /* c_cflag bit meaning */
-#define CBAUD  037
-#define  B0000 /* hang up */
-#define  B50   001
-#define  B75   002
-#define  B110  003
-#define  B134  004
-#define  B150  005
-#define  B200  006
-#define  B300  007
-#define  B600  010
-#define  B1200 011
-#define  B1800 012
-#define  B2400 013
-#define  B4800 014
-#define  B9600 015
-#define  B19200016
-#define  B38400017
+#define CBAUD  0x001f
+#define  B00x  /* hang up */
+#define  B50   0x0001
+#define  B75   0x0002
+#define  B110  0x0003
+#define  B134  0x0004
+#define  B150  0x0005
+#define  B200  0x0006
+#define  B300  0x0007
+#define  B600  0x0008
+#define  B1200 0x0009
+#define  B1800  

Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-26 Thread Ilpo Järvinen
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.


Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-26 Thread Ilpo Järvinen
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-...@vger.kernel.org
> > > Cc: Ivan Kokshaysky 
> > > Cc: Matt Turner 
> > > Cc: linux-al...@vger.kernel.org
> > > Cc: Thomas Bogendoerfer 
> > > Cc: linux-m...@vger.kernel.org
> > > Cc: "James E.J. Bottomley" 
> > > Cc: Helge Deller 
> > > Cc: linux-par...@vger.kernel.org
> > > Cc: Michael Ellerman 
> > > Cc: Benjamin Herrenschmidt 
> > > Cc: Paul Mackerras 
> > > Cc: linuxppc-dev@lists.ozlabs.org
> > > Cc: "David S. Miller" 
> > > Cc: sparcli...@vger.kernel.org
> > > Cc: Arnd Bergmann 
> > > Cc: linux-a...@vger.kernel.org
> > > Cc: linux-...@vger.kernel.org
> > > Signed-off-by: Ilpo Järvinen 
> > > ---

> > >  #define CMSPAR0100  /* mark or space (stick) parity 
> > > */
> > >  #define CRTSCTS   0200  /* 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 HUPCL0004
> > >  
> > >  #define CLOCAL   0010
> > > +#define ADDRB0040/* address bit */
> > >  #define CMSPAR 0100  /* mark or space (stick) parity 
> > > */
> > >  #define CRTSCTS0200  /* 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 B350  0x1012
> > >  #define B400  0x1013  */
> > >  #define CIBAUD 0x100f  /* input baud rate (not used) */
> > > +#define ADDRB  0x2000  /* address bit */
> > >  #define CMSPAR 0x4000  /* mark or space (stick) parity */
> > >  #define CRTSCTS0x8000  /* 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.

Re: [PATCH v5 06/10] serial: General support for multipoint addresses

2022-04-26 Thread Ilpo Järvinen
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-...@vger.kernel.org
> > Cc: Ivan Kokshaysky 
> > Cc: Matt Turner 
> > Cc: linux-al...@vger.kernel.org
> > Cc: Thomas Bogendoerfer 
> > Cc: linux-m...@vger.kernel.org
> > Cc: "James E.J. Bottomley" 
> > Cc: Helge Deller 
> > Cc: linux-par...@vger.kernel.org
> > Cc: Michael Ellerman 
> > Cc: Benjamin Herrenschmidt 
> > Cc: Paul Mackerras 
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: Yoshinori Sato 
> > Cc: Rich Felker 
> > Cc: linux...@vger.kernel.org
> > Cc: "David S. Miller" 
> > Cc: sparcli...@vger.kernel.org
> > Cc: Chris Zankel 
> > Cc: Max Filippov 
> > Cc: linux-xte...@linux-xtensa.org
> > Cc: Arnd Bergmann 
> > Cc: linux-a...@vger.kernel.org
> > Cc: linux-...@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen 
> > ---

> > 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.


Re: [PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-26 Thread Ilpo Järvinen
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-...@vger.kernel.org
> > Cc: Ivan Kokshaysky 
> > Cc: Matt Turner 
> > Cc: linux-al...@vger.kernel.org
> > Cc: Thomas Bogendoerfer 
> > Cc: linux-m...@vger.kernel.org
> > Cc: "James E.J. Bottomley" 
> > Cc: Helge Deller 
> > Cc: linux-par...@vger.kernel.org
> > Cc: Michael Ellerman 
> > Cc: Benjamin Herrenschmidt 
> > Cc: Paul Mackerras 
> > Cc: linuxppc-dev@lists.ozlabs.org
> > Cc: "David S. Miller" 
> > Cc: sparcli...@vger.kernel.org
> > Cc: Arnd Bergmann 
> > Cc: linux-a...@vger.kernel.org
> > Cc: linux-...@vger.kernel.org
> > Signed-off-by: Ilpo Järvinen 
> > ---
> >  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  0004
> >  
> >  #define CLOCAL 0010
> > +#define ADDRB  0040/* address bit */
> >  #define CMSPAR   0100  /* mark or space (stick) parity 
> > */
> >  #define CRTSCTS  0200  /* 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 B350 0010016
> >  #define B400 0010017
> >  #define CIBAUD   00200360  /* input baud rate */
> > +#define ADDRB0040  /* address bit */
> >  #define CMSPAR   0100  /* mark or space (stick) parity */
> >  #define CRTSCTS  0200  /* 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  B350 0010016
> >  #define  B400 0010017
> >  #define CIBAUD00200360 /* input baud rate */
> > +#define ADDRB0040  /* address bit */
> 
> tabs where the rest were not?
> 
> >  #define CMSPAR0100  /* mark or space (stick) parity */
> >  #define CRTSCTS   0200  /*

[PATCH v5 06/10] serial: General support for multipoint addresses

2022-04-26 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: linux...@vger.kernel.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: linux-xte...@linux-xtensa.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 .../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 se

[PATCH v5 05/10] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-26 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0040/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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 B350 0010016
 #define B400 0010017
 #define CIBAUD   00200360  /* input baud rate */
+#define ADDRB0040  /* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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  B350 0010016
 #define  B400 0010017
 #define CIBAUD00200360 /* input baud rate */
+#define ADDRB0040  /* address bit */
 #define CMSPAR0100  /* mark or space (stick) parity */
 #define CRTSCTS   0200  /* 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0040/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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 B350  0x1012
 #define B400  0x1013  */
 #define CIBAUD   0x100f  /* input baud rate (not used) */
+#define ADDRB0x2000  /* address bit */
 #define CMSPAR   0x4000  /* mark or space (stick) parity */
 #define CRTSCTS  0x8000  /* flow control */
 
diff --git a/driver

[PATCH v4 09/13] serial: General support for multipoint addresses

2022-04-25 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: linux...@vger.kernel.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: linux-xte...@linux-xtensa.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 .../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 se

[PATCH v4 08/13] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-25 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0040/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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 B350 0010016
 #define B400 0010017
 #define CIBAUD   00200360  /* input baud rate */
+#define ADDRB0040  /* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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  B350 0010016
 #define  B400 0010017
 #define CIBAUD00200360 /* input baud rate */
+#define ADDRB0040  /* address bit */
 #define CMSPAR0100  /* mark or space (stick) parity */
 #define CRTSCTS   0200  /* 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0040/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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 B350  0x1012
 #define B400  0x1013  */
 #define CIBAUD   0x100f  /* input baud rate (not used) */
+#define ADDRB0x2000  /* address bit */
 #define CMSPAR   0x4000  /* mark or space (stick) parity */
 #define CRTSCTS  0x8000  /* flow control */
 
diff --git a/driver

[PATCH v3 08/12] serial: General support for multipoint addresses

2022-04-11 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: linux...@vger.kernel.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: linux-xte...@linux-xtensa.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 .../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 se

[PATCH v3 07/12] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-11 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0040/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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 B350 0010016
 #define B400 0010017
 #define CIBAUD   00200360  /* input baud rate */
+#define ADDRB0040  /* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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  B350 0010016
 #define  B400 0010017
 #define CIBAUD00200360 /* input baud rate */
+#define ADDRB0040  /* address bit */
 #define CMSPAR0100  /* mark or space (stick) parity */
 #define CRTSCTS   0200  /* 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0040/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* 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 B350  0x1012
 #define B400  0x1013  */
 #define CIBAUD   0x100f  /* input baud rate (not used) */
+#define ADDRB0x2000  /* address bit */
 #define CMSPAR   0x4000  /* mark or space (stick) parity */
 #define CRTSCTS  0x8000  /* flow control */
 
diff --git a/driver

Re: [PATCH v2 07/12] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-04 Thread Ilpo Järvinen
On Mon, 4 Apr 2022, Arnd Bergmann wrote:

> On Mon, Apr 4, 2022 at 10:29 AM Ilpo Järvinen
>  wrote:
> 
> >
> >  #define CLOCAL 0010
> > +#define ADDRB  01000   /* address bit */
> >  #define CMSPAR   0100  /* mark or space (stick) parity */
> >  #define CRTSCTS  0200  /* flow control */
> >
> > diff --git a/arch/mips/include/uapi/asm/termbits.h 
> > b/arch/mips/include/uapi/asm/termbits.h
> > index dfeffba729b7..e7ea31cfec78 100644
> > --- a/arch/mips/include/uapi/asm/termbits.h
> > +++ b/arch/mips/include/uapi/asm/termbits.h
> > @@ -181,6 +181,7 @@ struct ktermios {
> >  #define B300 0010015
> >  #define B350 0010016
> >  #define B400 0010017
> > +#define ADDRB002   /* address bit */
> >  #define CIBAUD   00200360  /* input baud rate */
> >  #define CMSPAR   0100  /* mark or space (stick) parity */
> >  #define CRTSCTS  0200  /* flow control */
> 
> It looks like the top bits are used the same way on all architectures
> already, while the bottom bits of the flag differ. Could you pick
> the next free bit from the top to use the same value 040
> everywhere?

040 isn't the top of the use:

diff --git a/arch/alpha/include/uapi/asm/termbits.h 
b/arch/alpha/include/uapi/asm/termbits.h
index 4575ba34a0ea..285169c794ec 100644
--- a/arch/alpha/include/uapi/asm/termbits.h
+++ b/arch/alpha/include/uapi/asm/termbits.h
@@ -178,10 +178,11 @@ struct ktermios {
 #define PARENB 0001
 #define PARODD 0002
 #define HUPCL  0004
 
 #define CLOCAL 0010
+#define ADDRB  01000   /* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
 
 #define CIBAUD 0760
 #define IBSHIFT16
diff --git a/arch/sparc/include/uapi/asm/termbits.h 
b/arch/sparc/include/uapi/asm/termbits.h
index ce5ad5d0f105..4ad60c4acf65 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -198,10 +198,11 @@ struct ktermios {
adjust CBAUD constant and drivers accordingly.
 #define B400  0x1013  */
+#define ADDRB0x2000  /* address bit */
 #define CIBAUD   0x100f  /* input baud rate (not used) */
 #define CMSPAR   0x4000  /* mark or space (stick) parity */
 #define CRTSCTS  0x8000  /* flow control */


Somehow I managed to convince myself earlier there isn't a bit available 
that would be consistent across archs but now that I recheck the 
040 bit (0x2000) you propose, it seems to be that nothing is 
using it.

It's not suprising I didn't get the magnitude of those long octal numbers 
right. ...They are such a pain to interpret correctly.


-- 
 i.


[PATCH v2 08/12] serial: General support for multipoint addresses

2022-04-04 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: linux...@vger.kernel.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: linux-xte...@linux-xtensa.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 .../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 ++-
 include/linux/serial_core.h   |  6 ++
 include/uapi/asm-generic/ioctls.h |  3 +
 include/uapi/linux/serial.h   |  8 +++
 13 files changed, 123 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 TIOCGICOUNT0x545D  /* rea

[PATCH v2 07/12] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-04-04 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 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..285169c794ec 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  01000   /* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
 
diff --git a/arch/mips/include/uapi/asm/termbits.h 
b/arch/mips/include/uapi/asm/termbits.h
index dfeffba729b7..e7ea31cfec78 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -181,6 +181,7 @@ struct ktermios {
 #define B300 0010015
 #define B350 0010016
 #define B400 0010017
+#define ADDRB002   /* address bit */
 #define CIBAUD   00200360  /* input baud rate */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
diff --git a/arch/parisc/include/uapi/asm/termbits.h 
b/arch/parisc/include/uapi/asm/termbits.h
index 40e920f8d683..629be061f5d5 100644
--- a/arch/parisc/include/uapi/asm/termbits.h
+++ b/arch/parisc/include/uapi/asm/termbits.h
@@ -158,6 +158,7 @@ struct ktermios {
 #define  B300 0010015
 #define  B350 0010016
 #define  B400 0010017
+#define ADDRB002   /* address bit */
 #define CIBAUD00200360 /* input baud rate */
 #define CMSPAR0100  /* mark or space (stick) parity */
 #define CRTSCTS   0200  /* flow control */
diff --git a/arch/powerpc/include/uapi/asm/termbits.h 
b/arch/powerpc/include/uapi/asm/termbits.h
index ed18bc61f63d..1b778ac562a4 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0020/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
 
diff --git a/arch/sparc/include/uapi/asm/termbits.h 
b/arch/sparc/include/uapi/asm/termbits.h
index ce5ad5d0f105..4ad60c4acf65 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -200,6 +200,7 @@ struct ktermios {
 #define B300  0x1011
 #define B350  0x1012
 #define B400  0x1013  */
+#define ADDRB0x2000  /* address bit */
 #define CIBAUD   0x100f  /* input baud rate (not used) */
 #define CMSPAR   0x4000  /* mark or space (sti

Re: [RFC PATCH 6/7] serial: General support for multipoint addresses

2022-03-10 Thread Ilpo Järvinen
On Wed, 9 Mar 2022, Lukas Wunner wrote:

> On Mon, Mar 07, 2022 at 11:48:01AM +0200, Ilpo Järvinen wrote:
> > On Sun, 6 Mar 2022, Lukas Wunner wrote:
> > > On Wed, Mar 02, 2022 at 11:56:05AM +0200, Ilpo Järvinen wrote:
> > > > This change is necessary for supporting devices with RS485
> > > > multipoint addressing [*].
> > > 
> > > If this is only used with RS485, why can't we just store the
> > > addresses in struct serial_rs485 and use the existing TIOCSRS485
> > > and TIOCGRS485 ioctls?  There's 20 bytes of padding left in
> > > struct serial_rs485 which you could use.  No need to add more
> > > user-space ABI.
> > 
> > It could if it is agreed that serial multipoint addressing is just
> > a thing in RS-485 and nowhere else? In that case, there is no point
> > in adding more generic support for it.
> 
> It's just that the above-quoted sentence in the commit message
> specifically mentions RS485.

That sentence is just to justify why addressing mode is needed,
not to take a stance on whether it is only used with RS485 or not.

> If you intend to use it with RS232
> as well, that should be made explicit, otherwise one wonders why
> it wasn't integrated into struct serial_rs485.
> 
> I have no idea how common 9th bit addressing mode is with RS232.
> Goggle turns up links saying it's mainly used with RS485, "but also
> RS232".  Since RS232 isn't a bus but a point-to-point link,
> 9th bit addressing doesn't seem to make as much sense.

While I don't know any better, I can image though that with an 
RS232-to-RS485 converter, it could make some sense.

If I put them back to serial_rs485 / rs485 config, it's basically just 
where I initially started from with this patchset (offlist).


-- 
 i.


Re: [RFC PATCH 6/7] serial: General support for multipoint addresses

2022-03-07 Thread Ilpo Järvinen
On Sun, 6 Mar 2022, Lukas Wunner wrote:

> On Wed, Mar 02, 2022 at 11:56:05AM +0200, Ilpo Järvinen wrote:
> 
> > This change is necessary for supporting devices with RS485
> > multipoint addressing [*].
> 
> If this is only used with RS485, why can't we just store the
> addresses in struct serial_rs485 and use the existing TIOCSRS485
> and TIOCGRS485 ioctls?  There's 20 bytes of padding left in
> struct serial_rs485 which you could use.  No need to add more
> user-space ABI.

It could if it is agreed that serial multipoint addressing is just
a thing in RS-485 and nowhere else? In that case, there is no point
in adding more generic support for it.

> > [*] 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.
> 
> Is 9th bit addressing actually used by an Intel customer or was
> it implemented just for feature completeness? I think this mode
> isn't used often (I've never seen a use case myself), primarily
> because it requires disabling parity.

On what basis? ...The datasheet I'm looking at has a timing diagram 
with both D8 (9th bit) and parity so I think your information must be
incorrect. I don't have direct contacts with customers but I'm told
it's important for other org's customers.


-- 
 i.

[RFC PATCH 6/7] serial: General support for multipoint addresses

2022-03-02 Thread Ilpo Järvinen
This patch adds 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-...@vger.kernel.org
Cc: Richard Henderson 
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: linux...@vger.kernel.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Chris Zankel 
Cc: Max Filippov 
Cc: linux-xte...@linux-xtensa.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 .../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 ++-
 include/linux/serial_core.h   |  6 ++
 include/uapi/asm-generic/ioctls.h |  3 +
 include/uapi/linux/serial.h   |  8 +++
 13 files changed, 123 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) */

[RFC PATCH 5/7] serial: termbits: ADDRB to indicate 9th bit addressing mode

2022-03-02 Thread Ilpo Järvinen
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-...@vger.kernel.org
Cc: Richard Henderson 
Cc: Ivan Kokshaysky 
Cc: Matt Turner 
Cc: linux-al...@vger.kernel.org
Cc: Thomas Bogendoerfer 
Cc: linux-m...@vger.kernel.org
Cc: "James E.J. Bottomley" 
Cc: Helge Deller 
Cc: linux-par...@vger.kernel.org
Cc: Michael Ellerman 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: linuxppc-dev@lists.ozlabs.org
Cc: "David S. Miller" 
Cc: sparcli...@vger.kernel.org
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-...@vger.kernel.org
Signed-off-by: Ilpo Järvinen 
---
 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/tty/amiserial.c  | 6 +-
 drivers/tty/moxa.c   | 1 +
 drivers/tty/mxser.c  | 1 +
 drivers/tty/serial/serial_core.c | 2 ++
 drivers/tty/tty_ioctl.c  | 2 ++
 drivers/usb/serial/usb-serial.c  | 5 +++--
 include/uapi/asm-generic/termbits.h  | 1 +
 12 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/termbits.h 
b/arch/alpha/include/uapi/asm/termbits.h
index 4575ba34a0ea..285169c794ec 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  01000   /* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
 
diff --git a/arch/mips/include/uapi/asm/termbits.h 
b/arch/mips/include/uapi/asm/termbits.h
index dfeffba729b7..e7ea31cfec78 100644
--- a/arch/mips/include/uapi/asm/termbits.h
+++ b/arch/mips/include/uapi/asm/termbits.h
@@ -181,6 +181,7 @@ struct ktermios {
 #define B300 0010015
 #define B350 0010016
 #define B400 0010017
+#define ADDRB002   /* address bit */
 #define CIBAUD   00200360  /* input baud rate */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
diff --git a/arch/parisc/include/uapi/asm/termbits.h 
b/arch/parisc/include/uapi/asm/termbits.h
index 40e920f8d683..629be061f5d5 100644
--- a/arch/parisc/include/uapi/asm/termbits.h
+++ b/arch/parisc/include/uapi/asm/termbits.h
@@ -158,6 +158,7 @@ struct ktermios {
 #define  B300 0010015
 #define  B350 0010016
 #define  B400 0010017
+#define ADDRB002   /* address bit */
 #define CIBAUD00200360 /* input baud rate */
 #define CMSPAR0100  /* mark or space (stick) parity */
 #define CRTSCTS   0200  /* flow control */
diff --git a/arch/powerpc/include/uapi/asm/termbits.h 
b/arch/powerpc/include/uapi/asm/termbits.h
index ed18bc61f63d..1b778ac562a4 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  0004
 
 #define CLOCAL 0010
+#define ADDRB  0020/* address bit */
 #define CMSPAR   0100  /* mark or space (stick) parity */
 #define CRTSCTS  0200  /* flow control */
 
diff --git a/arch/sparc/include/uapi/asm/termbits.h 
b/arch/sparc/include/uapi/asm/termbits.h
index ce5ad5d0f105..4ad60c4acf65 100644
--- a/arch/sparc/include/uapi/asm/termbits.h
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -200,6 +200,7 @@ struct ktermios {
 #define B300  0x1011
 #define B350  0x1012
 #define B400  0x1013  */
+#define ADDRB0x2000  /* address bit */
 #define CIBAUD   0x100f  /* input baud rate (not used) */
 #define CMSPAR   0x4000  /* mark or space (stick) parity */
 #define CRTSCTS  0x8000  /* flow control */
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;

Re: Proposed prom parse fix + moving.

2009-04-17 Thread Ilpo Järvinen
On Fri, 17 Apr 2009, Michal Simek wrote:

 Grant Likely wrote:
  On Fri, Apr 17, 2009 at 12:08 AM, Michal Simek mon...@monstr.eu wrote:
  Hi All,
 
  I have got email from Ilpo about prom_parse file.
  I take this file from powerpc. Who did write prom_parse file and take care 
  about?
  
  Posting to the linuxppc-dev list is sufficient to start.  There are
  several people who may be interested.
  
  BTW: What about to move prom_parse file to any generic location as we 
  discussed in past?
  Any volunteer?
  
  I'm kind of working on it.  More specifically, I'm looking at
  factoring out fdt stuff into common code (drivers/of/of_fdt.c). But I
  haven't made a whole lot of progress yet.
  
   Original Message 
  Subject: [RFC!] [PATCH] microblaze: fix bug in error handling
  Date: Thu, 16 Apr 2009 23:05:53 +0300 (EEST)
  From: Ilpo Järvinen ilpo.jarvi...@helsinki.fi
  To: mon...@monstr.eu
  CC: microblaze-ucli...@itee.uq.edu.au
 
  While some version of the patches were on the lkml I read
  some part of the code briefly through but my feedback got
  stuck into postponed emails, so here's one correctness
  related issue I might have found (the rest were just
  cosmetic things).
 
  I'm not sure if the latter return needs the of_node_put or not
  but it seems more likely than not.
  
  Yes, it does.  This change is applicable to
  arch/powerpc/kernel/prom_parse.c too.
 
 ok.
 Ilpo: Can you create patch for both architectures?

Sure, but tomorrow as today is a deadline day :-).

-- 
 i.___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Re: Proposed prom parse fix + moving.

2009-04-17 Thread Ilpo Järvinen
On Fri, 17 Apr 2009, Ilpo Järvinen wrote:

 On Fri, 17 Apr 2009, Michal Simek wrote:
 
  Grant Likely wrote:
   On Fri, Apr 17, 2009 at 12:08 AM, Michal Simek mon...@monstr.eu wrote:
   Hi All,
  
   I have got email from Ilpo about prom_parse file.
   I take this file from powerpc. Who did write prom_parse file and take 
   care about?
   
   Posting to the linuxppc-dev list is sufficient to start.  There are
   several people who may be interested.
   
   BTW: What about to move prom_parse file to any generic location as we 
   discussed in past?
   Any volunteer?
   
   I'm kind of working on it.  More specifically, I'm looking at
   factoring out fdt stuff into common code (drivers/of/of_fdt.c). But I
   haven't made a whole lot of progress yet.
   
    Original Message 
   Subject: [RFC!] [PATCH] microblaze: fix bug in error handling
   Date: Thu, 16 Apr 2009 23:05:53 +0300 (EEST)
   From: Ilpo Järvinen ilpo.jarvi...@helsinki.fi
   To: mon...@monstr.eu
   CC: microblaze-ucli...@itee.uq.edu.au
  
   While some version of the patches were on the lkml I read
   some part of the code briefly through but my feedback got
   stuck into postponed emails, so here's one correctness
   related issue I might have found (the rest were just
   cosmetic things).
  
   I'm not sure if the latter return needs the of_node_put or not
   but it seems more likely than not.
   
   Yes, it does.  This change is applicable to
   arch/powerpc/kernel/prom_parse.c too.
  
  ok.
  Ilpo: Can you create patch for both architectures?
 
 Sure, but tomorrow as today is a deadline day :-).

Ok, here's combined patch for both. I came up with slightly
shorter and (IMHO) nicer variant for -EINVAL assignment than
in the first version.

--
[PATCH] powerpc  microblaze: add missing of_node_put to error handling

While reviewing some microblaze patches a while ago, I noticed
a suspicious error handling in of_irq_map_one(), which turned
out to be a copy from arch/powerpc. Grant Likely
grant.lik...@secretlab.ca confirmed that this is a real bug.

Merge error handling paths using goto with the normal return
path.

Powerppc compile tested.

Signed-off-by: Ilpo Järvinen ilpo.jarvi...@helsinki.fi
---
 arch/microblaze/kernel/prom_parse.c |   11 +--
 arch/powerpc/kernel/prom_parse.c|   11 +--
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/microblaze/kernel/prom_parse.c 
b/arch/microblaze/kernel/prom_parse.c
index ae0352e..d16c32f 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -903,7 +903,7 @@ int of_irq_map_one(struct device_node *device,
struct device_node *p;
const u32 *intspec, *tmp, *addr;
u32 intsize, intlen;
-   int res;
+   int res = -EINVAL;
 
pr_debug(of_irq_map_one: dev=%s, index=%d\n,
device-full_name, index);
@@ -926,21 +926,20 @@ int of_irq_map_one(struct device_node *device,
 
/* Get size of interrupt specifier */
tmp = of_get_property(p, #interrupt-cells, NULL);
-   if (tmp == NULL) {
-   of_node_put(p);
-   return -EINVAL;
-   }
+   if (tmp == NULL)
+   goto out;
intsize = *tmp;
 
pr_debug( intsize=%d intlen=%d\n, intsize, intlen);
 
/* Check index */
if ((index + 1) * intsize  intlen)
-   return -EINVAL;
+   goto out;
 
/* Get new specifier and map it */
res = of_irq_map_raw(p, intspec + index * intsize, intsize,
addr, out_irq);
+out:
of_node_put(p);
return res;
 }
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 8f0856f..8362620 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -971,7 +971,7 @@ int of_irq_map_one(struct device_node *device, int index, 
struct of_irq *out_irq
struct device_node *p;
const u32 *intspec, *tmp, *addr;
u32 intsize, intlen;
-   int res;
+   int res = -EINVAL;
 
DBG(of_irq_map_one: dev=%s, index=%d\n, device-full_name, index);
 
@@ -995,21 +995,20 @@ int of_irq_map_one(struct device_node *device, int index, 
struct of_irq *out_irq
 
/* Get size of interrupt specifier */
tmp = of_get_property(p, #interrupt-cells, NULL);
-   if (tmp == NULL) {
-   of_node_put(p);
-   return -EINVAL;
-   }
+   if (tmp == NULL)
+   goto out;
intsize = *tmp;
 
DBG( intsize=%d intlen=%d\n, intsize, intlen);
 
/* Check index */
if ((index + 1) * intsize  intlen)
-   return -EINVAL;
+   goto out;
 
/* Get new specifier and map it */
res = of_irq_map_raw(p, intspec + index * intsize, intsize,
 addr, out_irq);
+out:
of_node_put(p);
return res;
 }
-- 
1.5.6.5

[PATCH] powerpc/spufs: Remove invalid semicolon after if statement

2008-08-18 Thread Ilpo Järvinen

Signed-off-by: Ilpo Järvinen [EMAIL PROTECTED]
---
 arch/powerpc/platforms/cell/spufs/sched.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/sched.c 
b/arch/powerpc/platforms/cell/spufs/sched.c
index 2deeeba..f7e5af8 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -1030,7 +1030,7 @@ void spuctx_switch_state(struct spu_context *ctx,
node = spu-node;
if (old_state == SPU_UTIL_USER)
atomic_dec(cbe_spu_info[node].busy_spus);
-   if (new_state == SPU_UTIL_USER);
+   if (new_state == SPU_UTIL_USER)
atomic_inc(cbe_spu_info[node].busy_spus);
}
 }
-- 
1.5.2.2
___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev