Change the semantics of pci_create_slot() such that it does not
require a hotplug release() method when creating a slot. Now, we
can use this interface to create a pci_slot for any physical PCI
slots, not just hotpluggable ones.
Add new pci_slot_add_hotplug() interface so that various PCI hotplug
drivers can add hotplug release() methods to pre-existing physical
slots.
Signed-off-by: Alex Chiang <[email protected]>
---
drivers/pci/hotplug/pci_hotplug_core.c | 2 +-
drivers/pci/slot.c | 36 +++++++++++++++++++++++++++----
include/linux/pci.h | 4 ++-
3 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index c667684..c4b3e61 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -568,7 +568,7 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr)
return -EINVAL;
}
- pci_slot = pci_create_slot(bus, slot_nr, slot->name, hotplug_release);
+ pci_slot = pci_slot_add_hotplug(bus, slot_nr, hotplug_release);
if (IS_ERR(pci_slot))
return PTR_ERR(pci_slot);
slot->pci_slot = pci_slot;
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 5f0b69b..61e86b2 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -71,20 +71,47 @@ static int create_sysfs_files(struct pci_slot *slot)
return result;
}
+struct pci_slot *pci_slot_add_hotplug(struct pci_bus *parent, int slot_nr,
+ void (*release)(struct pci_slot *))
+{
+ struct pci_slot *slot;
+ int found = 0;
+
+ down_write(&pci_bus_sem);
+
+ /* This slot should have already been created, so look for it. If
+ * we can't find it, return -EEXIST.
+ */
+ for (slot = parent->slot; slot; slot = slot->next)
+ if (slot->number == slot_nr) {
+ found = 1;
+ break;
+ }
+
+ if (!found) {
+ slot = ERR_PTR(-EEXIST);
+ goto out;
+ }
+
+ slot->release = release;
+ out:
+ up_write(&pci_bus_sem);
+ return slot;
+}
+EXPORT_SYMBOL_GPL(pci_slot_add_hotplug);
+
struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
- const char *name, void (*release)(struct pci_slot *))
+ const char *name)
{
struct pci_slot *slot;
int err;
down_write(&pci_bus_sem);
- /* If we've already created this slot, return -EEXIST. The same slot
- * may be described twice (eg, by ACPI and PCIe) */
+ /* If we've already created this slot, just return. */
for (slot = parent->slot; slot; slot = slot->next) {
if (slot->number != slot_nr)
continue;
- slot = ERR_PTR(-EEXIST);
goto out;
}
@@ -96,7 +123,6 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
slot->bus = parent;
slot->number = slot_nr;
- slot->release = release;
kobject_set_name(&slot->kobj, "%s", name);
kobj_set_kset_s(slot, pci_slots_subsys);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a075667..62116a5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -483,7 +483,9 @@ static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *s
struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
- const char *name, void (*release)(struct pci_slot *));
+ const char *name);
+struct pci_slot *pci_slot_add_hotplug(struct pci_bus *parent, int slot_nr,
+ void (*release)(struct pci_slot *));
int pci_scan_slot(struct pci_bus *bus, int devfn);
struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn);
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus);
--
1.5.3.1.1.g1e61
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]