Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 82357
b: refs/heads/master
c: 5c796ae
h: refs/heads/master
i:
  82355: 1e99b81
v: v3
  • Loading branch information
Ian Abbott authored and Greg Kroah-Hartman committed Feb 1, 2008
1 parent 7d04a30 commit 6e75670
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4600c9d74e23b5696acf66a36ce5f2cfbcdecc6c
refs/heads/master: 5c796ae7a7ebe56967ed9b9963d7c16d733635ff
39 changes: 35 additions & 4 deletions trunk/drivers/pci/hotplug/fakephp.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include "../pci.h"

#if !defined(MODULE)
Expand All @@ -63,10 +64,16 @@ struct dummy_slot {
struct list_head node;
struct hotplug_slot *slot;
struct pci_dev *dev;
struct work_struct remove_work;
unsigned long removed;
};

static int debug;
static LIST_HEAD(slot_list);
static struct workqueue_struct *dummyphp_wq;

static void pci_rescan_worker(struct work_struct *work);
static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);

static int enable_slot (struct hotplug_slot *slot);
static int disable_slot (struct hotplug_slot *slot);
Expand Down Expand Up @@ -109,7 +116,7 @@ static int add_slot(struct pci_dev *dev)
slot->name = &dev->dev.bus_id[0];
dbg("slot->name = %s\n", slot->name);

dslot = kmalloc(sizeof(struct dummy_slot), GFP_KERNEL);
dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
if (!dslot)
goto error_info;

Expand Down Expand Up @@ -164,6 +171,14 @@ static void remove_slot(struct dummy_slot *dslot)
err("Problem unregistering a slot %s\n", dslot->slot->name);
}

/* called from the single-threaded workqueue handler to remove a slot */
static void remove_slot_worker(struct work_struct *work)
{
struct dummy_slot *dslot =
container_of(work, struct dummy_slot, remove_work);
remove_slot(dslot);
}

/**
* pci_rescan_slot - Rescan slot
* @temp: Device template. Should be set: bus and devfn.
Expand Down Expand Up @@ -267,11 +282,17 @@ static inline void pci_rescan(void) {
pci_rescan_buses(&pci_root_buses);
}

/* called from the single-threaded workqueue handler to rescan all pci buses */
static void pci_rescan_worker(struct work_struct *work)
{
pci_rescan();
}

static int enable_slot(struct hotplug_slot *hotplug_slot)
{
/* mis-use enable_slot for rescanning of the pci bus */
pci_rescan();
cancel_work_sync(&pci_rescan_work);
queue_work(dummyphp_wq, &pci_rescan_work);
return -ENODEV;
}

Expand Down Expand Up @@ -306,6 +327,10 @@ static int disable_slot(struct hotplug_slot *slot)
err("Can't remove PCI devices with other PCI devices behind it yet.\n");
return -ENODEV;
}
if (test_and_set_bit(0, &dslot->removed)) {
dbg("Slot already scheduled for removal\n");
return -ENODEV;
}
/* search for subfunctions and disable them first */
if (!(dslot->dev->devfn & 7)) {
for (func = 1; func < 8; func++) {
Expand All @@ -328,8 +353,9 @@ static int disable_slot(struct hotplug_slot *slot)
/* remove the device from the pci core */
pci_remove_bus_device(dslot->dev);

/* blow away this sysfs entry and other parts. */
remove_slot(dslot);
/* queue work item to blow away this sysfs entry and other parts. */
INIT_WORK(&dslot->remove_work, remove_slot_worker);
queue_work(dummyphp_wq, &dslot->remove_work);

return 0;
}
Expand All @@ -340,6 +366,7 @@ static void cleanup_slots (void)
struct list_head *next;
struct dummy_slot *dslot;

destroy_workqueue(dummyphp_wq);
list_for_each_safe (tmp, next, &slot_list) {
dslot = list_entry (tmp, struct dummy_slot, node);
remove_slot(dslot);
Expand All @@ -351,6 +378,10 @@ static int __init dummyphp_init(void)
{
info(DRIVER_DESC "\n");

dummyphp_wq = create_singlethread_workqueue(MY_NAME);
if (!dummyphp_wq)
return -ENOMEM;

return pci_scan_buses();
}

Expand Down

0 comments on commit 6e75670

Please sign in to comment.