[PATCH 4/(3+1)] Add quirks for ACPI PCI slot detection driver

Kenji Kaneshige
2008-03-11T13:23:46Z

ACPI spec says that OSPM checks with the bus driver for _ADR devices
to verify the presence of the device. But there are hardwares that
provide _STA for PCI hotplug slots to indicate the presence of the
device. For those hardwares, we want to ignore _STA and evaluate _SUN
by force, otherwise PCI hotplug slots would not be detected.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>

---
drivers/acpi/pci_slot.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 43 insertions(+), 4 deletions(-)

Index: linux-2.6.25-rc4/drivers/acpi/pci_slot.c
===================================================================
--- linux-2.6.25-rc4.orig/drivers/acpi/pci_slot.c
+++ linux-2.6.25-rc4/drivers/acpi/pci_slot.c
@@ -31,6 +31,7 @@
#include <acpi/acpi_drivers.h>

static int debug;
+static int ignore_sta;

#define DRIVER_VERSION "0.1"
#define DRIVER_AUTHOR "Alex Chiang <achiang@hp.com>"
@@ -73,10 +74,20 @@ check_slot(acpi_handle handle, int *devi
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
dbg("Checking slot on path: %s\n", (char *)buffer.pointer);

- status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
- if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
- retval = -1;
- goto out;
+ /*
+ * ACPI spec says that OSPM checks with the bus driver for
+ * _ADR devices to verify the presence of the device. But
+ * there are hardwares that provide _STA for PCI hotplug slots
+ * to indicate the presence of the device. For those
+ * hardwares, we want to ignore _STA and evaluate _SUN by
+ * force, otherwise PCI hotplug slots would not be detected.
+ */
+ if (!ignore_sta) {
+ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
+ if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT)) {
+ retval = -1;
+ goto out;
+ }
}

status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
@@ -311,9 +322,37 @@ acpi_pci_slot_remove(acpi_handle handle)
err("%s: unregister_slot failure - %d\n", __FUNCTION__, status);
}

+#ifdef CONFIG_DMI
+static int ignore_sta_before_sun(const struct dmi_system_id *d)
+{
+ info("%s detected: will ignore _STA before calling _SUN\n", d->ident);
+ ignore_sta = 1;
+ return 0;
+}
+
+static struct dmi_system_id acpi_pci_slot_dmi_table[] __initdata = {
+ /*
+ * Ignore _STA if the hardware provides _STA to indicate the
+ * presence of PCI adapter card on PCI hotplug slot.
+ */
+ /* Please add appropriate values for HP/IBM servers.
+ {
+ .callback = ignore_sta_before_sun,
+ .ident = "",
+ .matches = {
+ DMI_MATCH(DMI_BIOS_VENDOR, ""),
+ DMI_MATCH(DMI_BIOS_VERSION, ""),
+ },
+ },
+ */
+ {}
+};
+#endif /* CONFIG_DMI */
+
static int __init
acpi_pci_slot_init(void)
{
+ dmi_check_system(acpi_pci_slot_dmi_table);
acpi_pci_register_driver(&acpi_pci_slot_driver);
return 0;
}