提交 1bc9fed3 编写于 作者: X Xiang Chen 提交者: Yongqiang Liu

scsi: hisi_sas: Change hisi_sas_control_phy() phyup timeout

mainline inclusion
from mainline-5.17-rc1
commit 512623de
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4UT5N
CVE: NA

-------------------------------------------

The time of phyup not only depends on the controller but also the type of
disk connected. As an example, from experience, for some SATA disks the
amount of time from reset/power-on to receive the D2H FIS for phyup can
take upto and more than 10s sometimes. According to the specification of
some SATA disks such as ST14000NM0018, the max time from power-on to ready
is 30s.

Based on this the current timeout of phyup at 2s which is not enough. So
set the value as HISI_SAS_WAIT_PHYUP_TIMEOUT (30s) in
hisi_sas_control_phy().

For v3 hw there is a pre-existing workaround for a HW bug, being that we
issue a link reset when the OOB occurs but the phyup does not. The current
phyup timeout is HISI_SAS_WAIT_PHYUP_TIMEOUT. So if this does occur from
when issuing a phy enable or similar via hisi_sas_control_phy(), the
subsequent HW workaround linkreset processing calls hisi_sas_control_phy(),
but this will pend the original phy reset timing out, so it is safe.

Link: https://lore.kernel.org/r/1645703489-87194-3-git-send-email-john.garry@huawei.comSigned-off-by: NXiang Chen <chenxiang66@hisilicon.com>
Signed-off-by: NJohn Garry <john.garry@huawei.com>
Signed-off-by: NMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: NXingui Yang <yangxingui@huawei.com>
conflict:
	drivers/scsi/hisi_sas/hisi_sas.h
	drivers/scsi/hisi_sas/hisi_sas_main.c
Reviewed-by: NXingui Yang <yangxingui@huawei.com>
Reviewed-by: Nkang fenglong <kangfenglong@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 8fdd6417
...@@ -88,6 +88,7 @@ ...@@ -88,6 +88,7 @@
#define HISI_SAS_PROT_MASK (HISI_SAS_DIF_PROT_MASK | HISI_SAS_DIX_PROT_MASK) #define HISI_SAS_PROT_MASK (HISI_SAS_DIF_PROT_MASK | HISI_SAS_DIX_PROT_MASK)
#define HISI_SAS_WAIT_PHYUP_TIMEOUT (30 * HZ)
#define CLEAR_ITCT_TIMEOUT 20 #define CLEAR_ITCT_TIMEOUT 20
struct hisi_hba; struct hisi_hba;
......
...@@ -1783,6 +1783,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) ...@@ -1783,6 +1783,7 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
int rc, reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT || int rc, reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT ||
!dev_is_sata(device)) ? true : false; !dev_is_sata(device)) ? true : false;
struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
struct device *dev = hisi_hba->dev;
struct sas_ha_struct *sas_ha = &hisi_hba->sha; struct sas_ha_struct *sas_ha = &hisi_hba->sha;
DECLARE_COMPLETION_ONSTACK(phyreset); DECLARE_COMPLETION_ONSTACK(phyreset);
...@@ -1809,7 +1810,8 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) ...@@ -1809,7 +1810,8 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
struct hisi_sas_phy *phy = struct hisi_sas_phy *phy =
container_of(sas_phy, struct hisi_sas_phy, sas_phy); container_of(sas_phy, struct hisi_sas_phy, sas_phy);
/* Wait for I_T reset complete, time out after 2s */ /* Wait for I_T reset complete, time out after 2s */
int ret = wait_for_completion_timeout(&phyreset, 2 * HZ); int ret = wait_for_completion_timeout(&phyreset,
HISI_SAS_WAIT_PHYUP_TIMEOUT);
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&phy->lock, flags); spin_lock_irqsave(&phy->lock, flags);
...@@ -1818,8 +1820,10 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device) ...@@ -1818,8 +1820,10 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
spin_unlock_irqrestore(&phy->lock, flags); spin_unlock_irqrestore(&phy->lock, flags);
/* report PHY down if timed out */ /* report PHY down if timed out */
if (!ret) if (!ret) {
dev_warn(dev, "phy%d reset timeout\n", sas_phy->id);
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0); hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
}
} else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) } else if (sas_dev->dev_status != HISI_SAS_DEV_INIT)
/* Sleep 2s, wait for I_T reset at expander env except fail */ /* Sleep 2s, wait for I_T reset at expander env except fail */
if (!rc) if (!rc)
......
...@@ -2874,7 +2874,6 @@ static const struct hisi_sas_hw_error port_ecc_axi_error[] = { ...@@ -2874,7 +2874,6 @@ static const struct hisi_sas_hw_error port_ecc_axi_error[] = {
}, },
}; };
#define WAIT_PHYUP_TIMEOUT_V2_HW 20
static void wait_phyup_timedout_v2_hw(struct timer_list *t) static void wait_phyup_timedout_v2_hw(struct timer_list *t)
{ {
struct hisi_sas_phy *phy = from_timer(phy, t, timer); struct hisi_sas_phy *phy = from_timer(phy, t, timer);
...@@ -2894,7 +2893,7 @@ static void phy_oob_ready_v2_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -2894,7 +2893,7 @@ static void phy_oob_ready_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
if (!timer_pending(&phy->timer)) { if (!timer_pending(&phy->timer)) {
dev_dbg(dev, "phy%d OOB ready\n", phy_no); dev_dbg(dev, "phy%d OOB ready\n", phy_no);
phy->timer.function = wait_phyup_timedout_v2_hw; phy->timer.function = wait_phyup_timedout_v2_hw;
phy->timer.expires = jiffies + WAIT_PHYUP_TIMEOUT_V2_HW * HZ; phy->timer.expires = jiffies + HISI_SAS_WAIT_PHYUP_TIMEOUT;
add_timer(&phy->timer); add_timer(&phy->timer);
} }
} }
......
...@@ -1890,7 +1890,6 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -1890,7 +1890,6 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, irq_value);
} }
#define WAIT_PHYUP_TIMEOUT_V3_HW 20
static void wait_phyup_timedout_v3_hw(struct timer_list *t) static void wait_phyup_timedout_v3_hw(struct timer_list *t)
{ {
struct hisi_sas_phy *phy = from_timer(phy, t, timer); struct hisi_sas_phy *phy = from_timer(phy, t, timer);
...@@ -1917,7 +1916,7 @@ static void handle_chl_int0_v3_hw(struct hisi_hba *hisi_hba, int phy_no) ...@@ -1917,7 +1916,7 @@ static void handle_chl_int0_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
if (!timer_pending(&phy->timer)) { if (!timer_pending(&phy->timer)) {
phy->timer.function = wait_phyup_timedout_v3_hw; phy->timer.function = wait_phyup_timedout_v3_hw;
phy->timer.expires = jiffies + phy->timer.expires = jiffies +
WAIT_PHYUP_TIMEOUT_V3_HW * HZ; HISI_SAS_WAIT_PHYUP_TIMEOUT;
add_timer(&phy->timer); add_timer(&phy->timer);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册