aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c63
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 */
563static 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 */
702static 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);