Alex Chiang wrote: > * Kenji Kaneshige <kaneshige.kenji@xxxxxxxxxxxxxx>: >> There is a problem that some non hot-pluggable PCIe slots are detected >> as hot-pluggable by pciehp on some platforms. The immediate cause of >> this problem is that hot-plug capable bit in the Slot Capabilities >> register is set even for non hot-pluggable slots on those platforms. >> It seems a BIOS/hardware problem, but we need workaround about that. >> >> Some of those platforms define hot-pluggable PCIe slots on ACPI >> namespace properly, while hot-plug capable bit in the Slot >> Capabilities register is set improperly. So using ACPI namespace >> information in pciehp to detect PCIe hot-pluggable slots would be a >> workaround. >> >> This patch adds 'pciehp_detect_mode' module option. When 'acpi' is >> specified, pciehp uses ACPI namespace information to detect PCIe >> hot-pluggable slots. >> >> Signed-off-by: Kenji Kaneshige <kaneshige.kenji@xxxxxxxxxxxxxx> >> >> --- >> drivers/pci/hotplug/Makefile | 3 + >> drivers/pci/hotplug/pciehp.h | 15 ++++- >> drivers/pci/hotplug/pciehp_acpi.c | 114 ++++++++++++++++++++++++++++++++++++++ >> drivers/pci/hotplug/pciehp_core.c | 1 >> 4 files changed, 132 insertions(+), 1 deletion(-) >> >> Index: 20081212/drivers/pci/hotplug/pciehp.h >> =================================================================== >> --- 20081212.orig/drivers/pci/hotplug/pciehp.h >> +++ 20081212/drivers/pci/hotplug/pciehp.h >> @@ -220,11 +220,23 @@ struct hpc_ops { >> #include <acpi/actypes.h> >> #include <linux/pci-acpi.h> >> >> +extern void __init pciehp_acpi_slot_detection_init(void); >> +extern int pciehp_acpi_slot_detection_check(struct pci_dev *dev); >> + >> +static inline void pciehp_firmware_init(void) >> +{ >> + pciehp_acpi_slot_detection_init(); >> +} >> + >> static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev) >> { >> + int retval; >> u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | >> OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); >> - return acpi_get_hp_hw_control_from_firmware(dev, flags); >> + retval = acpi_get_hp_hw_control_from_firmware(dev, flags); >> + if (retval) >> + return retval; >> + return pciehp_acpi_slot_detection_check(dev); >> } >> >> static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, >> @@ -235,6 +247,7 @@ static inline int pciehp_get_hp_params_f >> return 0; >> } >> #else >> +#define pciehp_firmware_init() do {} while (0) >> #define pciehp_get_hp_hw_control_from_firmware(dev) 0 >> #define pciehp_get_hp_params_from_firmware(dev, hpp) (-ENODEV) >> #endif /* CONFIG_ACPI */ >> Index: 20081212/drivers/pci/hotplug/pciehp_acpi.c >> =================================================================== >> --- /dev/null >> +++ 20081212/drivers/pci/hotplug/pciehp_acpi.c >> @@ -0,0 +1,114 @@ >> +/* >> + * ACPI related functions for PCI Express Hot Plug driver. >> + * >> + * Copyright (C) 2008 Kenji Kaneshige >> + * Copyright (C) 2008 Fujitsu Limited. >> + * >> + * All rights reserved. >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or (at >> + * your option) any later version. >> + * >> + * This program is distributed in the hope that it will be useful, but >> + * WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or >> + * NON INFRINGEMENT. See the GNU General Public License for more >> + * details. >> + * >> + * You should have received a copy of the GNU General Public License >> + * along with this program; if not, write to the Free Software >> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. >> + * >> + */ >> + >> +#include <linux/acpi.h> >> +#include "pciehp.h" >> + >> +#define PCIEHP_DETECT_PCIE (0) >> +#define PCIEHP_DETECT_ACPI (1) >> +#define PCIEHP_DETECT_DEFAULT PCIEHP_DETECT_PCIE >> + >> +static int slot_detection_mode; >> +static char *pciehp_detect_mode; >> +module_param(pciehp_detect_mode, charp, 0444); >> +MODULE_PARM_DESC(pciehp_detect_mode, >> + "Slot detection mode: pcie, acpi\n" >> + " pcie - Use PCIe based slot detection (default)\n" >> + " acpi - Use ACPI for slot detection\n"); >> + > > I would prefer that we do not add module params at all, and just > make the driver always autodetect the mode. You have the 'auto' > code in your 2nd patch, but it would be better to remove the > params and just always do the autodetect. > >> +static int is_ejectable(acpi_handle handle) >> +{ >> + acpi_status status; >> + acpi_handle tmp; >> + unsigned long long removable; >> + status = acpi_get_handle(handle, "_ADR", &tmp); >> + if (ACPI_FAILURE(status)) >> + return 0; >> + status = acpi_get_handle(handle, "_EJ0", &tmp); >> + if (ACPI_SUCCESS(status)) >> + return 1; >> + status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable); >> + if (ACPI_SUCCESS(status) && removable) >> + return 1; >> + return 0; >> +} >> + >> +static acpi_status >> +check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) >> +{ >> + int *found = (int *)context; >> + if (is_ejectable(handle)) { >> + *found = 1; >> + return AE_CTRL_TERMINATE; >> + } >> + return AE_OK; >> +} > > This code is very similar to what we already have in acpiphp. > > Is there any way you could figure out how to make both pciehp and > acpiphp share this code? > Yes, we can put those functions in pcihp_acpi.c so that pciehp and acpiphp share the code. I'll update the patch. Thanks, Kenji Kaneshige -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html