Commit fe99740c authored by Alex Chiang's avatar Alex Chiang Committed by Jesse Barnes

PCI: construct one fakephp slot per PCI slot

Register one slot per slot, rather than one slot per function.  Change the
name of the slot to fake%d instead of the pci address.
Signed-off-by: default avatarAlex Chiang <achiang@hp.com>
Signed-off-by: default avatarMatthew Wilcox <matthew@wil.cx>
Cc: Greg KH <greg@kroah.com>
Cc: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Cc: Len Brown <lenb@kernel.org>
Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 64dab204
...@@ -66,6 +66,7 @@ struct dummy_slot { ...@@ -66,6 +66,7 @@ struct dummy_slot {
struct pci_dev *dev; struct pci_dev *dev;
struct work_struct remove_work; struct work_struct remove_work;
unsigned long removed; unsigned long removed;
char name[8];
}; };
static int debug; static int debug;
...@@ -100,6 +101,7 @@ static int add_slot(struct pci_dev *dev) ...@@ -100,6 +101,7 @@ static int add_slot(struct pci_dev *dev)
struct dummy_slot *dslot; struct dummy_slot *dslot;
struct hotplug_slot *slot; struct hotplug_slot *slot;
int retval = -ENOMEM; int retval = -ENOMEM;
static int count = 1;
slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
if (!slot) if (!slot)
...@@ -113,13 +115,13 @@ static int add_slot(struct pci_dev *dev) ...@@ -113,13 +115,13 @@ static int add_slot(struct pci_dev *dev)
slot->info->max_bus_speed = PCI_SPEED_UNKNOWN; slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN; slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
slot->name = &dev->dev.bus_id[0];
dbg("slot->name = %s\n", slot->name);
dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL); dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
if (!dslot) if (!dslot)
goto error_info; goto error_info;
slot->name = dslot->name;
snprintf(slot->name, sizeof(dslot->name), "fake%d", count++);
dbg("slot->name = %s\n", slot->name);
slot->ops = &dummy_hotplug_slot_ops; slot->ops = &dummy_hotplug_slot_ops;
slot->release = &dummy_release; slot->release = &dummy_release;
slot->private = dslot; slot->private = dslot;
...@@ -148,17 +150,17 @@ static int add_slot(struct pci_dev *dev) ...@@ -148,17 +150,17 @@ static int add_slot(struct pci_dev *dev)
static int __init pci_scan_buses(void) static int __init pci_scan_buses(void)
{ {
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
int retval = 0; int lastslot = 0;
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
retval = add_slot(dev); if (PCI_FUNC(dev->devfn) > 0 &&
if (retval) { lastslot == PCI_SLOT(dev->devfn))
pci_dev_put(dev); continue;
break; lastslot = PCI_SLOT(dev->devfn);
} add_slot(dev);
} }
return retval; return 0;
} }
static void remove_slot(struct dummy_slot *dslot) static void remove_slot(struct dummy_slot *dslot)
...@@ -296,23 +298,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) ...@@ -296,23 +298,9 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
return 0; return 0;
} }
/* find the hotplug_slot for the pci_dev */
static struct hotplug_slot *get_slot_from_dev(struct pci_dev *dev)
{
struct dummy_slot *dslot;
list_for_each_entry(dslot, &slot_list, node) {
if (dslot->dev == dev)
return dslot->slot;
}
return NULL;
}
static int disable_slot(struct hotplug_slot *slot) static int disable_slot(struct hotplug_slot *slot)
{ {
struct dummy_slot *dslot; struct dummy_slot *dslot;
struct hotplug_slot *hslot;
struct pci_dev *dev; struct pci_dev *dev;
int func; int func;
...@@ -322,41 +310,27 @@ static int disable_slot(struct hotplug_slot *slot) ...@@ -322,41 +310,27 @@ static int disable_slot(struct hotplug_slot *slot)
dbg("%s - physical_slot = %s\n", __func__, slot->name); dbg("%s - physical_slot = %s\n", __func__, slot->name);
/* don't disable bridged devices just yet, we can't handle them easily... */ for (func = 7; func >= 0; func--) {
if (dslot->dev->subordinate) { dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func);
err("Can't remove PCI devices with other PCI devices behind it yet.\n"); if (!dev)
return -ENODEV; continue;
}
if (test_and_set_bit(0, &dslot->removed)) { if (test_and_set_bit(0, &dslot->removed)) {
dbg("Slot already scheduled for removal\n"); dbg("Slot already scheduled for removal\n");
return -ENODEV; return -ENODEV;
}
/* search for subfunctions and disable them first */
if (!(dslot->dev->devfn & 7)) {
for (func = 1; func < 8; func++) {
dev = pci_get_slot(dslot->dev->bus,
dslot->dev->devfn + func);
if (dev) {
hslot = get_slot_from_dev(dev);
if (hslot)
disable_slot(hslot);
else {
err("Hotplug slot not found for subfunction of PCI device\n");
return -ENODEV;
}
pci_dev_put(dev);
} else
dbg("No device in slot found\n");
} }
}
/* remove the device from the pci core */ /* queue work item to blow away this sysfs entry and other
pci_remove_bus_device(dslot->dev); * parts.
*/
INIT_WORK(&dslot->remove_work, remove_slot_worker);
queue_work(dummyphp_wq, &dslot->remove_work);
/* queue work item to blow away this sysfs entry and other parts. */ /* blow away this sysfs entry and other parts. */
INIT_WORK(&dslot->remove_work, remove_slot_worker); remove_slot(dslot);
queue_work(dummyphp_wq, &dslot->remove_work);
pci_dev_put(dev);
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment