Convert PCIe Hot Plug to using pci_request_feature
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
This commit is contained in:
parent
0436b48adb
commit
ce9844cd72
@ -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),
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 */
|
||||
@ -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 */
|
||||
@ -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
|
||||
};
|
||||
@ -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];
|
||||
@ -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
|
||||
@ -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.
|
||||
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 }
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user