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 /drivers/net/sky2.c | |
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>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 31 |
1 files changed, 22 insertions, 9 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) |