Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[sfrench/cifs-2.6.git] / drivers / scsi / hisi_sas / hisi_sas_v2_hw.c
index b1f097dabd0187f55b8990b0939dda6614fcba8f..d02c2a791981f9a68893efcfc9811666e6494c74 100644 (file)
@@ -406,80 +406,70 @@ static const struct hisi_sas_hw_error one_bit_ecc_errors[] = {
                .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF),
                .msk = HGC_DQE_ECC_1B_ADDR_MSK,
                .shift = HGC_DQE_ECC_1B_ADDR_OFF,
-               .msg = "hgc_dqe_acc1b_intr found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_dqe_acc1b_intr found: Ram address is 0x%08X\n",
                .reg = HGC_DQE_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_1B_OFF),
                .msk = HGC_IOST_ECC_1B_ADDR_MSK,
                .shift = HGC_IOST_ECC_1B_ADDR_OFF,
-               .msg = "hgc_iost_acc1b_intr found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_iost_acc1b_intr found: Ram address is 0x%08X\n",
                .reg = HGC_IOST_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_1B_OFF),
                .msk = HGC_ITCT_ECC_1B_ADDR_MSK,
                .shift = HGC_ITCT_ECC_1B_ADDR_OFF,
-               .msg = "hgc_itct_acc1b_intr found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_itct_acc1b_intr found: am address is 0x%08X\n",
                .reg = HGC_ITCT_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF),
                .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK,
                .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF,
-               .msg = "hgc_iostl_acc1b_intr found:  \
-                               memory address is 0x%08X\n",
+               .msg = "hgc_iostl_acc1b_intr found: memory address is 0x%08X\n",
                .reg = HGC_LM_DFX_STATUS2,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF),
                .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK,
                .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF,
-               .msg = "hgc_itctl_acc1b_intr found: \
-                               memory address is 0x%08X\n",
+               .msg = "hgc_itctl_acc1b_intr found: memory address is 0x%08X\n",
                .reg = HGC_LM_DFX_STATUS2,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_1B_OFF),
                .msk = HGC_CQE_ECC_1B_ADDR_MSK,
                .shift = HGC_CQE_ECC_1B_ADDR_OFF,
-               .msg = "hgc_cqe_acc1b_intr found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_cqe_acc1b_intr found: Ram address is 0x%08X\n",
                .reg = HGC_CQE_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF),
                .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK,
                .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF,
-               .msg = "rxm_mem0_acc1b_intr found: \
-                               memory address is 0x%08X\n",
+               .msg = "rxm_mem0_acc1b_intr found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS14,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF),
                .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK,
                .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF,
-               .msg = "rxm_mem1_acc1b_intr found: \
-                               memory address is 0x%08X\n",
+               .msg = "rxm_mem1_acc1b_intr found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS14,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF),
                .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK,
                .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF,
-               .msg = "rxm_mem2_acc1b_intr found: \
-                               memory address is 0x%08X\n",
+               .msg = "rxm_mem2_acc1b_intr found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS14,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF),
                .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK,
                .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF,
-               .msg = "rxm_mem3_acc1b_intr found: \
-                               memory address is 0x%08X\n",
+               .msg = "rxm_mem3_acc1b_intr found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS15,
        },
 };
@@ -489,80 +479,70 @@ static const struct hisi_sas_hw_error multi_bit_ecc_errors[] = {
                .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF),
                .msk = HGC_DQE_ECC_MB_ADDR_MSK,
                .shift = HGC_DQE_ECC_MB_ADDR_OFF,
-               .msg = "hgc_dqe_accbad_intr (0x%x) found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_dqe_accbad_intr (0x%x) found: Ram address is 0x%08X\n",
                .reg = HGC_DQE_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF),
                .msk = HGC_IOST_ECC_MB_ADDR_MSK,
                .shift = HGC_IOST_ECC_MB_ADDR_OFF,
-               .msg = "hgc_iost_accbad_intr (0x%x) found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_iost_accbad_intr (0x%x) found: Ram address is 0x%08X\n",
                .reg = HGC_IOST_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF),
                .msk = HGC_ITCT_ECC_MB_ADDR_MSK,
                .shift = HGC_ITCT_ECC_MB_ADDR_OFF,
-               .msg = "hgc_itct_accbad_intr (0x%x) found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_itct_accbad_intr (0x%x) found: Ram address is 0x%08X\n",
                .reg = HGC_ITCT_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF),
                .msk = HGC_LM_DFX_STATUS2_IOSTLIST_MSK,
                .shift = HGC_LM_DFX_STATUS2_IOSTLIST_OFF,
