From 4cb6772936ebacb24b373822591bb2d3ec55e25d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 25 Feb 2017 06:11:36 +0000 Subject: [PATCH] Create pcib_request_feature. pcib_request_feature allows drivers to request the firmware (ACPI) release certain features it may be using. ACPI normally manages things like hot plug, advanced error reporting and other features until the OS requests ACPI to relenquish control since it is taking over. Sponsored by: Netflix --- sys/dev/pci/pci_if.m | 5 +++++ sys/dev/pci/pci_pci.c | 24 ++++++++++++++++++++++++ sys/dev/pci/pcib_if.m | 9 +++++++++ 3 files changed, 38 insertions(+) diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m index 11fa5d75d92..07fabbd000e 100644 --- a/sys/dev/pci/pci_if.m +++ b/sys/dev/pci/pci_if.m @@ -60,6 +60,11 @@ HEADER { PCI_ID_RID, PCI_ID_MSI, }; + + enum pci_feature { + PCI_FEATURE_HP, /* Hot Plug feature */ + PCI_FEATURE_AER, /* Advanced Error Reporting */ + }; } diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index 553b9cb8a28..3a9bf15cb34 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -76,6 +76,8 @@ static void pcib_pcie_ab_timeout(void *arg); static void pcib_pcie_cc_timeout(void *arg); static void pcib_pcie_dll_timeout(void *arg); #endif +static int pcib_request_feature(device_t pcib, device_t dev, + enum pci_feature feature); static device_method_t pcib_methods[] = { /* Device interface */ @@ -119,6 +121,7 @@ static device_method_t pcib_methods[] = { DEVMETHOD(pcib_try_enable_ari, pcib_try_enable_ari), DEVMETHOD(pcib_ari_enabled, pcib_ari_enabled), DEVMETHOD(pcib_decode_rid, pcib_ari_decode_rid), + DEVMETHOD(pcib_request_feature, pcib_request_feature), DEVMETHOD_END }; @@ -2829,3 +2832,24 @@ pcib_try_enable_ari(device_t pcib, device_t dev) 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 + * request to take it over, or the platform has no such firmware, in which case + * the request will be approved. If the request is approved, the OS is expected + * to make use of the feature or render it harmless. + */ +static int +pcib_request_feature(device_t pcib, device_t dev, enum pci_feature feature) +{ + device_t bus; + + /* + * Our parent is necessarily a pci bus. Its parent will either be + * another pci bridge (which passes it up) or a host bridge that can + * approve or reject the request. + */ + bus = device_get_parent(pcib); + return (PCIB_REQUEST_FEATURE(device_get_parent(bus), dev, feature)); +} diff --git a/sys/dev/pci/pcib_if.m b/sys/dev/pci/pcib_if.m index 530744a2f14..32f2804de31 100644 --- a/sys/dev/pci/pcib_if.m +++ b/sys/dev/pci/pcib_if.m @@ -212,3 +212,12 @@ METHOD void decode_rid { int *slot; int *func; } DEFAULT pcib_decode_rid; + +# +# Request control of PCI features from host firmware, if any. +# +METHOD int request_feature { + device_t pcib; + device_t dev; + enum pci_feature feature; +};