From: Xingui Yang <yangxingui@huawei.com>
To: <john.g.garry@oracle.com>, <yanaijie@huawei.com>,
<jejb@linux.ibm.com>, <martin.petersen@oracle.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 1/2] scsi: libsas: Add PHYE_NOTIFY_ENABLE_SPINUP phy event for ASC/ASCQ=0x04/0x11
Date: Mon, 3 Aug 2026 10:05:35 +0800 [thread overview]
Message-ID: <20260803020536.546544-2-yangxingui@huawei.com> (raw)
In-Reply-To: <20260803020536.546544-1-yangxingui@huawei.com>
When a SAS device is in the Active_Wait or Idle_Wait power state, it
returns NOT_READY with ASC/ASCQ = 0x04/0x11 (notify (enable spinup)
required), indicating that a NOTIFY(ENABLE SPINUP) primitive is needed to
trigger media spinup.
Add a PHYE_NOTIFY_ENABLE_SPINUP phy event and an optional
lldd_notify_enable_spinup callback to sas_domain_function_template. Sense
detection is done in sas_ssp_task_spinup_notify(), called from
sas_ssp_task_response() which is the common entry point for all SAS LLDDs.
Signed-off-by: Xingui Yang <yangxingui@huawei.com>
---
drivers/scsi/libsas/sas_internal.h | 2 ++
drivers/scsi/libsas/sas_phy.c | 12 ++++++++
drivers/scsi/libsas/sas_scsi_host.c | 45 +++++++++++++++++++++++++++++
drivers/scsi/libsas/sas_task.c | 2 ++
include/scsi/libsas.h | 9 ++++++
5 files changed, 70 insertions(+)
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
index 7dce0f587149..fa06f50b0bf0 100644
--- a/drivers/scsi/libsas/sas_internal.h
+++ b/drivers/scsi/libsas/sas_internal.h
@@ -107,6 +107,8 @@ extern const work_func_t sas_port_event_fns[PORT_NUM_EVENTS];
void sas_task_internal_done(struct sas_task *task);
void sas_task_internal_timedout(struct timer_list *t);
+void sas_ssp_task_spinup_notify(struct sas_task *task,
+ struct ssp_response_iu *iu);
int sas_execute_tmf(struct domain_device *device, void *parameter,
int para_len, int force_phy_id,
struct sas_tmf_task *tmf);
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c
index 58f08dc2c187..897a5b46db78 100644
--- a/drivers/scsi/libsas/sas_phy.c
+++ b/drivers/scsi/libsas/sas_phy.c
@@ -111,6 +111,17 @@ static void sas_phye_shutdown(struct work_struct *work)
phy->in_shutdown = 0;
}
+static void sas_phye_notify_enable_spinup(struct work_struct *work)
+{
+ struct asd_sas_event *ev = to_asd_sas_event(work);
+ struct asd_sas_phy *phy = ev->phy;
+ struct sas_ha_struct *sas_ha = phy->ha;
+ struct sas_internal *i =
+ to_sas_internal(sas_ha->shost->transportt);
+
+ i->dft->lldd_notify_enable_spinup(phy);
+}
+
/* ---------- Phy class registration ---------- */
int sas_register_phys(struct sas_ha_struct *sas_ha)
@@ -186,4 +197,5 @@ const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = {
[PHYE_SPINUP_HOLD] = sas_phye_spinup_hold,
[PHYE_RESUME_TIMEOUT] = sas_phye_resume_timeout,
[PHYE_SHUTDOWN] = sas_phye_shutdown,
+ [PHYE_NOTIFY_ENABLE_SPINUP] = sas_phye_notify_enable_spinup,
};
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index c83282733ec4..bb1dfc16d8d1 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -34,6 +34,51 @@
#include <linux/scatterlist.h>
#include <linux/libata.h>
+/*
+ * If the SSP response carries NOT_READY sense with ASC/ASCQ = 0x04/0x11
+ * ("notify (enable spinup) required"), queue a PHYE_NOTIFY_ENABLE_SPINUP
+ * phy event so the LLDD can send a NOTIFY(ENABLE SPINUP) primitive.
+ */
+void sas_ssp_task_spinup_notify(struct sas_task *task,
+ struct ssp_response_iu *iu)
+{
+ struct domain_device *dev = task->dev;
+ struct sas_ha_struct *ha = dev->port->ha;
+ struct sas_internal *i = to_sas_internal(ha->shost->transportt);
+ struct scsi_sense_hdr sshdr;
+ struct sas_phy *local_phy;
+ struct asd_sas_phy *phy;
+ u32 sense_len;
+
+ /*
+ * NOTIFY(ENABLE SPINUP) must be sent on the local phy directly
+ * attached to the target. Skip expander-attached devices.
+ */
+ if (dev->parent && dev_is_expander(dev->parent->dev_type))
+ return;
+
+ if (!i->dft->lldd_notify_enable_spinup)
+ return;
+
+ if (iu->status != SAM_STAT_CHECK_CONDITION)
+ return;
+
+ sense_len = min_t(u32, be32_to_cpu(iu->sense_data_len),
+ SAS_STATUS_BUF_SIZE);
+ if (!scsi_normalize_sense(iu->sense_data, sense_len, &sshdr))
+ return;
+
+ if (sshdr.sense_key != NOT_READY ||
+ sshdr.asc != 0x04 || sshdr.ascq != 0x11)
+ return;
+
+ local_phy = sas_get_local_phy(dev);
+ phy = ha->sas_phy[local_phy->number];
+ sas_put_local_phy(local_phy);
+
+ sas_notify_phy_event(phy, PHYE_NOTIFY_ENABLE_SPINUP, GFP_ATOMIC);
+}
+
/* record final status and free the task */
static void sas_end_task(struct scsi_cmnd *sc, struct sas_task *task)
{
diff --git a/drivers/scsi/libsas/sas_task.c b/drivers/scsi/libsas/sas_task.c
index e9d291007817..d1eb6ce90626 100644
--- a/drivers/scsi/libsas/sas_task.c
+++ b/drivers/scsi/libsas/sas_task.c
@@ -29,6 +29,8 @@ void sas_ssp_task_response(struct device *dev, struct sas_task *task,
be32_to_cpu(iu->sense_data_len));
memcpy(tstat->buf, iu->sense_data, tstat->buf_valid_size);
+ sas_ssp_task_spinup_notify(task, iu);
+
if (iu->status != SAM_STAT_CHECK_CONDITION)
dev_warn(dev, "dev %016llx sent sense data, but stat(0x%x) is not CHECK CONDITION\n",
SAS_ADDR(task->dev->sas_addr), iu->status);
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 163f23c92b41..945b7cfe0224 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -49,6 +49,7 @@ enum phy_event {
PHYE_SPINUP_HOLD, /* hot plug SATA, no COMWAKE sent */
PHYE_RESUME_TIMEOUT,
PHYE_SHUTDOWN,
+ PHYE_NOTIFY_ENABLE_SPINUP, /* NOTIFY(ENABLE SPINUP) primitive */
PHY_NUM_EVENTS,
};
@@ -674,6 +675,14 @@ struct sas_domain_function_template {
/* GPIO support */
int (*lldd_write_gpio)(struct sas_ha_struct *, u8 reg_type,
u8 reg_index, u8 reg_count, u8 *write_data);
+
+ /*
+ * Optional callback invoked when an SSP target returns NOT_READY
+ * with ASC/ASCQ = 0x04/0x11 ("notify (enable spinup) required"),
+ * indicating the device is in Active_Wait/Idle_Wait state and
+ * needs a NOTIFY(ENABLE SPINUP) primitive to proceed.
+ */
+ void (*lldd_notify_enable_spinup)(struct asd_sas_phy *phy);
};
extern int sas_register_ha(struct sas_ha_struct *);
--
2.43.0
next prev parent reply other threads:[~2026-08-03 2:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-03 2:05 [PATCH v3 0/2] scsi: libsas: Support spinup notification for SAS devices Xingui Yang
2026-08-03 2:05 ` Xingui Yang [this message]
2026-08-03 4:17 ` [PATCH v3 1/2] scsi: libsas: Add PHYE_NOTIFY_ENABLE_SPINUP phy event for ASC/ASCQ=0x04/0x11 sashiko-bot
2026-08-03 2:05 ` [PATCH v3 2/2] scsi: hisi_sas: Add lldd_notify_enable_spinup callback for SAS devices Xingui Yang
2026-08-03 2:36 ` sashiko-bot
2026-08-04 7:35 ` [PATCH v3 0/2] scsi: libsas: Support spinup notification " John Garry
2026-08-04 9:30 ` yangxingui
2026-08-05 11:43 ` John Garry
2026-08-06 1:45 ` yangxingui
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=20260803020536.546544-2-yangxingui@huawei.com \
--to=yangxingui@huawei.com \
--cc=jejb@linux.ibm.com \
--cc=john.g.garry@oracle.com \
--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=martin.petersen@oracle.com \
--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