aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2005-11-24 22:28:53 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-09 15:13:17 -0500
commitbd62e271401c5ebf33a0dd24d89baf706f213251 (patch)
tree77b8e2cd249df83b0d256f8126047a037a1fc542 /drivers/pci/hotplug
parentf467f6187fc60c954a9509b3a3e17ef89a4f6f22 (diff)
[PATCH] 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>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/shpchp.h1
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c37
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c26
3 files changed, 27 insertions, 37 deletions
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 55b0cd15f348..ce0e9b6ce833 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -101,6 +101,7 @@ struct controller {
101 u32 cap_offset; 101 u32 cap_offset;
102 unsigned long mmio_base; 102 unsigned long mmio_base;
103 unsigned long mmio_size; 103 unsigned long mmio_size;
104 volatile int cmd_busy;
104}; 105};
105 106
106struct hotplug_params { 107struct hotplug_params {
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 58619359ad08..25ccb0e47593 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -248,7 +248,6 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
248 up(&ctrl->crit_sect); 248 up(&ctrl->crit_sect);
249 return WRONG_BUS_FREQUENCY; 249 return WRONG_BUS_FREQUENCY;
250 } 250 }
251 wait_for_ctrl_irq (ctrl);
252 251
253 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { 252 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
254 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", 253 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_slot)
330 up(&ctrl->crit_sect); 329 up(&ctrl->crit_sect);
331 return -1; 330 return -1;
332 } 331 }
333
334 /* Wait for the command to complete */
335 wait_for_ctrl_irq (ctrl);
336 332
337 rc = p_slot->hpc_ops->check_cmd_status(ctrl); 333 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
338 if (rc) { 334 if (rc) {
@@ -352,7 +348,6 @@ static int board_added(struct slot *p_slot)
352 up(&ctrl->crit_sect); 348 up(&ctrl->crit_sect);
353 return WRONG_BUS_FREQUENCY; 349 return WRONG_BUS_FREQUENCY;
354 } 350 }
355 wait_for_ctrl_irq (ctrl);
356 351
357 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { 352 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
358 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n", 353 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_slot)
367 up(&ctrl->crit_sect); 362 up(&ctrl->crit_sect);
368 return rc; 363 return rc;
369 } 364 }
370 wait_for_ctrl_irq (ctrl);
371 365
372 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { 366 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
373 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); 367 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
@@ -494,7 +488,6 @@ static int board_added(struct slot *p_slot)
494 up(&ctrl->crit_sect); 488 up(&ctrl->crit_sect);
495 return rc; 489 return rc;
496 } 490 }
497 wait_for_ctrl_irq (ctrl);
498 491
499 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) { 492 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
500 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc); 493 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
@@ -532,9 +525,6 @@ static int board_added(struct slot *p_slot)
532 525
533 p_slot->hpc_ops->green_led_on(p_slot); 526 p_slot->hpc_ops->green_led_on(p_slot);
534 527
535 /* Wait for the command to complete */
536 wait_for_ctrl_irq (ctrl);
537
538 /* Done with exclusive hardware access */ 528 /* Done with exclusive hardware access */
539 up(&ctrl->crit_sect); 529 up(&ctrl->crit_sect);
540 530
@@ -552,8 +542,6 @@ err_exit:
552 up(&ctrl->crit_sect); 542 up(&ctrl->crit_sect);
553 return rc; 543 return rc;
554 } 544 }
555 /* Wait for the command to complete */
556 wait_for_ctrl_irq (ctrl);
557 545
558 rc = p_slot->hpc_ops->check_cmd_status(ctrl); 546 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
559 if (rc) { 547 if (rc) {
@@ -603,8 +591,6 @@ static int remove_board(struct slot *p_slot)
603 up(&ctrl->crit_sect); 591 up(&ctrl->crit_sect);
604 return rc; 592 return rc;
605 } 593 }
606 /* Wait for the command to complete */
607 wait_for_ctrl_irq (ctrl);
608 594
609 rc = p_slot->hpc_ops->check_cmd_status(ctrl); 595 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
610 if (rc) { 596 if (rc) {
@@ -621,8 +607,6 @@ static int remove_board(struct slot *p_slot)
621 up(&ctrl->crit_sect); 607 up(&ctrl->crit_sect);
622 return rc; 608 return rc;
623 } 609 }
624 /* Wait for the command to complete */
625 wait_for_ctrl_irq (ctrl);
626 610
627 /* Done with exclusive hardware access */ 611 /* Done with exclusive hardware access */
628 up(&ctrl->crit_sect); 612 up(&ctrl->crit_sect);
@@ -676,9 +660,6 @@ static void shpchp_pushbutton_thread (unsigned long slot)
676 660
677 p_slot->hpc_ops->green_led_off(p_slot); 661 p_slot->hpc_ops->green_led_off(p_slot);
678 662
679 /* Wait for the command to complete */
680 wait_for_ctrl_irq (p_slot->ctrl);
681
682 /* Done with exclusive hardware access */ 663 /* Done with exclusive hardware access */
683 up(&p_slot->ctrl->crit_sect); 664 up(&p_slot->ctrl->crit_sect);
684 } 665 }
@@ -790,14 +771,9 @@ static void interrupt_event_handler(struct controller *ctrl)
790 down(&ctrl->crit_sect); 771 down(&ctrl->crit_sect);
791 772
792 p_slot->hpc_ops->green_led_on(p_slot); 773 p_slot->hpc_ops->green_led_on(p_slot);
793 /* Wait for the command to complete */
794 wait_for_ctrl_irq (ctrl);
795 774
796 p_slot->hpc_ops->set_attention_status(p_slot, 0); 775 p_slot->hpc_ops->set_attention_status(p_slot, 0);
797 776
798 /* Wait for the command to complete */
799 wait_for_ctrl_irq (ctrl);
800
801 /* Done with exclusive hardware access */ 777 /* Done with exclusive hardware access */
802 up(&ctrl->crit_sect); 778 up(&ctrl->crit_sect);
803 break; 779 break;
@@ -806,12 +782,8 @@ static void interrupt_event_handler(struct controller *ctrl)
806 down(&ctrl->crit_sect); 782 down(&ctrl->crit_sect);
807 783
808 p_slot->hpc_ops->green_led_off(p_slot); 784 p_slot->hpc_ops->green_led_off(p_slot);
809 /* Wait for the command to complete */
810 wait_for_ctrl_irq (ctrl);
811 785
812 p_slot->hpc_ops->set_attention_status(p_slot, 0); 786 p_slot->hpc_ops->set_attention_status(p_slot, 0);
813 /* Wait for the command to complete */
814 wait_for_ctrl_irq (ctrl);
815 787
816 /* Done with exclusive hardware access */ 788 /* Done with exclusive hardware access */
817 up(&ctrl->crit_sect); 789 up(&ctrl->crit_sect);
@@ -845,14 +817,9 @@ static void interrupt_event_handler(struct controller *ctrl)
845 817
846 /* blink green LED and turn off amber */ 818 /* blink green LED and turn off amber */
847 p_slot->hpc_ops->green_led_blink(p_slot); 819 p_slot->hpc_ops->green_led_blink(p_slot);
848 /* Wait for the command to complete */
849 wait_for_ctrl_irq (ctrl);
850 820
851 p_slot->hpc_ops->set_attention_status(p_slot, 0); 821 p_slot->hpc_ops->set_attention_status(p_slot, 0);
852 822
853 /* Wait for the command to complete */
854 wait_for_ctrl_irq (ctrl);
855
856 /* Done with exclusive hardware access */ 823 /* Done with exclusive hardware access */
857 up(&ctrl->crit_sect); 824 up(&ctrl->crit_sect);
858 825
@@ -870,12 +837,8 @@ static void interrupt_event_handler(struct controller *ctrl)
870 down(&ctrl->crit_sect); 837 down(&ctrl->crit_sect);
871 838
872 p_slot->hpc_ops->set_attention_status(p_slot, 1); 839 p_slot->hpc_ops->set_attention_status(p_slot, 1);
873 /* Wait for the command to complete */
874 wait_for_ctrl_irq (ctrl);
875 840
876 p_slot->hpc_ops->green_led_off(p_slot); 841 p_slot->hpc_ops->green_led_off(p_slot);
877 /* Wait for the command to complete */
878 wait_for_ctrl_irq (ctrl);
879 842
880 /* Done with exclusive hardware access */ 843 /* Done with exclusive hardware access */
881 up(&ctrl->crit_sect); 844 up(&ctrl->crit_sect);
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index f25e11645071..b4226ff3a854 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -275,6 +275,25 @@ static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds)
275 return; 275 return;
276} 276}
277 277
278static inline int shpc_wait_cmd(struct controller *ctrl)
279{
280 int retval = 0;
281 unsigned int timeout_msec = shpchp_poll_mode ? 2000 : 1000;
282 unsigned long timeout = msecs_to_jiffies(timeout_msec);
283 int rc = wait_event_interruptible_timeout(ctrl->queue,
284 !ctrl->cmd_busy, timeout);
285 if (!rc) {
286 retval = -EIO;
287 err("Command not completed in %d msec\n", timeout_msec);
288 } else if (rc < 0) {
289 retval = -EINTR;
290 info("Command was interrupted by a signal\n");
291 }
292 ctrl->cmd_busy = 0;
293
294 return retval;
295}
296
278static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) 297static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
279{ 298{
280 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle; 299 struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
@@ -314,8 +333,14 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
314 /* To make sure the Controller Busy bit is 0 before we send out the 333 /* To make sure the Controller Busy bit is 0 before we send out the
315 * command. 334 * command.
316 */ 335 */
336 slot->ctrl->cmd_busy = 1;
317 writew(temp_word, php_ctlr->creg + CMD); 337 writew(temp_word, php_ctlr->creg + CMD);
318 338
339 /*
340 * Wait for command completion.
341 */
342 retval = shpc_wait_cmd(slot->ctrl);
343
319 DBG_LEAVE_ROUTINE 344 DBG_LEAVE_ROUTINE
320 return retval; 345 return retval;
321} 346}
@@ -1064,6 +1089,7 @@ static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs)
1064 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1089 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE);
1065 temp_dword &= 0xfffdffff; 1090 temp_dword &= 0xfffdffff;
1066 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 1091 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE);
1092 ctrl->cmd_busy = 0;
1067 wake_up_interruptible(&ctrl->queue); 1093 wake_up_interruptible(&ctrl->queue);
1068 } 1094 }
1069 1095