diff options
-rw-r--r-- | drivers/pci/pci.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 5737b8a9a732..0b3e20f1b6f7 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2028,18 +2028,24 @@ static int __pcie_flr(struct pci_dev *dev, int probe) | |||
2028 | pci_block_user_cfg_access(dev); | 2028 | pci_block_user_cfg_access(dev); |
2029 | 2029 | ||
2030 | /* Wait for Transaction Pending bit clean */ | 2030 | /* Wait for Transaction Pending bit clean */ |
2031 | pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); | ||
2032 | if (!(status & PCI_EXP_DEVSTA_TRPND)) | ||
2033 | goto transaction_done; | ||
2034 | |||
2031 | msleep(100); | 2035 | msleep(100); |
2032 | pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); | 2036 | pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); |
2033 | if (status & PCI_EXP_DEVSTA_TRPND) { | 2037 | if (!(status & PCI_EXP_DEVSTA_TRPND)) |
2034 | dev_info(&dev->dev, "Busy after 100ms while trying to reset; " | 2038 | goto transaction_done; |
2039 | |||
2040 | dev_info(&dev->dev, "Busy after 100ms while trying to reset; " | ||
2035 | "sleeping for 1 second\n"); | 2041 | "sleeping for 1 second\n"); |
2036 | ssleep(1); | 2042 | ssleep(1); |
2037 | pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); | 2043 | pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status); |
2038 | if (status & PCI_EXP_DEVSTA_TRPND) | 2044 | if (status & PCI_EXP_DEVSTA_TRPND) |
2039 | dev_info(&dev->dev, "Still busy after 1s; " | 2045 | dev_info(&dev->dev, "Still busy after 1s; " |
2040 | "proceeding with reset anyway\n"); | 2046 | "proceeding with reset anyway\n"); |
2041 | } | ||
2042 | 2047 | ||
2048 | transaction_done: | ||
2043 | pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL, | 2049 | pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL, |
2044 | PCI_EXP_DEVCTL_BCR_FLR); | 2050 | PCI_EXP_DEVCTL_BCR_FLR); |
2045 | mdelay(100); | 2051 | mdelay(100); |
@@ -2066,18 +2072,24 @@ static int __pci_af_flr(struct pci_dev *dev, int probe) | |||
2066 | pci_block_user_cfg_access(dev); | 2072 | pci_block_user_cfg_access(dev); |
2067 | 2073 | ||
2068 | /* Wait for Transaction Pending bit clean */ | 2074 | /* Wait for Transaction Pending bit clean */ |
2075 | pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); | ||
2076 | if (!(status & PCI_AF_STATUS_TP)) | ||
2077 | goto transaction_done; | ||
2078 | |||
2069 | msleep(100); | 2079 | msleep(100); |
2070 | pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); | 2080 | pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); |
2071 | if (status & PCI_AF_STATUS_TP) { | 2081 | if (!(status & PCI_AF_STATUS_TP)) |
2072 | dev_info(&dev->dev, "Busy after 100ms while trying to" | 2082 | goto transaction_done; |
2073 | " reset; sleeping for 1 second\n"); | 2083 | |
2074 | ssleep(1); | 2084 | dev_info(&dev->dev, "Busy after 100ms while trying to" |
2075 | pci_read_config_byte(dev, | 2085 | " reset; sleeping for 1 second\n"); |
2076 | cappos + PCI_AF_STATUS, &status); | 2086 | ssleep(1); |
2077 | if (status & PCI_AF_STATUS_TP) | 2087 | pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status); |
2078 | dev_info(&dev->dev, "Still busy after 1s; " | 2088 | if (status & PCI_AF_STATUS_TP) |
2079 | "proceeding with reset anyway\n"); | 2089 | dev_info(&dev->dev, "Still busy after 1s; " |
2080 | } | 2090 | "proceeding with reset anyway\n"); |
2091 | |||
2092 | transaction_done: | ||
2081 | pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); | 2093 | pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR); |
2082 | mdelay(100); | 2094 | mdelay(100); |
2083 | 2095 | ||