PCI: Add pci_wait_for_pending_transaction()
New routine to avoid duplication of code to wait for pending PCI transactions to complete. Signed-off-by: Casey Leedom <leedom@chelsio.com> Signed-off-by: Vipul Pandya <vipul@chelsio.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
3b2f64d00c
commit
3775a209d3
|
@ -3098,19 +3098,17 @@ int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_set_dma_seg_boundary);
|
EXPORT_SYMBOL(pci_set_dma_seg_boundary);
|
||||||
|
|
||||||
static int pcie_flr(struct pci_dev *dev, int probe)
|
/**
|
||||||
|
* pci_wait_for_pending_transaction - waits for pending transaction
|
||||||
|
* @dev: the PCI device to operate on
|
||||||
|
*
|
||||||
|
* Return 0 if transaction is pending 1 otherwise.
|
||||||
|
*/
|
||||||
|
int pci_wait_for_pending_transaction(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 cap;
|
|
||||||
u16 status;
|
u16 status;
|
||||||
|
|
||||||
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
|
|
||||||
if (!(cap & PCI_EXP_DEVCAP_FLR))
|
|
||||||
return -ENOTTY;
|
|
||||||
|
|
||||||
if (probe)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Wait for Transaction Pending bit clean */
|
/* Wait for Transaction Pending bit clean */
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (i)
|
if (i)
|
||||||
|
@ -3118,13 +3116,27 @@ static int pcie_flr(struct pci_dev *dev, int probe)
|
||||||
|
|
||||||
pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
|
pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status);
|
||||||
if (!(status & PCI_EXP_DEVSTA_TRPND))
|
if (!(status & PCI_EXP_DEVSTA_TRPND))
|
||||||
goto clear;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_err(&dev->dev, "transaction is not cleared; "
|
return 0;
|
||||||
"proceeding with reset anyway\n");
|
}
|
||||||
|
EXPORT_SYMBOL(pci_wait_for_pending_transaction);
|
||||||
|
|
||||||
|
static int pcie_flr(struct pci_dev *dev, int probe)
|
||||||
|
{
|
||||||
|
u32 cap;
|
||||||
|
|
||||||
|
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
|
||||||
|
if (!(cap & PCI_EXP_DEVCAP_FLR))
|
||||||
|
return -ENOTTY;
|
||||||
|
|
||||||
|
if (probe)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!pci_wait_for_pending_transaction(dev))
|
||||||
|
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);
|
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
||||||
|
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
|
|
@ -914,6 +914,7 @@ bool pci_check_and_unmask_intx(struct pci_dev *dev);
|
||||||
void pci_msi_off(struct pci_dev *dev);
|
void pci_msi_off(struct pci_dev *dev);
|
||||||
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
|
int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size);
|
||||||
int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
|
int pci_set_dma_seg_boundary(struct pci_dev *dev, unsigned long mask);
|
||||||
|
int pci_wait_for_pending_transaction(struct pci_dev *dev);
|
||||||
int pcix_get_max_mmrbc(struct pci_dev *dev);
|
int pcix_get_max_mmrbc(struct pci_dev *dev);
|
||||||
int pcix_get_mmrbc(struct pci_dev *dev);
|
int pcix_get_mmrbc(struct pci_dev *dev);
|
||||||
int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
|
int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc);
|
||||||
|
|
Loading…
Reference in New Issue