Too much mess.
+++ /dev/null
-From 6aa0365a3c8512587fffd42fe438768709ddef8e Mon Sep 17 00:00:00 2001
-From: Damien Le Moal <dlemoal@kernel.org>
-Date: Thu, 15 Jun 2023 17:18:53 +0900
-Subject: ata: libata-scsi: Avoid deadlock on rescan after device resume
-
-From: Damien Le Moal <dlemoal@kernel.org>
-
-commit 6aa0365a3c8512587fffd42fe438768709ddef8e upstream.
-
-When an ATA port is resumed from sleep, the port is reset and a power
-management request issued to libata EH to reset the port and rescanning
-the device(s) attached to the port. Device rescanning is done by
-scheduling an ata_scsi_dev_rescan() work, which will execute
-scsi_rescan_device().
-
-However, scsi_rescan_device() takes the generic device lock, which is
-also taken by dpm_resume() when the SCSI device is resumed as well. If
-a device rescan execution starts before the completion of the SCSI
-device resume, the rcu locking used to refresh the cached VPD pages of
-the device, combined with the generic device locking from
-scsi_rescan_device() and from dpm_resume() can cause a deadlock.
-
-Avoid this situation by changing struct ata_port scsi_rescan_task to be
-a delayed work instead of a simple work_struct. ata_scsi_dev_rescan() is
-modified to check if the SCSI device associated with the ATA device that
-must be rescanned is not suspended. If the SCSI device is still
-suspended, ata_scsi_dev_rescan() returns early and reschedule itself for
-execution after an arbitrary delay of 5ms.
-
-Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
-Reported-by: Joe Breuer <linux-kernel@jmbreuer.net>
-Closes: https://bugzilla.kernel.org/show_bug.cgi?id=217530
-Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
-Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
-Reviewed-by: Hannes Reinecke <hare@suse.de>
-Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
-Tested-by: Joe Breuer <linux-kernel@jmbreuer.net>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/ata/libata-core.c | 3 ++-
- drivers/ata/libata-eh.c | 2 +-
- drivers/ata/libata-scsi.c | 22 +++++++++++++++++++++-
- include/linux/libata.h | 2 +-
- 4 files changed, 25 insertions(+), 4 deletions(-)
-
---- a/drivers/ata/libata-core.c
-+++ b/drivers/ata/libata-core.c
-@@ -5340,7 +5340,7 @@ struct ata_port *ata_port_alloc(struct a
-
- mutex_init(&ap->scsi_scan_mutex);
- INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
-- INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
-+ INIT_DELAYED_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
- INIT_LIST_HEAD(&ap->eh_done_q);
- init_waitqueue_head(&ap->eh_wait_q);
- init_completion(&ap->park_req_pending);
-@@ -5974,6 +5974,7 @@ static void ata_port_detach(struct ata_p
- WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED));
-
- cancel_delayed_work_sync(&ap->hotplug_task);
-+ cancel_delayed_work_sync(&ap->scsi_rescan_task);
-
- skip_eh:
- /* clean up zpodd on port removal */
---- a/drivers/ata/libata-eh.c
-+++ b/drivers/ata/libata-eh.c
-@@ -2957,7 +2957,7 @@ static int ata_eh_revalidate_and_attach(
- ehc->i.flags |= ATA_EHI_SETMODE;
-
- /* schedule the scsi_rescan_device() here */
-- schedule_work(&(ap->scsi_rescan_task));
-+ schedule_delayed_work(&ap->scsi_rescan_task, 0);
- } else if (dev->class == ATA_DEV_UNKNOWN &&
- ehc->tries[dev->devno] &&
- ata_class_enabled(ehc->classes[dev->devno])) {
---- a/drivers/ata/libata-scsi.c
-+++ b/drivers/ata/libata-scsi.c
-@@ -4598,10 +4598,11 @@ int ata_scsi_user_scan(struct Scsi_Host
- void ata_scsi_dev_rescan(struct work_struct *work)
- {
- struct ata_port *ap =
-- container_of(work, struct ata_port, scsi_rescan_task);
-+ container_of(work, struct ata_port, scsi_rescan_task.work);
- struct ata_link *link;
- struct ata_device *dev;
- unsigned long flags;
-+ bool delay_rescan = false;
-
- mutex_lock(&ap->scsi_scan_mutex);
- spin_lock_irqsave(ap->lock, flags);
-@@ -4615,6 +4616,21 @@ void ata_scsi_dev_rescan(struct work_str
- if (scsi_device_get(sdev))
- continue;
-
-+ /*
-+ * If the rescan work was scheduled because of a resume
-+ * event, the port is already fully resumed, but the
-+ * SCSI device may not yet be fully resumed. In such
-+ * case, executing scsi_rescan_device() may cause a
-+ * deadlock with the PM code on device_lock(). Prevent
-+ * this by giving up and retrying rescan after a short
-+ * delay.
-+ */
-+ delay_rescan = sdev->sdev_gendev.power.is_suspended;
-+ if (delay_rescan) {
-+ scsi_device_put(sdev);
-+ break;
-+ }
-+
- spin_unlock_irqrestore(ap->lock, flags);
- scsi_rescan_device(&(sdev->sdev_gendev));
- scsi_device_put(sdev);
-@@ -4624,4 +4640,8 @@ void ata_scsi_dev_rescan(struct work_str
-
- spin_unlock_irqrestore(ap->lock, flags);
- mutex_unlock(&ap->scsi_scan_mutex);
-+
-+ if (delay_rescan)
-+ schedule_delayed_work(&ap->scsi_rescan_task,
-+ msecs_to_jiffies(5));
- }
---- a/include/linux/libata.h
-+++ b/include/linux/libata.h
-@@ -874,7 +874,7 @@ struct ata_port {
-
- struct mutex scsi_scan_mutex;
- struct delayed_work hotplug_task;
-- struct work_struct scsi_rescan_task;
-+ struct delayed_work scsi_rescan_task;
-
- unsigned int hsm_task_state;
-
+++ /dev/null
-From fb99ef17865035a6657786d4b2af11a27ba23f9b Mon Sep 17 00:00:00 2001
-From: Damien Le Moal <dlemoal@kernel.org>
-Date: Fri, 25 Aug 2023 15:41:14 +0900
-Subject: ata: libata-scsi: link ata port and scsi device
-
-From: Damien Le Moal <dlemoal@kernel.org>
-
-commit fb99ef17865035a6657786d4b2af11a27ba23f9b upstream.
-
-There is no direct device ancestry defined between an ata_device and
-its scsi device which prevents the power management code from correctly
-ordering suspend and resume operations. Create such ancestry with the
-ata device as the parent to ensure that the scsi device (child) is
-suspended before the ata device and that resume handles the ata device
-before the scsi device.
-
-The parent-child (supplier-consumer) relationship is established between
-the ata_port (parent) and the scsi device (child) with the function
-device_add_link(). The parent used is not the ata_device as the PM
-operations are defined per port and the status of all devices connected
-through that port is controlled from the port operations.
-
-The device link is established with the new function
-ata_scsi_slave_alloc(), and this function is used to define the
-->slave_alloc callback of the scsi host template of all ata drivers.
-
-Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
-Cc: stable@vger.kernel.org
-Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
-Reviewed-by: Hannes Reinecke <hare@suse.de>
-Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
-Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
-Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
-Reviewed-by: John Garry <john.g.garry@oracle.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/ata/libata-scsi.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
- include/linux/libata.h | 2 ++
- 2 files changed, 42 insertions(+), 5 deletions(-)
-
---- a/drivers/ata/libata-scsi.c
-+++ b/drivers/ata/libata-scsi.c
-@@ -1104,6 +1104,42 @@ int ata_scsi_dev_config(struct scsi_devi
- }
-
- /**
-+ * ata_scsi_slave_alloc - Early setup of SCSI device
-+ * @sdev: SCSI device to examine
-+ *
-+ * This is called from scsi_alloc_sdev() when the scsi device
-+ * associated with an ATA device is scanned on a port.
-+ *
-+ * LOCKING:
-+ * Defined by SCSI layer. We don't really care.
-+ */
-+
-+int ata_scsi_slave_alloc(struct scsi_device *sdev)
-+{
-+ struct ata_port *ap = ata_shost_to_port(sdev->host);
-+ struct device_link *link;
-+
-+ ata_scsi_sdev_config(sdev);
-+
-+ /*
-+ * Create a link from the ata_port device to the scsi device to ensure
-+ * that PM does suspend/resume in the correct order: the scsi device is
-+ * consumer (child) and the ata port the supplier (parent).
-+ */
-+ link = device_link_add(&sdev->sdev_gendev, &ap->tdev,
-+ DL_FLAG_STATELESS |
-+ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
-+ if (!link) {
-+ ata_port_err(ap, "Failed to create link to scsi device %s\n",
-+ dev_name(&sdev->sdev_gendev));
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(ata_scsi_slave_alloc);
-+
-+/**
- * ata_scsi_slave_config - Set SCSI device attributes
- * @sdev: SCSI device to examine
- *
-@@ -1119,14 +1155,11 @@ int ata_scsi_slave_config(struct scsi_de
- {
- struct ata_port *ap = ata_shost_to_port(sdev->host);
- struct ata_device *dev = __ata_scsi_find_dev(ap, sdev);
-- int rc = 0;
--
-- ata_scsi_sdev_config(sdev);
-
- if (dev)
-- rc = ata_scsi_dev_config(sdev, dev);
-+ return ata_scsi_dev_config(sdev, dev);
-
-- return rc;
-+ return 0;
- }
- EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
-
-@@ -1153,6 +1186,8 @@ void ata_scsi_slave_destroy(struct scsi_
- if (!ap->ops->error_handler)
- return;
-
-+ device_link_remove(&sdev->sdev_gendev, &ap->tdev);
-+
- spin_lock_irqsave(ap->lock, flags);
- dev = __ata_scsi_find_dev(ap, sdev);
- if (dev && dev->sdev) {
---- a/include/linux/libata.h
-+++ b/include/linux/libata.h
-@@ -1168,6 +1168,7 @@ extern int ata_std_bios_param(struct scs
- struct block_device *bdev,
- sector_t capacity, int geom[]);
- extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev);
-+extern int ata_scsi_slave_alloc(struct scsi_device *sdev);
- extern int ata_scsi_slave_config(struct scsi_device *sdev);
- extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
- extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
-@@ -1416,6 +1417,7 @@ extern struct device_attribute *ata_comm
- .this_id = ATA_SHT_THIS_ID, \
- .emulated = ATA_SHT_EMULATED, \
- .proc_name = drv_name, \
-+ .slave_alloc = ata_scsi_slave_alloc, \
- .slave_destroy = ata_scsi_slave_destroy, \
- .bios_param = ata_std_bios_param, \
- .unlock_native_capacity = ata_scsi_unlock_native_capacity
+++ /dev/null
-From 0a8589055936d8feb56477123a8373ac634018fa Mon Sep 17 00:00:00 2001
-From: Damien Le Moal <dlemoal@kernel.org>
-Date: Mon, 24 Jul 2023 13:23:14 +0900
-Subject: ata,scsi: do not issue START STOP UNIT on resume
-
-From: Damien Le Moal <dlemoal@kernel.org>
-
-commit 0a8589055936d8feb56477123a8373ac634018fa upstream.
-
-During system resume, ata_port_pm_resume() triggers ata EH to
-1) Resume the controller
-2) Reset and rescan the ports
-3) Revalidate devices
-This EH execution is started asynchronously from ata_port_pm_resume(),
-which means that when sd_resume() is executed, none or only part of the
-above processing may have been executed. However, sd_resume() issues a
-START STOP UNIT to wake up the drive from sleep mode. This command is
-translated to ATA with ata_scsi_start_stop_xlat() and issued to the
-device. However, depending on the state of execution of the EH process
-and revalidation triggerred by ata_port_pm_resume(), two things may
-happen:
-1) The START STOP UNIT fails if it is received before the controller has
- been reenabled at the beginning of the EH execution. This is visible
- with error messages like:
-
-ata10.00: device reported invalid CHS sector 0
-sd 9:0:0:0: [sdc] Start/Stop Unit failed: Result: hostbyte=DID_OK driverbyte=DRIVER_OK
-sd 9:0:0:0: [sdc] Sense Key : Illegal Request [current]
-sd 9:0:0:0: [sdc] Add. Sense: Unaligned write command
-sd 9:0:0:0: PM: dpm_run_callback(): scsi_bus_resume+0x0/0x90 returns -5
-sd 9:0:0:0: PM: failed to resume async: error -5
-
-2) The START STOP UNIT command is received while the EH process is
- on-going, which mean that it is stopped and must wait for its
- completion, at which point the command is rather useless as the drive
- is already fully spun up already. This case results also in a
- significant delay in sd_resume() which is observable by users as
- the entire system resume completion is delayed.
-
-Given that ATA devices will be woken up by libata activity on resume,
-sd_resume() has no need to issue a START STOP UNIT command, which solves
-the above mentioned problems. Do not issue this command by introducing
-the new scsi_device flag no_start_on_resume and setting this flag to 1
-in ata_scsi_dev_config(). sd_resume() is modified to issue a START STOP
-UNIT command only if this flag is not set.
-
-Reported-by: Paul Ausbeck <paula@soe.ucsc.edu>
-Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215880
-Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
-Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
-Tested-by: Tanner Watkins <dalzot@gmail.com>
-Tested-by: Paul Ausbeck <paula@soe.ucsc.edu>
-Reviewed-by: Hannes Reinecke <hare@suse.de>
-Reviewed-by: Bart Van Assche <bvanassche@acm.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/ata/libata-scsi.c | 7 +++++++
- drivers/scsi/sd.c | 9 ++++++---
- include/scsi/scsi_device.h | 1 +
- 3 files changed, 14 insertions(+), 3 deletions(-)
-
---- a/drivers/ata/libata-scsi.c
-+++ b/drivers/ata/libata-scsi.c
-@@ -1061,7 +1061,14 @@ int ata_scsi_dev_config(struct scsi_devi
- }
- } else {
- sdev->sector_size = ata_id_logical_sector_size(dev->id);
-+ /*
-+ * Stop the drive on suspend but do not issue START STOP UNIT
-+ * on resume as this is not necessary and may fail: the device
-+ * will be woken up by ata_port_pm_resume() with a port reset
-+ * and device revalidation.
-+ */
- sdev->manage_start_stop = 1;
-+ sdev->no_start_on_resume = 1;
- }
-
- /*
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -3681,7 +3681,7 @@ static int sd_suspend_runtime(struct dev
- static int sd_resume(struct device *dev)
- {
- struct scsi_disk *sdkp = dev_get_drvdata(dev);
-- int ret;
-+ int ret = 0;
-
- if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */
- return 0;
-@@ -3689,8 +3689,11 @@ static int sd_resume(struct device *dev)
- if (!sdkp->device->manage_start_stop)
- return 0;
-
-- sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
-- ret = sd_start_stop_device(sdkp, 1);
-+ if (!sdkp->device->no_start_on_resume) {
-+ sd_printk(KERN_NOTICE, sdkp, "Starting disk\n");
-+ ret = sd_start_stop_device(sdkp, 1);
-+ }
-+
- if (!ret)
- opal_unlock_from_suspend(sdkp->opal_dev);
- return ret;
---- a/include/scsi/scsi_device.h
-+++ b/include/scsi/scsi_device.h
-@@ -185,6 +185,7 @@ struct scsi_device {
- unsigned no_start_on_add:1; /* do not issue start on add */
- unsigned allow_restart:1; /* issue START_UNIT in error handler */
- unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */
-+ unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */
- unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */
- unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
- unsigned select_no_atn:1;
+++ /dev/null
-From 7cc5aad6c98e0b7e9ab744d1ac7e385e886bb869 Mon Sep 17 00:00:00 2001
-From: Bart Van Assche <bvanassche@acm.org>
-Date: Mon, 29 Nov 2021 11:45:59 -0800
-Subject: scsi: core: Declare 'scsi_scan_type' static
-
-From: Bart Van Assche <bvanassche@acm.org>
-
-commit 7cc5aad6c98e0b7e9ab744d1ac7e385e886bb869 upstream.
-
-'scsi_scan_type' is only used in one source file. Hence declare it static.
-
-Link: https://lore.kernel.org/r/20211129194609.3466071-3-bvanassche@acm.org
-Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Bart Van Assche <bvanassche@acm.org>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/scsi_scan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/scsi/scsi_scan.c
-+++ b/drivers/scsi/scsi_scan.c
-@@ -97,7 +97,7 @@ MODULE_PARM_DESC(max_luns,
- #define SCSI_SCAN_TYPE_DEFAULT "sync"
- #endif
-
--char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT;
-+static char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT;
-
- module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type),
- S_IRUGO|S_IWUSR);
+++ /dev/null
-From stable+bounces-244970-greg=kroah.com@vger.kernel.org Sat May 9 21:38:57 2026
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 9 May 2026 12:08:46 -0400
-Subject: scsi: core: pm: Rely on the device driver core for async power management
-To: stable@vger.kernel.org
-Cc: Bart Van Assche <bvanassche@acm.org>, Alan Stern <stern@rowland.harvard.edu>, Dan Williams <dan.j.williams@intel.com>, Hannes Reinecke <hare@suse.com>, Adrian Hunter <adrian.hunter@intel.com>, Martin Kepplinger <martin.kepplinger@puri.sm>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
-Message-ID: <20260509160849.3584738-1-sashal@kernel.org>
-
-From: Bart Van Assche <bvanassche@acm.org>
-
-[ Upstream commit a19a93e4c6a98c9c0f2f5a6db76846f10d7d1f85 ]
-
-Instead of implementing asynchronous resume support in the SCSI core, rely
-on the device driver core for resuming SCSI devices asynchronously.
-Instead of only supporting asynchronous resumes, also support asynchronous
-suspends.
-
-Link: https://lore.kernel.org/r/20211006215453.3318929-2-bvanassche@acm.org
-Cc: Alan Stern <stern@rowland.harvard.edu>
-Cc: Dan Williams <dan.j.williams@intel.com>
-Cc: Hannes Reinecke <hare@suse.com>
-Cc: Adrian Hunter <adrian.hunter@intel.com>
-Cc: Martin Kepplinger <martin.kepplinger@puri.sm>
-Signed-off-by: Bart Van Assche <bvanassche@acm.org>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Stable-dep-of: 1e111c4b3a72 ("scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/hosts.c | 1 +
- drivers/scsi/scsi.c | 8 --------
- drivers/scsi/scsi_pm.c | 44 ++------------------------------------------
- drivers/scsi/scsi_priv.h | 4 +---
- drivers/scsi/scsi_scan.c | 17 +++++++++++++++++
- drivers/scsi/scsi_sysfs.c | 1 +
- drivers/scsi/sd.c | 1 -
- 7 files changed, 22 insertions(+), 54 deletions(-)
-
---- a/drivers/scsi/hosts.c
-+++ b/drivers/scsi/hosts.c
-@@ -487,6 +487,7 @@ struct Scsi_Host *scsi_host_alloc(struct
- dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
- shost->shost_gendev.bus = &scsi_bus_type;
- shost->shost_gendev.type = &scsi_host_type;
-+ scsi_enable_async_suspend(&shost->shost_gendev);
-
- device_initialize(&shost->shost_dev);
- shost->shost_dev.parent = &shost->shost_gendev;
---- a/drivers/scsi/scsi.c
-+++ b/drivers/scsi/scsi.c
-@@ -86,14 +86,6 @@ unsigned int scsi_logging_level;
- EXPORT_SYMBOL(scsi_logging_level);
- #endif
-
--/*
-- * Domain for asynchronous system resume operations. It is marked 'exclusive'
-- * to avoid being included in the async_synchronize_full() that is invoked by
-- * dpm_resume().
-- */
--ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain);
--EXPORT_SYMBOL(scsi_sd_pm_domain);
--
- #ifdef CONFIG_SCSI_LOGGING
- void scsi_log_send(struct scsi_cmnd *cmd)
- {
---- a/drivers/scsi/scsi_pm.c
-+++ b/drivers/scsi/scsi_pm.c
-@@ -56,9 +56,6 @@ static int scsi_dev_type_suspend(struct
- const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int err;
-
-- /* flush pending in-flight resume operations, suspend is synchronous */
-- async_synchronize_full_domain(&scsi_sd_pm_domain);
--
- err = scsi_device_quiesce(to_scsi_device(dev));
- if (err == 0) {
- err = cb(dev, pm);
-@@ -123,48 +120,11 @@ scsi_bus_suspend_common(struct device *d
- return err;
- }
-
--static void async_sdev_resume(void *dev, async_cookie_t cookie)
--{
-- scsi_dev_type_resume(dev, do_scsi_resume);
--}
--
--static void async_sdev_thaw(void *dev, async_cookie_t cookie)
--{
-- scsi_dev_type_resume(dev, do_scsi_thaw);
--}
--
--static void async_sdev_restore(void *dev, async_cookie_t cookie)
--{
-- scsi_dev_type_resume(dev, do_scsi_restore);
--}
--
- static int scsi_bus_resume_common(struct device *dev,
- int (*cb)(struct device *, const struct dev_pm_ops *))
- {
-- async_func_t fn;
--
-- if (!scsi_is_sdev_device(dev))
-- fn = NULL;
-- else if (cb == do_scsi_resume)
-- fn = async_sdev_resume;
-- else if (cb == do_scsi_thaw)
-- fn = async_sdev_thaw;
-- else if (cb == do_scsi_restore)
-- fn = async_sdev_restore;
-- else
-- fn = NULL;
--
-- if (fn) {
-- async_schedule_domain(fn, dev, &scsi_sd_pm_domain);
--
-- /*
-- * If a user has disabled async probing a likely reason
-- * is due to a storage enclosure that does not inject
-- * staggered spin-ups. For safety, make resume
-- * synchronous as well in that case.
-- */
-- if (strncmp(scsi_scan_type, "async", 5) != 0)
-- async_synchronize_full_domain(&scsi_sd_pm_domain);
-+ if (scsi_is_sdev_device(dev)) {
-+ scsi_dev_type_resume(dev, cb);
- } else {
- pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
---- a/drivers/scsi/scsi_priv.h
-+++ b/drivers/scsi/scsi_priv.h
-@@ -117,7 +117,7 @@ extern void scsi_exit_procfs(void);
- #endif /* CONFIG_PROC_FS */
-
- /* scsi_scan.c */
--extern char scsi_scan_type[];
-+void scsi_enable_async_suspend(struct device *dev);
- extern int scsi_complete_async_scans(void);
- extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
- unsigned int, u64, enum scsi_scan_mode);
-@@ -171,8 +171,6 @@ static inline int scsi_autopm_get_host(s
- static inline void scsi_autopm_put_host(struct Scsi_Host *h) {}
- #endif /* CONFIG_PM */
-
--extern struct async_domain scsi_sd_pm_domain;
--
- /* scsi_dh.c */
- #ifdef CONFIG_SCSI_DH
- void scsi_dh_add_device(struct scsi_device *sdev);
---- a/drivers/scsi/scsi_scan.c
-+++ b/drivers/scsi/scsi_scan.c
-@@ -123,6 +123,22 @@ struct async_scan_data {
- };
-
- /**
-+ * scsi_enable_async_suspend - Enable async suspend and resume
-+ */
-+void scsi_enable_async_suspend(struct device *dev)
-+{
-+ /*
-+ * If a user has disabled async probing a likely reason is due to a
-+ * storage enclosure that does not inject staggered spin-ups. For
-+ * safety, make resume synchronous as well in that case.
-+ */
-+ if (strncmp(scsi_scan_type, "async", 5) != 0)
-+ return;
-+ /* Enable asynchronous suspend and resume. */
-+ device_enable_async_suspend(dev);
-+}
-+
-+/**
- * scsi_complete_async_scans - Wait for asynchronous scans to complete
- *
- * When this function returns, any host which started scanning before
-@@ -499,6 +515,7 @@ static struct scsi_target *scsi_alloc_ta
- dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
- dev->bus = &scsi_bus_type;
- dev->type = &scsi_target_type;
-+ scsi_enable_async_suspend(dev);
- starget->id = id;
- starget->channel = channel;
- starget->can_queue = 0;
---- a/drivers/scsi/scsi_sysfs.c
-+++ b/drivers/scsi/scsi_sysfs.c
-@@ -1643,6 +1643,7 @@ void scsi_sysfs_device_initialize(struct
- device_initialize(&sdev->sdev_gendev);
- sdev->sdev_gendev.bus = &scsi_bus_type;
- sdev->sdev_gendev.type = &scsi_dev_type;
-+ scsi_enable_async_suspend(&sdev->sdev_gendev);
- dev_set_name(&sdev->sdev_gendev, "%d:%d:%d:%llu",
- sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -3505,7 +3505,6 @@ static int sd_remove(struct device *dev)
- sdkp = dev_get_drvdata(dev);
- scsi_autopm_get_device(sdkp->device);
-
-- async_synchronize_full_domain(&scsi_sd_pm_domain);
- device_del(&sdkp->dev);
- del_gendisk(sdkp->disk);
- sd_shutdown(dev);
+++ /dev/null
-From 776141dda77f153379a2eea0887f76cb3e6c8062 Mon Sep 17 00:00:00 2001
-From: Bart Van Assche <bvanassche@acm.org>
-Date: Mon, 29 Nov 2021 11:45:58 -0800
-Subject: scsi: core: Suppress a kernel-doc warning
-
-From: Bart Van Assche <bvanassche@acm.org>
-
-commit 776141dda77f153379a2eea0887f76cb3e6c8062 upstream.
-
-Suppress the following kernel-doc warning:
-
-drivers/scsi/scsi_scan.c:129: warning: Function parameter or member 'dev' not described in 'scsi_enable_async_suspend'
-
-Link: https://lore.kernel.org/r/20211129194609.3466071-2-bvanassche@acm.org
-Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
-Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
-Signed-off-by: Bart Van Assche <bvanassche@acm.org>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/scsi_scan.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/scsi/scsi_scan.c
-+++ b/drivers/scsi/scsi_scan.c
-@@ -122,7 +122,7 @@ struct async_scan_data {
- struct completion prev_finished;
- };
-
--/**
-+/*
- * scsi_enable_async_suspend - Enable async suspend and resume
- */
- void scsi_enable_async_suspend(struct device *dev)
+++ /dev/null
-From stable+bounces-244971-greg=kroah.com@vger.kernel.org Sat May 9 21:38:58 2026
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 9 May 2026 12:08:47 -0400
-Subject: scsi: sd: Add error handling support for add_disk()
-To: stable@vger.kernel.org
-Cc: Luis Chamberlain <mcgrof@kernel.org>, Christoph Hellwig <hch@lst.de>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
-Message-ID: <20260509160849.3584738-2-sashal@kernel.org>
-
-From: Luis Chamberlain <mcgrof@kernel.org>
-
-[ Upstream commit 2a7a891f4c406822801ecd676b076c64de072c9e ]
-
-We never checked for errors on add_disk() as this function returned
-void. Now that this is fixed, use the shiny new error handling.
-
-As with the error handling for device_add() we follow the same logic and
-just put the device so that cleanup is done via the scsi_disk_release().
-
-Link: https://lore.kernel.org/r/20211015233028.2167651-2-mcgrof@kernel.org
-Reviewed-by: Christoph Hellwig <hch@lst.de>
-Acked-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Stable-dep-of: 1e111c4b3a72 ("scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/sd.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -3458,7 +3458,13 @@ static int sd_probe(struct device *dev)
- pm_runtime_set_autosuspend_delay(dev,
- sdp->host->hostt->rpm_autosuspend_delay);
- }
-- device_add_disk(dev, gd, NULL);
-+
-+ error = device_add_disk(dev, gd, NULL);
-+ if (error) {
-+ put_device(&sdkp->dev);
-+ goto out;
-+ }
-+
- if (sdkp->capacity)
- sd_dif_config_host(sdkp);
-
+++ /dev/null
-From stable+bounces-244973-greg=kroah.com@vger.kernel.org Sat May 9 21:39:04 2026
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 9 May 2026 12:08:49 -0400
-Subject: scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails
-To: stable@vger.kernel.org
-Cc: Yang Xiuwei <yangxiuwei@kylinos.cn>, John Garry <john.g.garry@oracle.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
-Message-ID: <20260509160849.3584738-4-sashal@kernel.org>
-
-From: Yang Xiuwei <yangxiuwei@kylinos.cn>
-
-[ Upstream commit 1e111c4b3a726df1254670a5cc4868cedb946d37 ]
-
-If device_add(&sdkp->disk_dev) fails, put_device() runs
-scsi_disk_release(), which frees the scsi_disk but leaves the gendisk
-referenced. The device_add_disk() error path in sd_probe() calls
-put_disk(gd); call put_disk(gd) here to mirror that cleanup.
-
-Fixes: 265dfe8ebbab ("scsi: sd: Free scsi_disk device via put_device()")
-Cc: stable@vger.kernel.org
-Reviewed-by: John Garry <john.g.garry@oracle.com>
-Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
-Link: https://patch.msgid.link/20260330014952.152776-1-yangxiuwei@kylinos.cn
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/sd.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -3420,6 +3420,7 @@ static int sd_probe(struct device *dev)
- error = device_add(&sdkp->disk_dev);
- if (error) {
- put_device(&sdkp->disk_dev);
-+ put_disk(gd);
- goto out;
- }
-
+++ /dev/null
-From 785538bfdd682c8e962341d585f9b88262a0475e Mon Sep 17 00:00:00 2001
-From: Bart Van Assche <bvanassche@acm.org>
-Date: Tue, 16 Aug 2022 10:26:38 -0700
-Subject: scsi: sd: Revert "Rework asynchronous resume support"
-
-From: Bart Van Assche <bvanassche@acm.org>
-
-commit 785538bfdd682c8e962341d585f9b88262a0475e upstream.
-
-Although commit 88f1669019bd ("scsi: sd: Rework asynchronous resume support")
-eliminates a delay for some ATA disks after resume, it causes resume of ATA
-disks to fail on other setups. See also:
-
- * "Resume process hangs for 5-6 seconds starting sometime in 5.16"
- (https://bugzilla.kernel.org/show_bug.cgi?id=215880).
-
- * Geert's regression report
- (https://lore.kernel.org/linux-scsi/alpine.DEB.2.22.394.2207191125130.1006766@ramsan.of.borg/).
-
-This is what I understand about this issue:
-
- * During resume, ata_port_pm_resume() starts the SCSI error handler. This
- changes the SCSI host state into SHOST_RECOVERY and causes
- scsi_queue_rq() to return BLK_STS_RESOURCE.
-
- * sd_resume() calls sd_start_stop_device() for ATA devices. That function
- in turn calls sd_submit_start() which tries to submit a START STOP UNIT
- command. That command can only be submitted after the SCSI error handler
- has changed the SCSI host state back to SHOST_RUNNING.
-
- * The SCSI error handler runs on its own thread and calls
- schedule_work(&(ap->scsi_rescan_task)). That causes
- ata_scsi_dev_rescan() to be called from the context of a kernel
- workqueue. That call hangs in blk_mq_get_tag(). I'm not sure why - maybe
- because all available tags have been allocated by sd_submit_start()
- calls (this is a guess).
-
-Link: https://lore.kernel.org/r/20220816172638.538734-1-bvanassche@acm.org
-Fixes: 88f1669019bd ("scsi: sd: Rework asynchronous resume support")
-Cc: Damien Le Moal <damien.lemoal@opensource.wdc.com>
-Cc: Hannes Reinecke <hare@suse.de>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: gzhqyz@gmail.com
-Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
-Reported-by: gzhqyz@gmail.com
-Reported-and-tested-by: Vlastimil Babka <vbabka@suse.cz>
-Tested-by: John Garry <john.garry@huawei.com>
-Tested-by: Hans de Goede <hdegoede@redhat.com>
-Signed-off-by: Bart Van Assche <bvanassche@acm.org>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/sd.c | 84 +++++++++++-------------------------------------------
- drivers/scsi/sd.h | 5 ---
- 2 files changed, 18 insertions(+), 71 deletions(-)
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -105,7 +105,6 @@ static void sd_config_discard(struct scs
- static void sd_config_write_same(struct scsi_disk *);
- static int sd_revalidate_disk(struct gendisk *);
- static void sd_unlock_native_capacity(struct gendisk *disk);
--static void sd_start_done_work(struct work_struct *work);
- static int sd_probe(struct device *);
- static int sd_remove(struct device *);
- static void sd_shutdown(struct device *);
-@@ -3404,7 +3403,6 @@ static int sd_probe(struct device *dev)
- sdkp->max_retries = SD_MAX_RETRIES;
- atomic_set(&sdkp->openers, 0);
- atomic_set(&sdkp->device->ioerr_cnt, 0);
-- INIT_WORK(&sdkp->start_done_work, sd_start_done_work);
-
- if (!sdp->request_queue->rq_timeout) {
- if (sdp->type != TYPE_MOD)
-@@ -3565,69 +3563,12 @@ static void scsi_disk_release(struct dev
- kfree(sdkp);
- }
-
--/* Process sense data after a START command finished. */
--static void sd_start_done_work(struct work_struct *work)
--{
-- struct scsi_disk *sdkp = container_of(work, typeof(*sdkp),
-- start_done_work);
-- struct scsi_sense_hdr sshdr;
-- int res = sdkp->start_result;
--
-- if (res == 0)
-- return;
--
-- sd_print_result(sdkp, "Start/Stop Unit failed", res);
--
-- if (res < 0)
-- return;
--
-- if (scsi_normalize_sense(sdkp->start_sense_buffer,
-- sdkp->start_sense_len, &sshdr))
-- sd_print_sense_hdr(sdkp, &sshdr);
--}
--
--/* A START command finished. May be called from interrupt context. */
--static void sd_start_done(struct request *req, blk_status_t status)
--{
-- const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
-- struct scsi_disk *sdkp = scsi_disk(req->q->disk);
--
-- sdkp->start_result = scmd->result;
-- WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE);
-- sdkp->start_sense_len = scmd->sense_len;
-- memcpy(sdkp->start_sense_buffer, scmd->sense_buffer,
-- ARRAY_SIZE(sdkp->start_sense_buffer));
-- WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work));
--}
--
--/* Submit a START command asynchronously. */
--static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len)
--{
-- struct scsi_device *sdev = sdkp->device;
-- struct request_queue *q = sdev->request_queue;
-- struct request *req;
-- struct scsi_cmnd *scmd;
--
-- req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM);
-- if (IS_ERR(req))
-- return PTR_ERR(req);
--
-- scmd = blk_mq_rq_to_pdu(req);
-- scmd->cmd_len = cmd_len;
-- memcpy(scmd->cmnd, cmd, cmd_len);
-- scmd->allowed = sdkp->max_retries;
-- req->timeout = SD_TIMEOUT;
-- req->rq_flags |= RQF_PM | RQF_QUIET;
-- req->end_io = sd_start_done;
-- blk_execute_rq_nowait(req, /*at_head=*/true);
--
-- return 0;
--}
--
- static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
- {
- unsigned char cmd[6] = { START_STOP }; /* START_VALID */
-+ struct scsi_sense_hdr sshdr;
- struct scsi_device *sdp = sdkp->device;
-+ int res;
-
- if (start)
- cmd[4] |= 1; /* START */
-@@ -3638,10 +3579,23 @@ static int sd_start_stop_device(struct s
- if (!scsi_device_online(sdp))
- return -ENODEV;
-
-- /* Wait until processing of sense data has finished. */
-- flush_work(&sdkp->start_done_work);
-+ res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-+ SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
-+ if (res) {
-+ sd_print_result(sdkp, "Start/Stop Unit failed", res);
-+ if (res > 0 && scsi_sense_valid(&sshdr)) {
-+ sd_print_sense_hdr(sdkp, &sshdr);
-+ /* 0x3a is medium not present */
-+ if (sshdr.asc == 0x3a)
-+ res = 0;
-+ }
-+ }
-
-- return sd_submit_start(sdkp, cmd, sizeof(cmd));
-+ /* SCSI error codes must not go to the generic layer */
-+ if (res)
-+ return -EIO;
-+
-+ return 0;
- }
-
- /*
-@@ -3668,8 +3622,6 @@ static void sd_shutdown(struct device *d
- sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
- sd_start_stop_device(sdkp, 0);
- }
--
-- flush_work(&sdkp->start_done_work);
- }
-
- static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
---- a/drivers/scsi/sd.h
-+++ b/drivers/scsi/sd.h
-@@ -130,11 +130,6 @@ struct scsi_disk {
- unsigned urswrz : 1;
- unsigned security : 1;
- unsigned ignore_medium_access_errors : 1;
--
-- int start_result;
-- u32 start_sense_len;
-- u8 start_sense_buffer[SCSI_SENSE_BUFFERSIZE];
-- struct work_struct start_done_work;
- };
- #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
-
+++ /dev/null
-From 88f1669019bd62b3009a3cebf772fbaaa21b9f38 Mon Sep 17 00:00:00 2001
-From: Bart Van Assche <bvanassche@acm.org>
-Date: Thu, 30 Jun 2022 12:57:03 -0700
-Subject: scsi: sd: Rework asynchronous resume support
-
-From: Bart Van Assche <bvanassche@acm.org>
-
-commit 88f1669019bd62b3009a3cebf772fbaaa21b9f38 upstream.
-
-For some technologies, e.g. an ATA bus, resuming can take multiple
-seconds. Waiting for resume to finish can cause a very noticeable delay.
-Hence this commit that restores the behavior from before "scsi: core: pm:
-Rely on the device driver core for async power management" for most SCSI
-devices.
-
-This commit introduces a behavior change: if the START command fails, do
-not consider this as a SCSI disk resume failure.
-
-Link: https://bugzilla.kernel.org/show_bug.cgi?id=215880
-Link: https://lore.kernel.org/r/20220630195703.10155-3-bvanassche@acm.org
-Fixes: a19a93e4c6a9 ("scsi: core: pm: Rely on the device driver core for async power management")
-Cc: Ming Lei <ming.lei@redhat.com>
-Cc: Hannes Reinecke <hare@suse.de>
-Cc: John Garry <john.garry@huawei.com>
-Cc: ericspero@icloud.com
-Cc: jason600.groome@gmail.com
-Tested-by: jason600.groome@gmail.com
-Signed-off-by: Bart Van Assche <bvanassche@acm.org>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/sd.c | 84 ++++++++++++++++++++++++++++++++++++++++++------------
- drivers/scsi/sd.h | 5 +++
- 2 files changed, 71 insertions(+), 18 deletions(-)
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -105,6 +105,7 @@ static void sd_config_discard(struct scs
- static void sd_config_write_same(struct scsi_disk *);
- static int sd_revalidate_disk(struct gendisk *);
- static void sd_unlock_native_capacity(struct gendisk *disk);
-+static void sd_start_done_work(struct work_struct *work);
- static int sd_probe(struct device *);
- static int sd_remove(struct device *);
- static void sd_shutdown(struct device *);
-@@ -3403,6 +3404,7 @@ static int sd_probe(struct device *dev)
- sdkp->max_retries = SD_MAX_RETRIES;
- atomic_set(&sdkp->openers, 0);
- atomic_set(&sdkp->device->ioerr_cnt, 0);
-+ INIT_WORK(&sdkp->start_done_work, sd_start_done_work);
-
- if (!sdp->request_queue->rq_timeout) {
- if (sdp->type != TYPE_MOD)
-@@ -3563,12 +3565,69 @@ static void scsi_disk_release(struct dev
- kfree(sdkp);
- }
-
-+/* Process sense data after a START command finished. */
-+static void sd_start_done_work(struct work_struct *work)
-+{
-+ struct scsi_disk *sdkp = container_of(work, typeof(*sdkp),
-+ start_done_work);
-+ struct scsi_sense_hdr sshdr;
-+ int res = sdkp->start_result;
-+
-+ if (res == 0)
-+ return;
-+
-+ sd_print_result(sdkp, "Start/Stop Unit failed", res);
-+
-+ if (res < 0)
-+ return;
-+
-+ if (scsi_normalize_sense(sdkp->start_sense_buffer,
-+ sdkp->start_sense_len, &sshdr))
-+ sd_print_sense_hdr(sdkp, &sshdr);
-+}
-+
-+/* A START command finished. May be called from interrupt context. */
-+static void sd_start_done(struct request *req, blk_status_t status)
-+{
-+ const struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(req);
-+ struct scsi_disk *sdkp = scsi_disk(req->q->disk);
-+
-+ sdkp->start_result = scmd->result;
-+ WARN_ON_ONCE(scmd->sense_len > SCSI_SENSE_BUFFERSIZE);
-+ sdkp->start_sense_len = scmd->sense_len;
-+ memcpy(sdkp->start_sense_buffer, scmd->sense_buffer,
-+ ARRAY_SIZE(sdkp->start_sense_buffer));
-+ WARN_ON_ONCE(!schedule_work(&sdkp->start_done_work));
-+}
-+
-+/* Submit a START command asynchronously. */
-+static int sd_submit_start(struct scsi_disk *sdkp, u8 cmd[], u8 cmd_len)
-+{
-+ struct scsi_device *sdev = sdkp->device;
-+ struct request_queue *q = sdev->request_queue;
-+ struct request *req;
-+ struct scsi_cmnd *scmd;
-+
-+ req = scsi_alloc_request(q, REQ_OP_DRV_IN, BLK_MQ_REQ_PM);
-+ if (IS_ERR(req))
-+ return PTR_ERR(req);
-+
-+ scmd = blk_mq_rq_to_pdu(req);
-+ scmd->cmd_len = cmd_len;
-+ memcpy(scmd->cmnd, cmd, cmd_len);
-+ scmd->allowed = sdkp->max_retries;
-+ req->timeout = SD_TIMEOUT;
-+ req->rq_flags |= RQF_PM | RQF_QUIET;
-+ req->end_io = sd_start_done;
-+ blk_execute_rq_nowait(req, /*at_head=*/true);
-+
-+ return 0;
-+}
-+
- static int sd_start_stop_device(struct scsi_disk *sdkp, int start)
- {
- unsigned char cmd[6] = { START_STOP }; /* START_VALID */
-- struct scsi_sense_hdr sshdr;
- struct scsi_device *sdp = sdkp->device;
-- int res;
-
- if (start)
- cmd[4] |= 1; /* START */
-@@ -3579,23 +3638,10 @@ static int sd_start_stop_device(struct s
- if (!scsi_device_online(sdp))
- return -ENODEV;
-
-- res = scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL, &sshdr,
-- SD_TIMEOUT, sdkp->max_retries, 0, RQF_PM, NULL);
-- if (res) {
-- sd_print_result(sdkp, "Start/Stop Unit failed", res);
-- if (res > 0 && scsi_sense_valid(&sshdr)) {
-- sd_print_sense_hdr(sdkp, &sshdr);
-- /* 0x3a is medium not present */
-- if (sshdr.asc == 0x3a)
-- res = 0;
-- }
-- }
-+ /* Wait until processing of sense data has finished. */
-+ flush_work(&sdkp->start_done_work);
-
-- /* SCSI error codes must not go to the generic layer */
-- if (res)
-- return -EIO;
--
-- return 0;
-+ return sd_submit_start(sdkp, cmd, sizeof(cmd));
- }
-
- /*
-@@ -3622,6 +3668,8 @@ static void sd_shutdown(struct device *d
- sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n");
- sd_start_stop_device(sdkp, 0);
- }
-+
-+ flush_work(&sdkp->start_done_work);
- }
-
- static int sd_suspend_common(struct device *dev, bool ignore_stop_errors)
---- a/drivers/scsi/sd.h
-+++ b/drivers/scsi/sd.h
-@@ -130,6 +130,11 @@ struct scsi_disk {
- unsigned urswrz : 1;
- unsigned security : 1;
- unsigned ignore_medium_access_errors : 1;
-+
-+ int start_result;
-+ u32 start_sense_len;
-+ u8 start_sense_buffer[SCSI_SENSE_BUFFERSIZE];
-+ struct work_struct start_done_work;
- };
- #define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
-
+++ /dev/null
-From 0296bea01cfa6526be6bd2d16dc83b4e7f1af91f Mon Sep 17 00:00:00 2001
-From: Li Nan <linan122@huawei.com>
-Date: Fri, 8 Dec 2023 16:23:35 +0800
-Subject: scsi: sd: Unregister device if device_add_disk() failed in sd_probe()
-
-From: Li Nan <linan122@huawei.com>
-
-commit 0296bea01cfa6526be6bd2d16dc83b4e7f1af91f upstream.
-
-"if device_add() succeeds, you should call device_del() when you want to
-get rid of it."
-
-In sd_probe(), device_add_disk() fails when device_add() has already
-succeeded, so change put_device() to device_unregister() to ensure device
-resources are released.
-
-Fixes: 2a7a891f4c40 ("scsi: sd: Add error handling support for add_disk()")
-Signed-off-by: Li Nan <linan122@huawei.com>
-Link: https://lore.kernel.org/r/20231208082335.1754205-1-linan666@huaweicloud.com
-Reviewed-by: Bart Van Assche <bvanassche@acm.org>
-Reviewed-by: Yu Kuai <yukuai3@huawei.com>
-Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/sd.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -3419,7 +3419,7 @@ static int sd_probe(struct device *dev)
-
- error = device_add(&sdkp->disk_dev);
- if (error) {
-- put_device(&sdkp->disk_dev);
-+ device_unregister(&sdkp->disk_dev);
- put_disk(gd);
- goto out;
- }
+++ /dev/null
-From stable+bounces-244972-greg=kroah.com@vger.kernel.org Sat May 9 21:39:01 2026
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 9 May 2026 12:08:48 -0400
-Subject: sd: rename the scsi_disk.dev field
-To: stable@vger.kernel.org
-Cc: Christoph Hellwig <hch@lst.de>, Bart Van Assche <bvanassche@acm.org>, Chaitanya Kulkarni <kch@nvidia.com>, Ming Lei <ming.lei@redhat.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Jens Axboe <axboe@kernel.dk>, Sasha Levin <sashal@kernel.org>
-Message-ID: <20260509160849.3584738-3-sashal@kernel.org>
-
-From: Christoph Hellwig <hch@lst.de>
-
-[ Upstream commit fad45c3007a18064da759b4dba35eb722bc64e97 ]
-
-dev is very hard to grep for. Give the field a more descriptive name and
-documents its purpose.
-
-Signed-off-by: Christoph Hellwig <hch@lst.de>
-Reviewed-by: Bart Van Assche <bvanassche@acm.org>
-Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
-Reviewed-by: Ming Lei <ming.lei@redhat.com>
-Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
-Link: https://lore.kernel.org/r/20220308055200.735835-5-hch@lst.de
-Signed-off-by: Jens Axboe <axboe@kernel.dk>
-Stable-dep-of: 1e111c4b3a72 ("scsi: sd: fix missing put_disk() when device_add(&disk_dev) fails")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/scsi/sd.c | 22 +++++++++++-----------
- drivers/scsi/sd.h | 9 +++++++--
- 2 files changed, 18 insertions(+), 13 deletions(-)
-
---- a/drivers/scsi/sd.c
-+++ b/drivers/scsi/sd.c
-@@ -674,7 +674,7 @@ static struct scsi_disk *scsi_disk_get(s
- if (disk->private_data) {
- sdkp = scsi_disk(disk);
- if (scsi_device_get(sdkp->device) == 0)
-- get_device(&sdkp->dev);
-+ get_device(&sdkp->disk_dev);
- else
- sdkp = NULL;
- }
-@@ -687,7 +687,7 @@ static void scsi_disk_put(struct scsi_di
- struct scsi_device *sdev = sdkp->device;
-
- mutex_lock(&sd_ref_mutex);
-- put_device(&sdkp->dev);
-+ put_device(&sdkp->disk_dev);
- scsi_device_put(sdev);
- mutex_unlock(&sd_ref_mutex);
- }
-@@ -3412,14 +3412,14 @@ static int sd_probe(struct device *dev)
- SD_MOD_TIMEOUT);
- }
-
-- device_initialize(&sdkp->dev);
-- sdkp->dev.parent = get_device(dev);
-- sdkp->dev.class = &sd_disk_class;
-- dev_set_name(&sdkp->dev, "%s", dev_name(dev));
-+ device_initialize(&sdkp->disk_dev);
-+ sdkp->disk_dev.parent = get_device(dev);
-+ sdkp->disk_dev.class = &sd_disk_class;
-+ dev_set_name(&sdkp->disk_dev, "%s", dev_name(dev));
-
-- error = device_add(&sdkp->dev);
-+ error = device_add(&sdkp->disk_dev);
- if (error) {
-- put_device(&sdkp->dev);
-+ put_device(&sdkp->disk_dev);
- goto out;
- }
-
-@@ -3461,7 +3461,7 @@ static int sd_probe(struct device *dev)
-
- error = device_add_disk(dev, gd, NULL);
- if (error) {
-- put_device(&sdkp->dev);
-+ put_device(&sdkp->disk_dev);
- goto out;
- }
-
-@@ -3511,7 +3511,7 @@ static int sd_remove(struct device *dev)
- sdkp = dev_get_drvdata(dev);
- scsi_autopm_get_device(sdkp->device);
-
-- device_del(&sdkp->dev);
-+ device_del(&sdkp->disk_dev);
- del_gendisk(sdkp->disk);
- sd_shutdown(dev);
-
-@@ -3519,7 +3519,7 @@ static int sd_remove(struct device *dev)
-
- mutex_lock(&sd_ref_mutex);
- dev_set_drvdata(dev, NULL);
-- put_device(&sdkp->dev);
-+ put_device(&sdkp->disk_dev);
- mutex_unlock(&sd_ref_mutex);
-
- return 0;
---- a/drivers/scsi/sd.h
-+++ b/drivers/scsi/sd.h
-@@ -70,7 +70,12 @@ enum {
- struct scsi_disk {
- struct scsi_driver *driver; /* always &sd_template */
- struct scsi_device *device;
-- struct device dev;
-+
-+ /*
-+ * disk_dev is used to show attributes in /sys/class/scsi_disk/,
-+ * but otherwise not really needed. Do not use for refcounting.
-+ */
-+ struct device disk_dev;
- struct gendisk *disk;
- struct opal_dev *opal_dev;
- #ifdef CONFIG_BLK_DEV_ZONED
-@@ -126,7 +131,7 @@ struct scsi_disk {
- unsigned security : 1;
- unsigned ignore_medium_access_errors : 1;
- };
--#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev)
-+#define to_scsi_disk(obj) container_of(obj, struct scsi_disk, disk_dev)
-
- static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
- {
crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch
-scsi-core-pm-rely-on-the-device-driver-core-for-async-power-management.patch
-scsi-sd-add-error-handling-support-for-add_disk.patch
-sd-rename-the-scsi_disk.dev-field.patch
-scsi-sd-fix-missing-put_disk-when-device_add-disk_dev-fails.patch
alsa-aloop-fix-peer-runtime-uaf-during-format-change-stop.patch
printk-add-print_hex_dump_devel.patch
crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
media-rc-ttusbir-fix-inverted-error-logic.patch
batman-adv-tp_meter-fix-tp_vars-reference-leak-in-receiver-shutdown.patch
media-rc-igorplugusb-fix-control-request-setup-packet.patch
-scsi-core-suppress-a-kernel-doc-warning.patch
-scsi-core-declare-scsi_scan_type-static.patch
-scsi-sd-rework-asynchronous-resume-support.patch
-scsi-sd-revert-rework-asynchronous-resume-support.patch
nvme-fix-discard-support-without-oncs.patch
-ata-libata-scsi-avoid-deadlock-on-rescan-after-device-resume.patch
-ata-scsi-do-not-issue-start-stop-unit-on-resume.patch
-ata-libata-scsi-link-ata-port-and-scsi-device.patch
-scsi-sd-unregister-device-if-device_add_disk-failed-in-sd_probe.patch