aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/eeh_pe.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/eeh_pe.c')
-rw-r--r--arch/powerpc/kernel/eeh_pe.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
index f0c353fa655a..995c2a284630 100644
--- a/arch/powerpc/kernel/eeh_pe.c
+++ b/arch/powerpc/kernel/eeh_pe.c
@@ -503,13 +503,17 @@ static void *__eeh_pe_state_mark(void *data, void *flag)
503 struct eeh_dev *edev, *tmp; 503 struct eeh_dev *edev, *tmp;
504 struct pci_dev *pdev; 504 struct pci_dev *pdev;
505 505
506 /* 506 /* Keep the state of permanently removed PE intact */
507 * Mark the PE with the indicated state. Also, 507 if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) &&
508 * the associated PCI device will be put into 508 (state & (EEH_PE_ISOLATED | EEH_PE_RECOVERING)))
509 * I/O frozen state to avoid I/O accesses from 509 return NULL;
510 * the PCI device driver. 510
511 */
512 pe->state |= state; 511 pe->state |= state;
512
513 /* Offline PCI devices if applicable */
514 if (state != EEH_PE_ISOLATED)
515 return NULL;
516
513 eeh_pe_for_each_dev(pe, edev, tmp) { 517 eeh_pe_for_each_dev(pe, edev, tmp) {
514 pdev = eeh_dev_to_pci_dev(edev); 518 pdev = eeh_dev_to_pci_dev(edev);
515 if (pdev) 519 if (pdev)
@@ -532,6 +536,27 @@ void eeh_pe_state_mark(struct eeh_pe *pe, int state)
532 eeh_pe_traverse(pe, __eeh_pe_state_mark, &state); 536 eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
533} 537}
534 538
539static void *__eeh_pe_dev_mode_mark(void *data, void *flag)
540{
541 struct eeh_dev *edev = data;
542 int mode = *((int *)flag);
543
544 edev->mode |= mode;
545
546 return NULL;
547}
548
549/**
550 * eeh_pe_dev_state_mark - Mark state for all device under the PE
551 * @pe: EEH PE
552 *
553 * Mark specific state for all child devices of the PE.
554 */
555void eeh_pe_dev_mode_mark(struct eeh_pe *pe, int mode)
556{
557 eeh_pe_dev_traverse(pe, __eeh_pe_dev_mode_mark, &mode);
558}
559
535/** 560/**
536 * __eeh_pe_state_clear - Clear state for the PE 561 * __eeh_pe_state_clear - Clear state for the PE
537 * @data: EEH PE 562 * @data: EEH PE
@@ -546,8 +571,16 @@ static void *__eeh_pe_state_clear(void *data, void *flag)
546 struct eeh_pe *pe = (struct eeh_pe *)data; 571 struct eeh_pe *pe = (struct eeh_pe *)data;
547 int state = *((int *)flag); 572 int state = *((int *)flag);
548 573
574 /* Keep the state of permanently removed PE intact */
575 if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) &&
576 (state & EEH_PE_ISOLATED))
577 return NULL;
578
549 pe->state &= ~state; 579 pe->state &= ~state;
550 pe->check_count = 0; 580
581 /* Clear check count since last isolation */
582 if (state & EEH_PE_ISOLATED)
583 pe->check_count = 0;
551 584
552 return NULL; 585 return NULL;
553} 586}