diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-01-30 14:37:55 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-02-07 02:00:35 -0500 |
commit | 2d42d21f11c20b94ea0222637e20e2630845afe4 (patch) | |
tree | ed740ea45977801bb9017291449a8c8fa57bb4fe | |
parent | 08c06d8a9063c81f6a21c9f275aa1ee49d4bf380 (diff) |
[PATCH] sky2: pci config space checking
There were bugs in mmconfig access to PCI space, up to and
include 2.6.16-rc1. These prevented the sky2 driver from being
able to clear PCI express errors.
This patch makes the driver check (during probe), for errors
in PCI config access and fail.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r-- | drivers/net/sky2.c | 31 | ||||
-rw-r--r-- | drivers/net/sky2.h | 8 |
2 files changed, 22 insertions, 17 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index c236c5984743..e04c4f40e0bb 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -2142,7 +2142,7 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2142 | { | 2142 | { |
2143 | u16 status; | 2143 | u16 status; |
2144 | u8 t8, pmd_type; | 2144 | u8 t8, pmd_type; |
2145 | int i; | 2145 | int i, err; |
2146 | 2146 | ||
2147 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2147 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2148 | 2148 | ||
@@ -2164,19 +2164,24 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2164 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2164 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
2165 | 2165 | ||
2166 | /* clear PCI errors, if any */ | 2166 | /* clear PCI errors, if any */ |
2167 | pci_read_config_word(hw->pdev, PCI_STATUS, &status); | 2167 | err = pci_read_config_word(hw->pdev, PCI_STATUS, &status); |
2168 | if (err) | ||
2169 | goto pci_err; | ||
2170 | |||
2168 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2171 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
2169 | pci_write_config_word(hw->pdev, PCI_STATUS, | 2172 | err = pci_write_config_word(hw->pdev, PCI_STATUS, |
2170 | status | PCI_STATUS_ERROR_BITS); | 2173 | status | PCI_STATUS_ERROR_BITS); |
2174 | if (err) | ||
2175 | goto pci_err; | ||
2171 | 2176 | ||
2172 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); | 2177 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
2173 | 2178 | ||
2174 | /* clear any PEX errors */ | 2179 | /* clear any PEX errors */ |
2175 | if (is_pciex(hw)) { | 2180 | if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) { |
2176 | u16 lstat; | 2181 | err = pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, |
2177 | pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, | 2182 | 0xffffffffUL); |
2178 | 0xffffffffUL); | 2183 | if (err) |
2179 | pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat); | 2184 | goto pci_err; |
2180 | } | 2185 | } |
2181 | 2186 | ||
2182 | pmd_type = sky2_read8(hw, B2_PMD_TYP); | 2187 | pmd_type = sky2_read8(hw, B2_PMD_TYP); |
@@ -2288,6 +2293,14 @@ static int sky2_reset(struct sky2_hw *hw) | |||
2288 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); | 2293 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
2289 | 2294 | ||
2290 | return 0; | 2295 | return 0; |
2296 | |||
2297 | pci_err: | ||
2298 | /* This is to catch a BIOS bug workaround where | ||
2299 | * mmconfig table doesn't have other buses. | ||
2300 | */ | ||
2301 | printk(KERN_ERR PFX "%s: can't access PCI config space\n", | ||
2302 | pci_name(hw->pdev)); | ||
2303 | return err; | ||
2291 | } | 2304 | } |
2292 | 2305 | ||
2293 | static u32 sky2_supported_modes(const struct sky2_hw *hw) | 2306 | static u32 sky2_supported_modes(const struct sky2_hw *hw) |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 95518921001c..70525ac501de 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -1867,14 +1867,6 @@ static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg) | |||
1867 | return readb(hw->regs + reg); | 1867 | return readb(hw->regs + reg); |
1868 | } | 1868 | } |
1869 | 1869 | ||
1870 | /* This should probably go away, bus based tweeks suck */ | ||
1871 | static inline int is_pciex(const struct sky2_hw *hw) | ||
1872 | { | ||
1873 | u32 status; | ||
1874 | pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status); | ||
1875 | return (status & PCI_OS_PCI_X) == 0; | ||
1876 | } | ||
1877 | |||
1878 | static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val) | 1870 | static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val) |
1879 | { | 1871 | { |
1880 | writel(val, hw->regs + reg); | 1872 | writel(val, hw->regs + reg); |