aboutsummaryrefslogtreecommitdiffstats
path: root/pci
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2005-11-28 14:03:52 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2005-11-28 14:03:52 -0800
commit6679fbe6bdbce2f3cf532e354bbc8398d9b6672a (patch)
treeae91179f8be23d188873d8460db4c205f5519009 /pci
parentd38f69ec46298606986c5b2cb9ef9292ca642968 (diff)
downloadpatches-6679fbe6bdbce2f3cf532e354bbc8398d9b6672a.tar.gz
shpchp patches
Diffstat (limited to 'pci')
-rw-r--r--pci/shpchp-fix-improper-mmio-mapping.patch178
-rw-r--r--pci/shpchp-fix-improper-reference-to-mode-1-ecc-capability-bit.patch31
-rw-r--r--pci/shpchp-fix-improper-reference-to-slot-avail-regsister.patch87
-rw-r--r--pci/shpchp-fix-improper-wait-for-command-completion.patch247
-rw-r--r--pci/shpchp-fix-improper-write-to-command-completion-detect-bit.patch36
-rw-r--r--pci/shpchp-replace-pci_find_slot-with-pci_get_slot.patch109
6 files changed, 688 insertions, 0 deletions
diff --git a/pci/shpchp-fix-improper-mmio-mapping.patch b/pci/shpchp-fix-improper-mmio-mapping.patch
new file mode 100644
index 0000000000000..6ca78e29e1ea2
--- /dev/null
+++ b/pci/shpchp-fix-improper-mmio-mapping.patch
@@ -0,0 +1,178 @@
+From kaneshige.kenji@jp.fujitsu.com Wed Nov 23 18:42:59 2005
+Message-ID: <4385274B.5010407@jp.fujitsu.com>
+Date: Thu, 24 Nov 2005 11:36:59 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>, <kristen.c.accardi@intel.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Subject: shpchp: fix improper mmio mapping
+
+Current SHPCHP driver seems not to map MMIO region properly. This
+patch fixes this bug. This patch also cleanup the code.
+
+Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/hotplug/shpchp.h | 3 +
+ drivers/pci/hotplug/shpchp_core.c | 2 -
+ drivers/pci/hotplug/shpchp_hpc.c | 73 +++++++++++++++++++++++---------------
+ 3 files changed, 49 insertions(+), 29 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h
++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h
+@@ -98,6 +98,9 @@ struct controller {
+ enum pci_bus_speed speed;
+ u32 first_slot; /* First physical slot number */
+ u8 slot_bus; /* Bus where the slots handled by this controller sit */
++ u32 cap_offset;
++ unsigned long mmio_base;
++ unsigned long mmio_size;
+ };
+
+ struct hotplug_params {
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
+@@ -791,7 +791,7 @@ static void hpc_release_ctlr(struct cont
+ }
+ if (php_ctlr->pci_dev) {
+ iounmap(php_ctlr->creg);
+- release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0));
++ release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
+ php_ctlr->pci_dev = NULL;
+ }
+
+@@ -1320,19 +1320,34 @@ static struct hpc_ops shpchp_hpc_ops = {
+ .check_cmd_status = hpc_check_cmd_status,
+ };
+
++inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
++ u32 *value)
++{
++ int rc;
++ u32 cap_offset = ctrl->cap_offset;
++ struct pci_dev *pdev = ctrl->pci_dev;
++
++ rc = pci_write_config_byte(pdev, cap_offset + DWORD_SELECT, index);
++ if (rc)
++ return rc;
++ return pci_read_config_dword(pdev, cap_offset + DWORD_DATA, value);
++}
++
+ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
+ {
+ struct php_ctlr_state_s *php_ctlr, *p;
+ void *instance_id = ctrl;
+- int rc;
++ int rc, num_slots = 0;
+ u8 hp_slot;
+ static int first = 1;
+- u32 shpc_cap_offset, shpc_base_offset;
++ u32 shpc_base_offset;
+ u32 tempdword, slot_reg;
+ u8 i;
+
+ DBG_ENTER_ROUTINE
+
++ 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);
+
+@@ -1347,41 +1362,45 @@ int shpc_init(struct controller * ctrl,
+
+ if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
+ PCI_DEVICE_ID_AMD_GOLAM_7450)) {
+- shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */
++ /* amd shpc driver doesn't use Base Offset; assume 0 */
++ ctrl->mmio_base = pci_resource_start(pdev, 0);
++ ctrl->mmio_size = pci_resource_len(pdev, 0);
+ } else {
+- if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) {
+- err("%s : shpc_cap_offset == 0\n", __FUNCTION__);
++ ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);
++ if (!ctrl->cap_offset) {
++ err("%s : cap_offset == 0\n", __FUNCTION__);
+ goto abort_free_ctlr;
+ }
+- dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset);
+-
+- rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET);
++ dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
++
++ rc = shpc_indirect_creg_read(ctrl, 0, &shpc_base_offset);
+ if (rc) {
+- err("%s : pci_word_config_byte failed\n", __FUNCTION__);
++ err("%s: cannot read base_offset\n", __FUNCTION__);
+ goto abort_free_ctlr;
+ }
+-
+- rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset);
++
++ rc = shpc_indirect_creg_read(ctrl, 3, &tempdword);
+ if (rc) {
+- err("%s : pci_read_config_dword failed\n", __FUNCTION__);
++ err("%s: cannot read slot config\n", __FUNCTION__);
+ goto abort_free_ctlr;
+ }
++ num_slots = tempdword & SLOT_NUM;
++ dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
+
+- for (i = 0; i <= 14; i++) {
+- rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , i);
+- if (rc) {
+- err("%s : pci_word_config_byte failed\n", __FUNCTION__);
+- goto abort_free_ctlr;
+- }
+-
+- rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword);
++ for (i = 0; i < 9 + num_slots; i++) {
++ rc = shpc_indirect_creg_read(ctrl, i, &tempdword);
+ if (rc) {
+- err("%s : pci_read_config_dword failed\n", __FUNCTION__);
++ err("%s: cannot read creg (index = %d)\n",
++ __FUNCTION__, i);
+ goto abort_free_ctlr;
+ }
+ dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
+ tempdword);
+ }
++
++ ctrl->mmio_base =
++ pci_resource_start(pdev, 0) + shpc_base_offset;
++ ctrl->mmio_size = 0x24 + 0x4 * num_slots;
+ }
+
+ if (first) {
+@@ -1395,16 +1414,16 @@ int shpc_init(struct controller * ctrl,
+ if (pci_enable_device(pdev))
+ goto abort_free_ctlr;
+
+- if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) {
++ if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
+ err("%s: cannot reserve MMIO region\n", __FUNCTION__);
+ goto abort_free_ctlr;
+ }
+
+- php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
++ php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
+ if (!php_ctlr->creg) {
+- err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0),
+- pci_resource_start(pdev, 0) + shpc_base_offset);
+- release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0));
++ err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
++ ctrl->mmio_size, ctrl->mmio_base);
++ release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
+ goto abort_free_ctlr;
+ }
+ dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_core.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_core.c
+@@ -377,8 +377,6 @@ static int shpc_probe(struct pci_dev *pd
+ goto err_out_free_ctrl;
+ }
+
+- ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
+-
+ pci_set_drvdata(pdev, ctrl);
+
+ ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
diff --git a/pci/shpchp-fix-improper-reference-to-mode-1-ecc-capability-bit.patch b/pci/shpchp-fix-improper-reference-to-mode-1-ecc-capability-bit.patch
new file mode 100644
index 0000000000000..ac4ccb1a3d360
--- /dev/null
+++ b/pci/shpchp-fix-improper-reference-to-mode-1-ecc-capability-bit.patch
@@ -0,0 +1,31 @@
+From kaneshige.kenji@jp.fujitsu.com Wed Nov 23 18:37:41 2005
+Message-ID: <438526D9.1020605@jp.fujitsu.com>
+Date: Thu, 24 Nov 2005 11:35:05 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>, <kristen.c.accardi@intel.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Subject: shpchp: fix improper reference to Mode 1 ECC Capability" bit
+
+The hpc_get_mode1_ECC_cap() function of SHPCHP driver seems to refer
+the wrong bit for refering the "Mode 1 ECC Capability" bit. This bug
+seems not to cause any problem so far. But I think this should be
+fixed. This patch fixes this bug.
+
+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 | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
+@@ -604,7 +604,7 @@ static int hpc_get_mode1_ECC_cap(struct
+ sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG);
+
+ if (pi == 2) {
+- *mode = (sec_bus_status & 0x0100) >> 7;
++ *mode = (sec_bus_status & 0x0100) >> 8;
+ } else {
+ retval = -1;
+ }
diff --git a/pci/shpchp-fix-improper-reference-to-slot-avail-regsister.patch b/pci/shpchp-fix-improper-reference-to-slot-avail-regsister.patch
new file mode 100644
index 0000000000000..bdce2eab7434d
--- /dev/null
+++ b/pci/shpchp-fix-improper-reference-to-slot-avail-regsister.patch
@@ -0,0 +1,87 @@
+From kaneshige.kenji@jp.fujitsu.com Wed Nov 23 20:48:14 2005
+Message-ID: <43854511.9060405@jp.fujitsu.com>
+Date: Thu, 24 Nov 2005 13:44:01 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>, <kristen.c.accardi@intel.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Subject: shpchp: fix improper reference to Slot Avail Regsister
+
+The hpc_get_max_bus_speed() function of the SHPCHP driver seems to
+refer wrong bits in the "Slot Avail Register I" and "Slot Avail
+Register II". This patch fixes this bug. And this also cleanup the
+code.
+
+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 | 33 ++++++++++++++++-----------------
+ 1 file changed, 16 insertions(+), 17 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
+@@ -1121,7 +1121,6 @@ static int hpc_get_max_bus_speed (struct
+ int retval = 0;
+ u8 pi;
+ u32 slot_avail1, slot_avail2;
+- int slot_num;
+
+ DBG_ENTER_ROUTINE
+
+@@ -1140,39 +1139,39 @@ static int hpc_get_max_bus_speed (struct
+ slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2);
+
+ if (pi == 2) {
+- if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27) ) != 0 )
++ if (slot_avail2 & SLOT_133MHZ_PCIX_533)
+ bus_speed = PCIX_133MHZ_533;
+- else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23) ) != 0 )
++ else if (slot_avail2 & SLOT_100MHZ_PCIX_533)
+ bus_speed = PCIX_100MHZ_533;
+- else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19) ) != 0 )
++ else if (slot_avail2 & SLOT_66MHZ_PCIX_533)
+ bus_speed = PCIX_66MHZ_533;
+- else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15) ) != 0 )
++ else if (slot_avail2 & SLOT_133MHZ_PCIX_266)
+ bus_speed = PCIX_133MHZ_266;
+- else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11) ) != 0 )
++ else if (slot_avail2 & SLOT_100MHZ_PCIX_266)
+ bus_speed = PCIX_100MHZ_266;
+- else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7) ) != 0 )
++ else if (slot_avail2 & SLOT_66MHZ_PCIX_266)
+ bus_speed = PCIX_66MHZ_266;
+- else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 )
++ else if (slot_avail1 & SLOT_133MHZ_PCIX)
+ bus_speed = PCIX_133MHZ;
+- else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 )
++ else if (slot_avail1 & SLOT_100MHZ_PCIX)
+ bus_speed = PCIX_100MHZ;
+- else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 )
++ else if (slot_avail1 & SLOT_66MHZ_PCIX)
+ bus_speed = PCIX_66MHZ;
+- else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
++ else if (slot_avail2 & SLOT_66MHZ)
+ bus_speed = PCI_66MHZ;
+- else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
++ else if (slot_avail1 & SLOT_33MHZ)
+ bus_speed = PCI_33MHZ;
+ else bus_speed = PCI_SPEED_UNKNOWN;
+ } else {
+- if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 )
++ if (slot_avail1 & SLOT_133MHZ_PCIX)
+ bus_speed = PCIX_133MHZ;
+- else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 )
++ else if (slot_avail1 & SLOT_100MHZ_PCIX)
+ bus_speed = PCIX_100MHZ;
+- else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 )
++ else if (slot_avail1 & SLOT_66MHZ_PCIX)
+ bus_speed = PCIX_66MHZ;
+- else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 )
++ else if (slot_avail2 & SLOT_66MHZ)
+ bus_speed = PCI_66MHZ;
+- else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 )
++ else if (slot_avail1 & SLOT_33MHZ)
+ bus_speed = PCI_33MHZ;
+ else bus_speed = PCI_SPEED_UNKNOWN;
+ }
diff --git a/pci/shpchp-fix-improper-wait-for-command-completion.patch b/pci/shpchp-fix-improper-wait-for-command-completion.patch
new file mode 100644
index 0000000000000..61ec54a9fd301
--- /dev/null
+++ b/pci/shpchp-fix-improper-wait-for-command-completion.patch
@@ -0,0 +1,247 @@
+From kaneshige.kenji@jp.fujitsu.com Thu Nov 24 19:32:27 2005
+Message-ID: <438684F5.4080107@jp.fujitsu.com>
+Date: Fri, 25 Nov 2005 12:28:53 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>, <kristen.c.accardi@intel.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Subject: shpchp: fix improper wait for command completion
+
+Current SHPCHP driver uses msleep_interruptible() function to wait for
+a command completion event. But I think this would cause an unnecessary
+long wait until timeout, if command completion interrupt came before
+task state was changed to TASK_INTERRUPTIBLE. This patch fixes this
+issue. With this patch, command completion becomes faster as follows:
+
+o Without this patch
+
+ # time echo 1 > power
+
+ real 0m4.708s
+ user 0m0.000s
+ sys 0m0.524s
+
+o With this patch
+
+ # time echo 1 > power
+
+ real 0m2.221s
+ user 0m0.000s
+ sys 0m0.532s
+
+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 | 37 -------------------------------------
+ drivers/pci/hotplug/shpchp_hpc.c | 26 ++++++++++++++++++++++++++
+ 3 files changed, 27 insertions(+), 37 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp.h
++++ gregkh-2.6/drivers/pci/hotplug/shpchp.h
+@@ -101,6 +101,7 @@ struct controller {
+ u32 cap_offset;
+ unsigned long mmio_base;
+ unsigned long mmio_size;
++ volatile int cmd_busy;
+ };
+
+ struct hotplug_params {
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
+@@ -275,6 +275,25 @@ static void start_int_poll_timer(struct
+ return;
+ }
+
++static inline int shpc_wait_cmd(struct controller *ctrl)
++{
++ int retval = 0;
++ unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;
++ unsigned long timeout = msecs_to_jiffies(timeout_msec);
++ int rc = wait_event_interruptible_timeout(ctrl->queue,
++ !ctrl->cmd_busy, timeout);
++ if (!rc) {
++ retval = -EIO;
++ err("Command not completed in %d msec\n", timeout_msec);
++ } else if (rc < 0) {
++ retval = -EINTR;
++ info("Command was interrupted by a signal\n");
++ }
++ ctrl->cmd_busy = 0;
++
++ return retval;
++}
++
+ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
+ {
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
+@@ -314,8 +333,14 @@ static int shpc_write_cmd(struct slot *s
+ /* To make sure the Controller Busy bit is 0 before we send out the
+ * command.
+ */
++ slot->ctrl->cmd_busy = 1;
+ writew(temp_word, php_ctlr->creg + CMD);
+
++ /*
++ * Wait for command completion.
++ */
++ retval = shpc_wait_cmd(slot->ctrl);
++
+ DBG_LEAVE_ROUTINE
+ return retval;
+ }
+@@ -1064,6 +1089,7 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
+ temp_dword &= 0xfffdffff;
+ writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
++ ctrl->cmd_busy = 0;
+ wake_up_interruptible(&ctrl->queue);
+ }
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_ctrl.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_ctrl.c
+@@ -248,7 +248,6 @@ static int change_bus_speed(struct contr
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+- wait_for_ctrl_irq (ctrl);
+
+ 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",
+@@ -330,9 +329,6 @@ static int board_added(struct slot *p_sl
+ up(&ctrl->crit_sect);
+ return -1;
+ }
+-
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ rc = p_slot->hpc_ops->check_cmd_status(ctrl);
+ if (rc) {
+@@ -352,7 +348,6 @@ static int board_added(struct slot *p_sl
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+- wait_for_ctrl_irq (ctrl);
+
+ 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",
+@@ -367,7 +362,6 @@ static int board_added(struct slot *p_sl
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+- wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
+@@ -494,7 +488,6 @@ static int board_added(struct slot *p_sl
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+- wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
+@@ -532,9 +525,6 @@ static int board_added(struct slot *p_sl
+
+ p_slot->hpc_ops->green_led_on(p_slot);
+
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+-
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+
+@@ -552,8 +542,6 @@ err_exit:
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ rc = p_slot->hpc_ops->check_cmd_status(ctrl);
+ if (rc) {
+@@ -603,8 +591,6 @@ static int remove_board(struct slot *p_s
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ rc = p_slot->hpc_ops->check_cmd_status(ctrl);
+ if (rc) {
+@@ -621,8 +607,6 @@ static int remove_board(struct slot *p_s
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+@@ -676,9 +660,6 @@ static void shpchp_pushbutton_thread (un
+
+ p_slot->hpc_ops->green_led_off(p_slot);
+
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (p_slot->ctrl);
+-
+ /* Done with exclusive hardware access */
+ up(&p_slot->ctrl->crit_sect);
+ }
+@@ -790,14 +771,9 @@ static void interrupt_event_handler(stru
+ down(&ctrl->crit_sect);
+
+ p_slot->hpc_ops->green_led_on(p_slot);
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+-
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+ break;
+@@ -806,12 +782,8 @@ static void interrupt_event_handler(stru
+ down(&ctrl->crit_sect);
+
+ p_slot->hpc_ops->green_led_off(p_slot);
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+@@ -845,14 +817,9 @@ static void interrupt_event_handler(stru
+
+ /* blink green LED and turn off amber */
+ p_slot->hpc_ops->green_led_blink(p_slot);
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ p_slot->hpc_ops->set_attention_status(p_slot, 0);
+
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+-
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
+
+@@ -870,12 +837,8 @@ static void interrupt_event_handler(stru
+ down(&ctrl->crit_sect);
+
+ p_slot->hpc_ops->set_attention_status(p_slot, 1);
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ p_slot->hpc_ops->green_led_off(p_slot);
+- /* Wait for the command to complete */
+- wait_for_ctrl_irq (ctrl);
+
+ /* Done with exclusive hardware access */
+ up(&ctrl->crit_sect);
diff --git a/pci/shpchp-fix-improper-write-to-command-completion-detect-bit.patch b/pci/shpchp-fix-improper-write-to-command-completion-detect-bit.patch
new file mode 100644
index 0000000000000..76a4b8b5b2637
--- /dev/null
+++ b/pci/shpchp-fix-improper-write-to-command-completion-detect-bit.patch
@@ -0,0 +1,36 @@
+From kaneshige.kenji@jp.fujitsu.com Wed Nov 23 18:43:14 2005
+Message-ID: <438527E1.20709@jp.fujitsu.com>
+Date: Thu, 24 Nov 2005 11:39:29 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>, <kristen.c.accardi@intel.com>
+CC: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Subject: shpchp: fix improper write to Command Completion Detect bit
+
+Current SHPCHP driver writes a '0' to the Command Completion Detect
+bit to clear the Command Complete Interrupt Pending. But according to
+the SHPC spec (See 4.7.3.1 System Interrupts), SHPCHP driver must
+write '1'. This patch fixes this bug.
+
+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 | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_hpc.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_hpc.c
+@@ -1058,11 +1058,11 @@ static irqreturn_t shpc_isr(int IRQ, voi
+ if (intr_loc & 0x0001) {
+ /*
+ * Command Complete Interrupt Pending
+- * RO only - clear by writing 0 to the Command Completion
++ * RO only - clear by writing 1 to the Command Completion
+ * Detect bit in Controller SERR-INT register
+ */
+ temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
+- temp_dword &= 0xfffeffff;
++ temp_dword &= 0xfffdffff;
+ writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
+ wake_up_interruptible(&ctrl->queue);
+ }
diff --git a/pci/shpchp-replace-pci_find_slot-with-pci_get_slot.patch b/pci/shpchp-replace-pci_find_slot-with-pci_get_slot.patch
new file mode 100644
index 0000000000000..e06288f10443a
--- /dev/null
+++ b/pci/shpchp-replace-pci_find_slot-with-pci_get_slot.patch
@@ -0,0 +1,109 @@
+From kaneshige.kenji@jp.fujitsu.com Thu Nov 24 19:27:04 2005
+Message-ID: <43868335.3080001@jp.fujitsu.com>
+Date: Fri, 25 Nov 2005 12:21:25 +0900
+From: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+To: Greg KH <greg@kroah.com>
+CC: <kristen.c.accardi@intel.com>
+Subject: shpchp: replace pci_find_slot() with pci_get_slot()
+
+
+This patch replaces pci_find_slot() with pci_get_slot() in the SHPCHP
+driver. This enables SHPCHP driver to work on multiple PCI segment
+systems.
+
+Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/pci/hotplug/shpchp_pci.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- gregkh-2.6.orig/drivers/pci/hotplug/shpchp_pci.c
++++ gregkh-2.6/drivers/pci/hotplug/shpchp_pci.c
+@@ -89,10 +89,11 @@ int shpchp_configure_device(struct slot
+ struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
+ int num, fn;
+
+- dev = pci_find_slot(p_slot->bus, PCI_DEVFN(p_slot->device, 0));
++ dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
+ if (dev) {
+ err("Device %s already exists at %x:%x, cannot hot-add\n",
+ pci_name(dev), p_slot->bus, p_slot->device);
++ pci_dev_put(dev);
+ return -EINVAL;
+ }
+
+@@ -103,12 +104,13 @@ int shpchp_configure_device(struct slot
+ }
+
+ for (fn = 0; fn < 8; fn++) {
+- if (!(dev = pci_find_slot(p_slot->bus,
+- PCI_DEVFN(p_slot->device, fn))))
++ dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
++ if (!dev)
+ continue;
+ if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot hot-add display device %s\n",
+ pci_name(dev));
++ pci_dev_put(dev);
+ continue;
+ }
+ if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
+@@ -124,18 +126,21 @@ int shpchp_configure_device(struct slot
+ }
+ if (busnr >= end) {
+ err("No free bus for hot-added bridge\n");
++ pci_dev_put(dev);
+ continue;
+ }
+ child = pci_add_new_bus(parent, dev, busnr);
+ if (!child) {
+ err("Cannot add new bus for %s\n",
+ pci_name(dev));
++ pci_dev_put(dev);
+ continue;
+ }
+ child->subordinate = pci_do_scan_bus(child);
+ pci_bus_size_bridges(child);
+ }
+ program_fw_provided_values(dev);
++ pci_dev_put(dev);
+ }
+
+ pci_bus_assign_resources(parent);
+@@ -149,17 +154,19 @@ int shpchp_unconfigure_device(struct slo
+ int rc = 0;
+ int j;
+ u8 bctl = 0;
+-
++ struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
++
+ dbg("%s: bus/dev = %x/%x\n", __FUNCTION__, p_slot->bus, p_slot->device);
+
+ for (j=0; j<8 ; j++) {
+- struct pci_dev* temp = pci_find_slot(p_slot->bus,
++ struct pci_dev* temp = pci_get_slot(parent,
+ (p_slot->device << 3) | j);
+ if (!temp)
+ continue;
+ if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
++ pci_dev_put(temp);
+ continue;
+ }
+ if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+@@ -167,10 +174,12 @@ int shpchp_unconfigure_device(struct slo
+ if (bctl & PCI_BRIDGE_CTL_VGA) {
+ err("Cannot remove display device %s\n",
+ pci_name(temp));
++ pci_dev_put(temp);
+ continue;
+ }
+ }
+ pci_remove_bus_device(temp);
++ pci_dev_put(temp);
+ }
+ return rc;
+ }