Skip to content

Commit e7c2988

Browse files
committed
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: David S. Miller <davem@davemloft.net>
2 parents 5a1c63f + ec46bf9 commit e7c2988

File tree

11 files changed

+61
-85
lines changed

11 files changed

+61
-85
lines changed

drivers/net/ethernet/marvell/skge.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515
#define PCI_VPD_ROM_SZ 7L<<14 /* VPD ROM size 0=256, 1=512, ... */
1616
#define PCI_REV_DESC 1<<2 /* Reverse Descriptor bytes */
1717

18-
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
19-
PCI_STATUS_SIG_SYSTEM_ERROR | \
20-
PCI_STATUS_REC_MASTER_ABORT | \
21-
PCI_STATUS_REC_TARGET_ABORT | \
22-
PCI_STATUS_PARITY)
23-
2418
enum csr_regs {
2519
B0_RAP = 0x0000,
2620
B0_CTST = 0x0004,

drivers/net/ethernet/marvell/sky2.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,6 @@ enum {
252252
};
253253

254254

255-
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
256-
PCI_STATUS_SIG_SYSTEM_ERROR | \
257-
PCI_STATUS_REC_MASTER_ABORT | \
258-
PCI_STATUS_REC_TARGET_ABORT | \
259-
PCI_STATUS_PARITY)
260-
261255
enum csr_regs {
262256
B0_RAP = 0x0000,
263257
B0_CTST = 0x0004,

drivers/net/ethernet/realtek/r8169_main.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4357,13 +4357,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
43574357
{
43584358
struct rtl8169_private *tp = netdev_priv(dev);
43594359
struct pci_dev *pdev = tp->pci_dev;
4360-
u16 pci_status, pci_cmd;
4360+
int pci_status_errs;
4361+
u16 pci_cmd;
43614362

43624363
pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
4363-
pci_read_config_word(pdev, PCI_STATUS, &pci_status);
43644364

4365-
netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status = 0x%04x)\n",
4366-
pci_cmd, pci_status);
4365+
pci_status_errs = pci_status_get_and_clear_errors(pdev);
4366+
4367+
netif_err(tp, intr, dev, "PCI error (cmd = 0x%04x, status_errs = 0x%04x)\n",
4368+
pci_cmd, pci_status_errs);
43674369

43684370
/*
43694371
* The recovery sequence below admits a very elaborated explanation:
@@ -4380,11 +4382,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
43804382

43814383
pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
43824384

4383-
pci_write_config_word(pdev, PCI_STATUS,
4384-
pci_status & (PCI_STATUS_DETECTED_PARITY |
4385-
PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_REC_MASTER_ABORT |
4386-
PCI_STATUS_REC_TARGET_ABORT | PCI_STATUS_SIG_TARGET_ABORT));
4387-
43884385
rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
43894386
}
43904387

drivers/net/ethernet/sun/cassini.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,34 +1716,26 @@ static int cas_pci_interrupt(struct net_device *dev, struct cas *cp,
17161716
pr_cont("\n");
17171717

17181718
if (stat & PCI_ERR_OTHER) {
1719-
u16 cfg;
1719+
int pci_errs;
17201720

17211721
/* Interrogate PCI config space for the
17221722
* true cause.
17231723
*/
1724-
pci_read_config_word(cp->pdev, PCI_STATUS, &cfg);
1725-
netdev_err(dev, "Read PCI cfg space status [%04x]\n", cfg);
1726-
if (cfg & PCI_STATUS_PARITY)
1724+
pci_errs = pci_status_get_and_clear_errors(cp->pdev);
1725+
1726+
netdev_err(dev, "PCI status errors[%04x]\n", pci_errs);
1727+
if (pci_errs & PCI_STATUS_PARITY)
17271728
netdev_err(dev, "PCI parity error detected\n");
1728-
if (cfg & PCI_STATUS_SIG_TARGET_ABORT)
1729+
if (pci_errs & PCI_STATUS_SIG_TARGET_ABORT)
17291730
netdev_err(dev, "PCI target abort\n");
1730-
if (cfg & PCI_STATUS_REC_TARGET_ABORT)
1731+
if (pci_errs & PCI_STATUS_REC_TARGET_ABORT)
17311732
netdev_err(dev, "PCI master acks target abort\n");
1732-
if (cfg & PCI_STATUS_REC_MASTER_ABORT)
1733+
if (pci_errs & PCI_STATUS_REC_MASTER_ABORT)
17331734
netdev_err(dev, "PCI master abort\n");
1734-
if (cfg & PCI_STATUS_SIG_SYSTEM_ERROR)
1735+
if (pci_errs & PCI_STATUS_SIG_SYSTEM_ERROR)
17351736
netdev_err(dev, "PCI system error SERR#\n");
1736-
if (cfg & PCI_STATUS_DETECTED_PARITY)
1737+
if (pci_errs & PCI_STATUS_DETECTED_PARITY)
17371738
netdev_err(dev, "PCI parity error\n");
1738-
1739-
/* Write the error bits back to clear them. */
1740-
cfg &= (PCI_STATUS_PARITY |
1741-
PCI_STATUS_SIG_TARGET_ABORT |
1742-
PCI_STATUS_REC_TARGET_ABORT |
1743-
PCI_STATUS_REC_MASTER_ABORT |
1744-
PCI_STATUS_SIG_SYSTEM_ERROR |
1745-
PCI_STATUS_DETECTED_PARITY);
1746-
pci_write_config_word(cp->pdev, PCI_STATUS, cfg);
17471739
}
17481740

