Skip to content

Commit

Permalink
pciehp: Event handling rework
Browse files Browse the repository at this point in the history
The event handler of PCIEHP driver is unnecessarily very complex. In
addition, current event handler can only a fixed number of events at
the same time, and some of events would be lost if several number of
events happened at the same time.

This patch simplify the event handler using 'work queue', and it also
fix the above-mentioned issue.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Kenji Kaneshige authored and Greg Kroah-Hartman committed May 3, 2007
1 parent f7bdd12 commit 5d386e1
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 389 deletions.
16 changes: 8 additions & 8 deletions drivers/pci/hotplug/pciehp.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ extern int pciehp_poll_mode;
extern int pciehp_poll_time;
extern int pciehp_debug;
extern int pciehp_force;
extern struct workqueue_struct *pciehp_wq;

#define dbg(format, arg...) \
do { \
Expand Down Expand Up @@ -70,14 +71,16 @@ struct slot {
struct list_head slot_list;
char name[SLOT_NAME_SIZE];
unsigned long last_emi_toggle;
struct delayed_work work; /* work for button event */
struct mutex lock;
};

struct event_info {
u32 event_type;
u8 hp_slot;
struct slot *p_slot;
struct work_struct work;
};

#define MAX_EVENTS 10
struct controller {
struct controller *next;
struct mutex crit_sect; /* critical section mutex */
Expand All @@ -86,11 +89,9 @@ struct controller {
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
struct list_head slot_list;
struct event_info event_queue[MAX_EVENTS];
struct slot *slot;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 next_event;
u8 bus;
u8 device;
u8 function;
Expand Down Expand Up @@ -149,16 +150,15 @@ struct controller {
#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP)
#define EMI(cap) (cap & EMI_PRSN)

extern int pciehp_event_start_thread(void);
extern void pciehp_event_stop_thread(void);
extern int pciehp_enable_slot(struct slot *slot);
extern int pciehp_disable_slot(struct slot *slot);
extern int pciehp_sysfs_enable_slot(struct slot *slot);
extern int pciehp_sysfs_disable_slot(struct slot *slot);
extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
extern int pciehp_configure_device(struct slot *p_slot);
extern int pciehp_unconfigure_device(struct slot *p_slot);
extern void queue_pushbutton_work(struct work_struct *work);
int pcie_init(struct controller *ctrl, struct pcie_device *dev);

/* Global variables */
Expand Down
44 changes: 8 additions & 36 deletions drivers/pci/hotplug/pciehp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ int pciehp_debug;
int pciehp_poll_mode;
int pciehp_poll_time;
int pciehp_force;
struct workqueue_struct *pciehp_wq;
struct controller *pciehp_ctrl_list;

#define DRIVER_VERSION "0.4"
Expand All @@ -62,7 +63,6 @@ MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"

#define PCIE_MODULE_NAME "pciehp"

static int pcie_start_thread (void);
static int set_attention_status (struct hotplug_slot *slot, u8 value);
static int enable_slot (struct hotplug_slot *slot);
static int disable_slot (struct hotplug_slot *slot);
Expand Down Expand Up @@ -229,6 +229,8 @@ static int init_slots(struct controller *ctrl)
slot->device = ctrl->slot_device_offset + i;
slot->hpc_ops = ctrl->hpc_ops;
slot->number = ctrl->first_slot;
mutex_init(&slot->lock);
INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);

/* register this slot with the hotplug pci core */
hotplug_slot->private = slot;
Expand Down Expand Up @@ -286,6 +288,9 @@ static void cleanup_slots(struct controller *ctrl)
if (EMI(ctrl->ctrlcap))
sysfs_remove_file(&slot->hotplug_slot->kobj,
&hotplug_slot_attr_lock.attr);
cancel_delayed_work(&slot->work);
flush_scheduled_work();
flush_workqueue(pciehp_wq);
pci_hp_deregister(slot->hotplug_slot);
}
}
Expand Down Expand Up @@ -314,7 +319,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)

dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);

return pciehp_enable_slot(slot);
return pciehp_sysfs_enable_slot(slot);
}


Expand All @@ -324,7 +329,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)

dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);

return pciehp_disable_slot(slot);
return pciehp_sysfs_disable_slot(slot);
}

static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
Expand Down Expand Up @@ -466,9 +471,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_

t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset);

/* Finish setting up the hot plug ctrl device */
ctrl->next_event = 0;

if (!pciehp_ctrl_list) {
pciehp_ctrl_list = ctrl;
ctrl->next = NULL;
Expand Down Expand Up @@ -496,22 +498,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
return -ENODEV;
}


static int pcie_start_thread(void)
{
int retval = 0;

dbg("Initialize + Start the notification/polling mechanism \n");

retval = pciehp_event_start_thread();
if (retval) {
dbg("pciehp_event_start_thread() failed\n");
return retval;
}

return retval;
}

static void __exit unload_pciehpd(void)
{
struct controller *ctrl;
Expand All @@ -529,10 +515,6 @@ static void __exit unload_pciehpd(void)

kfree(tctrl);
}

/* Stop the notification mechanism */
pciehp_event_stop_thread();

}

static void pciehp_remove (struct pcie_device *device)
Expand Down Expand Up @@ -585,21 +567,11 @@ static int __init pcied_init(void)
pciehp_poll_mode = 1;
#endif

retval = pcie_start_thread();
if (retval)
goto error_hpc_init;

retval = pcie_port_service_register(&hpdriver_portdrv);
dbg("pcie_port_service_register = %d\n", retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
if (retval)
dbg("%s: Failure to register service\n", __FUNCTION__);

error_hpc_init:
if (retval) {
pciehp_event_stop_thread();
};

return retval;
}

Expand Down
Loading

0 comments on commit 5d386e1

Please sign in to comment.