-               .msg = "hgc_iostl_accbad_intr (0x%x) found: \
-                               memory address is 0x%08X\n",
+               .msg = "hgc_iostl_accbad_intr (0x%x) found: memory address is 0x%08X\n",
                .reg = HGC_LM_DFX_STATUS2,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF),
                .msk = HGC_LM_DFX_STATUS2_ITCTLIST_MSK,
                .shift = HGC_LM_DFX_STATUS2_ITCTLIST_OFF,
-               .msg = "hgc_itctl_accbad_intr (0x%x) found: \
-                               memory address is 0x%08X\n",
+               .msg = "hgc_itctl_accbad_intr (0x%x) found: memory address is 0x%08X\n",
                .reg = HGC_LM_DFX_STATUS2,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF),
                .msk = HGC_CQE_ECC_MB_ADDR_MSK,
                .shift = HGC_CQE_ECC_MB_ADDR_OFF,
-               .msg = "hgc_cqe_accbad_intr (0x%x) found: \
-                               Ram address is 0x%08X\n",
+               .msg = "hgc_cqe_accbad_intr (0x%x) found: Ram address is 0x%08X\n",
                .reg = HGC_CQE_ECC_ADDR,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF),
                .msk = HGC_RXM_DFX_STATUS14_MEM0_MSK,
                .shift = HGC_RXM_DFX_STATUS14_MEM0_OFF,
-               .msg = "rxm_mem0_accbad_intr (0x%x) found: \
-                       memory address is 0x%08X\n",
+               .msg = "rxm_mem0_accbad_intr (0x%x) found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS14,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF),
                .msk = HGC_RXM_DFX_STATUS14_MEM1_MSK,
                .shift = HGC_RXM_DFX_STATUS14_MEM1_OFF,
-               .msg = "rxm_mem1_accbad_intr (0x%x) found: \
-                       memory address is 0x%08X\n",
+               .msg = "rxm_mem1_accbad_intr (0x%x) found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS14,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF),
                .msk = HGC_RXM_DFX_STATUS14_MEM2_MSK,
                .shift = HGC_RXM_DFX_STATUS14_MEM2_OFF,
-               .msg = "rxm_mem2_accbad_intr (0x%x) found: \
-                               memory address is 0x%08X\n",
+               .msg = "rxm_mem2_accbad_intr (0x%x) found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS14,
        },
        {
                .irq_msk = BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF),
                .msk = HGC_RXM_DFX_STATUS15_MEM3_MSK,
                .shift = HGC_RXM_DFX_STATUS15_MEM3_OFF,
-               .msg = "rxm_mem3_accbad_intr (0x%x) found: \
-                               memory address is 0x%08X\n",
+               .msg = "rxm_mem3_accbad_intr (0x%x) found: memory address is 0x%08X\n",
                .reg = HGC_RXM_DFX_STATUS15,
        },
 };
@@ -843,8 +823,9 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device)
        struct hisi_sas_device *sas_dev = NULL;
        int i, sata_dev = dev_is_sata(device);
        int sata_idx = -1;
+       unsigned long flags;
 
-       spin_lock(&hisi_hba->lock);
+       spin_lock_irqsave(&hisi_hba->lock, flags);
 
        if (sata_dev)
                if (!sata_index_alloc_v2_hw(hisi_hba, &sata_idx))
@@ -874,7 +855,7 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device)
        }
 
 out:
-       spin_unlock(&hisi_hba->lock);
+       spin_unlock_irqrestore(&hisi_hba->lock, flags);
 
        return sas_dev;
 }
@@ -2376,7 +2357,9 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
 
        if (unlikely(aborted)) {
                ts->stat = SAS_ABORTED_TASK;
+               spin_lock_irqsave(&hisi_hba->lock, flags);
                hisi_sas_slot_task_free(hisi_hba, task, slot);
+               spin_unlock_irqrestore(&hisi_hba->lock, flags);
                return -1;
        }
 
@@ -2951,25 +2934,58 @@ static irqreturn_t fatal_ecc_int_v2_hw(int irq_no, void *p)
        return IRQ_HANDLED;
 }
 
-#define AXI_ERR_NR     8
-static const char axi_err_info[AXI_ERR_NR][32] = {
-       "IOST_AXI_W_ERR",
-       "IOST_AXI_R_ERR",
-       "ITCT_AXI_W_ERR",
-       "ITCT_AXI_R_ERR",
-       "SATA_AXI_W_ERR",
-       "SATA_AXI_R_ERR",
-       "DQE_AXI_R_ERR",
-       "CQE_AXI_W_ERR"
+static const struct hisi_sas_hw_error axi_error[] = {
+       { .msk = BIT(0), .msg = "IOST_AXI_W_ERR" },
+       { .msk = BIT(1), .msg = "IOST_AXI_R_ERR" },
+       { .msk = BIT(2), .msg = "ITCT_AXI_W_ERR" },
+       { .msk = BIT(3), .msg = "ITCT_AXI_R_ERR" },
+       { .msk = BIT(4), .msg = "SATA_AXI_W_ERR" },
+       { .msk = BIT(5), .msg = "SATA_AXI_R_ERR" },
+       { .msk = BIT(6), .msg = "DQE_AXI_R_ERR" },
+       { .msk = BIT(7), .msg = "CQE_AXI_W_ERR" },
+       {},
+};
+
+static const struct hisi_sas_hw_error fifo_error[] = {
+       { .msk = BIT(8),  .msg = "CQE_WINFO_FIFO" },
+       { .msk = BIT(9),  .msg = "CQE_MSG_FIFIO" },
+       { .msk = BIT(10), .msg = "GETDQE_FIFO" },
+       { .msk = BIT(11), .msg = "CMDP_FIFO" },
+       { .msk = BIT(12), .msg = "AWTCTRL_FIFO" },
+       {},
 };
 
-#define FIFO_ERR_NR    5
-static const char fifo_err_info[FIFO_ERR_NR][32] = {
-       "CQE_WINFO_FIFO",
-       "CQE_MSG_FIFIO",
-       "GETDQE_FIFO",
-       "CMDP_FIFO",
-       "AWTCTRL_FIFO"
+static const struct hisi_sas_hw_error fatal_axi_errors[] = {
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_WP_DEPTH_OFF),
+               .msg = "write pointer and depth",
+       },
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF),
+               .msg = "iptt no match slot",
+       },
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_RP_DEPTH_OFF),
+               .msg = "read pointer and depth",
+       },
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_AXI_OFF),
+               .reg = HGC_AXI_FIFO_ERR_INFO,
+               .sub = axi_error,
+       },
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_FIFO_OFF),
+               .reg = HGC_AXI_FIFO_ERR_INFO,
+               .sub = fifo_error,
+       },
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_LM_OFF),
+               .msg = "LM add/fetch list",
+       },
+       {
+               .irq_msk = BIT(ENT_INT_SRC3_ABT_OFF),
+               .msg = "SAS_HGC_ABT fetch LM list",
+       },
 };
 
 static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p)
@@ -2977,98 +2993,47 @@ static irqreturn_t fatal_axi_int_v2_hw(int irq_no, void *p)
        struct hisi_hba *hisi_hba = p;
        u32 irq_value, irq_msk, err_value;
        struct device *dev = hisi_hba->dev;
+       const struct hisi_sas_hw_error *axi_error;
+       int i;
 
        irq_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK3);
        hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, irq_msk | 0xfffffffe);
 
        irq_value = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
-       if (irq_value) {
-               if (irq_value & BIT(ENT_INT_SRC3_WP_DEPTH_OFF)) {
-                       hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
-                                       1 << ENT_INT_SRC3_WP_DEPTH_OFF);
-                       dev_warn(dev, "write pointer and depth error (0x%x) \
-                              found!\n",
-                              irq_value);
-                       queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-               }
-
-               if (irq_value & BIT(ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF)) {
-                       hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
-                                        1 <<
-                                        ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF);
-                       dev_warn(dev, "iptt no match slot error (0x%x) found!\n",
-                             irq_value);
-                       queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-               }
 
