]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ata: libata-scsi: fix requeue of deferred ATA PASS-THROUGH commands
authorIgor Pylypiv <ipylypiv@google.com>
Sun, 12 Apr 2026 15:36:37 +0000 (08:36 -0700)
committerNiklas Cassel <cassel@kernel.org>
Sun, 12 Apr 2026 17:57:59 +0000 (19:57 +0200)
Commit 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
introduced ata_scsi_requeue_deferred_qc() to handle commands deferred
during resets or NCQ failures. This deferral logic completed commands
with DID_SOFT_ERROR to trigger a retry in the SCSI mid-layer.

However, DID_SOFT_ERROR is subject to scsi_cmd_retry_allowed() checks.
ATA PASS-THROUGH commands sent via SG_IO ioctl have scmd->allowed set
to zero. This causes the mid-layer to fail the command immediately
instead of retrying, even though the command was never actually issued
to the hardware.

Switch to DID_REQUEUE to ensure these commands are inserted back into
the request queue regardless of retry limits.

Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Igor Pylypiv <ipylypiv@google.com>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
drivers/ata/libata-scsi.c

index b15830bedd3a9e730f4bfe50e44695223adaf975..f44612e269a4d6ea943825f6f491e2014c7c6bd3 100644 (file)
@@ -1695,12 +1695,12 @@ void ata_scsi_requeue_deferred_qc(struct ata_port *ap)
        /*
         * If we have a deferred qc when a reset occurs or NCQ commands fail,
         * do not try to be smart about what to do with this deferred command
-        * and simply retry it by completing it with DID_SOFT_ERROR.
+        * and simply requeue it by completing it with DID_REQUEUE.
         */
        if (qc) {
                ap->deferred_qc = NULL;
                cancel_work(&ap->deferred_qc_work);
-               ata_scsi_qc_done(qc, true, DID_SOFT_ERROR << 16);
+               ata_scsi_qc_done(qc, true, DID_REQUEUE << 16);
        }
 }