Skip to content

Commit e9e224d

Browse files
committed
Merge branch 'pci/enumeration'
- Enable Configuration RRS SV early instead of during child bus scanning (Bjorn Helgaas) - Cache offset of Resizable BAR capability to avoid redundant searches for it (Bjorn Helgaas) - Fix reference leaks in pci_register_host_bridge() and pci_alloc_child_bus() (Ma Ke) - Drop put_device() in pci_register_host_bridge() left over from converting device_register() to device_add() (Dan Carpenter) * pci/enumeration: PCI: Remove stray put_device() in pci_register_host_bridge() PCI: Fix reference leak in pci_alloc_child_bus() PCI: Fix reference leak in pci_register_host_bridge() PCI: Cache offset of Resizable BAR capability PCI: Enable Configuration RRS SV early
2 parents 651aa90 + 6e8d06e commit e9e224d

File tree

4 files changed

+28
-11
lines changed

4 files changed

+28
-11
lines changed

drivers/pci/pci.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,7 +1879,7 @@ static void pci_restore_rebar_state(struct pci_dev *pdev)
18791879
unsigned int pos, nbars, i;
18801880
u32 ctrl;
18811881

1882-
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
1882+
pos = pdev->rebar_cap;
18831883
if (!pos)
18841884
return;
18851885

@@ -3726,6 +3726,11 @@ void pci_acs_init(struct pci_dev *dev)
37263726
pci_enable_acs(dev);
37273727
}
37283728

3729+
void pci_rebar_init(struct pci_dev *pdev)
3730+
{
3731+
pdev->rebar_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
3732+
}
3733+
37293734
/**
37303735
* pci_rebar_find_pos - find position of resize ctrl reg for BAR
37313736
* @pdev: PCI device
@@ -3740,7 +3745,7 @@ static int pci_rebar_find_pos(struct pci_dev *pdev, int bar)
37403745
unsigned int pos, nbars, i;
37413746
u32 ctrl;
37423747

3743-
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR);
3748+
pos = pdev->rebar_cap;
37443749
if (!pos)
37453750
return -ENOTSUPP;
37463751

drivers/pci/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ static inline int acpi_get_rc_resources(struct device *dev, const char *hid,
826826
}
827827
#endif
828828

829+
void pci_rebar_init(struct pci_dev *pdev);
829830
int pci_rebar_get_current_size(struct pci_dev *pdev, int bar);
830831
int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size);
831832
static inline u64 pci_rebar_size_to_bytes(int size)

drivers/pci/probe.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
954954
resource_size_t offset, next_offset;
955955
LIST_HEAD(resources);
956956
struct resource *res, *next_res;
957+
bool bus_registered = false;
957958
char addr[64], *fmt;
958959
const char *name;
959960
int err;
@@ -996,10 +997,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
996997
/* Temporarily move resources off the list */
997998
list_splice_init(&bridge->windows, &resources);
998999
err = device_add(&bridge->dev);
999-
if (err) {
1000-
put_device(&bridge->dev);
1000+
if (err)
10011001
goto free;
1002-
}
1002+
10031003
bus->bridge = get_device(&bridge->dev);
10041004
device_enable_async_suspend(bus->bridge);
10051005
pci_set_bus_of_node(bus);
@@ -1018,6 +1018,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
10181018
name = dev_name(&bus->dev);
10191019

10201020
err = device_register(&bus->dev);
1021+
bus_registered = true;
10211022
if (err)
10221023
goto unregister;
10231024

@@ -1104,12 +1105,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
11041105
unregister:
11051106
put_device(&bridge->dev);
11061107
device_del(&bridge->dev);
1107-
11081108
free:
11091109
#ifdef CONFIG_PCI_DOMAINS_GENERIC
11101110
pci_bus_release_domain_nr(parent, bus->domain_nr);
11111111
#endif
1112-
kfree(bus);
1112+
if (bus_registered)
1113+
put_device(&bus->dev);
1114+
else
1115+
kfree(bus);
1116+
11131117
return err;
11141118
}
11151119

@@ -1218,7 +1222,10 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
12181222
add_dev:
12191223
pci_set_bus_msi_domain(child);
12201224
ret = device_register(&child->dev);
1221-
WARN_ON(ret < 0);
1225+
if (WARN_ON(ret < 0)) {
1226+
put_device(&child->dev);
1227+
return NULL;
1228+
}
12221229

12231230
pcibios_add_bus(child);
12241231

@@ -1374,8 +1381,6 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
13741381
pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
13751382
bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
13761383

1377-
pci_enable_rrs_sv(dev);
1378-
13791384
if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
13801385
!is_cardbus && !broken) {
13811386
unsigned int cmax, buses;
@@ -1616,6 +1621,11 @@ void set_pcie_port_type(struct pci_dev *pdev)
16161621
pdev->pcie_cap = pos;
16171622
pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
16181623
pdev->pcie_flags_reg = reg16;
1624+
1625+
type = pci_pcie_type(pdev);
1626+
if (type == PCI_EXP_TYPE_ROOT_PORT)
1627+
pci_enable_rrs_sv(pdev);
1628+
16191629
pci_read_config_dword(pdev, pos + PCI_EXP_DEVCAP, &pdev->devcap);
16201630
pdev->pcie_mpss = FIELD_GET(PCI_EXP_DEVCAP_PAYLOAD, pdev->devcap);
16211631

@@ -1632,7 +1642,6 @@ void set_pcie_port_type(struct pci_dev *pdev)
16321642
* correctly so detect impossible configurations here and correct
16331643
* the port type accordingly.
16341644
*/
1635-
type = pci_pcie_type(pdev);
16361645
if (type == PCI_EXP_TYPE_DOWNSTREAM) {
16371646
/*
16381647
* If pdev claims to be downstream port but the parent
@@ -2565,6 +2574,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
25652574
pci_rcec_init(dev); /* Root Complex Event Collector */
25662575
pci_doe_init(dev); /* Data Object Exchange */
25672576
pci_tph_init(dev); /* TLP Processing Hints */
2577+
pci_rebar_init(dev); /* Resizable BAR */
25682578

25692579
pcie_report_downtraining(dev);
25702580
pci_init_reset_methods(dev);

include/linux/pci.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ struct pci_dev {
353353
struct pci_dev *rcec; /* Associated RCEC device */
354354
#endif
355355
u32 devcap; /* PCIe Device Capabilities */
356+
u16 rebar_cap; /* Resizable BAR capability offset */
356357
u8 pcie_cap; /* PCIe capability offset */
357358
u8 msi_cap; /* MSI capability offset */
358359
u8 msix_cap; /* MSI-X capability offset */

0 commit comments

Comments
 (0)