Merge branch 'pci/bjorn-remove-fakephp' into next
* pci/bjorn-remove-fakephp: PCI: Remove the fakephp driver
This commit is contained in:
commit
be017b255e
4 changed files with 1 additions and 222 deletions
|
@ -253,38 +253,6 @@ Who: Dave Jones <davej@redhat.com>, Matthew Garrett <mjg@redhat.com>
|
||||||
|
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
What: fakephp and associated sysfs files in /sys/bus/pci/slots/
|
|
||||||
When: 2011
|
|
||||||
Why: In 2.6.27, the semantics of /sys/bus/pci/slots was redefined to
|
|
||||||
represent a machine's physical PCI slots. The change in semantics
|
|
||||||
had userspace implications, as the hotplug core no longer allowed
|
|
||||||
drivers to create multiple sysfs files per physical slot (required
|
|
||||||
for multi-function devices, e.g.). fakephp was seen as a developer's
|
|
||||||
tool only, and its interface changed. Too late, we learned that
|
|
||||||
there were some users of the fakephp interface.
|
|
||||||
|
|
||||||
In 2.6.30, the original fakephp interface was restored. At the same
|
|
||||||
time, the PCI core gained the ability that fakephp provided, namely
|
|
||||||
function-level hot-remove and hot-add.
|
|
||||||
|
|
||||||
Since the PCI core now provides the same functionality, exposed in:
|
|
||||||
|
|
||||||
/sys/bus/pci/rescan
|
|
||||||
/sys/bus/pci/devices/.../remove
|
|
||||||
/sys/bus/pci/devices/.../rescan
|
|
||||||
|
|
||||||
there is no functional reason to maintain fakephp as well.
|
|
||||||
|
|
||||||
We will keep the existing module so that 'modprobe fakephp' will
|
|
||||||
present the old /sys/bus/pci/slots/... interface for compatibility,
|
|
||||||
but users are urged to migrate their applications to the API above.
|
|
||||||
|
|
||||||
After a reasonable transition period, we will remove the legacy
|
|
||||||
fakephp interface.
|
|
||||||
Who: Alex Chiang <achiang@hp.com>
|
|
||||||
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
What: CONFIG_RFKILL_INPUT
|
What: CONFIG_RFKILL_INPUT
|
||||||
When: 2.6.33
|
When: 2.6.33
|
||||||
Why: Should be implemented in userspace, policy daemon.
|
Why: Should be implemented in userspace, policy daemon.
|
||||||
|
|
|
@ -17,28 +17,6 @@ menuconfig HOTPLUG_PCI
|
||||||
|
|
||||||
if HOTPLUG_PCI
|
if HOTPLUG_PCI
|
||||||
|
|
||||||
config HOTPLUG_PCI_FAKE
|
|
||||||
tristate "Fake PCI Hotplug driver"
|
|
||||||
help
|
|
||||||
Say Y here if you want to use the fake PCI hotplug driver. It can
|
|
||||||
be used to simulate PCI hotplug events if even if your system is
|
|
||||||
not PCI hotplug capable.
|
|
||||||
|
|
||||||
This driver will "emulate" removing PCI devices from the system.
|
|
||||||
If the "power" file is written to with "0" then the specified PCI
|
|
||||||
device will be completely removed from the kernel.
|
|
||||||
|
|
||||||
WARNING, this does NOT turn off the power to the PCI device.
|
|
||||||
This is a "logical" removal, not a physical or electrical
|
|
||||||
removal.
|
|
||||||
|
|
||||||
Use this module at your own risk. You have been warned!
|
|
||||||
|
|
||||||
To compile this driver as a module, choose M here: the
|
|
||||||
module will be called fakephp.
|
|
||||||
|
|
||||||
When in doubt, say N.
|
|
||||||
|
|
||||||
config HOTPLUG_PCI_COMPAQ
|
config HOTPLUG_PCI_COMPAQ
|
||||||
tristate "Compaq PCI Hotplug driver"
|
tristate "Compaq PCI Hotplug driver"
|
||||||
depends on X86 && PCI_BIOS
|
depends on X86 && PCI_BIOS
|
||||||
|
@ -143,7 +121,7 @@ config HOTPLUG_PCI_SHPC
|
||||||
|
|
||||||
config HOTPLUG_PCI_RPA
|
config HOTPLUG_PCI_RPA
|
||||||
tristate "RPA PCI Hotplug driver"
|
tristate "RPA PCI Hotplug driver"
|
||||||
depends on PPC_PSERIES && EEH && !HOTPLUG_PCI_FAKE
|
depends on PPC_PSERIES && EEH
|
||||||
help
|
help
|
||||||
Say Y here if you have a RPA system that supports PCI Hotplug.
|
Say Y here if you have a RPA system that supports PCI Hotplug.
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,6 @@ obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
|
||||||
|
|
||||||
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
|
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
|
||||||
|
|
||||||
# Link this last so it doesn't claim devices that have a real hotplug driver
|
|
||||||
obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
|
|
||||||
|
|
||||||
pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o
|
pci_hotplug-objs := pci_hotplug_core.o pcihp_slot.o
|
||||||
|
|
||||||
ifdef CONFIG_HOTPLUG_PCI_CPCI
|
ifdef CONFIG_HOTPLUG_PCI_CPCI
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
/* Works like the fakephp driver used to, except a little better.
|
|
||||||
*
|
|
||||||
* - It's possible to remove devices with subordinate busses.
|
|
||||||
* - New PCI devices that appear via any method, not just a fakephp triggered
|
|
||||||
* rescan, will be noticed.
|
|
||||||
* - Devices that are removed via any method, not just a fakephp triggered
|
|
||||||
* removal, will also be noticed.
|
|
||||||
*
|
|
||||||
* Uses nothing from the pci-hotplug subsystem.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/kobject.h>
|
|
||||||
#include <linux/sysfs.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/slab.h>
|
|
||||||
#include "../pci.h"
|
|
||||||
|
|
||||||
struct legacy_slot {
|
|
||||||
struct kobject kobj;
|
|
||||||
struct pci_dev *dev;
|
|
||||||
struct list_head list;
|
|
||||||
};
|
|
||||||
|
|
||||||
static LIST_HEAD(legacy_list);
|
|
||||||
|
|
||||||
static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
|
||||||
struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
|
|
||||||
strcpy(buf, "1\n");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void remove_callback(void *data)
|
|
||||||
{
|
|
||||||
pci_stop_and_remove_bus_device((struct pci_dev *)data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
|
|
||||||
const char *buf, size_t len)
|
|
||||||
{
|
|
||||||
struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
|
|
||||||
unsigned long val;
|
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &val) < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (val)
|
|
||||||
pci_rescan_bus(slot->dev->bus);
|
|
||||||
else
|
|
||||||
sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback,
|
|
||||||
slot->dev, THIS_MODULE);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct attribute *legacy_attrs[] = {
|
|
||||||
&(struct attribute){ .name = "power", .mode = 0644 },
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void legacy_release(struct kobject *kobj)
|
|
||||||
{
|
|
||||||
struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
|
|
||||||
|
|
||||||
pci_dev_put(slot->dev);
|
|
||||||
kfree(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct kobj_type legacy_ktype = {
|
|
||||||
.sysfs_ops = &(const struct sysfs_ops){
|
|
||||||
.store = legacy_store, .show = legacy_show
|
|
||||||
},
|
|
||||||
.release = &legacy_release,
|
|
||||||
.default_attrs = legacy_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int legacy_add_slot(struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL);
|
|
||||||
|
|
||||||
if (!slot)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
if (kobject_init_and_add(&slot->kobj, &legacy_ktype,
|
|
||||||
&pci_slots_kset->kobj, "%s",
|
|
||||||
dev_name(&pdev->dev))) {
|
|
||||||
dev_warn(&pdev->dev, "Failed to created legacy fake slot\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
slot->dev = pci_dev_get(pdev);
|
|
||||||
|
|
||||||
list_add(&slot->list, &legacy_list);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int legacy_notify(struct notifier_block *nb,
|
|
||||||
unsigned long action, void *data)
|
|
||||||
{
|
|
||||||
struct pci_dev *pdev = to_pci_dev(data);
|
|
||||||
|
|
||||||
if (action == BUS_NOTIFY_ADD_DEVICE) {
|
|
||||||
legacy_add_slot(pdev);
|
|
||||||
} else if (action == BUS_NOTIFY_DEL_DEVICE) {
|
|
||||||
struct legacy_slot *slot;
|
|
||||||
|
|
||||||
list_for_each_entry(slot, &legacy_list, list)
|
|
||||||
if (slot->dev == pdev)
|
|
||||||
goto found;
|
|
||||||
|
|
||||||
dev_warn(&pdev->dev, "Missing legacy fake slot?");
|
|
||||||
return -ENODEV;
|
|
||||||
found:
|
|
||||||
kobject_del(&slot->kobj);
|
|
||||||
list_del(&slot->list);
|
|
||||||
kobject_put(&slot->kobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct notifier_block legacy_notifier = {
|
|
||||||
.notifier_call = legacy_notify
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init init_legacy(void)
|
|
||||||
{
|
|
||||||
struct pci_dev *pdev = NULL;
|
|
||||||
|
|
||||||
/* Add existing devices */
|
|
||||||
for_each_pci_dev(pdev)
|
|
||||||
legacy_add_slot(pdev);
|
|
||||||
|
|
||||||
/* Be alerted of any new ones */
|
|
||||||
bus_register_notifier(&pci_bus_type, &legacy_notifier);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
module_init(init_legacy);
|
|
||||||
|
|
||||||
static void __exit remove_legacy(void)
|
|
||||||
{
|
|
||||||
struct legacy_slot *slot, *tmp;
|
|
||||||
|
|
||||||
bus_unregister_notifier(&pci_bus_type, &legacy_notifier);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(slot, tmp, &legacy_list, list) {
|
|
||||||
list_del(&slot->list);
|
|
||||||
kobject_del(&slot->kobj);
|
|
||||||
kobject_put(&slot->kobj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
module_exit(remove_legacy);
|
|
||||||
|
|
||||||
|
|
||||||
MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>");
|
|
||||||
MODULE_DESCRIPTION("Legacy version of the fakephp interface");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
Loading…
Reference in a new issue