Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
  PCI: bus speed strings should be const
  PCI hotplug: Fix build with CONFIG_ACPI unset
  PCI: PCIe: Remove the port driver module exit routine
  PCI: PCIe: Move PCIe PME code to the pcie directory
  PCI: PCIe: Disable PCIe port services during port initialization
  PCI: PCIe: Ask BIOS for control of all native services at once
  ACPI/PCI: Negotiate _OSC control bits before requesting them
  ACPI/PCI: Do not preserve _OSC control bits returned by a query
  ACPI/PCI: Make acpi_pci_query_osc() return control bits
  ACPI/PCI: Reorder checks in acpi_pci_osc_control_set()
  PCI: PCIe: Introduce commad line switch for disabling port services
  PCI: PCIe AER: Introduce pci_aer_available()
  x86/PCI: only define pci_domain_nr if PCI and PCI_DOMAINS are set
  PCI: provide stub pci_domain_nr function for !CONFIG_PCI configs
This commit is contained in:
Linus Torvalds 2010-09-07 16:00:17 -07:00
commit d56557af19
24 changed files with 281 additions and 291 deletions

View file

@ -338,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
acpi_handle chandle, handle;
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
OSC_SHPC_NATIVE_HP_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
flags &= OSC_SHPC_NATIVE_HP_CONTROL;
if (!flags) {
err("Invalid flags %u specified!\n", flags);
return -EINVAL;
@ -360,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
dbg("Trying to get hotplug control for %s\n",
(char *)string.pointer);
status = acpi_pci_osc_control_set(handle, flags);
status = acpi_pci_osc_control_set(handle, &flags, flags);
if (ACPI_SUCCESS(status))
goto got_one;
if (status == AE_SUPPORT)

View file

@ -176,19 +176,11 @@ 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);
retval = acpi_get_hp_hw_control_from_firmware(dev, flags);
if (retval)
return retval;
return pciehp_acpi_slot_detection_check(dev);
}
#else
#define pciehp_firmware_init() do {} while (0)
#define pciehp_get_hp_hw_control_from_firmware(dev) 0
static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
{
return 0;
}
#endif /* CONFIG_ACPI */
#endif /* _PCIEHP_H */

View file

@ -85,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev)
acpi_handle handle;
struct dummy_slot *slot, *tmp;
struct pci_dev *pdev = dev->port;
/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
if (pciehp_get_hp_hw_control_from_firmware(pdev))
return -ENODEV;
pos = pci_pcie_cap(pdev);
if (!pos)
return -ENODEV;

View file

@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644);
MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");
#define PCIE_MODULE_NAME "pciehp"
@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev)
dev_info(&dev->device,
"Bypassing BIOS check for pciehp use on %s\n",
pci_name(dev->port));
else if (pciehp_get_hp_hw_control_from_firmware(dev->port))
else if (pciehp_acpi_slot_detection_check(dev->port))
goto err_out_none;
ctrl = pcie_init(dev);

View file

@ -140,8 +140,10 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
#ifdef CONFIG_PCIEAER
void pci_no_aer(void);
bool pci_aer_available(void);
#else
static inline void pci_no_aer(void) { }
static inline bool pci_aer_available(void) { return false; }
#endif
static inline int pci_no_d1d2(struct pci_dev *dev)

View file

@ -6,10 +6,11 @@
obj-$(CONFIG_PCIEASPM) += aspm.o
pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o
obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
# Build PCI Express AER if needed
obj-$(CONFIG_PCIEAER) += aer/
obj-$(CONFIG_PCIE_PME) += pme/
obj-$(CONFIG_PCIE_PME) += pme.o

View file

