Blob Blame History Raw
From 744d4cd546dfa6be16144e8eeacfd4dde276709d Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@suse.com>
Date: Tue, 14 Jan 2020 11:20:23 +0100
Subject: [PATCH] make some Fujitsu systems run
Patch-mainline: Never (experimental)
References: bsc#1141558

On some systems the presense bit must be obeyed even if the
link is indicated to be active.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
 drivers/pci/hotplug/pciehp.h      |    3 +++
 drivers/pci/hotplug/pciehp_core.c |   17 +++++++++++++++++
 drivers/pci/hotplug/pciehp_ctrl.c |    3 +++
 3 files changed, 23 insertions(+)

--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -113,6 +113,9 @@ struct controller {
 	unsigned int cmd_busy:1;
 	unsigned int link_active_reporting:1;
 	unsigned int notification_enabled:1;
+#ifndef __GENKSYMS__
+	bool always_heed_presense_bit;
+#endif
 	unsigned int power_fault_detected;
 	atomic_t pending_events;
 	u8 state;
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -36,6 +36,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/dmi.h>
 #include "pciehp.h"
 #include <linux/interrupt.h>
 #include <linux/time.h>
@@ -206,6 +207,20 @@ static void pciehp_check_presence(struct
 	up_read(&ctrl->reset_lock);
 }
 
+static void check_for_broken_active_bit(struct controller *ctrl)
+{
+	const char *product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
+
+	if (!product_name)
+		return;
+
+	if (	strstr(product_name, "PRIMEQUEST 2400E3") ||
+		strstr(product_name, "PRIMEQUEST 2400L3") ||
+		strstr(product_name, "PRIMEQUEST 2800E3") ||
+		strstr(product_name, "PRIMEQUEST 2800L3"))
+			ctrl->always_heed_presense_bit = true;
+}
+
 static int pciehp_probe(struct pcie_device *dev)
 {
 	int rc;
@@ -229,6 +244,8 @@ static int pciehp_probe(struct pcie_devi
 	}
 	set_service_data(dev, ctrl);
 
+	check_for_broken_active_bit(ctrl);
+
 	/* Setup the slot information structures */
 	rc = init_slot(ctrl);
 	if (rc) {
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -300,6 +300,9 @@ static int __pciehp_enable_slot(struct c
 {
 	u8 getstatus = 0;
 
+	if (ctrl->always_heed_presense_bit && !pciehp_card_present(ctrl))
+		return -ENODEV;
+
 	if (MRL_SENS(ctrl)) {
 		pciehp_get_latch_status(ctrl, &getstatus);
 		if (getstatus) {