diff --git a/drivers/pci/rebar.c b/drivers/pci/rebar.c index ecdebdeb2dff..39f8cf3b70d5 100644 --- a/drivers/pci/rebar.c +++ b/drivers/pci/rebar.c @@ -295,7 +295,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size, int exclude_bars) { struct pci_host_bridge *host; - int old, ret; /* Check if we must preserve the firmware's resource assignment */ host = pci_find_host_bridge(dev->bus); @@ -308,21 +307,6 @@ int pci_resize_resource(struct pci_dev *dev, int resno, int size, if (!pci_rebar_size_supported(dev, resno, size)) return -EINVAL; - old = pci_rebar_get_current_size(dev, resno); - if (old < 0) - return old; - - ret = pci_rebar_set_size(dev, resno, size); - if (ret) - return ret; - - ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars); - if (ret) - goto error_resize; - return 0; - -error_resize: - pci_rebar_set_size(dev, resno, old); - return ret; + return pci_do_resource_release_and_resize(dev, resno, size, exclude_bars); } EXPORT_SYMBOL(pci_resize_resource); diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 6e90f46f52af..a61d38777cdc 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -2504,12 +2504,20 @@ int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size struct resource *b_win, *r; LIST_HEAD(saved); unsigned int i; - int ret = 0; + int old, ret; b_win = pbus_select_window(bus, res); if (!b_win) return -EINVAL; + old = pci_rebar_get_current_size(pdev, resno); + if (old < 0) + return old; + + ret = pci_rebar_set_size(pdev, resno, size); + if (ret) + return ret; + pci_dev_for_each_resource(pdev, r, i) { if (i >= PCI_BRIDGE_RESOURCES) break; @@ -2542,7 +2550,15 @@ out: return ret; restore: - /* Revert to the old configuration */ + /* + * Revert to the old configuration. + * + * BAR Size must be restored first because it affects the read-only + * bits in BAR (the old address might not be restorable otherwise + * due to low address bits). + */ + pci_rebar_set_size(pdev, resno, old); + list_for_each_entry(dev_res, &saved, list) { struct resource *res = dev_res->res; struct pci_dev *dev = dev_res->dev; @@ -2556,8 +2572,7 @@ restore: restore_dev_resource(dev_res); - ret = pci_claim_resource(dev, i); - if (ret) + if (pci_claim_resource(dev, i)) continue; if (i < PCI_BRIDGE_RESOURCES) {