]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
scsi: hisi_sas: tidy channel interrupt handler for v3 hw
authorXiaofei Tan <tanxiaofei@huawei.com>
Wed, 18 Jul 2018 14:14:26 +0000 (22:14 +0800)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 1 Oct 2018 16:23:18 +0000 (18:23 +0200)
BugLink: https://bugs.launchpad.net/bugs/1794172
The ISR of channel interrupt of v3 hw is a little long and messy. This
patch tidies it by relocating CHL_INT1 and CHL_INT2 handling to new
function separately.

Signed-off-by: Xiaofei Tan <tanxiaofei@huawei.com>
Signed-off-by: John Garry <john.garry@huawei.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
(cherry picked from commit d9d51e0cf462cf12956cbc95b1fd55d90c7c9ac5)
Signed-off-by: dann frazier <dann.frazier@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c

index 4b8895c6dccd657a0824029edac30dac5523fc06..c8fae5d5ca103dc871550866ccd361c780883925 100644 (file)
@@ -1333,11 +1333,83 @@ static const struct hisi_sas_hw_error port_axi_error[] = {
        },
 };
 
-static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
 {
-       struct hisi_hba *hisi_hba = p;
+       u32 irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT1);
+       u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT1_MSK);
        struct device *dev = hisi_hba->dev;
+       int i;
+
+       irq_value &= ~irq_msk;
+       if (!irq_value)
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(port_axi_error); i++) {
+               const struct hisi_sas_hw_error *error = &port_axi_error[i];
+
+               if (!(irq_value & error->irq_msk))
+                       continue;
+
+               dev_err(dev, "%s error (phy%d 0x%x) found!\n",
+                       error->msg, phy_no, irq_value);
+               queue_work(hisi_hba->wq, &hisi_hba->rst_work);
+       }
+
+       hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value);
+}
+
+static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
+{
+       u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK);
+       u32 irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2);
+       struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
        struct pci_dev *pci_dev = hisi_hba->pci_dev;
+       struct device *dev = hisi_hba->dev;
+
+       irq_value &= ~irq_msk;
+       if (!irq_value)
+               return;
+
+       if (irq_value & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
+               dev_warn(dev, "phy%d identify timeout\n", phy_no);
+               hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
+       }
+
+       if (irq_value & BIT(CHL_INT2_STP_LINK_TIMEOUT_OFF)) {
+               u32 reg_value = hisi_sas_phy_read32(hisi_hba, phy_no,
+                               STP_LINK_TIMEOUT_STATE);
+
+               dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
+                        phy_no, reg_value);
+               if (reg_value & BIT(4))
+                       hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
+       }
+
+       hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value);
+
+       if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
+           (pci_dev->revision == 0x20)) {
+               u32 reg_value;
+               int rc;
+
+               rc = hisi_sas_read32_poll_timeout_atomic(
+                               HILINK_ERR_DFX, reg_value,
+                               !((reg_value >> 8) & BIT(phy_no)),
+                               1000, 10000);
+               if (rc) {
+                       disable_phy_v3_hw(hisi_hba, phy_no);
+                       hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2,
+                                            BIT(CHL_INT2_RX_INVLD_DW_OFF));
+                       hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW);
+                       mdelay(1);
+                       enable_phy_v3_hw(hisi_hba, phy_no);
+               }
+       }
+}
+
+static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
+{
+       struct hisi_hba *hisi_hba = p;
        u32 irq_msk;
        int phy_no = 0;
 
@@ -1347,84 +1419,12 @@ static irqreturn_t int_chnl_int_v3_hw(int irq_no, void *p)
        while (irq_msk) {
                u32 irq_value0 = hisi_sas_phy_read32(hisi_hba, phy_no,
                                                     CHL_INT0);
-               u32 irq_value1 = hisi_sas_phy_read32(hisi_hba, phy_no,
-                                                    CHL_INT1);
-               u32 irq_value2 = hisi_sas_phy_read32(hisi_hba, phy_no,
-                                                    CHL_INT2);
-               u32 irq_msk1 = hisi_sas_phy_read32(hisi_hba, phy_no,
-                                                       CHL_INT1_MSK);
-               u32 irq_msk2 = hisi_sas_phy_read32(hisi_hba, phy_no,
-                                                       CHL_INT2_MSK);
-
-               irq_value1 &= ~irq_msk1;
-               irq_value2 &= ~irq_msk2;
-
-               if ((irq_msk & (4 << (phy_no * 4))) &&
-                                               irq_value1) {
-                       int i;
-
-                       for (i = 0; i < ARRAY_SIZE(port_axi_error); i++) {
-                               const struct hisi_sas_hw_error *error =
-                                               &port_axi_error[i];
-
-                               if (!(irq_value1 & error->irq_msk))
-                                       continue;
-
-                               dev_err(dev, "%s error (phy%d 0x%x) found!\n",
-                                       error->msg, phy_no, irq_value1);
-                               queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-                       }
-
-                       hisi_sas_phy_write32(hisi_hba, phy_no,
-                                            CHL_INT1, irq_value1);
-               }
 
-               if (irq_msk & (8 << (phy_no * 4)) && irq_value2) {
-                       struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
-
-                       if (irq_value2 & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) {
-                               dev_warn(dev, "phy%d identify timeout\n",
-                                                       phy_no);
-                               hisi_sas_notify_phy_event(phy,
-                                       HISI_PHYE_LINK_RESET);
-
-                       }
+               if (irq_msk & (4 << (phy_no * 4)))
+                       handle_chl_int1_v3_hw(hisi_hba, phy_no);
 
-                       if (irq_value2 & BIT(CHL_INT2_STP_LINK_TIMEOUT_OFF)) {
-                               u32 reg_value = hisi_sas_phy_read32(hisi_hba,
-                                               phy_no, STP_LINK_TIMEOUT_STATE);
-
-                               dev_warn(dev, "phy%d stp link timeout (0x%x)\n",
-                                                       phy_no, reg_value);
-                               if (reg_value & BIT(4))
-                                       hisi_sas_notify_phy_event(phy,
-                                               HISI_PHYE_LINK_RESET);
-                       }
-
-                       hisi_sas_phy_write32(hisi_hba, phy_no,
-                                            CHL_INT2, irq_value2);
-
-                       if ((irq_value2 & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
-                           (pci_dev->revision == 0x20)) {
-                               u32 reg_value;
-                               int rc;
-
-                               rc = hisi_sas_read32_poll_timeout_atomic(
-                                       HILINK_ERR_DFX, reg_value,
-                                       !((reg_value >> 8) & BIT(phy_no)),
-                                       1000, 10000);
-                               if (rc) {
-                                       disable_phy_v3_hw(hisi_hba, phy_no);
-                                       hisi_sas_phy_write32(hisi_hba, phy_no,
-                                               CHL_INT2,
-                                               BIT(CHL_INT2_RX_INVLD_DW_OFF));
-                                       hisi_sas_phy_read32(hisi_hba, phy_no,
-                                               ERR_CNT_INVLD_DW);
-                                       mdelay(1);
-                                       enable_phy_v3_hw(hisi_hba, phy_no);
-                               }
-                       }
-               }
+               if (irq_msk & (8 << (phy_no * 4)))
+                       handle_chl_int2_v3_hw(hisi_hba, phy_no);
 
                if (irq_msk & (2 << (phy_no * 4)) && irq_value0) {
                        hisi_sas_phy_write32(hisi_hba, phy_no,