diff options
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas.h | 8 | ||||
-rw-r--r-- | drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 368 |
2 files changed, 197 insertions, 179 deletions
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index ef2238c6e4da..ad6b2d18047b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -91,6 +91,14 @@ enum hisi_sas_dev_type { HISI_SAS_DEV_TYPE_SATA, }; +struct hisi_sas_hw_error { + u32 irq_msk; + u32 msk; + int shift; + const char *msg; + int reg; +}; + struct hisi_sas_phy { struct hisi_hba *hisi_hba; struct hisi_sas_port *port; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 41e8033ad1c8..bcbc16e4cec0 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -401,6 +401,172 @@ struct hisi_sas_err_record_v2 { __le32 dma_rx_err_type; }; +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", + .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", + .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", + .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", + .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", + .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", + .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", + .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", + .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", + .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", + .reg = HGC_RXM_DFX_STATUS15, + }, +}; + +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", + .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", + .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", + .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", + .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", + .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", + .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", + .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", + .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", + .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", + .reg = HGC_RXM_DFX_STATUS15, + }, +}; + enum { HISI_SAS_PHY_PHY_UPDOWN, HISI_SAS_PHY_CHNL_INT, @@ -2762,194 +2928,38 @@ static void one_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba, u32 irq_value) { struct device *dev = hisi_hba->dev; - u32 reg_val; - - if (irq_value & BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_DQE_ECC_ADDR); - dev_warn(dev, "hgc_dqe_acc1b_intr found: \ - Ram address is 0x%08X\n", - (reg_val & HGC_DQE_ECC_1B_ADDR_MSK) >> - HGC_DQE_ECC_1B_ADDR_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_IOST_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_IOST_ECC_ADDR); - dev_warn(dev, "hgc_iost_acc1b_intr found: \ - Ram address is 0x%08X\n", - (reg_val & HGC_IOST_ECC_1B_ADDR_MSK) >> - HGC_IOST_ECC_1B_ADDR_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_ITCT_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_ITCT_ECC_ADDR); - dev_warn(dev, "hgc_itct_acc1b_intr found: \ - Ram address is 0x%08X\n", - (reg_val & HGC_ITCT_ECC_1B_ADDR_MSK) >> - HGC_ITCT_ECC_1B_ADDR_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2); - dev_warn(dev, "hgc_iostl_acc1b_intr found: \ - memory address is 0x%08X\n", - (reg_val & HGC_LM_DFX_STATUS2_IOSTLIST_MSK) >> - HGC_LM_DFX_STATUS2_IOSTLIST_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2); - dev_warn(dev, "hgc_itctl_acc1b_intr found: \ - memory address is 0x%08X\n", - (reg_val & HGC_LM_DFX_STATUS2_ITCTLIST_MSK) >> - HGC_LM_DFX_STATUS2_ITCTLIST_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_CQE_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_CQE_ECC_ADDR); - dev_warn(dev, "hgc_cqe_acc1b_intr found: \ - Ram address is 0x%08X\n", - (reg_val & HGC_CQE_ECC_1B_ADDR_MSK) >> - HGC_CQE_ECC_1B_ADDR_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14); - dev_warn(dev, "rxm_mem0_acc1b_intr found: \ - memory address is 0x%08X\n", - (reg_val & HGC_RXM_DFX_STATUS14_MEM0_MSK) >> - HGC_RXM_DFX_STATUS14_MEM0_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14); - dev_warn(dev, "rxm_mem1_acc1b_intr found: \ - memory address is 0x%08X\n", - (reg_val & HGC_RXM_DFX_STATUS14_MEM1_MSK) >> - HGC_RXM_DFX_STATUS14_MEM1_OFF); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14); - dev_warn(dev, "rxm_mem2_acc1b_intr found: \ - memory address is 0x%08X\n", - (reg_val & HGC_RXM_DFX_STATUS14_MEM2_MSK) >> - HGC_RXM_DFX_STATUS14_MEM2_OFF); - } + const struct hisi_sas_hw_error *ecc_error; + u32 val; + int i; - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS15); - dev_warn(dev, "rxm_mem3_acc1b_intr found: \ - memory address is 0x%08X\n", - (reg_val & HGC_RXM_DFX_STATUS15_MEM3_MSK) >> - HGC_RXM_DFX_STATUS15_MEM3_OFF); + for (i = 0; i < ARRAY_SIZE(one_bit_ecc_errors); i++) { + ecc_error = &one_bit_ecc_errors[i]; + if (irq_value & ecc_error->irq_msk) { + val = hisi_sas_read32(hisi_hba, ecc_error->reg); + val &= ecc_error->msk; + val >>= ecc_error->shift; + dev_warn(dev, ecc_error->msg, val); + } } - } static void multi_bit_ecc_error_process_v2_hw(struct hisi_hba *hisi_hba, u32 irq_value) { - u32 reg_val; struct device *dev = hisi_hba->dev; + const struct hisi_sas_hw_error *ecc_error; + u32 val; + int i; - if (irq_value & BIT(SAS_ECC_INTR_DQE_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_DQE_ECC_ADDR); - dev_warn(dev, "hgc_dqe_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", - irq_value, - (reg_val & HGC_DQE_ECC_MB_ADDR_MSK) >> - HGC_DQE_ECC_MB_ADDR_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_IOST_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_IOST_ECC_ADDR); - dev_warn(dev, "hgc_iost_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", - irq_value, - (reg_val & HGC_IOST_ECC_MB_ADDR_MSK) >> - HGC_IOST_ECC_MB_ADDR_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_ITCT_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_ITCT_ECC_ADDR); - dev_warn(dev,"hgc_itct_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", - irq_value, - (reg_val & HGC_ITCT_ECC_MB_ADDR_MSK) >> - HGC_ITCT_ECC_MB_ADDR_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2); - dev_warn(dev, "hgc_iostl_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", - irq_value, - (reg_val & HGC_LM_DFX_STATUS2_IOSTLIST_MSK) >> - HGC_LM_DFX_STATUS2_IOSTLIST_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_LM_DFX_STATUS2); - dev_warn(dev, "hgc_itctl_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", - irq_value, - (reg_val & HGC_LM_DFX_STATUS2_ITCTLIST_MSK) >> - HGC_LM_DFX_STATUS2_ITCTLIST_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_CQE_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_CQE_ECC_ADDR); - dev_warn(dev, "hgc_cqe_accbad_intr (0x%x) found: \ - Ram address is 0x%08X\n", - irq_value, - (reg_val & HGC_CQE_ECC_MB_ADDR_MSK) >> - HGC_CQE_ECC_MB_ADDR_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14); - dev_warn(dev, "rxm_mem0_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", - irq_value, - (reg_val & HGC_RXM_DFX_STATUS14_MEM0_MSK) >> - HGC_RXM_DFX_STATUS14_MEM0_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14); - dev_warn(dev, "rxm_mem1_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", - irq_value, - (reg_val & HGC_RXM_DFX_STATUS14_MEM1_MSK) >> - HGC_RXM_DFX_STATUS14_MEM1_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS14); - dev_warn(dev, "rxm_mem2_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", - irq_value, - (reg_val & HGC_RXM_DFX_STATUS14_MEM2_MSK) >> - HGC_RXM_DFX_STATUS14_MEM2_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); - } - - if (irq_value & BIT(SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF)) { - reg_val = hisi_sas_read32(hisi_hba, HGC_RXM_DFX_STATUS15); - dev_warn(dev, "rxm_mem3_accbad_intr (0x%x) found: \ - memory address is 0x%08X\n", - irq_value, - (reg_val & HGC_RXM_DFX_STATUS15_MEM3_MSK) >> - HGC_RXM_DFX_STATUS15_MEM3_OFF); - queue_work(hisi_hba->wq, &hisi_hba->rst_work); + for (i = 0; i < ARRAY_SIZE(multi_bit_ecc_errors); i++) { + ecc_error = &multi_bit_ecc_errors[i]; + if (irq_value & ecc_error->irq_msk) { + val = hisi_sas_read32(hisi_hba, ecc_error->reg); + val &= ecc_error->msk; + val >>= ecc_error->shift; + dev_warn(dev, ecc_error->msg, irq_value, val); + queue_work(hisi_hba->wq, &hisi_hba->rst_work); + } } return; |