diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-26 19:56:37 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-26 19:56:37 -0800 |
commit | d8419c1249522fbe7c585d447c6e852cdc10a3f0 (patch) | |
tree | 938f570a5f85b033cc2743077cf33a767470ea37 /pci | |
parent | 7b8846146f3a6a6788eeb54f5f957f6cf998b211 (diff) | |
download | patches-d8419c1249522fbe7c585d447c6e852cdc10a3f0.tar.gz |
add pci hotplug patches
Diffstat (limited to 'pci')
-rw-r--r-- | pci/pcihp_skeleton.c-cleanup.patch | 125 | ||||
-rw-r--r-- | pci/shpchp-bugfix-add-missing-serialization.patch | 197 | ||||
-rw-r--r-- | pci/shpchp-cleanup-check-command-status.patch | 348 | ||||
-rw-r--r-- | pci/shpchp-cleanup-controller-list.patch | 105 | ||||
-rw-r--r-- | pci/shpchp-cleanup-init_slots.patch | 190 | ||||
-rw-r--r-- | pci/shpchp-cleanup-shpchp_core.c.patch | 280 | ||||
-rw-r--r-- | pci/shpchp-cleanup-slot-list.patch | 113 | ||||
-rw-r--r-- | pci/shpchp-fix-incorrect-return-value-of-interrupt-handler.patch | 55 | ||||
-rw-r--r-- | pci/shpchp-move-slot-name-into-struct-slot.patch | 97 | ||||
-rw-r--r-- | pci/shpchp-removed-unncessary-magic-member-from-slot.patch | 52 | ||||
-rw-r--r-- | pci/shpchp-replace-kmalloc-with-kzalloc-and-cleanup-arg-of-sizeof.patch | 89 |
11 files changed, 1651 insertions, 0 deletions
diff --git a/pci/pcihp_skeleton.c-cleanup.patch b/pci/pcihp_skeleton.c-cleanup.patch new file mode 100644 index 0000000000000..fd6fd73906431 --- /dev/null +++ b/pci/pcihp_skeleton.c-cleanup.patch @@ -0,0 +1,125 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 17:03:18 2006 +Message-ID: <43D81F6F.2030606@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 10:01:35 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: pcihpd-discuss@lists.sourceforge.net, Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 7/11] pcihp_skeleton.c cleanup + +This patch cleans up pcihp_skelton.c as follows. + + o Move slot name area into struct slot. + o Replace kmalloc with kzalloc and clean up the arg of sizeof() + o Fix the wrong use of get_*_status() functions. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/pci/hotplug/pcihp_skeleton.c | 33 +++++++++++---------------------- + 1 file changed, 11 insertions(+), 22 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/pcihp_skeleton.c ++++ gregkh-2.6/drivers/pci/hotplug/pcihp_skeleton.c +@@ -37,10 +37,12 @@ + #include <linux/init.h> + #include "pci_hotplug.h" + ++#define SLOT_NAME_SIZE 10 + struct slot { + u8 number; + struct hotplug_slot *hotplug_slot; + struct list_head slot_list; ++ char name[SLOT_NAME_SIZE]; + }; + + static LIST_HEAD(slot_list); +@@ -233,12 +235,10 @@ static void release_slot(struct hotplug_ + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + kfree(slot->hotplug_slot->info); +- kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); + } + +-#define SLOT_NAME_SIZE 10 + static void make_slot_name(struct slot *slot) + { + /* +@@ -257,7 +257,6 @@ static int __init init_slots(void) + struct slot *slot; + struct hotplug_slot *hotplug_slot; + struct hotplug_slot_info *info; +- char *name; + int retval = -ENOMEM; + int i; + +@@ -266,31 +265,23 @@ static int __init init_slots(void) + * with the pci_hotplug subsystem. + */ + for (i = 0; i < num_slots; ++i) { +- slot = kmalloc(sizeof(struct slot), GFP_KERNEL); ++ slot = kzalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) + goto error; +- memset(slot, 0, sizeof(struct slot)); + +- hotplug_slot = kmalloc(sizeof(struct hotplug_slot), +- GFP_KERNEL); ++ hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); + if (!hotplug_slot) + goto error_slot; +- memset(hotplug_slot, 0, sizeof (struct hotplug_slot)); + slot->hotplug_slot = hotplug_slot; + +- info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); ++ info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + goto error_hpslot; +- memset(info, 0, sizeof (struct hotplug_slot_info)); + hotplug_slot->info = info; + +- name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); +- if (!name) +- goto error_info; +- hotplug_slot->name = name; +- + slot->number = i; + ++ hotplug_slot->name = slot->name; + hotplug_slot->private = slot; + hotplug_slot->release = &release_slot; + make_slot_name(slot); +@@ -300,16 +291,16 @@ static int __init init_slots(void) + * Initialize the slot info structure with some known + * good values. + */ +- info->power_status = get_power_status(slot); +- info->attention_status = get_attention_status(slot); +- info->latch_status = get_latch_status(slot); +- info->adapter_status = get_adapter_status(slot); ++ get_power_status(hotplug_slot, &info->power_status); ++ get_attention_status(hotplug_slot, &info->attention_status); ++ get_latch_status(hotplug_slot, &info->latch_status); ++ get_adapter_status(hotplug_slot, &info->adapter_status); + + dbg("registering slot %d\n", i); + retval = pci_hp_register(slot->hotplug_slot); + if (retval) { + err("pci_hp_register failed with error %d\n", retval); +- goto error_name; ++ goto error_info; + } + + /* add slot to our internal list */ +@@ -317,8 +308,6 @@ static int __init init_slots(void) + } + + return 0; +-error_name: +- kfree(name); + error_info: + kfree(info); + error_hpslot: diff --git a/pci/shpchp-bugfix-add-missing-serialization.patch b/pci/shpchp-bugfix-add-missing-serialization.patch new file mode 100644 index 0000000000000..49be2533e42b1 --- /dev/null +++ b/pci/shpchp-bugfix-add-missing-serialization.patch @@ -0,0 +1,197 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 17:02:31 2006 +Message-ID: <43D81F31.9010608@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 10:00:33 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 6/11] shpchp - bugfix: add missing serialization + +Current shpchp driver might cause system panic because of lack of +serialization. It can be reproduced very easily by the following +operation. + + # cd /sys/bus/pci/slots/<slot#> + # while true; do echo 0 > power ; echo 1 > power ; done & + # while true; do echo 0 > power ; echo 1 > power ; done & + +This patch fixes this issue by changing shpchp to get appropreate +semaphore for hot-plug operation. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp_ctrl.c | 66 +++++++++++++------------------------- + 1 file changed, 24 insertions(+), 42 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c +@@ -307,15 +307,10 @@ static int board_added(struct slot *p_sl + __FUNCTION__, p_slot->device, + ctrl->slot_device_offset, hp_slot); + +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + /* Power on slot without connecting to bus */ + rc = p_slot->hpc_ops->power_on_slot(p_slot); + if (rc) { + err("%s: Failed to power on slot\n", __FUNCTION__); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + return -1; + } + +@@ -325,14 +320,12 @@ static int board_added(struct slot *p_sl + + if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { + err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); +- mutex_unlock(&ctrl->crit_sect); + return WRONG_BUS_FREQUENCY; + } + + /* turn on board, blink green LED, turn off Amber LED */ + if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { + err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); +- mutex_unlock(&ctrl->crit_sect); + return rc; + } + } +@@ -346,16 +339,12 @@ static int board_added(struct slot *p_sl + + if (rc || adapter_speed == PCI_SPEED_UNKNOWN) { + err("%s: Can't get adapter speed or bus mode mismatch\n", __FUNCTION__); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + return WRONG_BUS_FREQUENCY; + } + + rc = p_slot->hpc_ops->get_cur_bus_speed(p_slot, &bus_speed); + if (rc || bus_speed == PCI_SPEED_UNKNOWN) { + err("%s: Can't get bus operation speed\n", __FUNCTION__); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + return WRONG_BUS_FREQUENCY; + } + +@@ -365,9 +354,6 @@ static int board_added(struct slot *p_sl + max_bus_speed = bus_speed; + } + +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- + if ((rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) { + err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__); + pi = 1; +@@ -744,29 +730,25 @@ static void interrupt_event_handler(stru + int shpchp_enable_slot (struct slot *p_slot) + { + u8 getstatus = 0; +- int rc; ++ int rc, retval = -ENODEV; + + /* Check to see if (latch closed, card present, power off) */ + mutex_lock(&p_slot->ctrl->crit_sect); + rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); + if (rc || !getstatus) { + info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); +- mutex_unlock(&p_slot->ctrl->crit_sect); +- return -ENODEV; ++ goto out; + } + rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + if (rc || getstatus) { + info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); +- mutex_unlock(&p_slot->ctrl->crit_sect); +- return -ENODEV; ++ goto out; + } + rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (rc || getstatus) { + info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); +- mutex_unlock(&p_slot->ctrl->crit_sect); +- return -ENODEV; ++ goto out; + } +- mutex_unlock(&p_slot->ctrl->crit_sect); + + p_slot->is_a_board = 1; + +@@ -781,27 +763,29 @@ int shpchp_enable_slot (struct slot *p_s + && p_slot->ctrl->num_slots == 1) { + /* handle amd pogo errata; this must be done before enable */ + amd_pogo_errata_save_misc_reg(p_slot); +- rc = board_added(p_slot); ++ retval = board_added(p_slot); + /* handle amd pogo errata; this must be done after enable */ + amd_pogo_errata_restore_misc_reg(p_slot); + } else +- rc = board_added(p_slot); ++ retval = board_added(p_slot); + +- if (rc) { ++ if (retval) { + p_slot->hpc_ops->get_adapter_status(p_slot, + &(p_slot->presence_save)); + p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); + } + + update_slot_info(p_slot); +- return rc; ++ out: ++ mutex_unlock(&p_slot->ctrl->crit_sect); ++ return retval; + } + + + int shpchp_disable_slot (struct slot *p_slot) + { + u8 getstatus = 0; +- int ret = 0; ++ int rc, retval = -ENODEV; + + if (!p_slot->ctrl) + return -ENODEV; +@@ -809,28 +793,26 @@ int shpchp_disable_slot (struct slot *p_ + /* Check to see if (latch closed, card present, power on) */ + mutex_lock(&p_slot->ctrl->crit_sect); + +- ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); +- if (ret || !getstatus) { ++ rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); ++ if (rc || !getstatus) { + info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); +- mutex_unlock(&p_slot->ctrl->crit_sect); +- return -ENODEV; ++ goto out; + } +- ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); +- if (ret || getstatus) { ++ rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); ++ if (rc || getstatus) { + info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); +- mutex_unlock(&p_slot->ctrl->crit_sect); +- return -ENODEV; ++ goto out; + } +- ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); +- if (ret || !getstatus) { ++ rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); ++ if (rc || !getstatus) { + info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); +- mutex_unlock(&p_slot->ctrl->crit_sect); +- return -ENODEV; ++ goto out; + } +- mutex_unlock(&p_slot->ctrl->crit_sect); + +- ret = remove_board(p_slot); ++ retval = remove_board(p_slot); + update_slot_info(p_slot); +- return ret; ++ out: ++ mutex_unlock(&p_slot->ctrl->crit_sect); ++ return retval; + } + diff --git a/pci/shpchp-cleanup-check-command-status.patch b/pci/shpchp-cleanup-check-command-status.patch new file mode 100644 index 0000000000000..d8a7a4e22b574 --- /dev/null +++ b/pci/shpchp-cleanup-check-command-status.patch @@ -0,0 +1,348 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 17:01:26 2006 +Message-ID: <43D81EEC.4000003@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 09:59:24 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 5/11] shpchp - cleanup check command status + +This patch cleanups codes that check the command status. For this, it +introduces a new semaphore "cmd_sem" for each controller. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp.h | 1 + drivers/pci/hotplug/shpchp_ctrl.c | 120 -------------------------------------- + drivers/pci/hotplug/shpchp_hpc.c | 25 ++++++- + 3 files changed, 23 insertions(+), 123 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -80,6 +80,7 @@ struct event_info { + struct controller { + struct list_head ctrl_list; + struct mutex crit_sect; /* critical section mutex */ ++ struct mutex cmd_lock; /* command lock */ + struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ + int num_slots; /* Number of slots on ctlr */ + int slot_num_inc; /* 1 or -1 */ +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c +@@ -231,6 +231,7 @@ static spinlock_t list_lock; + static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); + + static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); ++static int hpc_check_cmd_status(struct controller *ctrl); + + /* This is the interrupt polling timeout function. */ + static void int_poll_timeout(unsigned long lphp_ctlr) +@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *s + int i; + + DBG_ENTER_ROUTINE +- ++ ++ mutex_lock(&slot->ctrl->cmd_lock); ++ + if (!php_ctlr) { + err("%s: Invalid HPC controller handle!\n", __FUNCTION__); +- return -1; ++ retval = -EINVAL; ++ goto out; + } + + for (i = 0; i < 10; i++) { +@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *s + if (cmd_status & 0x1) { + /* After 1 sec and and the controller is still busy */ + err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); +- return -1; ++ retval = -EBUSY; ++ goto out; + } + + ++t_slot; +@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *s + * Wait for command completion. + */ + retval = shpc_wait_cmd(slot->ctrl); ++ if (retval) ++ goto out; ++ ++ cmd_status = hpc_check_cmd_status(slot->ctrl); ++ if (cmd_status) { ++ err("%s: Failed to issued command 0x%x (error code = %d)\n", ++ __FUNCTION__, cmd, cmd_status); ++ retval = -EIO; ++ } ++ out: ++ mutex_unlock(&slot->ctrl->cmd_lock); + + DBG_LEAVE_ROUTINE + return retval; +@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = { + .green_led_blink = hpc_set_green_led_blink, + + .release_ctlr = hpc_release_ctlr, +- .check_cmd_status = hpc_check_cmd_status, + }; + + inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, +@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, + dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); + + mutex_init(&ctrl->crit_sect); ++ mutex_init(&ctrl->cmd_lock); ++ + /* Setup wait queue */ + init_waitqueue_head(&ctrl->queue); + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c +@@ -242,21 +242,10 @@ static int change_bus_speed(struct contr + int rc = 0; + + dbg("%s: change to speed %d\n", __FUNCTION__, speed); +- mutex_lock(&ctrl->crit_sect); + if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { + err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); +- mutex_unlock(&ctrl->crit_sect); +- return WRONG_BUS_FREQUENCY; +- } +- +- if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { +- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", +- __FUNCTION__); +- err("%s: Error code (%d)\n", __FUNCTION__, rc); +- mutex_unlock(&ctrl->crit_sect); + return WRONG_BUS_FREQUENCY; + } +- mutex_unlock(&ctrl->crit_sect); + return rc; + } + +@@ -330,15 +319,6 @@ static int board_added(struct slot *p_sl + return -1; + } + +- rc = p_slot->hpc_ops->check_cmd_status(ctrl); +- if (rc) { +- err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- return -1; +- } +- +- + if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { + if (slots_not_empty) + return WRONG_BUS_FREQUENCY; +@@ -349,25 +329,12 @@ static int board_added(struct slot *p_sl + return WRONG_BUS_FREQUENCY; + } + +- if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { +- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", +- __FUNCTION__); +- err("%s: Error code (%d)\n", __FUNCTION__, rc); +- mutex_unlock(&ctrl->crit_sect); +- return WRONG_BUS_FREQUENCY; +- } + /* turn on board, blink green LED, turn off Amber LED */ + if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { + err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); + mutex_unlock(&ctrl->crit_sect); + return rc; + } +- +- if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { +- err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); +- mutex_unlock(&ctrl->crit_sect); +- return rc; +- } + } + + rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed); +@@ -481,22 +448,12 @@ static int board_added(struct slot *p_sl + return rc; + } + +- mutex_lock(&ctrl->crit_sect); + /* turn on board, blink green LED, turn off Amber LED */ + if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { + err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); +- mutex_unlock(&ctrl->crit_sect); + return rc; + } + +- if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { +- err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); +- mutex_unlock(&ctrl->crit_sect); +- return rc; +- } +- +- mutex_unlock(&ctrl->crit_sect); +- + /* Wait for ~1 second */ + wait_for_ctrl_irq (ctrl); + +@@ -520,40 +477,18 @@ static int board_added(struct slot *p_sl + p_slot->is_a_board = 0x01; + p_slot->pwr_save = 1; + +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + p_slot->hpc_ops->green_led_on(p_slot); + +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- + return 0; + + err_exit: +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + /* turn off slot, turn on Amber LED, turn off Green LED */ + rc = p_slot->hpc_ops->slot_disable(p_slot); + if (rc) { + err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + return rc; + } + +- rc = p_slot->hpc_ops->check_cmd_status(ctrl); +- if (rc) { +- err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- return rc; +- } +- +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- + return(rc); + } + +@@ -580,37 +515,19 @@ static int remove_board(struct slot *p_s + if (p_slot->is_a_board) + p_slot->status = 0x01; + +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + /* turn off slot, turn on Amber LED, turn off Green LED */ + rc = p_slot->hpc_ops->slot_disable(p_slot); + if (rc) { + err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + return rc; + } +- +- rc = p_slot->hpc_ops->check_cmd_status(ctrl); +- if (rc) { +- err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- return rc; +- } + + rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); + if (rc) { + err("%s: Issue of Set Attention command failed\n", __FUNCTION__); +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + return rc; + } + +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- + p_slot->pwr_save = 0; + p_slot->is_a_board = 0; + +@@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (un + } else { + p_slot->state = POWERON_STATE; + +- if (shpchp_enable_slot(p_slot)) { +- /* Wait for exclusive access to hardware */ +- mutex_lock(&p_slot->ctrl->crit_sect); +- ++ if (shpchp_enable_slot(p_slot)) + p_slot->hpc_ops->green_led_off(p_slot); + +- /* Done with exclusive hardware access */ +- mutex_unlock(&p_slot->ctrl->crit_sect); +- } + p_slot->state = STATIC_STATE; + } + +@@ -767,27 +678,12 @@ static void interrupt_event_handler(stru + + switch (p_slot->state) { + case BLINKINGOFF_STATE: +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + p_slot->hpc_ops->green_led_on(p_slot); +- + p_slot->hpc_ops->set_attention_status(p_slot, 0); +- +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + break; + case BLINKINGON_STATE: +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + p_slot->hpc_ops->green_led_off(p_slot); +- + p_slot->hpc_ops->set_attention_status(p_slot, 0); +- +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- + break; + default: + warn("Not a valid state\n"); +@@ -812,17 +708,10 @@ static void interrupt_event_handler(stru + info(msg_button_on, p_slot->number); + } + +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + /* blink green LED and turn off amber */ + p_slot->hpc_ops->green_led_blink(p_slot); +- + p_slot->hpc_ops->set_attention_status(p_slot, 0); + +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); +- + init_timer(&p_slot->task_event); + p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ + p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; +@@ -833,15 +722,8 @@ static void interrupt_event_handler(stru + } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { + /***********POWER FAULT********************/ + dbg("%s: power fault\n", __FUNCTION__); +- /* Wait for exclusive access to hardware */ +- mutex_lock(&ctrl->crit_sect); +- + p_slot->hpc_ops->set_attention_status(p_slot, 1); +- + p_slot->hpc_ops->green_led_off(p_slot); +- +- /* Done with exclusive hardware access */ +- mutex_unlock(&ctrl->crit_sect); + } else { + /* refresh notification */ + if (p_slot) diff --git a/pci/shpchp-cleanup-controller-list.patch b/pci/shpchp-cleanup-controller-list.patch new file mode 100644 index 0000000000000..98d3087f77ba6 --- /dev/null +++ b/pci/shpchp-cleanup-controller-list.patch @@ -0,0 +1,105 @@ +From pcihpd-discuss-admin@lists.sourceforge.net Wed Jan 25 17:01:01 2006 +Message-ID: <43D81EB6.5060405@jp.fujitsu.com> +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 4/11] shpchp - cleanup controller list +Date: Thu, 26 Jan 2006 09:58:30 +0900 + +This patch changes SHPCHP driver to use list_head structure for +managing controller list. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp.h | 4 ++-- + drivers/pci/hotplug/shpchp_core.c | 25 +++++++------------------ + drivers/pci/hotplug/shpchp_ctrl.c | 2 +- + 3 files changed, 10 insertions(+), 21 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -78,7 +78,7 @@ struct event_info { + }; + + struct controller { +- struct controller *next; ++ struct list_head ctrl_list; + struct mutex crit_sect; /* critical section mutex */ + struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ + int num_slots; /* Number of slots on ctlr */ +@@ -204,7 +204,7 @@ extern void shpchp_remove_ctrl_files(str + + + /* Global variables */ +-extern struct controller *shpchp_ctrl_list; ++extern struct list_head shpchp_ctrl_list; + + struct ctrl_reg { + volatile u32 base_offset; +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -38,7 +38,7 @@ + int shpchp_debug; + int shpchp_poll_mode; + int shpchp_poll_time; +-struct controller *shpchp_ctrl_list; /* = NULL */ ++LIST_HEAD(shpchp_ctrl_list); + + #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>" +@@ -452,13 +452,7 @@ static int shpc_probe(struct pci_dev *pd + /* Finish setting up the hot plug ctrl device */ + ctrl->next_event = 0; + +- if (!shpchp_ctrl_list) { +- shpchp_ctrl_list = ctrl; +- ctrl->next = NULL; +- } else { +- ctrl->next = shpchp_ctrl_list; +- shpchp_ctrl_list = ctrl; +- } ++ list_add(&ctrl->ctrl_list, &shpchp_ctrl_list); + + shpchp_create_ctrl_files(ctrl); + +@@ -493,22 +487,17 @@ static int shpc_start_thread(void) + + static void __exit unload_shpchpd(void) + { ++ struct list_head *tmp; ++ struct list_head *next; + struct controller *ctrl; +- struct controller *tctrl; +- +- ctrl = shpchp_ctrl_list; + +- while (ctrl) { ++ 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); +- + kfree (ctrl->pci_bus); + ctrl->hpc_ops->release_ctlr(ctrl); +- +- tctrl = ctrl; +- ctrl = ctrl->next; +- +- kfree(tctrl); ++ kfree(ctrl); + } + + /* Stop the notification mechanism */ +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c +@@ -688,7 +688,7 @@ static int event_thread(void* data) + if (pushbutton_pending) + shpchp_pushbutton_thread(pushbutton_pending); + else +- for (ctrl = shpchp_ctrl_list; ctrl; ctrl=ctrl->next) ++ list_for_each_entry(ctrl, &shpchp_ctrl_list, ctrl_list) + interrupt_event_handler(ctrl); + } + dbg("event_thread signals exit\n"); diff --git a/pci/shpchp-cleanup-init_slots.patch b/pci/shpchp-cleanup-init_slots.patch new file mode 100644 index 0000000000000..93149aac708d7 --- /dev/null +++ b/pci/shpchp-cleanup-init_slots.patch @@ -0,0 +1,190 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 16:57:14 2006 +Message-ID: <43D81E07.5060508@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 09:55:35 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 1/11] shpchp - cleanup init_slots() + +This patch cleanups init_slots() function of SHPCHP driver based on +pcihp_skelton.c. This patch has no functional change. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp.h | 7 -- + drivers/pci/hotplug/shpchp_core.c | 120 +++++++++++++++++++------------------- + 2 files changed, 63 insertions(+), 64 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -428,13 +428,6 @@ static inline void amd_pogo_errata_resto + pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); + } + +-#define SLOT_NAME_SIZE 10 +- +-static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) +-{ +- snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); +-} +- + enum php_ctlr_type { + PCI, + ISA, +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -99,89 +99,95 @@ static void release_slot(struct hotplug_ + kfree(slot); + } + ++#define SLOT_NAME_SIZE 10 ++static void make_slot_name(struct slot *slot) ++{ ++ snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", ++ slot->bus, slot->number); ++} ++ + static int init_slots(struct controller *ctrl) + { +- struct slot *new_slot; +- u8 number_of_slots; +- u8 slot_device; +- u32 slot_number, sun; +- int result = -ENOMEM; +- +- number_of_slots = ctrl->num_slots; +- slot_device = ctrl->slot_device_offset; +- slot_number = ctrl->first_slot; +- +- while (number_of_slots) { +- new_slot = (struct slot *) kmalloc(sizeof(struct slot), GFP_KERNEL); +- if (!new_slot) ++ struct slot *slot; ++ struct hotplug_slot *hotplug_slot; ++ struct hotplug_slot_info *info; ++ char *name; ++ int retval = -ENOMEM; ++ int i; ++ u32 sun; ++ ++ for (i = 0; i < ctrl->num_slots; i++) { ++ slot = kmalloc(sizeof(struct slot), GFP_KERNEL); ++ if (!slot) + goto error; ++ memset(slot, 0, sizeof(struct slot)); + +- memset(new_slot, 0, sizeof(struct slot)); +- new_slot->hotplug_slot = kmalloc (sizeof (struct hotplug_slot), GFP_KERNEL); +- if (!new_slot->hotplug_slot) ++ hotplug_slot = kmalloc(sizeof(struct hotplug_slot), ++ GFP_KERNEL); ++ if (!hotplug_slot) + goto error_slot; +- memset(new_slot->hotplug_slot, 0, sizeof (struct hotplug_slot)); ++ memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); ++ slot->hotplug_slot = hotplug_slot; + +- new_slot->hotplug_slot->info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL); +- if (!new_slot->hotplug_slot->info) ++ info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); ++ if (!info) + goto error_hpslot; +- memset(new_slot->hotplug_slot->info, 0, sizeof (struct hotplug_slot_info)); +- new_slot->hotplug_slot->name = kmalloc (SLOT_NAME_SIZE, GFP_KERNEL); +- if (!new_slot->hotplug_slot->name) ++ memset(info, 0, sizeof (struct hotplug_slot_info)); ++ hotplug_slot->info = info; ++ ++ name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); ++ if (!name) + goto error_info; ++ hotplug_slot->name = name; + +- new_slot->magic = SLOT_MAGIC; +- new_slot->ctrl = ctrl; +- new_slot->bus = ctrl->slot_bus; +- new_slot->device = slot_device; +- new_slot->hpc_ops = ctrl->hpc_ops; ++ slot->hp_slot = i; ++ slot->magic = SLOT_MAGIC; ++ slot->ctrl = ctrl; ++ slot->bus = ctrl->slot_bus; ++ slot->device = ctrl->slot_device_offset + i; ++ slot->hpc_ops = ctrl->hpc_ops; + + if (shpchprm_get_physical_slot_number(ctrl, &sun, +- new_slot->bus, new_slot->device)) ++ slot->bus, slot->device)) + goto error_name; + +- new_slot->number = sun; +- new_slot->hp_slot = slot_device - ctrl->slot_device_offset; ++ slot->number = sun; + + /* register this slot with the hotplug pci core */ +- new_slot->hotplug_slot->private = new_slot; +- new_slot->hotplug_slot->release = &release_slot; +- make_slot_name(new_slot->hotplug_slot->name, SLOT_NAME_SIZE, new_slot); +- new_slot->hotplug_slot->ops = &shpchp_hotplug_slot_ops; +- +- new_slot->hpc_ops->get_power_status(new_slot, &(new_slot->hotplug_slot->info->power_status)); +- new_slot->hpc_ops->get_attention_status(new_slot, &(new_slot->hotplug_slot->info->attention_status)); +- new_slot->hpc_ops->get_latch_status(new_slot, &(new_slot->hotplug_slot->info->latch_status)); +- new_slot->hpc_ops->get_adapter_status(new_slot, &(new_slot->hotplug_slot->info->adapter_status)); +- +- dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x slot_device_offset=%x\n", new_slot->bus, +- new_slot->device, new_slot->hp_slot, new_slot->number, ctrl->slot_device_offset); +- result = pci_hp_register (new_slot->hotplug_slot); +- if (result) { +- err ("pci_hp_register failed with error %d\n", result); ++ hotplug_slot->private = slot; ++ hotplug_slot->release = &release_slot; ++ make_slot_name(slot); ++ hotplug_slot->ops = &shpchp_hotplug_slot_ops; ++ ++ get_power_status(hotplug_slot, &info->power_status); ++ get_attention_status(hotplug_slot, &info->attention_status); ++ get_latch_status(hotplug_slot, &info->latch_status); ++ get_adapter_status(hotplug_slot, &info->adapter_status); ++ ++ dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x " ++ "slot_device_offset=%x\n", slot->bus, slot->device, ++ slot->hp_slot, slot->number, ctrl->slot_device_offset); ++ retval = pci_hp_register(slot->hotplug_slot); ++ if (retval) { ++ err("pci_hp_register failed with error %d\n", retval); + goto error_name; + } + +- new_slot->next = ctrl->slot; +- ctrl->slot = new_slot; +- +- number_of_slots--; +- slot_device++; +- slot_number += ctrl->slot_num_inc; ++ slot->next = ctrl->slot; ++ ctrl->slot = slot; + } + + return 0; +- + error_name: +- kfree(new_slot->hotplug_slot->name); ++ kfree(name); + error_info: +- kfree(new_slot->hotplug_slot->info); ++ kfree(info); + error_hpslot: +- kfree(new_slot->hotplug_slot); ++ kfree(hotplug_slot); + error_slot: +- kfree(new_slot); ++ kfree(slot); + error: +- return result; ++ return retval; + } + + static void cleanup_slots(struct controller *ctrl) diff --git a/pci/shpchp-cleanup-shpchp_core.c.patch b/pci/shpchp-cleanup-shpchp_core.c.patch new file mode 100644 index 0000000000000..c77a03bdb717c --- /dev/null +++ b/pci/shpchp-cleanup-shpchp_core.c.patch @@ -0,0 +1,280 @@ +From pcihpd-discuss-admin@lists.sourceforge.net Wed Jan 25 16:59:06 2006 +Message-ID: <43D81E55.4030107@jp.fujitsu.com> +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 2/11] shpchp - cleanup shpchp_core.c +Date: Thu, 26 Jan 2006 09:56:53 +0900 + +This patch cleanups some codes in shpchp_core.c. This patch has no +functional changes. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + + +--- + drivers/pci/hotplug/shpchp_core.c | 84 ++++++++++++++++---------------------- + 1 file changed, 36 insertions(+), 48 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -213,9 +213,12 @@ static int get_ctlr_slot_config(struct c + int rc; + int flags; + +- rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, &first_device_num, &physical_slot_num, &updown, &flags); ++ rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, ++ &first_device_num, &physical_slot_num, ++ &updown, &flags); + if (rc) { +- err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", __FUNCTION__, ctrl->bus, ctrl->device); ++ err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", ++ __FUNCTION__, ctrl->bus, ctrl->device); + return -1; + } + +@@ -224,19 +227,19 @@ static int get_ctlr_slot_config(struct c + ctrl->first_slot = physical_slot_num; + ctrl->slot_num_inc = updown; /* either -1 or 1 */ + +- dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d (%x:%x)\n", +- __FUNCTION__, num_ctlr_slots, first_device_num, physical_slot_num, updown, ctrl->bus, ctrl->device); ++ dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d " ++ "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num, ++ physical_slot_num, updown, ctrl->bus, ctrl->device); + + return 0; + } + +- + /* + * set_attention_status - Turns the Amber LED for a slot on, off or blink + */ + static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + +@@ -246,20 +249,18 @@ static int set_attention_status (struct + return 0; + } + +- + static int enable_slot (struct hotplug_slot *hotplug_slot) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + return shpchp_enable_slot(slot); + } + +- + static int disable_slot (struct hotplug_slot *hotplug_slot) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + +@@ -268,7 +269,7 @@ static int disable_slot (struct hotplug_ + + static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +@@ -282,7 +283,7 @@ static int get_power_status (struct hotp + + static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +@@ -296,7 +297,7 @@ static int get_attention_status (struct + + static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +@@ -310,7 +311,7 @@ static int get_latch_status (struct hotp + + static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +@@ -324,7 +325,7 @@ static int get_adapter_status (struct ho + + static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +@@ -336,11 +337,11 @@ static int get_address (struct hotplug_s + + static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +- ++ + retval = slot->hpc_ops->get_max_bus_speed(slot, value); + if (retval < 0) + *value = PCI_SPEED_UNKNOWN; +@@ -350,11 +351,11 @@ static int get_max_bus_speed (struct hot + + static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) + { +- struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); ++ struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + int retval; + + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); +- ++ + retval = slot->hpc_ops->get_cur_bus_speed(slot, value); + if (retval < 0) + *value = PCI_SPEED_UNKNOWN; +@@ -378,13 +379,13 @@ static int shpc_probe(struct pci_dev *pd + int rc; + struct controller *ctrl; + struct slot *t_slot; +- int first_device_num; /* first PCI device number supported by this SHPC */ +- int num_ctlr_slots; /* number of slots supported by this SHPC */ ++ int first_device_num; /* first PCI device number */ ++ int num_ctlr_slots; /* number of slots implemented */ + + if (!is_shpc_capable(pdev)) + return -ENODEV; + +- ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); ++ ctrl = kmalloc(sizeof(struct controller), GFP_KERNEL); + if (!ctrl) { + err("%s : out of memory\n", __FUNCTION__); + goto err_out_none; +@@ -393,31 +394,32 @@ static int shpc_probe(struct pci_dev *pd + + rc = shpc_init(ctrl, pdev); + if (rc) { +- dbg("%s: controller initialization failed\n", SHPC_MODULE_NAME); ++ dbg("%s: controller initialization failed\n", ++ SHPC_MODULE_NAME); + goto err_out_free_ctrl; + } + + pci_set_drvdata(pdev, ctrl); + +- ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL); ++ ctrl->pci_bus = kmalloc(sizeof (*ctrl->pci_bus), GFP_KERNEL); + if (!ctrl->pci_bus) { + err("out of memory\n"); + rc = -ENOMEM; + goto err_out_unmap_mmio_region; + } +- ++ + memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus)); + ctrl->bus = pdev->bus->number; + ctrl->slot_bus = pdev->subordinate->number; +- + ctrl->device = PCI_SLOT(pdev->devfn); + ctrl->function = PCI_FUNC(pdev->devfn); +- dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", ctrl->bus, ctrl->device, ctrl->function, pdev->irq); ++ ++ dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", ++ ctrl->bus, ctrl->device, ctrl->function, pdev->irq); + + /* +- * Save configuration headers for this and subordinate PCI buses ++ * Save configuration headers for this and subordinate PCI buses + */ +- + rc = get_ctlr_slot_config(ctrl); + if (rc) { + err(msg_initialization_err, rc); +@@ -427,7 +429,7 @@ static int shpc_probe(struct pci_dev *pd + num_ctlr_slots = ctrl->num_slots; + + ctrl->add_support = 1; +- ++ + /* Setup the slot information structures */ + rc = init_slots(ctrl); + if (rc) { +@@ -443,7 +445,8 @@ static int shpc_probe(struct pci_dev *pd + dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot); + + if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) { +- err(SHPC_MODULE_NAME ": Can't get current bus speed. Set to 33MHz PCI.\n"); ++ err(SHPC_MODULE_NAME ": Can't get current bus speed. " ++ "Set to 33MHz PCI.\n"); + ctrl->speed = PCI_SPEED_33MHz; + } + +@@ -474,11 +477,10 @@ 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(); +@@ -515,24 +517,12 @@ static void __exit unload_shpchpd(void) + + } + +- + static struct pci_device_id shpcd_pci_tbl[] = { +- { +- .class = ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), +- .class_mask = ~0, +- .vendor = PCI_ANY_ID, +- .device = PCI_ANY_ID, +- .subvendor = PCI_ANY_ID, +- .subdevice = PCI_ANY_ID, +- }, +- ++ {PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0)}, + { /* end: all zeroes */ } + }; +- + MODULE_DEVICE_TABLE(pci, shpcd_pci_tbl); + +- +- + static struct pci_driver shpc_driver = { + .name = SHPC_MODULE_NAME, + .id_table = shpcd_pci_tbl, +@@ -540,8 +530,6 @@ static struct pci_driver shpc_driver = { + /* remove: shpc_remove_one, */ + }; + +- +- + static int __init shpcd_init(void) + { + int retval = 0; diff --git a/pci/shpchp-cleanup-slot-list.patch b/pci/shpchp-cleanup-slot-list.patch new file mode 100644 index 0000000000000..d374faeb683e5 --- /dev/null +++ b/pci/shpchp-cleanup-slot-list.patch @@ -0,0 +1,113 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 16:59:16 2006 +Message-ID: <43D81E84.8080102@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 09:57:40 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 3/11] shpchp - cleanup slot list + +This patch changes SHPCHP driver to use list_head structure for +managing slot list. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp.h | 21 ++++++++------------- + drivers/pci/hotplug/shpchp_core.c | 21 ++++++++++----------- + 2 files changed, 18 insertions(+), 24 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -56,7 +56,6 @@ extern int shpchp_debug; + #define SLOT_MAGIC 0x67267321 + struct slot { + u32 magic; +- struct slot *next; + u8 bus; + u8 device; + u16 status; +@@ -87,7 +86,7 @@ struct controller { + struct pci_dev *pci_dev; + struct pci_bus *pci_bus; + struct event_info event_queue[10]; +- struct slot *slot; ++ struct list_head slot_list; + struct hpc_ops *hpc_ops; + wait_queue_head_t queue; /* sleep & wake process */ + u8 next_event; +@@ -315,23 +314,19 @@ static inline struct slot *get_slot (str + + static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device) + { +- struct slot *p_slot, *tmp_slot = NULL; ++ struct slot *slot; + + if (!ctrl) + return NULL; + +- p_slot = ctrl->slot; +- +- while (p_slot && (p_slot->device != device)) { +- tmp_slot = p_slot; +- p_slot = p_slot->next; +- } +- if (p_slot == NULL) { +- err("ERROR: shpchp_find_slot device=0x%x\n", device); +- p_slot = tmp_slot; ++ list_for_each_entry(slot, &ctrl->slot_list, slot_list) { ++ if (slot->device == device) ++ return slot; + } + +- return (p_slot); ++ err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); ++ ++ return NULL; + } + + static inline int wait_for_ctrl_irq (struct controller *ctrl) +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -173,8 +173,7 @@ static int init_slots(struct controller + goto error_name; + } + +- slot->next = ctrl->slot; +- ctrl->slot = slot; ++ list_add(&slot->slot_list, &ctrl->slot_list); + } + + return 0; +@@ -192,15 +191,14 @@ error: + + static void cleanup_slots(struct controller *ctrl) + { +- struct slot *old_slot, *next_slot; +- +- old_slot = ctrl->slot; +- ctrl->slot = NULL; +- +- while (old_slot) { +- next_slot = old_slot->next; +- pci_hp_deregister(old_slot->hotplug_slot); +- old_slot = next_slot; ++ struct list_head *tmp; ++ struct list_head *next; ++ struct slot *slot; ++ ++ list_for_each_safe(tmp, next, &ctrl->slot_list) { ++ slot = list_entry(tmp, struct slot, slot_list); ++ list_del(&slot->slot_list); ++ pci_hp_deregister(slot->hotplug_slot); + } + } + +@@ -391,6 +389,7 @@ static int shpc_probe(struct pci_dev *pd + goto err_out_none; + } + memset(ctrl, 0, sizeof(struct controller)); ++ INIT_LIST_HEAD(&ctrl->slot_list); + + rc = shpc_init(ctrl, pdev); + if (rc) { diff --git a/pci/shpchp-fix-incorrect-return-value-of-interrupt-handler.patch b/pci/shpchp-fix-incorrect-return-value-of-interrupt-handler.patch new file mode 100644 index 0000000000000..7cdc89c357c52 --- /dev/null +++ b/pci/shpchp-fix-incorrect-return-value-of-interrupt-handler.patch @@ -0,0 +1,55 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 17:08:13 2006 +Message-ID: <43D82075.4030401@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 10:05:57 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 11/11] shpchp - Fix incorrect return value of interrupt handler + +Current SHPCHP driver has a bug in its interrupt handler which cause +"IRQ #: nobody cared" oops. This problem can be reproduced easily by +the following operation. + + # cd /sys/bus/pci/slots/<slot#> + # while true; do echo 1 > attention ; done & + +The reason is that when command complete interrupt is raised, current +SHPCHP driver's interrupt handler returns IRQ_NONE regardless of if +the interrupt is handled or not. + +This patch fixes this issue. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp_hpc.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c +@@ -1109,14 +1109,8 @@ static irqreturn_t shpc_isr(int IRQ, voi + wake_up_interruptible(&ctrl->queue); + } + +- if ((intr_loc = (intr_loc >> 1)) == 0) { +- /* Unmask Global Interrupt Mask */ +- temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); +- temp_dword &= 0xfffffffe; +- writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); +- +- return IRQ_NONE; +- } ++ if ((intr_loc = (intr_loc >> 1)) == 0) ++ goto out; + + for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { + /* To find out which slot has interrupt pending */ +@@ -1146,6 +1140,7 @@ static irqreturn_t shpc_isr(int IRQ, voi + dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); + } + } ++ out: + if (!shpchp_poll_mode) { + /* Unmask Global Interrupt Mask */ + temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); diff --git a/pci/shpchp-move-slot-name-into-struct-slot.patch b/pci/shpchp-move-slot-name-into-struct-slot.patch new file mode 100644 index 0000000000000..ba9627ab82972 --- /dev/null +++ b/pci/shpchp-move-slot-name-into-struct-slot.patch @@ -0,0 +1,97 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 17:07:14 2006 +Message-ID: <43D82038.6050102@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 10:04:56 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 10/11] shpchp - move slot name into struct slot + +This patch moves slot name area into struct slot. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp.h | 2 ++ + drivers/pci/hotplug/shpchp_core.c | 14 +++----------- + 2 files changed, 5 insertions(+), 11 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -53,6 +53,7 @@ extern int shpchp_debug; + #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) + #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) + ++#define SLOT_NAME_SIZE 10 + struct slot { + u8 bus; + u8 device; +@@ -68,6 +69,7 @@ struct slot { + struct hpc_ops *hpc_ops; + struct hotplug_slot *hotplug_slot; + struct list_head slot_list; ++ char name[SLOT_NAME_SIZE]; + }; + + struct event_info { +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -94,12 +94,10 @@ static void release_slot(struct hotplug_ + dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); + + kfree(slot->hotplug_slot->info); +- kfree(slot->hotplug_slot->name); + kfree(slot->hotplug_slot); + kfree(slot); + } + +-#define SLOT_NAME_SIZE 10 + static void make_slot_name(struct slot *slot) + { + snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d", +@@ -111,7 +109,6 @@ static int init_slots(struct controller + struct slot *slot; + struct hotplug_slot *hotplug_slot; + struct hotplug_slot_info *info; +- char *name; + int retval = -ENOMEM; + int i; + u32 sun; +@@ -131,10 +128,7 @@ static int init_slots(struct controller + goto error_hpslot; + hotplug_slot->info = info; + +- name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); +- if (!name) +- goto error_info; +- hotplug_slot->name = name; ++ hotplug_slot->name = slot->name; + + slot->hp_slot = i; + slot->ctrl = ctrl; +@@ -144,7 +138,7 @@ static int init_slots(struct controller + + if (shpchprm_get_physical_slot_number(ctrl, &sun, + slot->bus, slot->device)) +- goto error_name; ++ goto error_info; + + slot->number = sun; + +@@ -165,15 +159,13 @@ static int init_slots(struct controller + retval = pci_hp_register(slot->hotplug_slot); + if (retval) { + err("pci_hp_register failed with error %d\n", retval); +- goto error_name; ++ goto error_info; + } + + list_add(&slot->slot_list, &ctrl->slot_list); + } + + return 0; +-error_name: +- kfree(name); + error_info: + kfree(info); + error_hpslot: diff --git a/pci/shpchp-removed-unncessary-magic-member-from-slot.patch b/pci/shpchp-removed-unncessary-magic-member-from-slot.patch new file mode 100644 index 0000000000000..38bb9dc083fca --- /dev/null +++ b/pci/shpchp-removed-unncessary-magic-member-from-slot.patch @@ -0,0 +1,52 @@ +From kaneshige.kenji@jp.fujitsu.com Wed Jan 25 17:05:23 2006 +Message-ID: <43D81FEC.1040804@jp.fujitsu.com> +Date: Thu, 26 Jan 2006 10:03:40 +0900 +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 9/11] shpchp - removed unncessary 'magic' member from slot + +This patch removes unnecessary 'magic' member from struct slot of +SHPCHP driver. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp.h | 6 ------ + drivers/pci/hotplug/shpchp_core.c | 1 - + 2 files changed, 7 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h ++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h +@@ -53,9 +53,7 @@ extern int shpchp_debug; + #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) + #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) + +-#define SLOT_MAGIC 0x67267321 + struct slot { +- u32 magic; + u8 bus; + u8 device; + u16 status; +@@ -287,10 +285,6 @@ static inline int slot_paranoia_check (s + dbg("%s - slot == NULL", function); + return -1; + } +- if (slot->magic != SLOT_MAGIC) { +- dbg("%s - bad magic number for slot", function); +- return -1; +- } + if (!slot->hotplug_slot) { + dbg("%s - slot->hotplug_slot == NULL!", function); + return -1; +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -137,7 +137,6 @@ static int init_slots(struct controller + hotplug_slot->name = name; + + slot->hp_slot = i; +- slot->magic = SLOT_MAGIC; + slot->ctrl = ctrl; + slot->bus = ctrl->slot_bus; + slot->device = ctrl->slot_device_offset + i; diff --git a/pci/shpchp-replace-kmalloc-with-kzalloc-and-cleanup-arg-of-sizeof.patch b/pci/shpchp-replace-kmalloc-with-kzalloc-and-cleanup-arg-of-sizeof.patch new file mode 100644 index 0000000000000..3ae50c39f4eca --- /dev/null +++ b/pci/shpchp-replace-kmalloc-with-kzalloc-and-cleanup-arg-of-sizeof.patch @@ -0,0 +1,89 @@ +From pcihpd-discuss-admin@lists.sourceforge.net Wed Jan 25 17:05:02 2006 +Message-ID: <43D81FB1.4020705@jp.fujitsu.com> +From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +To: Greg KH <gregkh@suse.de> +Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Subject: [PATCH 8/11] shpchp - replace kmalloc() with kzalloc() and cleanup arg of sizeof() +Date: Thu, 26 Jan 2006 10:02:41 +0900 + +This patch replaces kmalloc() and memset() pair with kzalloc() and +cleans up the arg of sizeof() in SHPCHP driver. + +Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/pci/hotplug/shpchp_core.c | 15 +++++---------- + drivers/pci/hotplug/shpchp_hpc.c | 4 +--- + 2 files changed, 6 insertions(+), 13 deletions(-) + +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c +@@ -117,22 +117,18 @@ static int init_slots(struct controller + u32 sun; + + for (i = 0; i < ctrl->num_slots; i++) { +- slot = kmalloc(sizeof(struct slot), GFP_KERNEL); ++ slot = kzalloc(sizeof(*slot), GFP_KERNEL); + if (!slot) + goto error; +- memset(slot, 0, sizeof(struct slot)); + +- hotplug_slot = kmalloc(sizeof(struct hotplug_slot), +- GFP_KERNEL); ++ hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); + if (!hotplug_slot) + goto error_slot; +- memset(hotplug_slot, 0, sizeof(struct hotplug_slot)); + slot->hotplug_slot = hotplug_slot; + +- info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); ++ info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + goto error_hpslot; +- memset(info, 0, sizeof (struct hotplug_slot_info)); + hotplug_slot->info = info; + + name = kmalloc(SLOT_NAME_SIZE, GFP_KERNEL); +@@ -383,12 +379,11 @@ static int shpc_probe(struct pci_dev *pd + if (!is_shpc_capable(pdev)) + return -ENODEV; + +- ctrl = kmalloc(sizeof(struct controller), GFP_KERNEL); ++ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) { + err("%s : out of memory\n", __FUNCTION__); + goto err_out_none; + } +- memset(ctrl, 0, sizeof(struct controller)); + INIT_LIST_HEAD(&ctrl->slot_list); + + rc = shpc_init(ctrl, pdev); +@@ -400,7 +395,7 @@ static int shpc_probe(struct pci_dev *pd + + pci_set_drvdata(pdev, ctrl); + +- ctrl->pci_bus = kmalloc(sizeof (*ctrl->pci_bus), GFP_KERNEL); ++ ctrl->pci_bus = kmalloc(sizeof(*ctrl->pci_bus), GFP_KERNEL); + if (!ctrl->pci_bus) { + err("out of memory\n"); + rc = -ENOMEM; +--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c ++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c +@@ -1390,15 +1390,13 @@ int shpc_init(struct controller * ctrl, + ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ + + spin_lock_init(&list_lock); +- php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); ++ php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL); + + if (!php_ctlr) { /* allocate controller state data */ + err("%s: HPC controller memory allocation error!\n", __FUNCTION__); + goto abort; + } + +- memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); +- + php_ctlr->pci_dev = pdev; /* save pci_dev in context */ + + if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == |