From: Xingui Yang <yangxingui@huawei.com>
To: <mkp@kernel.org>, <jejb@linux.ibm.com>, <john.garry@linux.dev>,
<yanaijie@huawei.com>
Cc: <linux-scsi@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<linuxarm@huawei.com>, <yangxingui@huawei.com>,
<liuyonglong@huawei.com>, <kangfenglong@huawei.com>
Subject: [PATCH v3 4/4] scsi: hisi_sas: Fix spinup failure for SAS SSP devices in Active_Wait state
Date: Fri, 9 Oct 2026 11:32:38 +0800 [thread overview]
Message-ID: <20261009033238.1076098-5-yangxingui@huawei.com> (raw)
In-Reply-To: <20261009033238.1076098-1-yangxingui@huawei.com>
SAS HDDs powered up with RNOT=1 wait in Active_Wait state for a
NOTIFY(ENABLE SPINUP) primitive and keep returning NOT_READY with
ASC/ASCQ 0x04/0x11, causing endless mid-layer retries and spinup
failure.
Parse the sense data in the slot completion path and, when
LU_NOT_READY_NOTIFY_REQUIRED is returned by a directly-attached SSP
device, queue work that sends the primitive from process context
(sl_notify_ssp() contains msleep()). The work takes a runtime PM
reference with pm_runtime_get_if_active(), pairing with
pm_runtime_put_sync() in the work, so the controller stays resumed
until the primitive is sent.
Fixes: 60b4a5ee9034 ("scsi: hisi_sas: add v3 cq interrupt handler")
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
---
drivers/scsi/hisi_sas/hisi_sas.h | 3 ++
drivers/scsi/hisi_sas/hisi_sas_main.c | 43 ++++++++++++++++++++++++++
drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 +++
drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +++
drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +++
5 files changed, 58 insertions(+)
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 1323ed8aa717..d48ba3747b81 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -163,6 +163,7 @@ enum hisi_sas_phy_event {
HISI_PHYE_PHY_UP = 0U,
HISI_PHYE_LINK_RESET,
HISI_PHYE_PHY_UP_PM,
+ HISI_PHYE_SPINUP_NOTIFY,
HISI_PHYES_NUM,
};
@@ -689,4 +690,6 @@ extern void hisi_sas_sync_cqs(struct hisi_hba *hisi_hba);
extern void hisi_sas_sync_poll_cqs(struct hisi_hba *hisi_hba);
extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba);
extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba);
+extern void hisi_sas_spinup_notify(struct hisi_hba *hisi_hba,
+ struct sas_task *task);
#endif
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 944ce19ae2fc..cf7aa0a699cd 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -996,10 +996,25 @@ static void hisi_sas_phyup_pm_work(struct work_struct *work)
pm_runtime_put_sync(dev);
}
+static void hisi_sas_spinup_notify_work(struct work_struct *work)
+{
+ struct hisi_sas_phy *phy =
+ container_of(work, typeof(*phy), works[HISI_PHYE_SPINUP_NOTIFY]);
+ struct hisi_hba *hisi_hba = phy->hisi_hba;
+ struct device *dev = hisi_hba->dev;
+ int phy_no = phy->sas_phy.id;
+
+ hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
+ dev_info(dev, "spinup notify primitive on phy%d\n", phy_no);
+
+ pm_runtime_put_sync(dev);
+}
+
static const work_func_t hisi_sas_phye_fns[HISI_PHYES_NUM] = {
[HISI_PHYE_PHY_UP] = hisi_sas_phyup_work,
[HISI_PHYE_LINK_RESET] = hisi_sas_linkreset_work,
[HISI_PHYE_PHY_UP_PM] = hisi_sas_phyup_pm_work,
+ [HISI_PHYE_SPINUP_NOTIFY] = hisi_sas_spinup_notify_work,
};
bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy,
@@ -1639,6 +1654,34 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba)
}
EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done);
+void hisi_sas_spinup_notify(struct hisi_hba *hisi_hba,
+ struct sas_task *task)
+{
+ struct task_status_struct *ts = &task->task_status;
+ struct domain_device *dev = task->dev;
+ struct scsi_sense_hdr sshdr;
+ struct sas_phy *local_phy;
+ struct hisi_sas_phy *phy;
+
+ if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size, &sshdr))
+ return;
+
+ if (sshdr.sense_key != NOT_READY ||
+ sshdr.sense_code != LU_NOT_READY_NOTIFY_REQUIRED)
+ return;
+
+ if (!pm_runtime_get_if_active(hisi_hba->dev))
+ return;
+
+ local_phy = sas_get_local_phy(dev);
+ phy = &hisi_hba->phy[local_phy->number];
+ if (!hisi_sas_notify_phy_event(phy, HISI_PHYE_SPINUP_NOTIFY))
+ pm_runtime_put(hisi_hba->dev);
+
+ sas_put_local_phy(local_phy);
+}
+EXPORT_SYMBOL_GPL(hisi_sas_spinup_notify);
+
static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba)
{
if (!hisi_hba->hw->soft_reset)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index fa94d7110714..5fcb8d5002f5 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -1272,6 +1272,10 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba,
&status_buffer->iu[0];
sas_ssp_task_response(dev, task, iu);
+ if (unlikely(ts->stat == SAS_SAM_STAT_CHECK_CONDITION &&
+ !dev_parent_is_expander(device)))
+ hisi_sas_spinup_notify(hisi_hba, task);
+
break;
}
case SAS_PROTOCOL_SMP:
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index f3516a0611dd..f16896e962fd 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -2427,6 +2427,10 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba,
&status_buffer->iu[0];
sas_ssp_task_response(dev, task, iu);
+ if (unlikely(ts->stat == SAS_SAM_STAT_CHECK_CONDITION &&
+ !dev_parent_is_expander(device)))
+ hisi_sas_spinup_notify(hisi_hba, task);
+
break;
}
case SAS_PROTOCOL_SMP:
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 030f050731ba..9391d031f5df 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -2447,6 +2447,10 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba,
sizeof(struct hisi_sas_err_record);
sas_ssp_task_response(dev, task, iu);
+ if (unlikely(ts->stat == SAS_SAM_STAT_CHECK_CONDITION &&
+ !dev_parent_is_expander(device)))
+ hisi_sas_spinup_notify(hisi_hba, task);
+
break;
}
case SAS_PROTOCOL_SMP: {
--
2.43.0
next prev parent reply other threads:[~2026-10-09 3:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 3:32 [PATCH v3 0/4] scsi: hisi_sas: Some misc fixes Xingui Yang
2026-10-09 3:32 ` [PATCH v3 1/4] scsi: libsas: Fix out-of-bounds memcpy in sas_ssp_task_response() Xingui Yang
2026-10-09 3:32 ` [PATCH v3 2/4] scsi: hisi_sas: Fix incorrect delay values from magic-number cleanup Xingui Yang
2026-10-09 3:32 ` [PATCH v3 3/4] scsi: hisi_sas: Clear PHY error counts on phyup Xingui Yang
2026-10-09 3:32 ` Xingui Yang [this message]
2026-10-09 9:08 ` [PATCH v3 0/4] scsi: hisi_sas: Some misc fixes yangxingui
2026-10-15 2:26 ` Martin K. Petersen
2026-10-15 3:51 ` yangxingui
2026-10-15 2:25 ` Martin K. Petersen
2026-10-24 3:24 ` Martin K. Petersen (Oracle)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261009033238.1076098-5-yangxingui@huawei.com \
--to=yangxingui@huawei.com \
--cc=jejb@linux.ibm.com \
--cc=john.garry@linux.dev \
--cc=kangfenglong@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linuxarm@huawei.com \
--cc=liuyonglong@huawei.com \
--cc=mkp@kernel.org \
--cc=yanaijie@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®