Merge tag 'pci-v6.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci
[linux-2.6-block.git] / drivers / pci / pcie / edr.c
index 5f4914d313a17404dd4c61f9145a3a76ac1a2375..e86298dbbcff602adb210378ceb033ae0ff155d5 100644 (file)
@@ -32,10 +32,10 @@ static int acpi_enable_dpc(struct pci_dev *pdev)
        int status = 0;
 
        /*
-        * Behavior when calling unsupported _DSM functions is undefined,
-        * so check whether EDR_PORT_DPC_ENABLE_DSM is supported.
+        * Per PCI Firmware r3.3, sec 4.6.12, EDR_PORT_DPC_ENABLE_DSM is
+        * optional. Return success if it's not implemented.
         */
-       if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 5,
+       if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 6,
                            1ULL << EDR_PORT_DPC_ENABLE_DSM))
                return 0;
 
@@ -46,12 +46,7 @@ static int acpi_enable_dpc(struct pci_dev *pdev)
        argv4.package.count = 1;
        argv4.package.elements = &req;
 
-       /*
-        * Per Downstream Port Containment Related Enhancements ECN to PCI
-        * Firmware Specification r3.2, sec 4.6.12, EDR_PORT_DPC_ENABLE_DSM is
-        * optional.  Return success if it's not implemented.
-        */
-       obj = acpi_evaluate_dsm(adev->handle, &pci_acpi_dsm_guid, 5,
+       obj = acpi_evaluate_dsm(adev->handle, &pci_acpi_dsm_guid, 6,
                                EDR_PORT_DPC_ENABLE_DSM, &argv4);
        if (!obj)
                return 0;
@@ -85,8 +80,9 @@ static struct pci_dev *acpi_dpc_port_get(struct pci_dev *pdev)
        u16 port;
 
        /*
-        * Behavior when calling unsupported _DSM functions is undefined,
-        * so check whether EDR_PORT_DPC_ENABLE_DSM is supported.
+        * If EDR_PORT_LOCATE_DSM is not implemented under the target of
+        * EDR, the target is the port that experienced the containment
+        * event (PCI Firmware r3.3, sec 4.6.13).
         */
        if (!acpi_check_dsm(adev->handle, &pci_acpi_dsm_guid, 5,
                            1ULL << EDR_PORT_LOCATE_DSM))
@@ -103,6 +99,16 @@ static struct pci_dev *acpi_dpc_port_get(struct pci_dev *pdev)
                return NULL;
        }
 
+       /*
+        * Bit 31 represents the success/failure of the operation. If bit
+        * 31 is set, the operation failed.
+        */
+       if (obj->integer.value & BIT(31)) {
+               ACPI_FREE(obj);
+               pci_err(pdev, "Locate Port _DSM failed\n");
+               return NULL;
+       }
+
        /*
         * Firmware returns DPC port BDF details in following format:
         *      15:8 = bus