17491741
/* For all PCI errors, we should reset the chip. */

drivers/net/ethernet/sun/sungem.c

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -545,37 +545,25 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta
545545
}
546546

547547
if (pci_estat & GREG_PCIESTAT_OTHER) {
548-
u16 pci_cfg_stat;
548+
int pci_errs;
549549

550550
/* Interrogate PCI config space for the
551551
* true cause.
552552
*/
553-
pci_read_config_word(gp->pdev, PCI_STATUS,
554-
&pci_cfg_stat);
555-
netdev_err(dev, "Read PCI cfg space status [%04x]\n",
556-
pci_cfg_stat);
557-
if (pci_cfg_stat & PCI_STATUS_PARITY)
553+
pci_errs = pci_status_get_and_clear_errors(gp->pdev);
554+
netdev_err(dev, "PCI status errors[%04x]\n", pci_errs);
555+
if (pci_errs & PCI_STATUS_PARITY)
558556
netdev_err(dev, "PCI parity error detected\n");
559-
if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT)
557+
if (pci_errs & PCI_STATUS_SIG_TARGET_ABORT)
560558
netdev_err(dev, "PCI target abort\n");
561-
if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT)
559+
if (pci_errs & PCI_STATUS_REC_TARGET_ABORT)
562560
netdev_err(dev, "PCI master acks target abort\n");
563-
if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT)
561+
if (pci_errs & PCI_STATUS_REC_MASTER_ABORT)
564562
netdev_err(dev, "PCI master abort\n");
565-
if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR)
563+
if (pci_errs & PCI_STATUS_SIG_SYSTEM_ERROR)
566564
netdev_err(dev, "PCI system error SERR#\n");
567-
if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY)
565+
if (pci_errs & PCI_STATUS_DETECTED_PARITY)
568566
netdev_err(dev, "PCI parity error\n");
569-
570-
/* Write the error bits back to clear them. */
571-
pci_cfg_stat &= (PCI_STATUS_PARITY |
572-
PCI_STATUS_SIG_TARGET_ABORT |
573-
PCI_STATUS_REC_TARGET_ABORT |
574-
PCI_STATUS_REC_MASTER_ABORT |
575-
PCI_STATUS_SIG_SYSTEM_ERROR |
576-
PCI_STATUS_DETECTED_PARITY);
577-
pci_write_config_word(gp->pdev,
578-
PCI_STATUS, pci_cfg_stat);
579567
}
580568

581569
/* For all PCI errors, we should reset the chip. */

drivers/net/fddi/skfp/drvfbi.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "h/supern_2.h"
2121
#include "h/skfbiinc.h"
2222
#include <linux/bitrev.h>
23-
#include <linux/pci_regs.h>
23+
#include <linux/pci.h>
2424

2525
#ifndef lint
2626
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)
112112
*/
113113
outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_ON) ; /* enable for writes */
114114
word = inpw(PCI_C(PCI_STATUS)) ;
115-
outpw(PCI_C(PCI_STATUS), word | PCI_ERRBITS) ;
115+
outpw(PCI_C(PCI_STATUS), word | PCI_STATUS_ERROR_BITS);
116116
outp(ADDR(B0_TST_CTRL), TST_CFG_WRITE_OFF) ; /* disable writes */
117117

