diff options
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 63 |
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index ca140580199c..210e53c2fdc1 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -555,32 +555,6 @@ static void handle_error_source(struct pcie_device *aerdev, | |||
555 | } | 555 | } |
556 | 556 | ||
557 | /** | 557 | /** |
558 | * get_e_source - retrieve an error source | ||
559 | * @rpc: pointer to the root port which holds an error | ||
560 | * | ||
561 | * Invoked by DPC handler to consume an error. | ||
562 | */ | ||
563 | static struct aer_err_source *get_e_source(struct aer_rpc *rpc) | ||
564 | { | ||
565 | struct aer_err_source *e_source; | ||
566 | unsigned long flags; | ||
567 | |||
568 | /* Lock access to Root error producer/consumer index */ | ||
569 | spin_lock_irqsave(&rpc->e_lock, flags); | ||
570 | if (rpc->prod_idx == rpc->cons_idx) { | ||
571 | spin_unlock_irqrestore(&rpc->e_lock, flags); | ||
572 | return NULL; | ||
573 | } | ||
574 | e_source = &rpc->e_sources[rpc->cons_idx]; | ||
575 | rpc->cons_idx++; | ||
576 | if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) | ||
577 | rpc->cons_idx = 0; | ||
578 | spin_unlock_irqrestore(&rpc->e_lock, flags); | ||
579 | |||
580 | return e_source; | ||
581 | } | ||
582 | |||
583 | /** | ||
584 | * get_device_error_info - read error status from dev and store it to info | 558 | * get_device_error_info - read error status from dev and store it to info |
585 | * @dev: pointer to the device expected to have a error record | 559 | * @dev: pointer to the device expected to have a error record |
586 | * @info: pointer to structure to store the error record | 560 | * @info: pointer to structure to store the error record |
@@ -717,6 +691,34 @@ static void aer_isr_one_error(struct pcie_device *p_device, | |||
717 | } | 691 | } |
718 | 692 | ||
719 | /** | 693 | /** |
694 | * get_e_source - retrieve an error source | ||
695 | * @rpc: pointer to the root port which holds an error | ||
696 | * @e_src: pointer to store retrieved error source | ||
697 | * | ||
698 | * Return 1 if an error source is retrieved, otherwise 0. | ||
699 | * | ||
700 | * Invoked by DPC handler to consume an error. | ||
701 | */ | ||
702 | static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src) | ||
703 | { | ||
704 | unsigned long flags; | ||
705 | int ret = 0; | ||
706 | |||
707 | /* Lock access to Root error producer/consumer index */ | ||
708 | spin_lock_irqsave(&rpc->e_lock, flags); | ||
709 | if (rpc->prod_idx != rpc->cons_idx) { | ||
710 | *e_src = rpc->e_sources[rpc->cons_idx]; | ||
711 | rpc->cons_idx++; | ||
712 | if (rpc->cons_idx == AER_ERROR_SOURCES_MAX) | ||
713 | rpc->cons_idx = 0; | ||
714 | ret = 1; | ||
715 | } | ||
716 | spin_unlock_irqrestore(&rpc->e_lock, flags); | ||
717 | |||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | /** | ||
720 | * aer_isr - consume errors detected by root port | 722 | * aer_isr - consume errors detected by root port |
721 | * @work: definition of this work item | 723 | * @work: definition of this work item |
722 | * | 724 | * |
@@ -726,14 +728,11 @@ void aer_isr(struct work_struct *work) | |||
726 | { | 728 | { |
727 | struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); | 729 | struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); |
728 | struct pcie_device *p_device = rpc->rpd; | 730 | struct pcie_device *p_device = rpc->rpd; |
729 | struct aer_err_source *e_src; | 731 | struct aer_err_source e_src; |
730 | 732 | ||
731 | mutex_lock(&rpc->rpc_mutex); | 733 | mutex_lock(&rpc->rpc_mutex); |
732 | e_src = get_e_source(rpc); | 734 | while (get_e_source(rpc, &e_src)) |
733 | while (e_src) { | 735 | aer_isr_one_error(p_device, &e_src); |
734 | aer_isr_one_error(p_device, e_src); | ||
735 | e_src = get_e_source(rpc); | ||
736 | } | ||
737 | mutex_unlock(&rpc->rpc_mutex); | 736 | mutex_unlock(&rpc->rpc_mutex); |
738 | 737 | ||
739 | wake_up(&rpc->wait_release); | 738 | wake_up(&rpc->wait_release); |