diff options
| author | Igor Pylypiv <ipylypiv@google.com> | 2026-04-12 18:36:37 +0300 |
|---|---|---|
| committer | Niklas Cassel <cassel@kernel.org> | 2026-04-12 20:57:59 +0300 |
| commit | 8ebf408e7d463eee02c348a3c8277b95587b710d (patch) | |
| tree | 60fafc44e78a8c0c320526cdf47633b09a6ddac8 | |
| parent | 797f629856c56595e138d69b8b0701ffe3cece21 (diff) | |
| download | linux-8ebf408e7d463eee02c348a3c8277b95587b710d.tar.xz | |
ata: libata-scsi: fix requeue of deferred ATA PASS-THROUGH commands
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>
| -rw-r--r-- | drivers/ata/libata-scsi.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b15830bedd3a..f44612e269a4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -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); } } |