118118
/*

drivers/net/fddi/skfp/h/skfbi.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,6 @@
3333
*/
3434
#define I2C_ADDR_VPD 0xA0 /* I2C address for the VPD EEPROM */
3535

36-
37-
#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)
38-
39-
40-
4136
/*
4237
* Control Register File:
4338
* Bank 0

drivers/pci/pci-bridge-emul.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,7 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
5050
(PCI_STATUS_CAP_LIST | PCI_STATUS_66MHZ |
5151
PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MASK) << 16),
5252
.rsvd = GENMASK(15, 10) | ((BIT(6) | GENMASK(3, 0)) << 16),
53-
.w1c = (PCI_STATUS_PARITY |
54-
PCI_STATUS_SIG_TARGET_ABORT |
55-
PCI_STATUS_REC_TARGET_ABORT |
56-
PCI_STATUS_REC_MASTER_ABORT |
57-
PCI_STATUS_SIG_SYSTEM_ERROR |
58-
PCI_STATUS_DETECTED_PARITY) << 16,
53+
.w1c = PCI_STATUS_ERROR_BITS << 16,
5954
},
6055
[PCI_CLASS_REVISION / 4] = { .ro = ~0 },
6156

@@ -100,12 +95,7 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
10095
PCI_STATUS_DEVSEL_MASK) << 16) |
10196
GENMASK(11, 8) | GENMASK(3, 0)),
10297

103-
.w1c = (PCI_STATUS_PARITY |
104-
PCI_STATUS_SIG_TARGET_ABORT |
105-
PCI_STATUS_REC_TARGET_ABORT |
106-
PCI_STATUS_REC_MASTER_ABORT |
107-
PCI_STATUS_SIG_SYSTEM_ERROR |
108-
PCI_STATUS_DETECTED_PARITY) << 16,
98+
.w1c = PCI_STATUS_ERROR_BITS << 16,
10999

110100
.rsvd = ((BIT(6) | GENMASK(4, 0)) << 16),
111101
},

drivers/pci/pci.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,29 @@ unsigned char pci_bus_max_busnr(struct pci_bus *bus)
173173
}
174174
EXPORT_SYMBOL_GPL(pci_bus_max_busnr);
175175

176+
/**
177+
* pci_status_get_and_clear_errors - return and clear error bits in PCI_STATUS
178+
* @pdev: the PCI device
179+
*
180+
* Returns error bits set in PCI_STATUS and clears them.
181+
*/
182+
int pci_status_get_and_clear_errors(struct pci_dev *pdev)
183+
{
184+
u16 status;
185+
int ret;
186+
187+
ret = pci_read_config_word(pdev, PCI_STATUS, &status);
188+
if (ret != PCIBIOS_SUCCESSFUL)
189+
return -EIO;
190+
191+
status &= PCI_STATUS_ERROR_BITS;
192+
if (status)
193+
pci_write_config_word(pdev, PCI_STATUS, status);
194+
195+
return status;
196+
}
197+
EXPORT_SYMBOL_GPL(pci_status_get_and_clear_errors);
198+
176199
#ifdef CONFIG_HAS_IOMEM
177200
void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
178201
{

include/linux/pci.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@
4242

4343
#include <linux/pci_ids.h>
4444

45+
#define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \
46+
PCI_STATUS_SIG_SYSTEM_ERROR | \
47+
PCI_STATUS_REC_MASTER_ABORT | \
48+
PCI_STATUS_REC_TARGET_ABORT | \
49+
PCI_STATUS_SIG_TARGET_ABORT | \
50+
PCI_STATUS_PARITY)
51+
4552
/*
4653
* The PCI interface treats multi-function devices as independent
4754
* 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);
12031210
bool pci_device_is_present(struct pci_dev *pdev);
12041211
void pci_ignore_hotplug(struct pci_dev *dev);
12051212
struct pci_dev *pci_real_dma_dev(struct pci_dev *dev);
1213+
int pci_status_get_and_clear_errors(struct pci_dev *pdev);
12061214

12071215
int __printf(6, 7) pci_request_irq(struct pci_dev *dev, unsigned int nr,
12081216
irq_handler_t handler, irq_handler_t thread_fn, void *dev_id,

0 commit comments

Comments
 (0)