Commit e7c29885 authored by David S. Miller's avatar David S. Miller

Merge branch...

Merge branch 'PCI-Add-and-use-constant-PCI_STATUS_ERROR_BITS-and-helper-pci_status_get_and_clear_errors'

Heiner Kallweit says:

====================
PCI: Add and use constant PCI_STATUS_ERROR_BITS and helper pci_status_get_and_clear_errors

Several drivers have own definitions for this constant, so move it
to the PCI core. In addition in multiple places the following code
sequence is used:
1. Read PCI_STATUS
2. Mask out non-error bits
3. Action based on set error bits
4. Write back set error bits to clear them

As this is a repeated pattern, add a helper to the PCI core.

Most affected drivers are network drivers. But as it's about core
PCI functionality, I suppose the series should go through the PCI
tree.

v2:
- fix formal issue with cover letter
v3:
- fix dumb typo in patch 7
v4:
- add patches 1-3
- move new constant PCI_STATUS_ERROR_BITS to include/linux/pci.h
- small improvements in commit messages
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5a1c63f1 ec46bf92
...@@ -15,12 +15,6 @@ ...@@ -15,12 +15,6 @@
#define PCI_VPD_ROM_SZ 7L<<14 /* VPD ROM size 0=256, 1=512, ... */ #define PCI_VPD_ROM_SZ 7L<<14 /* VPD ROM size 0=256, 1=512, ... */
#define PCI_REV_DESC 1<<2 /* Reverse Descriptor bytes */ #define PCI_REV_DESC 1<<2 /* Reverse Descriptor bytes */
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
PCI_STATUS_REC_MASTER_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
enum csr_regs { enum csr_regs {
B0_RAP = 0x0000, B0_RAP = 0x0000,
B0_CTST = 0x0004, B0_CTST = 0x0004,
......
...@@ -252,12 +252,6 @@ enum { ...@@ -252,12 +252,6 @@ enum {
}; };
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
PCI_STATUS_REC_MASTER_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
enum csr_regs { enum csr_regs {
B0_RAP = 0x0000, B0_RAP = 0x0000,
B0_CTST = 0x0004, B0_CTST = 0x0004,
......
...@@ -4357,13 +4357,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) ...@@ -4357,13 +4357,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
{ {
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev; struct pci_dev *pdev = tp->pci_dev;
u16 pci_status, pci_cmd; int pci_status_errs;
u16 pci_cmd;
pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
pci_read_config_word(pdev, PCI_STATUS, &pci_status);
netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status = 0x%04x)\n", pci_status_errs = pci_status_get_and_clear_errors(pdev);
pci_cmd, pci_status);
netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n",
pci_cmd, pci_status_errs);
/* /*
* The recovery sequence below admits a very elaborated explanation: * The recovery sequence below admits a very elaborated explanation:
...@@ -4380,11 +4382,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) ...@@ -4380,11 +4382,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
pci_write_config_word(pdev, PCI_STATUS,
pci_status & (PCI_STATUS_DETECTED_PARITY |
PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT));
rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
} }
......
...@@ -1716,34 +1716,26 @@ static int cas_pci_interrupt(struct net_device *dev, struct cas *cp, ...@@ -1716,34 +1716,26 @@ static int cas_pci_interrupt(struct net_device *dev, struct cas *cp,
pr_cont("\n"); pr_cont("\n");
if (stat & PCI_ERR_OTHER) { if (stat & PCI_ERR_OTHER) {
u16 cfg; int pci_errs;
/* Interrogate PCI config space for the /* Interrogate PCI config space for the
* true cause. * true cause.
*/ */
pci_read_config_word(cp->pdev, PCI_STATUS, &cfg); pci_errs = pci_status_get_and_clear_errors(cp->pdev);
netdev_err(dev, "Read PCI cfg space status [%04x]\n", cfg);
if (cfg & PCI_STATUS_PARITY) netdev_err(dev, "PCI status errors[%04x]\n", pci_errs);
if (pci_errs & PCI_STATUS_PARITY)
netdev_err(dev, "PCI parity error detected\n"); netdev_err(dev, "PCI parity error detected\n");
if (cfg & PCI_STATUS_SIG_TARGET_ABORT) if (pci_errs & PCI_STATUS_SIG_TARGET_ABORT)
netdev_err(dev, "PCI target abort\n"); netdev_err(dev, "PCI target abort\n");
if (cfg & PCI_STATUS_REC_TARGET_ABORT) if (pci_errs & PCI_STATUS_REC_TARGET_ABORT)
netdev_err(dev, "PCI master acks target abort\n"); netdev_err(dev, "PCI master acks target abort\n");
if (cfg & PCI_STATUS_REC_MASTER_ABORT) if (pci_errs & PCI_STATUS_REC_MASTER_ABORT)
netdev_err(dev, "PCI master abort\n"); netdev_err(dev, "PCI master abort\n");
if (cfg & PCI_STATUS_SIG_SYSTEM_ERROR) if (pci_errs & PCI_STATUS_SIG_SYSTEM_ERROR)
netdev_err(dev, "PCI system error SERR#\n"); netdev_err(dev, "PCI system error SERR#\n");
if (cfg & PCI_STATUS_DETECTED_PARITY) if (pci_errs & PCI_STATUS_DETECTED_PARITY)
netdev_err(dev, "PCI parity error\n"); netdev_err(dev, "PCI parity error\n");
/* Write the error bits back to clear them. */
cfg &= (PCI_STATUS_PARITY |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR |
PCI_STATUS_DETECTED_PARITY);
pci_write_config_word(cp->pdev, PCI_STATUS, cfg);
} }
/* For all PCI errors, we should reset the chip. */ /* For all PCI errors, we should reset the chip. */
......
...@@ -545,37 +545,25 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta ...@@ -545,37 +545,25 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
} }
if (pci_estat & GREG_PCIESTAT_OTHER) { if (pci_estat & GREG_PCIESTAT_OTHER) {
u16 pci_cfg_stat; int pci_errs;
/* Interrogate PCI config space for the /* Interrogate PCI config space for the
* true cause. * true cause.
*/ */
pci_read_config_word(gp->pdev, PCI_STATUS, pci_errs = pci_status_get_and_clear_errors(gp->pdev);
&pci_cfg_stat); netdev_err(dev, "PCI status errors[%04x]\n", pci_errs);
netdev_err(dev, "Read PCI cfg space status [%04x]\n", if (pci_errs & PCI_STATUS_PARITY)
pci_cfg_stat);
if (pci_cfg_stat & PCI_STATUS_PARITY)
netdev_err(dev, "PCI parity error detected\n"); netdev_err(dev, "PCI parity error detected\n");
if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT) if (pci_errs & PCI_STATUS_SIG_TARGET_ABORT)
netdev_err(dev, "PCI target abort\n"); netdev_err(dev, "PCI target abort\n");
if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT) if (pci_errs & PCI_STATUS_REC_TARGET_ABORT)
netdev_err(dev, "PCI master acks target abort\n"); netdev_err(dev, "PCI master acks target abort\n");
if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT) if (pci_errs & PCI_STATUS_REC_MASTER_ABORT)
netdev_err(dev, "PCI master abort\n"); netdev_err(dev, "PCI master abort\n");
if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR) if (pci_errs & PCI_STATUS_SIG_SYSTEM_ERROR)
netdev_err(dev, "PCI system error SERR#\n"); netdev_err(dev, "PCI system error SERR#\n");
if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY) if (pci_errs & PCI_STATUS_DETECTED_PARITY)
netdev_err(dev, "PCI parity error\n"); netdev_err(dev, "PCI parity error\n");
/* Write the error bits back to clear them. */
pci_cfg_stat &= (PCI_STATUS_PARITY |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR |
PCI_STATUS_DETECTED_PARITY);
pci_write_config_word(gp->pdev,
PCI_STATUS, pci_cfg_stat);
} }
/* For all PCI errors, we should reset the chip. */ /* For all PCI errors, we should reset the chip. */
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include "h/supern_2.h" #include "h/supern_2.h"
#include "h/skfbiinc.h" #include "h/skfbiinc.h"
#include <linux/bitrev.h> #include <linux/bitrev.h>
#include <linux/pci_regs.h> #include <linux/pci.h>
#ifndef lint #ifndef lint
static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ; static const char ID_sccs[] = "@(#)drvfbi.c 1.63 99/02/11 (C) SK " ;
...@@ -112,7 +112,7 @@ static void card_start(struct s_smc *smc) ...@@ -112,7 +112,7 @@ static void card_start(struct s_smc *smc)
*/ */
outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */ outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */
word = inpw(PCI_C(PCI_STATUS)) ; word = inpw(PCI_C(PCI_STATUS)) ;
outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ; outpw(PCI_C(PCI_STATUS), word | PCI_STATUS_ERROR_BITS);
outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */ outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */
/* /*
......
...@@ -33,11 +33,6 @@ ...@@ -33,11 +33,6 @@
*/ */
#define I2C_ADDR_VPD 0xA0 /* I2C address for the VPD EEPROM */ #define I2C_ADDR_VPD 0xA0 /* I2C address for the VPD EEPROM */
#define PCI_ERRBITS (PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_PARITY)
/* /*
* Control Register File: * Control Register File:
* Bank 0 * Bank 0
......
...@@ -50,12 +50,7 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = { ...@@ -50,12 +50,7 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
(PCI_STATUS_CAP_LIST | PCI_STATUS_66MHZ | (PCI_STATUS_CAP_LIST | PCI_STATUS_66MHZ |
PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MASK) << 16), PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MASK) << 16),
.rsvd = GENMASK(15, 10) | ((BIT(6) | GENMASK(3, 0)) << 16), .rsvd = GENMASK(15, 10) | ((BIT(6) | GENMASK(3, 0)) << 16),
.w1c = (PCI_STATUS_PARITY | .w1c = PCI_STATUS_ERROR_BITS << 16,
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR |
PCI_STATUS_DETECTED_PARITY) << 16,
}, },
[PCI_CLASS_REVISION / 4] = { .ro = ~0 }, [PCI_CLASS_REVISION / 4] = { .ro = ~0 },
...@@ -100,12 +95,7 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = { ...@@ -100,12 +95,7 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
PCI_STATUS_DEVSEL_MASK) << 16) | PCI_STATUS_DEVSEL_MASK) << 16) |
GENMASK(11, 8) | GENMASK(3, 0)), GENMASK(11, 8) | GENMASK(3, 0)),
.w1c = (PCI_STATUS_PARITY | .w1c = PCI_STATUS_ERROR_BITS << 16,
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR |
PCI_STATUS_DETECTED_PARITY) << 16,
.rsvd = ((BIT(6) | GENMASK(4, 0)) << 16), .rsvd = ((BIT(6) | GENMASK(4, 0)) << 16),
}, },
......
...@@ -173,6 +173,29 @@ unsigned char pci_bus_max_busnr(struct pci_bus *bus) ...@@ -173,6 +173,29 @@ unsigned char pci_bus_max_busnr(struct pci_bus *bus)
} }
EXPORT_SYMBOL_GPL(pci_bus_max_busnr); 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 #ifdef CONFIG_HAS_IOMEM
void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
{ {
......
...@@ -42,6 +42,13 @@ ...@@ -42,6 +42,13 @@
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
PCI_STATUS_SIG_SYSTEM_ERROR | \
PCI_STATUS_REC_MASTER_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_SIG_TARGET_ABORT | \
PCI_STATUS_PARITY)
/* /*
* The PCI interface treats multi-function devices as independent * The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded * devices. The slot/function address of each device is encoded
...@@ -1203,6 +1210,7 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags); ...@@ -1203,6 +1210,7 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags);
bool pci_device_is_present(struct pci_dev *pdev); bool pci_device_is_present(struct pci_dev *pdev);
void pci_ignore_hotplug(struct pci_dev *dev); void pci_ignore_hotplug(struct pci_dev *dev);
struct pci_dev *pci_real_dma_dev(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, 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, irq_handler_t handler, irq_handler_t thread_fn, void *dev_id,
......
...@@ -271,13 +271,8 @@ static void snd_bt87x_free_risc(struct snd_bt87x *chip) ...@@ -271,13 +271,8 @@ static void snd_bt87x_free_risc(struct snd_bt87x *chip)
static void snd_bt87x_pci_error(struct snd_bt87x *chip, unsigned int status) static void snd_bt87x_pci_error(struct snd_bt87x *chip, unsigned int status)
{ {
u16 pci_status; int pci_status = pci_status_get_and_clear_errors(chip->pci);
pci_read_config_word(chip->pci, PCI_STATUS, &pci_status);
pci_status &= PCI_STATUS_PARITY | PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_REC_MASTER_ABORT |
PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY;
pci_write_config_word(chip->pci, PCI_STATUS, pci_status);
if (pci_status != PCI_STATUS_DETECTED_PARITY) if (pci_status != PCI_STATUS_DETECTED_PARITY)
dev_err(chip->card->dev, dev_err(chip->card->dev,
"Aieee - PCI error! status %#08x, PCI status %#04x\n", "Aieee - PCI error! status %#08x, PCI status %#04x\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment