Linux SCSI subsystem development
 help / color / mirror / Atom feed
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


  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