aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2008-05-27 06:04:30 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-05-27 18:43:16 -0400
commit5808639bfa98d69f77a481d759570d85f164fea0 (patch)
treef691cf1890db51cb201a64c9420281684bf80608 /drivers/pci/hotplug/pciehp_hpc.c
parentdbd79aed1aea2bece0bf43cc2ff3b2f9baf48a08 (diff)
pciehp: fix slow probing
Fix the "pciehp probing slow" problem reported from Jan C. Nordholz in http://bugzilla.kernel.org/show_bug.cgi?id=10751. The command completed bit in Slot Status register applies only to commands issued to control the attention indicator, power indicator, power controller, or electromechanical interlock. However, writes to other parts of the Slot Control register would end up writing to the control fields. Hence, any write to Slot Control register is considered as a command. However, if the controller doesn't support any of attention indicator, power indicator, power controller and electromechanical interlock, command completed bit would not set in writing to Slot Control register. In this case, we should not wait for command completed bit set, otherwise all commands would be considered not completed in timeout seconds (1 sec.). The cause of the problem is pciehp driver didn't take this situation into account. This patch changes pciehp to take it into account. This patch also add the check for "No Command Completed Support" bit in Slot Capability register. If it is set, we should not wait for command completed bit set as well. This problem seems to be revealed by the commit c27fb883dffe11aa4cb35ecea1fa1832ba45d4da that fixed the bug that pciehp did not wait for command completed properly (pciehp just ignored the command completion event). Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 425a0f609977..70940fb3fffa 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -286,12 +286,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
286 goto out; 286 goto out;
287 } 287 }
288 288
289 if ((slot_status & CMD_COMPLETED) == CMD_COMPLETED ) { 289 if (slot_status & CMD_COMPLETED) {
290 /* After 1 sec and CMD_COMPLETED still not set, just 290 if (!ctrl->no_cmd_complete) {
291 proceed forward to issue the next command according 291 /*
292 to spec. Just print out the error message */ 292 * After 1 sec and CMD_COMPLETED still not set, just
293 dbg("%s: CMD_COMPLETED not clear after 1 sec.\n", 293 * proceed forward to issue the next command according
294 __func__); 294 * to spec. Just print out the error message.
295 */
296 dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
297 __func__);
298 } else if (!NO_CMD_CMPL(ctrl)) {
299 /*
300 * This controller semms to notify of command completed
301 * event even though it supports none of power
302 * controller, attention led, power led and EMI.
303 */
304 dbg("%s: Unexpected CMD_COMPLETED. Need to wait for "
305 "command completed event.\n", __func__);
306 ctrl->no_cmd_complete = 0;
307 } else {
308 dbg("%s: Unexpected CMD_COMPLETED. Maybe the "
309 "controller is broken.\n", __func__);
310 }
295 } 311 }
296 312
297 retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); 313 retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
@@ -315,7 +331,7 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
315 /* 331 /*
316 * Wait for command completion. 332 * Wait for command completion.
317 */ 333 */
318 if (!retval) 334 if (!retval && !ctrl->no_cmd_complete)
319 retval = pcie_wait_cmd(ctrl); 335 retval = pcie_wait_cmd(ctrl);
320 out: 336 out:
321 mutex_unlock(&ctrl->ctrl_lock); 337 mutex_unlock(&ctrl->ctrl_lock);
@@ -1130,6 +1146,7 @@ static inline void dbg_ctrl(struct controller *ctrl)
1130 dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no"); 1146 dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no");
1131 dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no"); 1147 dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no");
1132 dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no"); 1148 dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no");
1149 dbg(" Comamnd Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
1133 pciehp_readw(ctrl, SLOTSTATUS, &reg16); 1150 pciehp_readw(ctrl, SLOTSTATUS, &reg16);
1134 dbg("Slot Status : 0x%04x\n", reg16); 1151 dbg("Slot Status : 0x%04x\n", reg16);
1135 pciehp_readw(ctrl, SLOTSTATUS, &reg16); 1152 pciehp_readw(ctrl, SLOTSTATUS, &reg16);
@@ -1161,6 +1178,15 @@ int pcie_init(struct controller *ctrl, struct pcie_device *dev)
1161 mutex_init(&ctrl->ctrl_lock); 1178 mutex_init(&ctrl->ctrl_lock);
1162 init_waitqueue_head(&ctrl->queue); 1179 init_waitqueue_head(&ctrl->queue);
1163 dbg_ctrl(ctrl); 1180 dbg_ctrl(ctrl);
1181 /*
1182 * Controller doesn't notify of command completion if the "No
1183 * Command Completed Support" bit is set in Slot Capability
1184 * register or the controller supports none of power
1185 * controller, attention led, power led and EMI.
1186 */
1187 if (NO_CMD_CMPL(ctrl) ||
1188 !(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl)))
1189 ctrl->no_cmd_complete = 1;
1164 1190
1165 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", 1191 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
1166 pdev->vendor, pdev->device, 1192 pdev->vendor, pdev->device,