Message ID | e0251b07-d08f-df4d-7e80-9eba3d3e43af@gmail.com |
---|---|
State | New |
Headers | show |
Series | PCI: Add and use constant PCI_STATUS_ERROR_BITS and helper pci_status_get_and_clear_errors | expand |
On Sat, Feb 29, 2020 at 11:24:23PM +0100, Heiner Kallweit wrote: > Several drivers use the following code sequence: > 1. Read PCI_STATUS > 2. Mask out non-error bits > 3. Action based on error bits set > 4. Write back set error bits to clear them > > As this is a repeated pattern, add a helper to the PCI core. > > Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com> Nit: if you have any reason to revise this, I would prefer "pci_status_get_and_clear_errors()" (with parens) in the subject. > --- > v4: > - improve commit description > --- > drivers/pci/pci.c | 23 +++++++++++++++++++++++ > include/linux/pci.h | 1 + > 2 files changed, 24 insertions(+) > > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index d828ca835..c16b0ba2a 100644 > --- a/drivers/pci/pci.c > +++ b/drivers/pci/pci.c > @@ -173,6 +173,29 @@ unsigned char pci_bus_max_busnr(struct pci_bus *bus) > } > EXPORT_SYMBOL_GPL(pci_bus_max_busnr); > > +/** > + * pci_status_get_and_clear_errors - return and clear error bits in PCI_STATUS > + * @pdev: the PCI device > + * > + * Returns error bits set in PCI_STATUS and clears them. > + */ > +int pci_status_get_and_clear_errors(struct pci_dev *pdev) > +{ > + u16 status; > + int ret; > + > + ret = pci_read_config_word(pdev, PCI_STATUS, &status); > + if (ret != PCIBIOS_SUCCESSFUL) > + return -EIO; > + > + status &= PCI_STATUS_ERROR_BITS; > + if (status) > + pci_write_config_word(pdev, PCI_STATUS, status); > + > + return status; > +} > +EXPORT_SYMBOL_GPL(pci_status_get_and_clear_errors); > + > #ifdef CONFIG_HAS_IOMEM > void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) > { > diff --git a/include/linux/pci.h b/include/linux/pci.h > index 101d71e0a..7beaf51e9 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -1210,6 +1210,7 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags); > bool pci_device_is_present(struct pci_dev *pdev); > void pci_ignore_hotplug(struct pci_dev *dev); > struct pci_dev *pci_real_dma_dev(struct pci_dev *dev); > +int pci_status_get_and_clear_errors(struct pci_dev *pdev); > > int __printf(6, 7) pci_request_irq(struct pci_dev *dev, unsigned int nr, > irq_handler_t handler, irq_handler_t thread_fn, void *dev_id, > -- > 2.25.1 > >
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d828ca835..c16b0ba2a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -173,6 +173,29 @@ unsigned char pci_bus_max_busnr(struct pci_bus *bus) } EXPORT_SYMBOL_GPL(pci_bus_max_busnr); +/** + * pci_status_get_and_clear_errors - return and clear error bits in PCI_STATUS + * @pdev: the PCI device + * + * Returns error bits set in PCI_STATUS and clears them. + */ +int pci_status_get_and_clear_errors(struct pci_dev *pdev) +{ + u16 status; + int ret; + + ret = pci_read_config_word(pdev, PCI_STATUS, &status); + if (ret != PCIBIOS_SUCCESSFUL) + return -EIO; + + status &= PCI_STATUS_ERROR_BITS; + if (status) + pci_write_config_word(pdev, PCI_STATUS, status); + + return status; +} +EXPORT_SYMBOL_GPL(pci_status_get_and_clear_errors); + #ifdef CONFIG_HAS_IOMEM void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 101d71e0a..7beaf51e9 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1210,6 +1210,7 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags); bool pci_device_is_present(struct pci_dev *pdev); void pci_ignore_hotplug(struct pci_dev *dev); struct pci_dev *pci_real_dma_dev(struct pci_dev *dev); +int pci_status_get_and_clear_errors(struct pci_dev *pdev); int __printf(6, 7) pci_request_irq(struct pci_dev *dev, unsigned int nr, irq_handler_t handler, irq_handler_t thread_fn, void *dev_id,
Several drivers use the following code sequence: 1. Read PCI_STATUS 2. Mask out non-error bits 3. Action based on error bits set 4. Write back set error bits to clear them As this is a repeated pattern, add a helper to the PCI core. Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com> --- v4: - improve commit description --- drivers/pci/pci.c | 23 +++++++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 24 insertions(+)