--- /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
+@@ -3729,7 +3729,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;
+@@ -3737,8 +3737,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 77098e4bea37af51d3962efa88a5af2ea5e1ac57 Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 10 May 2026 11:31:03 +0200
+Subject: batman-adv: tp_meter: fix tp_vars reference leak in receiver shutdown
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 77098e4bea37af51d3962efa88a5af2ea5e1ac57 upstream.
+
+The receiver shutdown timer handler, batadv_tp_receiver_shutdown(), is
+responsible for releasing the tp_vars reference it holds. However, the
+existing logic for coordinating this release with batadv_tp_stop_all() was
+flawed.
+
+timer_shutdown_sync() guarantees the timer will not fire again after it
+returns, but it returns non-zero only when the timer was pending at the
+time of the call. If the timer had already expired (and
+batadv_tp_stop_all() would unsucessfully try to rearm itself),
+batadv_tp_stop_all() skips its batadv_tp_vars_put(), and
+batadv_tp_receiver_shutdown() fails to put its own reference as well.
+
+Fix this by introducing a new atomic variable receiving that is set to 1
+when the receiver is initialized and cleared atomically with atomic_xchg()
+by whichever side claims it first. Only the side that observes the
+transition from 1 to 0 is responsible for releasing the tp_vars timer
+reference, eliminating the uncertainty.
+
+Cc: stable@kernel.org
+Fixes: 3d3cf6a7314a ("batman-adv: stop tp_meter sessions during mesh teardown")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/tp_meter.c | 13 +++++++++++--
+ net/batman-adv/types.h | 3 +++
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+--- a/net/batman-adv/tp_meter.c
++++ b/net/batman-adv/tp_meter.c
+@@ -8,6 +8,7 @@
+ #include "main.h"
+
+ #include <linux/atomic.h>
++#include <linux/bug.h>
+ #include <linux/build_bug.h>
+ #include <linux/byteorder/generic.h>
+ #include <linux/cache.h>
+@@ -1157,6 +1158,9 @@ static void batadv_tp_receiver_shutdown(
+ spin_unlock_bh(&tp_vars->unacked_lock);
+
+ /* drop reference of timer */
++ if (WARN_ON(atomic_xchg(&tp_vars->receiving, 0) != 1))
++ return;
++
+ batadv_tp_vars_put(tp_vars);
+ }
+
+@@ -1375,6 +1379,7 @@ batadv_tp_init_recv(struct batadv_priv *
+
+ ether_addr_copy(tp_vars->other_end, icmp->orig);
+ tp_vars->role = BATADV_TP_RECEIVER;
++ atomic_set(&tp_vars->receiving, 1);
+ memcpy(tp_vars->session, icmp->session, sizeof(tp_vars->session));
+ tp_vars->last_recv = BATADV_TP_FIRST_SEQ;
+ tp_vars->bat_priv = bat_priv;
+@@ -1547,8 +1552,12 @@ void batadv_tp_stop_all(struct batadv_pr
+ break;
+ case BATADV_TP_RECEIVER:
+ batadv_tp_list_detach(tp_var);
+- if (timer_shutdown_sync(&tp_var->timer))
+- batadv_tp_vars_put(tp_var);
++ timer_shutdown_sync(&tp_var->timer);
++
++ if (atomic_xchg(&tp_var->receiving, 0) != 1)
++ break;
++
++ batadv_tp_vars_put(tp_var);
+ break;
+ }
+
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -1400,6 +1400,9 @@ struct batadv_tp_vars {
+ /** @sending: sending binary semaphore: 1 if sending, 0 is not */
+ atomic_t sending;
+
++ /** @receiving: receiving binary semaphore: 1 if receiving, 0 is not */
++ atomic_t receiving;
++
+ /** @reason: reason for a stopped session */
+ enum batadv_tp_meter_reason reason;
+
--- /dev/null
+From 344e6a4f7ff4756b9b3f75e0eb7eaec297e35540 Mon Sep 17 00:00:00 2001
+From: Thorsten Blum <thorsten.blum@linux.dev>
+Date: Wed, 11 Mar 2026 16:56:49 +0100
+Subject: crypto: nx - fix context leak in nx842_crypto_free_ctx
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+commit 344e6a4f7ff4756b9b3f75e0eb7eaec297e35540 upstream.
+
+Since the scomp conversion, nx842_crypto_alloc_ctx() allocates the
+context separately, but nx842_crypto_free_ctx() never releases it. Add
+the missing kfree(ctx) to nx842_crypto_free_ctx(), and reuse
+nx842_crypto_free_ctx() in the allocation error path.
+
+Fixes: 980b5705f4e7 ("crypto: nx - Migrate to scomp API")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -115,10 +115,7 @@ void *nx842_crypto_alloc_ctx(struct nx84
+ ctx->sbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
+ ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
+ if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) {
+- kfree(ctx->wmem);
+- free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER);
+- free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER);
+- kfree(ctx);
++ nx842_crypto_free_ctx(ctx);
+ return ERR_PTR(-ENOMEM);
+ }
+
+@@ -133,6 +130,7 @@ void nx842_crypto_free_ctx(void *p)
+ kfree(ctx->wmem);
+ free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER);
+ free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER);
++ kfree(ctx);
+ }
+ EXPORT_SYMBOL_GPL(nx842_crypto_free_ctx);
+
--- /dev/null
+From 171022c7d594c133a45f92357a2a91475edabe20 Mon Sep 17 00:00:00 2001
+From: Henri A <contact@henrialfonso.com>
+Date: Wed, 20 May 2026 10:25:44 -0400
+Subject: media: rc: igorplugusb: fix control request setup packet
+
+From: Henri A <contact@henrialfonso.com>
+
+commit 171022c7d594c133a45f92357a2a91475edabe20 upstream.
+
+Commit eac69475b01f ("media: rc: igorplugusb: heed coherency
+rules") changed the control request storage from an embedded struct to
+an allocated pointer so it can obey DMA coherency rules.
+
+However, the driver still passes &ir->request to usb_fill_control_urb().
+That points the URB setup packet at the pointer field itself rather than
+at the allocated struct usb_ctrlrequest.
+
+USB core then interprets pointer bytes as the setup packet. This can
+produce an invalid bRequestType and trigger the control direction warning
+reported by syzbot:
+
+ usb 2-1: BOGUS control dir, pipe 80003580 doesn't match bRequestType 0
+
+Pass ir->request itself as the setup packet.
+
+Fixes: eac69475b01f ("media: rc: igorplugusb: heed coherency rules")
+Reported-by: syzbot+11f0e4f957c7c3bf3d51@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=11f0e4f957c7c3bf3d51
+Tested-by: syzbot+11f0e4f957c7c3bf3d51@syzkaller.appspotmail.com
+Cc: stable@vger.kernel.org
+Assisted-by: Codex:GPT-5.5
+Signed-off-by: Henri A <contact@henrialfonso.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/rc/igorplugusb.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/rc/igorplugusb.c
++++ b/drivers/media/rc/igorplugusb.c
+@@ -183,7 +183,7 @@ static int igorplugusb_probe(struct usb_
+ goto fail;
+
+ usb_fill_control_urb(ir->urb, udev,
+- usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request,
++ usb_rcvctrlpipe(udev, 0), (uint8_t *)ir->request,
+ ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir);
+
+ usb_make_path(udev, ir->phys, sizeof(ir->phys));
--- /dev/null
+From 646ebdd3105809d84ed04aa9e92e47e89cc44502 Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Fri, 10 Apr 2026 23:03:09 +0200
+Subject: media: rc: ttusbir: fix inverted error logic
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit 646ebdd3105809d84ed04aa9e92e47e89cc44502 upstream.
+
+We have to report ENOMEM if no buffer is allocated.
+Typo dropped a "!". Restore it.
+
+Fixes: 50acaad3d202 ("media: rc: ttusbir: respect DMA coherency rules")
+Cc: stable@vger.kernel.org
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/media/rc/ttusbir.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/media/rc/ttusbir.c
++++ b/drivers/media/rc/ttusbir.c
+@@ -193,7 +193,7 @@ static int ttusbir_probe(struct usb_inte
+ tt = kzalloc(sizeof(*tt), GFP_KERNEL);
+ buffer = kzalloc(5, GFP_KERNEL);
+ rc = rc_allocate_device(RC_DRIVER_IR_RAW);
+- if (!tt || !rc || buffer) {
++ if (!tt || !rc || !buffer) {
+ ret = -ENOMEM;
+ goto out;
+ }
--- /dev/null
+From d3205ab75e99a47539ec91ef85ba488f4ddfeaa9 Mon Sep 17 00:00:00 2001
+From: Keith Busch <kbusch@kernel.org>
+Date: Mon, 3 Apr 2023 13:09:25 -0700
+Subject: nvme: fix discard support without oncs
+
+From: Keith Busch <kbusch@kernel.org>
+
+commit d3205ab75e99a47539ec91ef85ba488f4ddfeaa9 upstream.
+
+The device can report discard support without setting the ONCS DSM bit.
+When not set, the driver clears max_discard_size expecting it to be set
+later. We don't know the size until we have the namespace format,
+though, so setting it is deferred until configuring one, but the driver
+was abandoning the discard settings due to that initial clearing.
+
+Move the max_discard_size calculation above the check for a '0' discard
+size.
+
+Fixes: 1a86924e4f46475 ("nvme: fix interpretation of DMRSL")
+Reported-by: Laurence Oberman <loberman@redhat.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Reviewed-by: Niklas Cassel <niklas.cassel@wdc.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Tested-by: Laurence Oberman <loberman@redhat.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvme/host/core.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/nvme/host/core.c
++++ b/drivers/nvme/host/core.c
+@@ -1718,6 +1718,9 @@ static void nvme_config_discard(struct g
+ struct request_queue *queue = disk->queue;
+ u32 size = queue_logical_block_size(queue);
+
++ if (ctrl->dmrsl && ctrl->dmrsl <= nvme_sect_to_lba(ns, UINT_MAX))
++ ctrl->max_discard_sectors = nvme_lba_to_sect(ns, ctrl->dmrsl);
++
+ if (ctrl->max_discard_sectors == 0) {
+ blk_queue_flag_clear(QUEUE_FLAG_DISCARD, queue);
+ return;
+@@ -1736,9 +1739,6 @@ static void nvme_config_discard(struct g
+ if (blk_queue_flag_test_and_set(QUEUE_FLAG_DISCARD, queue))
+ return;
+
+- if (ctrl->dmrsl && ctrl->dmrsl <= nvme_sect_to_lba(ns, UINT_MAX))
+- ctrl->max_discard_sectors = nvme_lba_to_sect(ns, ctrl->dmrsl);
+-
+ blk_queue_max_discard_sectors(queue, ctrl->max_discard_sectors);
+ blk_queue_max_discard_segments(queue, ctrl->max_discard_segments);
+
--- /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 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 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
+@@ -3421,7 +3421,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;
+ }
fbdev-vt8500lcdfb-fix-dma_free_coherent-cpu_addr-parameter.patch
apparmor-validate-default-dfa-states-are-in-bounds.patch
x86-cpu-amd-move-the-zen3-btc_no-detection-to-the-zen3-init-function.patch
+crypto-nx-fix-context-leak-in-nx842_crypto_free_ctx.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
+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