summaryrefslogtreecommitdiff
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-10-02 23:02:10 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-02 23:02:10 -0400
commit954f9ac43b87b44152b8c21163cefd466a87145e (patch)
tree31c4197f975c66c96976948663e6ce844900b41a /drivers/pci/quirks.c
parent1b62ca7bf5775bed048032b7e779561e1fe66aa0 (diff)
parent7fe0b14b725d6d09a1d9e1409bd465cb88b587f9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
There's a Niagara 2 memcpy fix in this tree and I have a Kconfig fix from Dave Jones which requires the sparc-next changes which went upstream yesterday. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 51553179e967..7a451ff56ecc 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3081,17 +3081,36 @@ static int reset_intel_generic_dev(struct pci_dev *dev, int probe)
static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
{
- int pos;
+ int i;
+ u16 status;
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!pos)
- return -ENOTTY;
+ /*
+ * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf
+ *
+ * The 82599 supports FLR on VFs, but FLR support is reported only
+ * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
+ * Therefore, we can't use pcie_flr(), which checks the VF DEVCAP.
+ */
if (probe)
return 0;
- pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_BCR_FLR);
+ /* Wait for Transaction Pending bit clean */
+ for (i = 0; i < 4; i++) {
+ if (i)
+ msleep((1 << (i - 1)) * 100);
+
+ pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto clear;
+ }
+
+ dev_err(&dev->dev, "transaction is not cleared; "
+ "proceeding with reset anyway\n");
+
+clear:
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
+
msleep(100);
return 0;