aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/shpchp.h1
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c120
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c25
3 files changed, 23 insertions, 123 deletions
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index f6d606dde691..b1e2a7705835 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -80,6 +80,7 @@ struct event_info {
80struct controller { 80struct controller {
81 struct list_head ctrl_list; 81 struct list_head ctrl_list;
82 struct mutex crit_sect; /* critical section mutex */ 82 struct mutex crit_sect; /* critical section mutex */
83 struct mutex cmd_lock; /* command lock */
83 struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ 84 struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
84 int num_slots; /* Number of slots on ctlr */ 85 int num_slots; /* Number of slots on ctlr */
85 int slot_num_inc; /* 1 or -1 */ 86 int slot_num_inc; /* 1 or -1 */
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 3a8e733aead5..802c4c48d186 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -242,21 +242,10 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
242 int rc = 0; 242 int rc = 0;
243 243
244 dbg("%s: change to speed %d\n", __FUNCTION__, speed); 244 dbg("%s: change to speed %d\n", __FUNCTION__, speed);
245 mutex_lock(&ctrl->crit_sect);
246 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) { 245 if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
247 err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); 246 err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
248 mutex_unlock(&ctrl->crit_sect);
249 return WRONG_BUS_FREQUENCY;
250 }
251
252 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
253 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
254 __FUNCTION__);
255 err("%s: Error code (%d)\n", __FUNCTION__, rc);
256 mutex_unlock(&ctrl->crit_sect);
257 return WRONG_BUS_FREQUENCY; 247 return WRONG_BUS_FREQUENCY;
258 } 248 }
259 mutex_unlock(&ctrl->crit_sect);
260 return rc; 249 return rc;
261} 250}
262 251
@@ -330,15 +319,6 @@ static int board_added(struct slot *p_slot)
330 return -1; 319 return -1;
331 } 320 }
332 321
333 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
334 if (rc) {
335 err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc);
336 /* Done with exclusive hardware access */
337 mutex_unlock(&ctrl->crit_sect);
338 return -1;
339 }
340
341
342 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { 322 if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
343 if (slots_not_empty) 323 if (slots_not_empty)
344 return WRONG_BUS_FREQUENCY; 324 return WRONG_BUS_FREQUENCY;
@@ -349,25 +329,12 @@ static int board_added(struct slot *p_slot)
349 return WRONG_BUS_FREQUENCY; 329 return WRONG_BUS_FREQUENCY;
350 } 330 }
351 331
352 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
353 err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
354 __FUNCTION__);
355 err("%s: Error code (%d)\n", __FUNCTION__, rc);
356 mutex_unlock(&ctrl->crit_sect);
357 return WRONG_BUS_FREQUENCY;
358 }
359 /* turn on board, blink green LED, turn off Amber LED */ 332 /* turn on board, blink green LED, turn off Amber LED */
360 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { 333 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
361 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); 334 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
362 mutex_unlock(&ctrl->crit_sect); 335 mutex_unlock(&ctrl->crit_sect);
363 return rc; 336 return rc;
364 } 337 }
365
366 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
367 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
368 mutex_unlock(&ctrl->crit_sect);
369 return rc;
370 }
371 } 338 }
372 339
373 rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed); 340 rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
@@ -481,22 +448,12 @@ static int board_added(struct slot *p_slot)
481 return rc; 448 return rc;
482 } 449 }
483 450
484 mutex_lock(&ctrl->crit_sect);
485 /* turn on board, blink green LED, turn off Amber LED */ 451 /* turn on board, blink green LED, turn off Amber LED */
486 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { 452 if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
487 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); 453 err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
488 mutex_unlock(&ctrl->crit_sect);
489 return rc; 454 return rc;
490 } 455 }
491 456
492 if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
493 err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
494 mutex_unlock(&ctrl->crit_sect);
495 return rc;
496 }
497
498 mutex_unlock(&ctrl->crit_sect);
499
500 /* Wait for ~1 second */ 457 /* Wait for ~1 second */
501 wait_for_ctrl_irq (ctrl); 458 wait_for_ctrl_irq (ctrl);
502 459
@@ -520,40 +477,18 @@ static int board_added(struct slot *p_slot)
520 p_slot->is_a_board = 0x01; 477 p_slot->is_a_board = 0x01;
521 p_slot->pwr_save = 1; 478 p_slot->pwr_save = 1;
522 479
523 /* Wait for exclusive access to hardware */
524 mutex_lock(&ctrl->crit_sect);
525
526 p_slot->hpc_ops->green_led_on(p_slot); 480 p_slot->hpc_ops->green_led_on(p_slot);
527 481
528 /* Done with exclusive hardware access */
529 mutex_unlock(&ctrl->crit_sect);
530
531 return 0; 482 return 0;
532 483
533err_exit: 484err_exit:
534 /* Wait for exclusive access to hardware */
535 mutex_lock(&ctrl->crit_sect);
536
537 /* turn off slot, turn on Amber LED, turn off Green LED */ 485 /* turn off slot, turn on Amber LED, turn off Green LED */
538 rc = p_slot->hpc_ops->slot_disable(p_slot); 486 rc = p_slot->hpc_ops->slot_disable(p_slot);
539 if (rc) { 487 if (rc) {
540 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); 488 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
541 /* Done with exclusive hardware access */
542 mutex_unlock(&ctrl->crit_sect);
543 return rc; 489 return rc;
544 } 490 }
545 491
546 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
547 if (rc) {
548 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
549 /* Done with exclusive hardware access */
550 mutex_unlock(&ctrl->crit_sect);
551 return rc;
552 }
553
554 /* Done with exclusive hardware access */
555 mutex_unlock(&ctrl->crit_sect);
556
557 return(rc); 492 return(rc);
558} 493}
559 494
@@ -580,37 +515,19 @@ static int remove_board(struct slot *p_slot)
580 if (p_slot->is_a_board) 515 if (p_slot->is_a_board)
581 p_slot->status = 0x01; 516 p_slot->status = 0x01;
582 517
583 /* Wait for exclusive access to hardware */
584 mutex_lock(&ctrl->crit_sect);
585
586 /* turn off slot, turn on Amber LED, turn off Green LED */ 518 /* turn off slot, turn on Amber LED, turn off Green LED */
587 rc = p_slot->hpc_ops->slot_disable(p_slot); 519 rc = p_slot->hpc_ops->slot_disable(p_slot);
588 if (rc) { 520 if (rc) {
589 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); 521 err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
590 /* Done with exclusive hardware access */
591 mutex_unlock(&ctrl->crit_sect);
592 return rc; 522 return rc;
593 } 523 }
594
595 rc = p_slot->hpc_ops->check_cmd_status(ctrl);
596 if (rc) {
597 err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
598 /* Done with exclusive hardware access */
599 mutex_unlock(&ctrl->crit_sect);
600 return rc;
601 }
602 524
603 rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); 525 rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
604 if (rc) { 526 if (rc) {
605 err("%s: Issue of Set Attention command failed\n", __FUNCTION__); 527 err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
606 /* Done with exclusive hardware access */
607 mutex_unlock(&ctrl->crit_sect);
608 return rc; 528 return rc;
609 } 529 }
610 530
611 /* Done with exclusive hardware access */
612 mutex_unlock(&ctrl->crit_sect);
613
614 p_slot->pwr_save = 0; 531 p_slot->pwr_save = 0;
615 p_slot->is_a_board = 0; 532 p_slot->is_a_board = 0;
616 533
@@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (unsigned long slot)
654 } else { 571 } else {
655 p_slot->state = POWERON_STATE; 572 p_slot->state = POWERON_STATE;
656 573
657 if (shpchp_enable_slot(p_slot)) { 574 if (shpchp_enable_slot(p_slot))
658 /* Wait for exclusive access to hardware */
659 mutex_lock(&p_slot->ctrl->crit_sect);
660
661 p_slot->hpc_ops->green_led_off(p_slot); 575 p_slot->hpc_ops->green_led_off(p_slot);
662 576
663 /* Done with exclusive hardware access */
664 mutex_unlock(&p_slot->ctrl->crit_sect);
665 }
666 p_slot->state = STATIC_STATE; 577 p_slot->state = STATIC_STATE;
667 } 578 }
668 579
@@ -767,27 +678,12 @@ static void interrupt_event_handler(struct controller *ctrl)
767 678
768 switch (p_slot->state) { 679 switch (p_slot->state) {
769 case BLINKINGOFF_STATE: 680 case BLINKINGOFF_STATE:
770 /* Wait for exclusive access to hardware */
771 mutex_lock(&ctrl->crit_sect);
772
773 p_slot->hpc_ops->green_led_on(p_slot); 681 p_slot->hpc_ops->green_led_on(p_slot);
774
775 p_slot->hpc_ops->set_attention_status(p_slot, 0); 682 p_slot->hpc_ops->set_attention_status(p_slot, 0);
776
777 /* Done with exclusive hardware access */
778 mutex_unlock(&ctrl->crit_sect);
779 break; 683 break;
780 case BLINKINGON_STATE: 684 case BLINKINGON_STATE:
781 /* Wait for exclusive access to hardware */
782 mutex_lock(&ctrl->crit_sect);
783
784 p_slot->hpc_ops->green_led_off(p_slot); 685 p_slot->hpc_ops->green_led_off(p_slot);
785
786 p_slot->hpc_ops->set_attention_status(p_slot, 0); 686 p_slot->hpc_ops->set_attention_status(p_slot, 0);
787
788 /* Done with exclusive hardware access */
789 mutex_unlock(&ctrl->crit_sect);
790
791 break; 687 break;
792 default: 688 default:
793 warn("Not a valid state\n"); 689 warn("Not a valid state\n");
@@ -812,17 +708,10 @@ static void interrupt_event_handler(struct controller *ctrl)
812 info(msg_button_on, p_slot->number); 708 info(msg_button_on, p_slot->number);
813 } 709 }
814 710
815 /* Wait for exclusive access to hardware */
816 mutex_lock(&ctrl->crit_sect);
817
818 /* blink green LED and turn off amber */ 711 /* blink green LED and turn off amber */
819 p_slot->hpc_ops->green_led_blink(p_slot); 712 p_slot->hpc_ops->green_led_blink(p_slot);
820
821 p_slot->hpc_ops->set_attention_status(p_slot, 0); 713 p_slot->hpc_ops->set_attention_status(p_slot, 0);
822 714
823 /* Done with exclusive hardware access */
824 mutex_unlock(&ctrl->crit_sect);
825
826 init_timer(&p_slot->task_event); 715 init_timer(&p_slot->task_event);
827 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ 716 p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */
828 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; 717 p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
@@ -833,15 +722,8 @@ static void interrupt_event_handler(struct controller *ctrl)
833 } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { 722 } else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
834 /***********POWER FAULT********************/ 723 /***********POWER FAULT********************/
835 dbg("%s: power fault\n", __FUNCTION__); 724 dbg("%s: power fault\n", __FUNCTION__);
836 /* Wait for exclusive access to hardware */
837 mutex_lock(&ctrl->crit_sect);
838
839 p_slot->hpc_ops->set_attention_status(p_slot, 1); 725 p_slot->hpc_ops->set_attention_status(p_slot, 1);
840
841 p_slot->hpc_ops->green_led_off(p_slot); 726 p_slot->hpc_ops->green_led_off(p_slot);
842
843 /* Done with exclusive hardware access */
844 mutex_unlock(&ctrl->crit_sect);
845 } else { 727 } else {
846 /* refresh notification */ 728 /* refresh notification */
847 if (p_slot) 729 if (p_slot)
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index ae81427e42b1..c32a1b16704f 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -231,6 +231,7 @@ static spinlock_t list_lock;
231static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); 231static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);
232 232
233static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); 233static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
234static int hpc_check_cmd_status(struct controller *ctrl);
234 235
235/* This is the interrupt polling timeout function. */ 236/* This is the interrupt polling timeout function. */
236static void int_poll_timeout(unsigned long lphp_ctlr) 237static void int_poll_timeout(unsigned long lphp_ctlr)
@@ -303,10 +304,13 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
303 int i; 304 int i;
304 305
305 DBG_ENTER_ROUTINE 306 DBG_ENTER_ROUTINE
306 307
308 mutex_lock(&slot->ctrl->cmd_lock);
309
307 if (!php_ctlr) { 310 if (!php_ctlr) {
308 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 311 err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
309 return -1; 312 retval = -EINVAL;
313 goto out;
310 } 314 }
311 315
312 for (i = 0; i < 10; i++) { 316 for (i = 0; i < 10; i++) {
@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
323 if (cmd_status & 0x1) { 327 if (cmd_status & 0x1) {
324 /* After 1 sec and and the controller is still busy */ 328 /* After 1 sec and and the controller is still busy */
325 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); 329 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
326 return -1; 330 retval = -EBUSY;
331 goto out;
327 } 332 }
328 333
329 ++t_slot; 334 ++t_slot;
@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
340 * Wait for command completion. 345 * Wait for command completion.
341 */ 346 */
342 retval = shpc_wait_cmd(slot->ctrl); 347 retval = shpc_wait_cmd(slot->ctrl);
348 if (retval)
349 goto out;
350
351 cmd_status = hpc_check_cmd_status(slot->ctrl);
352 if (cmd_status) {
353 err("%s: Failed to issued command 0x%x (error code = %d)\n",
354 __FUNCTION__, cmd, cmd_status);
355 retval = -EIO;
356 }
357 out:
358 mutex_unlock(&slot->ctrl->cmd_lock);
343 359
344 DBG_LEAVE_ROUTINE 360 DBG_LEAVE_ROUTINE
345 return retval; 361 return retval;
@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
1343 .green_led_blink = hpc_set_green_led_blink, 1359 .green_led_blink = hpc_set_green_led_blink,
1344 1360
1345 .release_ctlr = hpc_release_ctlr, 1361 .release_ctlr = hpc_release_ctlr,
1346 .check_cmd_status = hpc_check_cmd_status,
1347}; 1362};
1348 1363
1349inline static int shpc_indirect_creg_read(struct controller *ctrl, int index, 1364inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
1455 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); 1470 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
1456 1471
1457 mutex_init(&ctrl->crit_sect); 1472 mutex_init(&ctrl->crit_sect);
1473 mutex_init(&ctrl->cmd_lock);
1474
1458 /* Setup wait queue */ 1475 /* Setup wait queue */
1459 init_waitqueue_head(&ctrl->queue); 1476 init_waitqueue_head(&ctrl->queue);
1460 1477