-               if (irq_value & BIT(ENT_INT_SRC3_RP_DEPTH_OFF)) {
-                       dev_warn(dev, "read pointer and depth error (0x%x) \
-                              found!\n",
-                              irq_value);
-                       queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-               }
-
-               if (irq_value & BIT(ENT_INT_SRC3_AXI_OFF)) {
-                       int i;
-
-                       hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
-                                       1 << ENT_INT_SRC3_AXI_OFF);
-                       err_value = hisi_sas_read32(hisi_hba,
-                                                   HGC_AXI_FIFO_ERR_INFO);
-
-                       for (i = 0; i < AXI_ERR_NR; i++) {
-                               if (err_value & BIT(i)) {
-                                       dev_warn(dev, "%s (0x%x) found!\n",
-                                             axi_err_info[i], irq_value);
-                                       queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-                               }
-                       }
-               }
-
-               if (irq_value & BIT(ENT_INT_SRC3_FIFO_OFF)) {
-                       int i;
-
-                       hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
-                                       1 << ENT_INT_SRC3_FIFO_OFF);
-                       err_value = hisi_sas_read32(hisi_hba,
-                                                   HGC_AXI_FIFO_ERR_INFO);
+       for (i = 0; i < ARRAY_SIZE(fatal_axi_errors); i++) {
+               axi_error = &fatal_axi_errors[i];
+               if (!(irq_value & axi_error->irq_msk))
+                       continue;
 
-                       for (i = 0; i < FIFO_ERR_NR; i++) {
-                               if (err_value & BIT(AXI_ERR_NR + i)) {
-                                       dev_warn(dev, "%s (0x%x) found!\n",
-                                             fifo_err_info[i], irq_value);
-                                       queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-                               }
+               hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
+                                1 << axi_error->shift);
+               if (axi_error->sub) {
+                       const struct hisi_sas_hw_error *sub = axi_error->sub;
+
+                       err_value = hisi_sas_read32(hisi_hba, axi_error->reg);
+                       for (; sub->msk || sub->msg; sub++) {
+                               if (!(err_value & sub->msk))
+                                       continue;
+                               dev_warn(dev, "%s (0x%x) found!\n",
+                                        sub->msg, irq_value);
+                               queue_work(hisi_hba->wq, &hisi_hba->rst_work);
                        }
-
-               }
-
-               if (irq_value & BIT(ENT_INT_SRC3_LM_OFF)) {
-                       hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
-                                       1 << ENT_INT_SRC3_LM_OFF);
-                       dev_warn(dev, "LM add/fetch list error (0x%x) found!\n",
-                             irq_value);
-                       queue_work(hisi_hba->wq, &hisi_hba->rst_work);
-               }
-
-               if (irq_value & BIT(ENT_INT_SRC3_ABT_OFF)) {
-                       hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
-                                       1 << ENT_INT_SRC3_ABT_OFF);
-                       dev_warn(dev, "SAS_HGC_ABT fetch LM list error (0x%x) found!\n",
-                             irq_value);
+               } else {
+                       dev_warn(dev, "%s (0x%x) found!\n",
+                                axi_error->msg, irq_value);
                        queue_work(hisi_hba->wq, &hisi_hba->rst_work);
                }
+       }
 
-               if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) {
-                       u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR);
-                       u32 dev_id = reg_val & ITCT_DEV_MSK;
-                       struct hisi_sas_device *sas_dev =
-                                       &hisi_hba->devices[dev_id];
+       if (irq_value & BIT(ENT_INT_SRC3_ITC_INT_OFF)) {
+               u32 reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR);
+               u32 dev_id = reg_val & ITCT_DEV_MSK;
+               struct hisi_sas_device *sas_dev = &hisi_hba->devices[dev_id];
 
-                       hisi_sas_write32(hisi_hba, ITCT_CLR, 0);
-                       dev_dbg(dev, "clear ITCT ok\n");
-                       complete(sas_dev->completion);
-               }
+               hisi_sas_write32(hisi_hba, ITCT_CLR, 0);
+               dev_dbg(dev, "clear ITCT ok\n");
+               complete(sas_dev->completion);
        }
 
        hisi_sas_write32(hisi_hba, ENT_INT_SRC3, irq_value);
@@ -3408,6 +3373,7 @@ static int soft_reset_v2_hw(struct hisi_hba *hisi_hba)
 
        interrupt_disable_v2_hw(hisi_hba);
        hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0x0);
+       hisi_sas_kill_tasklets(hisi_hba);
 
        hisi_sas_stop_phys(hisi_hba);
 
@@ -3458,7 +3424,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
        .start_delivery = start_delivery_v2_hw,
        .slot_complete = slot_complete_v2_hw,
        .phys_init = phys_init_v2_hw,
-       .phy_enable = enable_phy_v2_hw,
+       .phy_start = start_phy_v2_hw,
        .phy_disable = disable_phy_v2_hw,
        .phy_hard_reset = phy_hard_reset_v2_hw,
        .get_events = phy_get_events_v2_hw,
@@ -3491,16 +3457,11 @@ static int hisi_sas_v2_remove(struct platform_device *pdev)
 {
        struct sas_ha_struct *sha = platform_get_drvdata(pdev);
        struct hisi_hba *hisi_hba = sha->lldd_ha;
-       int i;
 
        if (timer_pending(&hisi_hba->timer))
                del_timer(&hisi_hba->timer);
 
-       for (i = 0; i < hisi_hba->queue_count; i++) {
-               struct hisi_sas_cq *cq = &hisi_hba->cq[i];
-
-               tasklet_kill(&cq->tasklet);
-       }
+       hisi_sas_kill_tasklets(hisi_hba);
 
        return hisi_sas_remove(pdev);
 }