Hidetoshi Seto wrote:
Have a function set_e_source() for ISR. This is paird with
get_e_source() which is already there and called by DPC.
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@xxxxxxxxxxxxxx>
---
drivers/pci/pcie/aer/aerdrv.c | 37 +++++++++++++++++++++++++++++--------
1 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 8344127..98d62d4 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -72,6 +72,34 @@ void pci_no_aer(void)
}
/**
+ * set_e_source - save an error source
+ * @rpc: pointer to the aer_rpc of the root port which save the error
+ * @status: error status to be saved
+ * @id: identifier of error device to be saved
+ *
+ * Invoked by Root Port's ISR with rpc->e_lock held.
+ * Return 1 on success, 0 on error.
+ */
+static int set_e_source(struct aer_rpc *rpc, unsigned int status,
+ unsigned int id)
+{
+ int next_prod_idx;
+
+ next_prod_idx = rpc->prod_idx + 1;
+ if (next_prod_idx == AER_ERROR_SOURCES_MAX)
+ next_prod_idx = 0;
+
+ if (next_prod_idx == rpc->cons_idx)
+ return 0;
+
+ rpc->e_sources[rpc->prod_idx].status = status;
+ rpc->e_sources[rpc->prod_idx].id = id;
+ rpc->prod_idx = next_prod_idx;
+
+ return 1;
+}
IMO, return 0 on success, non-zero on error is more natural.
+
+/**
* aer_irq - Root Port's ISR
* @irq: IRQ assigned to Root Port
* @context: pointer to Root Port data structure
@@ -83,7 +111,6 @@ irqreturn_t aer_irq(int irq, void *context)
unsigned int status, id;
struct pcie_device *pdev = (struct pcie_device *)context;
struct aer_rpc *rpc = get_service_data(pdev);
- int next_prod_idx;
unsigned long flags;
int pos;
@@ -107,10 +134,7 @@ irqreturn_t aer_irq(int irq, void *context)
pci_write_config_dword(pdev->port, pos + PCI_ERR_ROOT_STATUS, status);
/* Store error source for later DPC handler */
- next_prod_idx = rpc->prod_idx + 1;
- if (next_prod_idx == AER_ERROR_SOURCES_MAX)
- next_prod_idx = 0;
- if (next_prod_idx == rpc->cons_idx) {
+ if (!set_e_source(rpc, status, id)) {
/*
* Error Storm Condition - possibly the same error occurred.
* Drop the error.
@@ -118,9 +142,6 @@ irqreturn_t aer_irq(int irq, void *context)
spin_unlock_irqrestore(&rpc->e_lock, flags);
return IRQ_HANDLED;
}
- rpc->e_sources[rpc->prod_idx].status = status;
- rpc->e_sources[rpc->prod_idx].id = id;
- rpc->prod_idx = next_prod_idx;
spin_unlock_irqrestore(&rpc->e_lock, flags);
/* Invoke DPC handler */
How about the below?
(Please note that set_e_source() returns 0 on success in the following example)
...
if (!set_e_source(rpc, status, id))
schedule_work(&rpc->dpc_handler);
spin_unlock_irqrestore(&rpc->e_lock, flags);
return IRQ_HANDLED;
}
Thanks,
Kenji Kaneshige
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html