-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PCI: pciehp: add ACPI based slot detection
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@jp.fujitsu.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
- Loading branch information
Kenji Kaneshige
authored and
Jesse Barnes
committed
Jan 7, 2009
1 parent
873392c
commit c9ffa5a
Showing
4 changed files
with
132 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"); | ||
|
||
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; | ||
} | ||
|
||
static int pciehp_detect_acpi_slot(struct pci_bus *pbus) | ||
{ | ||
acpi_handle handle; | ||
struct pci_dev *pdev = pbus->self; | ||
int found = 0; | ||
|
||
if (!pdev){ | ||
int seg = pci_domain_nr(pbus), busnr = pbus->number; | ||
handle = acpi_get_pci_rootbridge_handle(seg, busnr); | ||
} else | ||
handle = DEVICE_ACPI_HANDLE(&(pdev->dev)); | ||
|
||
if (!handle) | ||
return 0; | ||
|
||
acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, | ||
check_hotplug, (void *)&found, NULL); | ||
return found; | ||
} | ||
|
||
int pciehp_acpi_slot_detection_check(struct pci_dev *dev) | ||
{ | ||
if (slot_detection_mode != PCIEHP_DETECT_ACPI) | ||
return 0; | ||
if (pciehp_detect_acpi_slot(dev->subordinate)) | ||
return 0; | ||
return -ENODEV; | ||
} | ||
|
||
static int __init parse_detect_mode(void) | ||
{ | ||
if (!pciehp_detect_mode) | ||
return PCIEHP_DETECT_DEFAULT; | ||
if (!strcmp(pciehp_detect_mode, "pcie")) | ||
return PCIEHP_DETECT_PCIE; | ||
if (!strcmp(pciehp_detect_mode, "acpi")) | ||
return PCIEHP_DETECT_ACPI; | ||
warn("bad specifier '%s' for pciehp_detect_mode. Use default\n", | ||
pciehp_detect_mode); | ||
return PCIEHP_DETECT_DEFAULT; | ||
} | ||
|
||
void __init pciehp_acpi_slot_detection_init(void) | ||
{ | ||
slot_detection_mode = parse_detect_mode(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters