Commit 13cd5ed6 authored by Xiang Chen's avatar Xiang Chen Committed by Martin K. Petersen

scsi: hisi_sas: fix a bug when free device for v3 hw

Use completion to wait on ITCT CLR interrupt finishing before
processing other things when freeing a device.

This is safer than the pre-existing process of polling the register.
Signed-off-by: default avatarXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: default avatarJohn Garry <john.garry@huawei.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b4241f0f
......@@ -393,7 +393,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, ENT_INT_SRC3, 0xffffffff);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffffffff);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff);
hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0);
hisi_sas_write32(hisi_hba, CHNL_ENT_INT_MSK, 0x0);
hisi_sas_write32(hisi_hba, HGC_COM_INT_MSK, 0x0);
......@@ -582,35 +582,24 @@ static void setup_itct_v3_hw(struct hisi_hba *hisi_hba,
static void free_device_v3_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_device *sas_dev)
{
DECLARE_COMPLETION_ONSTACK(completion);
u64 dev_id = sas_dev->device_id;
struct device *dev = hisi_hba->dev;
struct hisi_sas_itct *itct = &hisi_hba->itct[dev_id];
u32 reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
sas_dev->completion = &completion;
/* clear the itct interrupt state */
if (ENT_INT_SRC3_ITC_INT_MSK & reg_val)
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
ENT_INT_SRC3_ITC_INT_MSK);
/* clear the itct table*/
reg_val = hisi_sas_read32(hisi_hba, ITCT_CLR);
reg_val |= ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK);
reg_val = ITCT_CLR_EN_MSK | (dev_id & ITCT_DEV_MSK);
hisi_sas_write32(hisi_hba, ITCT_CLR, reg_val);
udelay(10);
reg_val = hisi_sas_read32(hisi_hba, ENT_INT_SRC3);
if (ENT_INT_SRC3_ITC_INT_MSK & reg_val) {
dev_dbg(dev, "got clear ITCT done interrupt\n");
/* invalid the itct state*/
memset(itct, 0, sizeof(struct hisi_sas_itct));
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
ENT_INT_SRC3_ITC_INT_MSK);
/* clear the itct */
hisi_sas_write32(hisi_hba, ITCT_CLR, 0);
dev_dbg(dev, "clear ITCT ok\n");
}
wait_for_completion(sas_dev->completion);
memset(itct, 0, sizeof(struct hisi_sas_itct));
}
static void dereg_device_v3_hw(struct hisi_hba *hisi_hba,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment