Skip to content

Commit

Permalink
[PATCH] shpchp: event handling rework
Browse files Browse the repository at this point in the history
The event handler of SHPCHP 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 by 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 Mar 23, 2006
1 parent 68c0b67 commit f7391f5
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 266 deletions.
13 changes: 6 additions & 7 deletions drivers/pci/hotplug/shpchp.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
extern int shpchp_poll_mode;
extern int shpchp_poll_time;
extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;

/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
Expand All @@ -70,11 +71,13 @@ struct slot {
struct hotplug_slot *hotplug_slot;
struct list_head slot_list;
char name[SLOT_NAME_SIZE];
struct work_struct work; /* work for button event */
};

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

struct controller {
Expand All @@ -85,11 +88,9 @@ struct controller {
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
struct event_info event_queue[10];
struct list_head slot_list;
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 @@ -180,9 +181,6 @@ struct hotplug_params {
/* sysfs functions for the hotplug controller info */
extern void shpchp_create_ctrl_files (struct controller *ctrl);

/* controller functions */
extern int shpchp_event_start_thread(void);
extern void shpchp_event_stop_thread(void);
extern int shpchp_enable_slot(struct slot *slot);
extern int shpchp_disable_slot(struct slot *slot);

Expand All @@ -201,7 +199,8 @@ extern void get_hp_params_from_firmware(struct pci_dev *dev,
extern int shpchprm_get_physical_slot_number(struct controller *ctrl,
u32 *sun, u8 busnum, u8 devnum);
extern void shpchp_remove_ctrl_files(struct controller *ctrl);

extern void cleanup_slots(struct controller *ctrl);
extern void shpchp_pushbutton_thread(void *data);

/* Global variables */
extern struct list_head shpchp_ctrl_list;
Expand Down
49 changes: 14 additions & 35 deletions drivers/pci/hotplug/shpchp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/workqueue.h>
#include "shpchp.h"

/* Global variables */
int shpchp_debug;
int shpchp_poll_mode;
int shpchp_poll_time;
LIST_HEAD(shpchp_ctrl_list);
struct workqueue_struct *shpchp_wq;

#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>"
Expand All @@ -57,7 +59,6 @@ MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");

#define SHPC_MODULE_NAME "shpchp"

static int shpc_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 @@ -141,6 +142,7 @@ static int init_slots(struct controller *ctrl)
goto error_info;

slot->number = sun;
INIT_WORK(&slot->work, shpchp_pushbutton_thread, slot);

/* register this slot with the hotplug pci core */
hotplug_slot->private = slot;
Expand Down Expand Up @@ -176,7 +178,7 @@ static int init_slots(struct controller *ctrl)
return retval;
}

static void cleanup_slots(struct controller *ctrl)
void cleanup_slots(struct controller *ctrl)
{
struct list_head *tmp;
struct list_head *next;
Expand All @@ -185,6 +187,8 @@ static void cleanup_slots(struct controller *ctrl)
list_for_each_safe(tmp, next, &ctrl->slot_list) {
slot = list_entry(tmp, struct slot, slot_list);
list_del(&slot->slot_list);
cancel_delayed_work(&slot->work);
flush_workqueue(shpchp_wq);
pci_hp_deregister(slot->hotplug_slot);
}
}
Expand Down Expand Up @@ -400,7 +404,7 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = get_ctlr_slot_config(ctrl);
if (rc) {
err(msg_initialization_err, rc);
goto err_out_unmap_mmio_region;
goto err_out_release_ctlr;
}
first_device_num = ctrl->slot_device_offset;
num_ctlr_slots = ctrl->num_slots;
Expand All @@ -411,7 +415,7 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = init_slots(ctrl);
if (rc) {
err(msg_initialization_err, 6);
goto err_out_free_ctrl_slot;
goto err_out_release_ctlr;
}

/* Now hpc_functions (slot->hpc_ops->functions) are ready */
Expand All @@ -427,40 +431,20 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ctrl->speed = PCI_SPEED_33MHz;
}

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

list_add(&ctrl->ctrl_list, &shpchp_ctrl_list);

shpchp_create_ctrl_files(ctrl);

return 0;

err_out_free_ctrl_slot:
cleanup_slots(ctrl);
err_out_unmap_mmio_region:
err_out_release_ctlr:
ctrl->hpc_ops->release_ctlr(ctrl);
err_out_free_ctrl:
kfree(ctrl);
err_out_none:
return -ENODEV;
}

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

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

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

return retval;
}

static void __exit unload_shpchpd(void)
{
struct list_head *tmp;
Expand All @@ -470,14 +454,11 @@ static void __exit unload_shpchpd(void)
list_for_each_safe(tmp, next, &shpchp_ctrl_list) {
ctrl = list_entry(tmp, struct controller, ctrl_list);
shpchp_remove_ctrl_files(ctrl);
cleanup_slots(ctrl);
ctrl->hpc_ops->release_ctlr(ctrl);
kfree(ctrl);
}

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

destroy_workqueue(shpchp_wq);
}

static struct pci_device_id shpcd_pci_tbl[] = {
Expand All @@ -501,17 +482,15 @@ static int __init shpcd_init(void)
shpchp_poll_mode = 1;
#endif

retval = shpc_start_thread();
if (retval)
goto error_hpc_init;
shpchp_wq = create_singlethread_workqueue("shpchpd");
if (!shpchp_wq)
return -ENOMEM;

retval = pci_register_driver(&shpc_driver);
dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n");

error_hpc_init:
if (retval) {
shpchp_event_stop_thread();
destroy_workqueue(shpchp_wq);
}
return retval;
}
Expand Down
Loading

0 comments on commit f7391f5

Please sign in to comment.