Skip to content

Commit

Permalink
Convert PCIe Hot Plug to using pci_request_feature
Browse files Browse the repository at this point in the history
Convert PCIe hot plug support over to asking the firmware, if any, for
permission to use the HotPlug hardware. Implement pci_request_feature
for ACPI. All other host pci connections to allowing all valid feature
requests.

Sponsored by: Netflix
  • Loading branch information
bsdimp committed Feb 25, 2017
1 parent 8a1926c commit 2858688
Show file tree
Hide file tree
Showing 32 changed files with 100 additions and 21 deletions.
2 changes: 1 addition & 1 deletion sys/arm/mv/mv_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ static device_method_t mv_pcib_methods[] = {
DEVMETHOD(pcib_read_config, mv_pcib_read_config),
DEVMETHOD(pcib_write_config, mv_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, mv_pcib_route_interrupt),

DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),
#if defined(SOC_MV_ARMADAXP)
DEVMETHOD(pcib_alloc_msi, mv_pcib_alloc_msi),
DEVMETHOD(pcib_release_msi, mv_pcib_release_msi),
Expand Down
1 change: 1 addition & 0 deletions sys/arm/nvidia/tegra_pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -1601,6 +1601,7 @@ static device_method_t tegra_pcib_methods[] = {
DEVMETHOD(pcib_alloc_msi, tegra_pcib_alloc_msi),
DEVMETHOD(pcib_release_msi, tegra_pcib_release_msi),
DEVMETHOD(pcib_map_msi, tegra_pcib_map_msi),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

#ifdef TEGRA_PCIB_MSI_ENABLE
/* MSI/MSI-X */
Expand Down
1 change: 1 addition & 0 deletions sys/arm/versatile/versatile_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ static device_method_t versatile_pci_methods[] = {
DEVMETHOD(pcib_read_config, versatile_pci_read_config),
DEVMETHOD(pcib_write_config, versatile_pci_write_config),
DEVMETHOD(pcib_route_interrupt, versatile_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/arm/xscale/i8134x/i81342_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ static device_method_t i81342_pci_methods[] = {
DEVMETHOD(pcib_read_config, i81342_pci_read_config),
DEVMETHOD(pcib_write_config, i81342_pci_write_config),
DEVMETHOD(pcib_route_interrupt, i81342_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/arm/xscale/ixp425/ixp425_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ static device_method_t ixppcib_methods[] = {
DEVMETHOD(pcib_read_config, ixppcib_read_config),
DEVMETHOD(pcib_write_config, ixppcib_write_config),
DEVMETHOD(pcib_route_interrupt, ixppcib_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
60 changes: 40 additions & 20 deletions sys/dev/acpica/acpi_pcib_acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct acpi_hpcib_softc {
device_t ap_dev;
ACPI_HANDLE ap_handle;
int ap_flags;
uint32_t ap_osc_ctl;

int ap_segment; /* PCI domain */
int ap_bus; /* bios-assigned bus number */
Expand Down Expand Up @@ -105,6 +106,8 @@ static int acpi_pcib_acpi_release_resource(device_t dev,
struct resource *r);
#endif
#endif
static int acpi_pcib_request_feature(device_t pcib, device_t dev,
enum pci_feature feature);

static device_method_t acpi_pcib_acpi_methods[] = {
/* Device interface */
Expand Down Expand Up @@ -145,6 +148,7 @@ static device_method_t acpi_pcib_acpi_methods[] = {
DEVMETHOD(pcib_release_msix, pcib_release_msix),
DEVMETHOD(pcib_map_msi, acpi_pcib_map_msi),
DEVMETHOD(pcib_power_for_sleep, acpi_pcib_power_for_sleep),
DEVMETHOD(pcib_request_feature, acpi_pcib_request_feature),

DEVMETHOD_END
};
Expand Down Expand Up @@ -298,8 +302,8 @@ first_decoded_bus(struct acpi_hpcib_softc *sc, rman_res_t *startp)
}
#endif

static void
acpi_pcib_osc(struct acpi_hpcib_softc *sc)
static int
acpi_pcib_osc(struct acpi_hpcib_softc *sc, uint32_t osc_ctl)
{
ACPI_STATUS status;
uint32_t cap_set[3];
Expand All @@ -317,33 +321,27 @@ acpi_pcib_osc(struct acpi_hpcib_softc *sc)
PCIM_OSC_SUPPORT_MSI;

/* Control Field */
cap_set[PCI_OSC_CTL] = 0;

#ifdef PCI_HP
/* Control Field: PCI Express Native Hot Plug */
cap_set[PCI_OSC_CTL] |= PCIM_OSC_CTL_PCIE_HP;
#endif
sc->ap_osc_ctl |= osc_ctl;
cap_set[PCI_OSC_CTL] = sc->ap_osc_ctl;

status = acpi_EvaluateOSC(sc->ap_handle, pci_host_bridge_uuid, 1,
nitems(cap_set), cap_set, cap_set, false);
if (ACPI_FAILURE(status)) {
if (status == AE_NOT_FOUND)
return;
return (0);
device_printf(sc->ap_dev, "_OSC failed: %s\n",
AcpiFormatException(status));
return;
return (EIO);
}

if (cap_set[PCI_OSC_STATUS] != 0) {
device_printf(sc->ap_dev, "_OSC returned error %#x\n",
cap_set[0]);
}
if (cap_set[PCI_OSC_STATUS] == 0)
sc->ap_osc_ctl = cap_set[PCI_OSC_CTL];

#ifdef PCI_HP
if ((cap_set[PCI_OSC_CTL] & PCIM_OSC_CTL_PCIE_HP) == 0 && bootverbose) {
device_printf(sc->ap_dev, "_OSC didn't allow HP control\n");
}
#endif
if (cap_set[PCI_OSC_STATUS] != 0 ||
(cap_set[PCI_OSC_CTL] & osc_ctl) != osc_ctl)
return (EIO);

return (0);
}

static int
Expand Down Expand Up @@ -372,7 +370,7 @@ acpi_pcib_acpi_attach(device_t dev)
if (!acpi_DeviceIsPresent(dev))
return (ENXIO);

acpi_pcib_osc(sc);
acpi_pcib_osc(sc, 0);

/*
* Get our segment number by evaluating _SEG.
Expand Down Expand Up @@ -722,3 +720,25 @@ acpi_pcib_acpi_release_resource(device_t dev, device_t child, int type, int rid,
}
#endif
#endif

static int
acpi_pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature)
{
uint32_t osc_ctl;
struct acpi_hpcib_softc *sc;

sc = device_get_softc(dev);

switch (feature) {
case PCI_FEATURE_HP:
osc_ctl = PCIM_OSC_CTL_PCIE_HP;
break;
case PCI_FEATURE_AER:
osc_ctl = PCIM_OSC_CTL_PCIE_AER;
break;
default:
return (EINVAL);
}

return (acpi_pcib_osc(sc, osc_ctl));
}
1 change: 1 addition & 0 deletions sys/dev/hyperv/pcib/vmbus_pcib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,7 @@ static device_method_t vmbus_pcib_methods[] = {
DEVMETHOD(pcib_alloc_msix, vmbus_pcib_alloc_msix),
DEVMETHOD(pcib_release_msix, vmbus_pcib_release_msix),
DEVMETHOD(pcib_map_msi, vmbus_pcib_map_msi),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/dev/ofw/ofwpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ static device_method_t ofw_pci_methods[] = {
/* pcib interface */
DEVMETHOD(pcib_maxslots, ofw_pci_maxslots),
DEVMETHOD(pcib_route_interrupt, ofw_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/dev/pci/pci_host_generic_fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ static device_method_t generic_pcie_fdt_methods[] = {
DEVMETHOD(pcib_release_msix, generic_pcie_fdt_release_msix),
DEVMETHOD(pcib_map_msi, generic_pcie_fdt_map_msi),
DEVMETHOD(pcib_get_id, generic_pcie_get_id),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_devinfo, generic_pcie_ofw_get_devinfo),
Expand Down
30 changes: 30 additions & 0 deletions sys/dev/pci/pci_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,17 @@ pcib_probe_hotplug(struct pcib_softc *sc)
}
}

/*
* Now that we're sure we want to do hot plug, ask the
* firmware, if any, if that's OK.
*/
if (pcib_request_feature(device_get_parent(device_get_parent(dev)), dev,
PCI_FEATURE_HP) != 0) {
if (bootverbose)
device_printf(dev, "Unable to activate hot plug feature.\n");
return;
}

sc->flags |= PCIB_HOTPLUG;
}

Expand Down Expand Up @@ -2833,6 +2844,25 @@ pcib_try_enable_ari(device_t pcib, device_t dev)
return (0);
}

int
pcib_request_feature_allow(device_t pcib, device_t dev,
enum pci_feature feature)
{
/*
* No host firmwrae we have to negotiate with, so we allow
* every valid feature requested.
*/
switch (feature) {
case PCI_FEATURE_AER:
case PCI_FEATURE_HP:
break;
default:
return (EINVAL);
}

return (0);
}

/*
* Pass the request to use this PCI feature up the tree. Either there's a
* firmware like ACPI that's using this feature that will approve (or deny) the
Expand Down
1 change: 1 addition & 0 deletions sys/dev/pci/pcib_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,6 @@ int pcib_get_id(device_t pcib, device_t dev, enum pci_id_type type,
uintptr_t *id);
void pcib_decode_rid(device_t pcib, uint16_t rid, int *bus,
int *slot, int *func);
int pcib_request_feature_allow(device_t pcib, device_t dev, enum pci_feature feature);

#endif
1 change: 1 addition & 0 deletions sys/dev/xen/pcifront/pcifront.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ static device_method_t xpcib_methods[] = {
DEVMETHOD(pcib_read_config, xpcib_read_config),
DEVMETHOD(pcib_write_config, xpcib_write_config),
DEVMETHOD(pcib_route_interrupt, xpcib_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/adm5120/admpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ static device_method_t admpci_methods[] = {
DEVMETHOD(pcib_read_config, admpci_read_config),
DEVMETHOD(pcib_write_config, admpci_write_config),
DEVMETHOD(pcib_route_interrupt, admpci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/atheros/ar71xx_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,7 @@ static device_method_t ar71xx_pci_methods[] = {
DEVMETHOD(pcib_read_config, ar71xx_pci_read_config),
DEVMETHOD(pcib_write_config, ar71xx_pci_write_config),
DEVMETHOD(pcib_route_interrupt, ar71xx_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/atheros/ar724x_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ static device_method_t ar724x_pci_methods[] = {
DEVMETHOD(pcib_read_config, ar724x_pci_read_config),
DEVMETHOD(pcib_write_config, ar724x_pci_write_config),
DEVMETHOD(pcib_route_interrupt, ar724x_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/atheros/qca955x_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ static device_method_t qca955x_pci_methods[] = {
DEVMETHOD(pcib_read_config, qca955x_pci_read_config),
DEVMETHOD(pcib_write_config, qca955x_pci_write_config),
DEVMETHOD(pcib_route_interrupt, qca955x_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/cavium/octopci.c
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ static device_method_t octopci_methods[] = {
DEVMETHOD(pcib_read_config, octopci_read_config),
DEVMETHOD(pcib_write_config, octopci_write_config),
DEVMETHOD(pcib_route_interrupt, octopci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/idt/idtpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ static device_method_t idtpci_methods[] = {
DEVMETHOD(pcib_read_config, idtpci_read_config),
DEVMETHOD(pcib_write_config, idtpci_write_config),
DEVMETHOD(pcib_route_interrupt, idtpci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/malta/gt_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ static device_method_t gt_pci_methods[] = {
DEVMETHOD(pcib_read_config, gt_pci_read_config),
DEVMETHOD(pcib_write_config, gt_pci_write_config),
DEVMETHOD(pcib_route_interrupt, gt_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/mediatek/mtk_pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ static device_method_t mtk_pci_methods[] = {
DEVMETHOD(pcib_read_config, mtk_pci_read_config),
DEVMETHOD(pcib_write_config, mtk_pci_write_config),
DEVMETHOD(pcib_route_interrupt, mtk_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* OFW bus interface */
DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
Expand Down
1 change: 1 addition & 0 deletions sys/mips/nlm/xlp_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ static device_method_t xlp_pcib_methods[] = {
DEVMETHOD(pcib_read_config, xlp_pcib_read_config),
DEVMETHOD(pcib_write_config, xlp_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, mips_pcib_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD(pcib_alloc_msi, xlp_alloc_msi),
DEVMETHOD(pcib_release_msi, xlp_release_msi),
Expand Down
1 change: 1 addition & 0 deletions sys/mips/rmi/xlr_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ static device_method_t xlr_pcib_methods[] = {
DEVMETHOD(pcib_read_config, xlr_pcib_read_config),
DEVMETHOD(pcib_write_config, xlr_pcib_write_config),
DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi),
DEVMETHOD(pcib_release_msi, xlr_release_msi),
Expand Down
1 change: 1 addition & 0 deletions sys/mips/rt305x/rt305x_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ static device_method_t rt305x_pci_methods[] = {
DEVMETHOD(pcib_read_config, rt305x_pci_read_config),
DEVMETHOD(pcib_write_config, rt305x_pci_write_config),
DEVMETHOD(pcib_route_interrupt, rt305x_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/mips/sibyte/sb_zbpci.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ static device_method_t zbpci_methods[] ={
DEVMETHOD(pcib_read_config, zbpci_read_config),
DEVMETHOD(pcib_write_config, zbpci_write_config),
DEVMETHOD(pcib_route_interrupt, zbpci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

{ 0, 0 }
};
Expand Down
1 change: 1 addition & 0 deletions sys/powerpc/ofw/ofw_pcib_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ static device_method_t ofw_pcib_pci_methods[] = {

/* pcib interface */
DEVMETHOD(pcib_route_interrupt, ofw_pcib_pci_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pcib_pci_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/powerpc/powermac/cpcht.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static device_method_t cpcht_methods[] = {
DEVMETHOD(pcib_alloc_msix, cpcht_alloc_msix),
DEVMETHOD(pcib_release_msix, cpcht_release_msix),
DEVMETHOD(pcib_map_msi, cpcht_map_msi),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down
1 change: 1 addition & 0 deletions sys/sparc64/pci/apb.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ static device_method_t apb_methods[] = {

/* pcib interface */
DEVMETHOD(pcib_route_interrupt, ofw_pcib_gen_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pcib_gen_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/sparc64/pci/fire.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ static device_method_t fire_methods[] = {
DEVMETHOD(pcib_alloc_msix, fire_alloc_msix),
DEVMETHOD(pcib_release_msix, fire_release_msix),
DEVMETHOD(pcib_map_msi, fire_map_msi),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/sparc64/pci/ofw_pcib.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ static device_method_t ofw_pcib_methods[] = {

/* pcib interface */
DEVMETHOD(pcib_route_interrupt, ofw_pcib_gen_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pcib_gen_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/sparc64/pci/psycho.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ static device_method_t psycho_methods[] = {
DEVMETHOD(pcib_read_config, psycho_read_config),
DEVMETHOD(pcib_write_config, psycho_write_config),
DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/sparc64/pci/schizo.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ static device_method_t schizo_methods[] = {
DEVMETHOD(pcib_read_config, schizo_read_config),
DEVMETHOD(pcib_write_config, schizo_write_config),
DEVMETHOD(pcib_route_interrupt, schizo_route_interrupt),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ofw_pci_get_node),
Expand Down
1 change: 1 addition & 0 deletions sys/x86/pci/pci_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ static device_method_t legacy_pcib_methods[] = {
DEVMETHOD(pcib_alloc_msix, legacy_pcib_alloc_msix),
DEVMETHOD(pcib_release_msix, pcib_release_msix),
DEVMETHOD(pcib_map_msi, legacy_pcib_map_msi),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),

DEVMETHOD_END
};
Expand Down

0 comments on commit 2858688

Please sign in to comment.