scsi: hisi_sas: Try wait commands before before controller reset
[linux-2.6-microblaze.git] / drivers / scsi / hisi_sas / hisi_sas_v2_hw.c
index 8def327..18dbaff 100644 (file)
 #define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF       19
 #define SAS_ECC_INTR_MSK               0x1ec
 #define HGC_ERR_STAT_EN                        0x238
+#define CQE_SEND_CNT                   0x248
 #define DLVRY_Q_0_BASE_ADDR_LO         0x260
 #define DLVRY_Q_0_BASE_ADDR_HI         0x264
 #define DLVRY_Q_0_DEPTH                        0x268
@@ -3501,6 +3502,23 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type,
        return 0;
 }
 
+static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,
+                                            int delay_ms, int timeout_ms)
+{
+       struct device *dev = hisi_hba->dev;
+       int entries, entries_old = 0, time;
+
+       for (time = 0; time < timeout_ms; time += delay_ms) {
+               entries = hisi_sas_read32(hisi_hba, CQE_SEND_CNT);
+               if (entries == entries_old)
+                       break;
+
+               entries_old = entries;
+               msleep(delay_ms);
+       }
+
+       dev_dbg(dev, "wait commands complete %dms\n", time);
+}
 
 static struct scsi_host_template sht_v2_hw = {
        .name                   = DRV_NAME,
@@ -3552,6 +3570,7 @@ static const struct hisi_sas_hw hisi_sas_v2_hw = {
        .soft_reset = soft_reset_v2_hw,
        .get_phys_state = get_phys_state_v2_hw,
        .write_gpio = write_gpio_v2_hw,
+       .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v2_hw,
        .sht = &sht_v2_hw,
 };