Browse Source

PCI: PCIe: Introduce commad line switch for disabling port services

Introduce kernel command line switch pcie_ports= allowing one to
disable all of the native PCIe port services, so that PCIe ports
are treated like PCI-to-PCI bridges.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Rafael J. Wysocki 14 years ago
parent
commit
79dd9182db

+ 4 - 0
Documentation/kernel-parameters.txt

@@ -2042,6 +2042,10 @@ and is between 256 and 4096 characters. It is defined in the file
 		force	Enable ASPM even on devices that claim not to support it.
 		force	Enable ASPM even on devices that claim not to support it.
 			WARNING: Forcing ASPM on may cause system lockups.
 			WARNING: Forcing ASPM on may cause system lockups.
 
 
+	pcie_ports=	[PCIE] PCIe ports handling:
+		compat	Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe
+			ports driver.
+
 	pcie_pme=	[PCIE,PM] Native PCIe PME signaling options:
 	pcie_pme=	[PCIE,PM] Native PCIe PME signaling options:
 			Format: {auto|force}[,nomsi]
 			Format: {auto|force}[,nomsi]
 		auto	Use native PCIe PME signaling if the BIOS allows the
 		auto	Use native PCIe PME signaling if the BIOS allows the

+ 2 - 0
drivers/pci/pcie/portdrv.h

@@ -20,6 +20,8 @@
 
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
 
+extern bool pcie_ports_disabled;
+
 extern struct bus_type pcie_port_bus_type;
 extern struct bus_type pcie_port_bus_type;
 extern int pcie_port_device_register(struct pci_dev *dev);
 extern int pcie_port_device_register(struct pci_dev *dev);
 #ifdef CONFIG_PM
 #ifdef CONFIG_PM

+ 3 - 0
drivers/pci/pcie/portdrv_core.c

@@ -494,6 +494,9 @@ static void pcie_port_shutdown_service(struct device *dev) {}
  */
  */
 int pcie_port_service_register(struct pcie_port_service_driver *new)
 int pcie_port_service_register(struct pcie_port_service_driver *new)
 {
 {
+	if (pcie_ports_disabled)
+		return -ENODEV;
+
 	new->driver.name = (char *)new->name;
 	new->driver.name = (char *)new->name;
 	new->driver.bus = &pcie_port_bus_type;
 	new->driver.bus = &pcie_port_bus_type;
 	new->driver.probe = pcie_port_probe_service;
 	new->driver.probe = pcie_port_probe_service;

+ 15 - 0
drivers/pci/pcie/portdrv_pci.c

@@ -29,6 +29,18 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
+/* If this switch is set, PCIe port native services should not be enabled. */
+bool pcie_ports_disabled;
+
+static int __init pcie_port_setup(char *str)
+{
+	if (!strncmp(str, "compat", 6))
+		pcie_ports_disabled = true;
+
+	return 1;
+}
+__setup("pcie_ports=", pcie_port_setup);
+
 /* global data */
 /* global data */
 
 
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
@@ -301,6 +313,9 @@ static int __init pcie_portdrv_init(void)
 {
 {
 	int retval;
 	int retval;
 
 
+	if (pcie_ports_disabled)
+		return -EACCES;
+
 	dmi_check_system(pcie_portdrv_dmi_table);
 	dmi_check_system(pcie_portdrv_dmi_table);
 
 
 	retval = pcie_port_bus_register();
 	retval = pcie_port_bus_register();