[PATCH v5 7/7] PCI: Create helper to print TLP Header and Prefix Log
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()
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
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()
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
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
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
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
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()
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
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
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
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
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
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()
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()
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
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()
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
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
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()
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
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()
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
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()
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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()
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()
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
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
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
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
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
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
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
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
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()
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
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
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
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
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
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
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
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
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()
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()
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
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
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
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
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
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
- 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.
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.
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
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