@ -72,6 +72,11 @@ void pci_no_aer(void)
pcie_aer_disable = 1; /* has priority over 'forceload' */
}
bool pci_aer_available(void)
{
return !pcie_aer_disable && pci_msi_enabled();
}
static int set_device_error_reporting(struct pci_dev *dev, void *data)
{
bool enable = *((bool *)data);
@ -411,9 +416,7 @@ static void aer_error_resume(struct pci_dev *dev)
*/
static int __init aer_service_init(void)
{
if (pcie_aer_disable)
return -ENXIO;
if (!pci_msi_enabled())
if (!pci_aer_available())
return -ENXIO;
return pcie_port_service_register(&aerdriver);
}

View file

@ -19,42 +19,6 @@
#include <acpi/apei.h>
#include "aerdrv.h"
/**
* aer_osc_setup - run ACPI _OSC method
* @pciedev: pcie_device which AER is being enabled on
*
* @return: Zero on success. Nonzero otherwise.
*
* Invoked when PCIe bus loads AER service driver. To avoid conflict with
* BIOS AER support requires BIOS to yield AER control to OS native driver.
**/
int aer_osc_setup(struct pcie_device *pciedev)
{
acpi_status status = AE_NOT_FOUND;
struct pci_dev *pdev = pciedev->port;
acpi_handle handle = NULL;
if (acpi_pci_disabled)
return -1;
handle = acpi_find_root_bridge_handle(pdev);
if (handle) {
status = acpi_pci_osc_control_set(handle,
OSC_PCI_EXPRESS_AER_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
}
if (ACPI_FAILURE(status)) {
dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't "
"init device: %s\n",
(status == AE_SUPPORT || status == AE_NOT_FOUND) ?
"no _OSC support" : "_OSC failed");
return -1;
}
return 0;
}
#ifdef CONFIG_ACPI_APEI
static inline int hest_match_pci(struct acpi_hest_aer_common *p,
struct pci_dev *pci)

View file

@ -772,22 +772,10 @@ void aer_isr(struct work_struct *work)
*/
int aer_init(struct pcie_device *dev)
{
if (pcie_aer_get_firmware_first(dev->port)) {
dev_printk(KERN_DEBUG, &dev->device,
"PCIe errors handled by platform firmware.\n");
goto out;
}
if (aer_osc_setup(dev))
goto out;
return 0;
out:
if (forceload) {
dev_printk(KERN_DEBUG, &dev->device,
"aerdrv forceload requested.\n");
pcie_aer_force_firmware_first(dev->port, 0);
return 0;
}
return -ENXIO;
return 0;
}

View file

@ -23,37 +23,12 @@
#include <linux/pci-acpi.h>
#include <linux/pm_runtime.h>
#include "../../pci.h"
#include "pcie_pme.h"
#include "../pci.h"
#include "portdrv.h"
#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
/*
* If set, this switch will prevent the PCIe root port PME service driver from
* being registered. Consequently, the interrupt-based PCIe PME signaling will
* not be used by any PCIe root ports in that case.
*/
static bool pcie_pme_disabled = true;
/*
* The PCI Express Base Specification 2.0, Section 6.1.8, states the following:
* "In order to maintain compatibility with non-PCI Express-aware system
* software, system power management logic must be configured by firmware to use
* the legacy mechanism of signaling PME by default. PCI Express-aware system
* software must notify the firmware prior to enabling native, interrupt-based
* PME signaling." However, if the platform doesn't provide us with a suitable
* notification mechanism or the notification fails, it is not clear whether or
* not we are supposed to use the interrupt-based PCIe PME signaling. The
* switch below can be used to indicate the desired behaviour. When set, it
* will make the kernel use the interrupt-based PCIe PME signaling regardless of
* the platform notification status, although the kernel will attempt to notify
* the platform anyway. When unset, it will prevent the kernel from using the
* the interrupt-based PCIe PME signaling if the platform notification fails,
* which is the default.
*/
static bool pcie_pme_force_enable;
/*
* If this switch is set, MSI will not be used for PCIe PME signaling. This
* causes the PCIe port driver to use INTx interrupts only, but it turns out
@ -64,38 +39,13 @@ bool pcie_pme_msi_disabled;
static int __init pcie_pme_setup(char *str)
{
if (!strncmp(str, "auto", 4))
pcie_pme_disabled = false;
else if (!strncmp(str, "force", 5))
pcie_pme_force_enable = true;
str = strchr(str, ',');
if (str) {
str++;
str += strspn(str, " \t");
if (*str && !strcmp(str, "nomsi"))
pcie_pme_msi_disabled = true;
}
if (!strncmp(str, "nomsi", 5))
pcie_pme_msi_disabled = true;
return 1;
}
__setup("pcie_pme=", pcie_pme_setup);
/**
* pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME.
* @srv: PCIe PME root port service to use for carrying out the check.
*
* Notify the platform that the native PCIe PME is going to be used and return
* 'true' if the control of the PCIe PME registers has been acquired from the
* platform.
*/
static bool pcie_pme_platform_setup(struct pcie_device *srv)
{
if (!pcie_pme_platform_notify(srv))
return true;
return pcie_pme_force_enable;
}
struct pcie_pme_service_data {
spinlock_t lock;
struct pcie_device *srv;
@ -108,7 +58,7 @@ struct pcie_pme_service_data {
* @dev: PCIe root port or event collector.
* @enable: Enable or disable the interrupt.
*/
static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
{
int rtctl_pos;
u16 rtctl;
@ -417,9 +367,6 @@ static int pcie_pme_probe(struct pcie_device *srv)
struct pcie_pme_service_data *data;
int ret;
if (!pcie_pme_platform_setup(srv))
return -EACCES;
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
@ -509,8 +456,7 @@ static struct pcie_port_service_driver pcie_pme_driver = {
*/
static int __init pcie_pme_service_init(void)
{
return pcie_pme_disabled ?
-ENODEV : pcie_port_service_register(&pcie_pme_driver);
return pcie_port_service_register(&pcie_pme_driver);
}
module_init(pcie_pme_service_init);

View file

@ -1,8 +0,0 @@
#
# Makefile for PCI-Express Root Port PME signaling driver
#
obj-$(CONFIG_PCIE_PME) += pmedriver.o
pmedriver-objs := pcie_pme.o
pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o

View file

@ -1,28 +0,0 @@
/*
* drivers/pci/pcie/pme/pcie_pme.h
*
* PCI Express Root Port PME signaling support
*
* Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*/
#ifndef _PCIE_PME_H_
#define _PCIE_PME_H_
struct pcie_device;
#ifdef CONFIG_ACPI
extern int pcie_pme_acpi_setup(struct pcie_device *srv);
static inline int pcie_pme_platform_notify(struct pcie_device *srv)
{
return pcie_pme_acpi_setup(srv);
}
#else /* !CONFIG_ACPI */
static inline int pcie_pme_platform_notify(struct pcie_device *srv)
{
return 0;
}
#endif /* !CONFIG_ACPI */
#endif

View file

@ -1,54 +0,0 @@
/*
* PCIe Native PME support, ACPI-related part
*
* Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*
* This file is subject to the terms and conditions of the GNU General Public
* License V2. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/pci-acpi.h>
#include <linux/pcieport_if.h>
/**
* pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME.
* @srv - PCIe PME service for a root port or event collector.
*
* Invoked when the PCIe bus type loads PCIe PME service driver. To avoid
* conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME
* control to the kernel.
*/
int pcie_pme_acpi_setup(struct pcie_device *srv)
{
acpi_status status = AE_NOT_FOUND;
struct pci_dev *port = srv->port;
acpi_handle handle;
int error = 0;
if (acpi_pci_disabled)
return -ENOSYS;
dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n");
handle = acpi_find_root_bridge_handle(port);
if (!handle)
return -EINVAL;
status = acpi_pci_osc_control_set(handle,
OSC_PCI_EXPRESS_PME_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
if (ACPI_FAILURE(status)) {
dev_info(&port->dev,
"Failed to receive control of PCIe PME service: %s\n",
(status == AE_SUPPORT || status == AE_NOT_FOUND) ?
"no _OSC support" : "ACPI _OSC failed");
error = -ENODEV;
}
return error;
}

View file

@ -20,6 +20,9 @@
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
extern bool pcie_ports_disabled;
extern bool pcie_ports_auto;
extern struct bus_type pcie_port_bus_type;
extern int pcie_port_device_register(struct pci_dev *dev);
#ifdef CONFIG_PM
@ -30,6 +33,8 @@ extern void pcie_port_device_remove(struct pci_dev *dev);
extern int __must_check pcie_port_bus_register(void);
extern void pcie_port_bus_unregister(void);
struct pci_dev;
#ifdef CONFIG_PCIE_PME
extern bool pcie_pme_msi_disabled;
@ -42,9 +47,26 @@ static inline bool pcie_pme_no_msi(void)
{
return pcie_pme_msi_disabled;
}
extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable);
#else /* !CONFIG_PCIE_PME */
static inline void pcie_pme_disable_msi(void) {}
static inline bool pcie_pme_no_msi(void) { return false; }
static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}
#endif /* !CONFIG_PCIE_PME */
#ifdef CONFIG_ACPI
extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask);
static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
{
return pcie_port_acpi_setup(port, mask);
}
#else /* !CONFIG_ACPI */
static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
{
return 0;
}
#endif /* !CONFIG_ACPI */
#endif /* _PORTDRV_H_ */

View file

@ -0,0 +1,77 @@
/*
* PCIe Port Native Services Support, ACPI-Related Part
*
* Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
*
* This file is subject to the terms and conditions of the GNU General Public
* License V2. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/pci-acpi.h>
#include <linux/pcieport_if.h>
#include "aer/aerdrv.h"
#include "../pci.h"
/**
* pcie_port_acpi_setup - Request the BIOS to release control of PCIe services.
* @port: PCIe Port service for a root port or event collector.
* @srv_mask: Bit mask of services that can be enabled for @port.
*
* Invoked when @port is identified as a PCIe port device. To avoid conflicts
* with the BIOS PCIe port native services support requires the BIOS to yield
* control of these services to the kernel. The mask of services that the BIOS
* allows to be enabled for @port is written to @srv_mask.
*
* NOTE: It turns out that we cannot do that for individual port services
* separately, because that would make some systems work incorrectly.
*/
int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
{
acpi_status status;
acpi_handle handle;
u32 flags;
if (acpi_pci_disabled)
return 0;
handle = acpi_find_root_bridge_handle(port);
if (!handle)
return -EINVAL;
flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
| OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
| OSC_PCI_EXPRESS_PME_CONTROL;
if (pci_aer_available()) {
if (pcie_aer_get_firmware_first(port))
dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n");
else
flags |= OSC_PCI_EXPRESS_AER_CONTROL;
}
status = acpi_pci_osc_control_set(handle, &flags,
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
if (ACPI_FAILURE(status)) {
dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n",
status);
return -ENODEV;
}
dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags);
*srv_mask = PCIE_PORT_SERVICE_VC;
if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
*srv_mask |= PCIE_PORT_SERVICE_HP;
if (flags & OSC_PCI_EXPRESS_PME_CONTROL)
*srv_mask |= PCIE_PORT_SERVICE_PME;
if (flags & OSC_PCI_EXPRESS_AER_CONTROL)
*srv_mask |= PCIE_PORT_SERVICE_AER;
return 0;
}

View file

@ -14,6 +14,8 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/pcieport_if.h>
#include <linux/aer.h>
#include <linux/pci-aspm.h>
#include "../pci.h"
#include "portdrv.h"
@ -236,24 +238,64 @@ static int get_port_device_capability(struct pci_dev *dev)
int services = 0, pos;
u16 reg16;
u32 reg32;
int cap_mask;
int err;
err = pcie_port_platform_notify(dev, &cap_mask);
if (pcie_ports_auto) {
if (err) {
pcie_no_aspm();
return 0;
}
} else {
cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
| PCIE_PORT_SERVICE_VC;
if (pci_aer_available())
cap_mask |= PCIE_PORT_SERVICE_AER;
}
pos = pci_pcie_cap(dev);
pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
/* Hot-Plug Capable */
if (reg16 & PCI_EXP_FLAGS_SLOT) {
if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
if (reg32 & PCI_EXP_SLTCAP_HPC)
if (reg32 & PCI_EXP_SLTCAP_HPC) {
services |= PCIE_PORT_SERVICE_HP;
/*
* Disable hot-plug interrupts in case they have been
* enabled by the BIOS and the hot-plug service driver
* is not loaded.
*/
pos += PCI_EXP_SLTCTL;
pci_read_config_word(dev, pos, &reg16);
reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
pci_write_config_word(dev, pos, reg16);
}
}
/* AER capable */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
if ((cap_mask & PCIE_PORT_SERVICE_AER)
&& pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
services |= PCIE_PORT_SERVICE_AER;
/*
* Disable AER on this port in case it's been enabled by the
* BIOS (the AER service driver will enable it when necessary).
*/
pci_disable_pcie_error_reporting(dev);
}
/* VC support */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
services |= PCIE_PORT_SERVICE_VC;
/* Root ports are capable of generating PME too */
if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
if ((cap_mask & PCIE_PORT_SERVICE_PME)
&& dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
services |= PCIE_PORT_SERVICE_PME;
/*
* Disable PME interrupt on this port in case it's been enabled
* by the BIOS (the PME service driver will enable it when
* necessary).
*/
pcie_pme_interrupt_enable(dev, false);
}
return services;
}
@ -494,6 +536,9 @@ static void pcie_port_shutdown_service(struct device *dev) {}
*/
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.bus = &pcie_port_bus_type;
new->driver.probe = pcie_port_probe_service;

View file

@ -15,6 +15,7 @@
#include <linux/pcieport_if.h>
#include <linux/aer.h>
#include <linux/dmi.h>
#include <linux/pci-aspm.h>
#include "portdrv.h"
#include "aer/aerdrv.h"
@ -29,6 +30,31 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
/* If this switch is set, PCIe port native services should not be enabled. */
bool pcie_ports_disabled;
/*
* If this switch is set, ACPI _OSC will be used to determine whether or not to
* enable PCIe port native services.
*/
bool pcie_ports_auto = true;
static int __init pcie_port_setup(char *str)
{
if (!strncmp(str, "compat", 6)) {
pcie_ports_disabled = true;
} else if (!strncmp(str, "native", 6)) {
pcie_ports_disabled = false;
pcie_ports_auto = false;
} else if (!strncmp(str, "auto", 4)) {
pcie_ports_disabled = false;
pcie_ports_auto = true;
}
return 1;
}
__setup("pcie_ports=", pcie_port_setup);
/* global data */
static int pcie_portdrv_restore_config(struct pci_dev *dev)
@ -301,6 +327,11 @@ static int __init pcie_portdrv_init(void)
{
int retval;
if (pcie_ports_disabled) {
pcie_no_aspm();
return -EACCES;
}
dmi_check_system(pcie_portdrv_dmi_table);
retval = pcie_port_bus_register();
@ -315,11 +346,4 @@ static int __init pcie_portdrv_init(void)
return retval;
}
static void __exit pcie_portdrv_exit(void)
{
pci_unregister_driver(&pcie_portdriver);
pcie_port_bus_unregister();
}
module_init(pcie_portdrv_init);
module_exit(pcie_portdrv_exit);

View file

@ -49,7 +49,7 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
}
/* these strings match up with the values in pci_bus_speed */
static char *pci_bus_speed_strings[] = {
static const char *pci_bus_speed_strings[] = {
"33 MHz PCI", /* 0x00 */
"66 MHz PCI", /* 0x01 */
"66 MHz PCI-X", /* 0x02 */